Commit e4a89040 authored by Adam Radford's avatar Adam Radford Committed by Linus Torvalds

[PATCH] 3ware driver update for 2.5.6-pre3

 - Fix bug in tw_aen_complete() where aen's could be lost.
   Fix tw_aen_drain_queue() to display useful info at init.
   Set tw_host->max_id for 12 port cards.
   Add ioctl support for raw command packet post from userspace
   with sglist fragments (parameter and io).
 - Fix read capacity to under report by 1 sector to fix get
   last sector ioctl.
 - Fix bug where more AEN codes weren't coming out during
   driver initialization.
   Improved handling of PCI aborts.
 - Fix bug in tw_findcards() where AEN code could be lost.
   Increase timeout in tw_aen_drain_queue() to 30 seconds.
 - Re-write raw command post with data ioctl method.
   Remove raid5 bounce buffers for raid5 for 6XXX for kernel 2.5
   Add tw_map/unmap_scsi_sg/single_data() for kernel 2.5
   Replace io_request_lock with host_lock for kernel 2.5
   Set max_cmd_len to 16 for 3dm for kernel 2.5
 - Set host->max_sectors back up to 256.
 - Modified pci parity error handling/clearing from config space
   during initialization.
 - Better handling of request sense opcode and sense information
   for failed commands.  Add tw_decode_sense().
   Replace all mdelay()'s with scsi_sleep().
 - Revert mdelay's and scsi_sleep's, this caused problems on
   some SMP systems.
 - Add pci_set_dma_mask(), rewrite kmalloc()/virt_to_bus() to
   pci_alloc/free_consistent().
parent fef4227e
This diff is collapsed.
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
Arnaldo Carvalho de Melo <acme@conectiva.com.br> Arnaldo Carvalho de Melo <acme@conectiva.com.br>
Brad Strand <linux@3ware.com> Brad Strand <linux@3ware.com>
Copyright (C) 1999-2001 3ware Inc. Copyright (C) 1999-2002 3ware Inc.
Kernel compatablity By: Andre Hedrick <andre@suse.com> Kernel compatablity By: Andre Hedrick <andre@suse.com>
Non-Copyright (C) 2000 Andre Hedrick <andre@suse.com> Non-Copyright (C) 2000 Andre Hedrick <andre@suse.com>
...@@ -62,7 +62,7 @@ ...@@ -62,7 +62,7 @@
static char *tw_aen_string[] = { static char *tw_aen_string[] = {
"AEN queue empty", // 0x000 "AEN queue empty", // 0x000
"Soft reset occurred", // 0x001 "Soft reset occurred", // 0x001
"Mirorr degraded: Unit #", // 0x002 "Unit degraded: Unit #", // 0x002
"Controller error", // 0x003 "Controller error", // 0x003
"Rebuild failed: Unit #", // 0x004 "Rebuild failed: Unit #", // 0x004
"Rebuild complete: Unit #", // 0x005 "Rebuild complete: Unit #", // 0x005
...@@ -90,10 +90,36 @@ static char *tw_aen_string[] = { ...@@ -90,10 +90,36 @@ static char *tw_aen_string[] = {
"DCB unsupported version: Port #", // 0x028 "DCB unsupported version: Port #", // 0x028
"Verify started: Unit #", // 0x029 "Verify started: Unit #", // 0x029
"Verify failed: Port #", // 0x02A "Verify failed: Port #", // 0x02A
"Verify complete: Unit #" // 0x02B "Verify complete: Unit #", // 0x02B
"Overwrote bad sector during rebuild: Port #", //0x2C
"Encountered bad sector during rebuild: Port #" //0x2D
}; };
#define TW_AEN_STRING_MAX 0x02C #define TW_AEN_STRING_MAX 0x02E
/*
Sense key lookup table
Format: ESDC/flags,SenseKey,AdditionalSenseCode,AdditionalSenseCodeQualifier
*/
static unsigned char tw_sense_table[][4] =
{
/* Codes for newer firmware */
// ATA Error SCSI Error
{0x01, 0x03, 0x13, 0x00}, // Address mark not found Address mark not found for data field
{0x04, 0x0b, 0x00, 0x00}, // Aborted command Aborted command
{0x10, 0x0b, 0x14, 0x00}, // ID not found Recorded entity not found
{0x40, 0x03, 0x11, 0x00}, // Uncorrectable ECC error Unrecovered read error
{0x61, 0x04, 0x00, 0x00}, // Device fault Hardware error
{0x84, 0x0b, 0x47, 0x00}, // Data CRC error SCSI parity error
{0xd0, 0x0b, 0x00, 0x00}, // Device busy Aborted command
{0xd1, 0x0b, 0x00, 0x00}, // Device busy Aborted command
/* Codes for older firmware */
// 3ware Error SCSI Error
{0x09, 0x0b, 0x00, 0x00}, // Unrecovered disk error Aborted command
{0x37, 0x0b, 0x04, 0x00}, // Unit offline Logical unit not ready
{0x51, 0x0b, 0x00, 0x00} // Unspecified Aborted command
};
/* Control register bit definitions */ /* Control register bit definitions */
#define TW_CONTROL_CLEAR_HOST_INTERRUPT 0x00080000 #define TW_CONTROL_CLEAR_HOST_INTERRUPT 0x00080000
...@@ -108,6 +134,7 @@ static char *tw_aen_string[] = { ...@@ -108,6 +134,7 @@ static char *tw_aen_string[] = {
#define TW_CONTROL_DISABLE_INTERRUPTS 0x00000040 #define TW_CONTROL_DISABLE_INTERRUPTS 0x00000040
#define TW_CONTROL_ISSUE_HOST_INTERRUPT 0x00000020 #define TW_CONTROL_ISSUE_HOST_INTERRUPT 0x00000020
#define TW_CONTROL_CLEAR_PARITY_ERROR 0x00800000 #define TW_CONTROL_CLEAR_PARITY_ERROR 0x00800000
#define TW_CONTROL_CLEAR_PCI_ABORT 0x00100000
/* Status register bit definitions */ /* Status register bit definitions */
#define TW_STATUS_MAJOR_VERSION_MASK 0xF0000000 #define TW_STATUS_MAJOR_VERSION_MASK 0xF0000000
...@@ -140,6 +167,7 @@ static char *tw_aen_string[] = { ...@@ -140,6 +167,7 @@ static char *tw_aen_string[] = {
#define TW_DEVICE_ID2 (0x1001) /* 7000 series controller */ #define TW_DEVICE_ID2 (0x1001) /* 7000 series controller */
#define TW_NUMDEVICES 2 #define TW_NUMDEVICES 2
#define TW_PCI_CLEAR_PARITY_ERRORS 0xc100 #define TW_PCI_CLEAR_PARITY_ERRORS 0xc100
#define TW_PCI_CLEAR_PCI_ABORT 0x2000
/* Command packet opcodes */ /* Command packet opcodes */
#define TW_OP_NOP 0x0 #define TW_OP_NOP 0x0
...@@ -153,6 +181,7 @@ static char *tw_aen_string[] = { ...@@ -153,6 +181,7 @@ static char *tw_aen_string[] = {
#define TW_OP_AEN_LISTEN 0x1c #define TW_OP_AEN_LISTEN 0x1c
#define TW_CMD_PACKET 0x1d #define TW_CMD_PACKET 0x1d
#define TW_ATA_PASSTHRU 0x1e #define TW_ATA_PASSTHRU 0x1e
#define TW_CMD_PACKET_WITH_DATA 0x1f
/* Asynchronous Event Notification (AEN) Codes */ /* Asynchronous Event Notification (AEN) Codes */
#define TW_AEN_QUEUE_EMPTY 0x0000 #define TW_AEN_QUEUE_EMPTY 0x0000
...@@ -169,7 +198,8 @@ static char *tw_aen_string[] = { ...@@ -169,7 +198,8 @@ static char *tw_aen_string[] = {
#define TW_AEN_SBUF_FAIL 0x0024 #define TW_AEN_SBUF_FAIL 0x0024
/* Misc defines */ /* Misc defines */
#define TW_ALIGNMENT 0x200 /* 16 D-WORDS */ #define TW_ALIGNMENT_6000 64 /* 64 bytes */
#define TW_ALIGNMENT_7000 4 /* 4 bytes */
#define TW_MAX_UNITS 16 #define TW_MAX_UNITS 16
#define TW_COMMAND_ALIGNMENT_MASK 0x1ff #define TW_COMMAND_ALIGNMENT_MASK 0x1ff
#define TW_INIT_MESSAGE_CREDITS 0x100 #define TW_INIT_MESSAGE_CREDITS 0x100
...@@ -179,7 +209,6 @@ static char *tw_aen_string[] = { ...@@ -179,7 +209,6 @@ static char *tw_aen_string[] = {
#define TW_ATA_PASS_SGL_MAX 60 #define TW_ATA_PASS_SGL_MAX 60
#define TW_MAX_PASSTHRU_BYTES 4096 #define TW_MAX_PASSTHRU_BYTES 4096
#define TW_Q_LENGTH 256 #define TW_Q_LENGTH 256
#define TW_MAX_BOUNCEBUF 16
#define TW_Q_START 0 #define TW_Q_START 0
#define TW_MAX_SLOT 32 #define TW_MAX_SLOT 32
#define TW_MAX_PCI_BUSES 255 #define TW_MAX_PCI_BUSES 255
...@@ -191,12 +220,9 @@ static char *tw_aen_string[] = { ...@@ -191,12 +220,9 @@ static char *tw_aen_string[] = {
#define TW_MAX_AEN_TRIES 100 #define TW_MAX_AEN_TRIES 100
#define TW_UNIT_ONLINE 1 #define TW_UNIT_ONLINE 1
#define TW_IN_INTR 1 #define TW_IN_INTR 1
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,7)
#define TW_MAX_SECTORS 256 #define TW_MAX_SECTORS 256
#else
#define TW_MAX_SECTORS 128
#endif
#define TW_AEN_WAIT_TIME 1000 #define TW_AEN_WAIT_TIME 1000
#define TW_IOCTL_WAIT_TIME (1 * HZ) /* 1 second */
/* Macros */ /* Macros */
#define TW_STATUS_ERRORS(x) \ #define TW_STATUS_ERRORS(x) \
...@@ -262,7 +288,6 @@ typedef struct TW_Command { ...@@ -262,7 +288,6 @@ typedef struct TW_Command {
} TW_Command; } TW_Command;
typedef struct TAG_TW_Ioctl { typedef struct TAG_TW_Ioctl {
int buffer;
unsigned char opcode; unsigned char opcode;
unsigned short table_id; unsigned short table_id;
unsigned char parameter_id; unsigned char parameter_id;
...@@ -345,11 +370,8 @@ typedef struct TAG_TW_Device_Extension { ...@@ -345,11 +370,8 @@ typedef struct TAG_TW_Device_Extension {
TW_Registers registers; TW_Registers registers;
u32 *alignment_virtual_address[TW_Q_LENGTH]; u32 *alignment_virtual_address[TW_Q_LENGTH];
u32 alignment_physical_address[TW_Q_LENGTH]; u32 alignment_physical_address[TW_Q_LENGTH];
u32 *bounce_buffer[TW_Q_LENGTH];
int is_unit_present[TW_MAX_UNITS]; int is_unit_present[TW_MAX_UNITS];
int is_raid_five[TW_MAX_UNITS];
int num_units; int num_units;
int num_raid_five;
u32 *command_packet_virtual_address[TW_Q_LENGTH]; u32 *command_packet_virtual_address[TW_Q_LENGTH];
u32 command_packet_physical_address[TW_Q_LENGTH]; u32 command_packet_physical_address[TW_Q_LENGTH];
struct pci_dev *tw_pci_dev; struct pci_dev *tw_pci_dev;
...@@ -381,22 +403,24 @@ typedef struct TAG_TW_Device_Extension { ...@@ -381,22 +403,24 @@ typedef struct TAG_TW_Device_Extension {
unsigned char aen_head; unsigned char aen_head;
unsigned char aen_tail; unsigned char aen_tail;
long flags; /* long req'd for set_bit --RR */ long flags; /* long req'd for set_bit --RR */
char *ioctl_data[TW_Q_LENGTH];
} TW_Device_Extension; } TW_Device_Extension;
/* Function prototypes */ /* Function prototypes */
int tw_aen_complete(TW_Device_Extension *tw_dev, int request_id); int tw_aen_complete(TW_Device_Extension *tw_dev, int request_id);
int tw_aen_drain_queue(TW_Device_Extension *tw_dev); int tw_aen_drain_queue(TW_Device_Extension *tw_dev);
int tw_aen_read_queue(TW_Device_Extension *tw_dev, int request_id); int tw_aen_read_queue(TW_Device_Extension *tw_dev, int request_id);
int tw_allocate_memory(TW_Device_Extension *tw_dev, int request_id, int size, int which); int tw_allocate_memory(TW_Device_Extension *tw_dev, int size, int which);
int tw_check_bits(u32 status_reg_value); int tw_check_bits(u32 status_reg_value);
int tw_check_errors(TW_Device_Extension *tw_dev); int tw_check_errors(TW_Device_Extension *tw_dev);
void tw_clear_attention_interrupt(TW_Device_Extension *tw_dev); void tw_clear_attention_interrupt(TW_Device_Extension *tw_dev);
void tw_clear_host_interrupt(TW_Device_Extension *tw_dev); void tw_clear_host_interrupt(TW_Device_Extension *tw_dev);
void tw_decode_bits(TW_Device_Extension *tw_dev, u32 status_reg_value); void tw_decode_bits(TW_Device_Extension *tw_dev, u32 status_reg_value);
void tw_decode_error(TW_Device_Extension *tw_dev, unsigned char status, unsigned char flags, unsigned char unit); void tw_decode_sense(TW_Device_Extension *tw_dev, int request_id, int fill_sense);
void tw_disable_interrupts(TW_Device_Extension *tw_dev); void tw_disable_interrupts(TW_Device_Extension *tw_dev);
int tw_empty_response_que(TW_Device_Extension *tw_dev); int tw_empty_response_que(TW_Device_Extension *tw_dev);
void tw_enable_interrupts(TW_Device_Extension *tw_dev); void tw_enable_interrupts(TW_Device_Extension *tw_dev);
void tw_enable_and_clear_interrupts(TW_Device_Extension *tw_dev);
int tw_findcards(Scsi_Host_Template *tw_host); int tw_findcards(Scsi_Host_Template *tw_host);
void tw_free_device_extension(TW_Device_Extension *tw_dev); void tw_free_device_extension(TW_Device_Extension *tw_dev);
int tw_initconnection(TW_Device_Extension *tw_dev, int message_credits); int tw_initconnection(TW_Device_Extension *tw_dev, int message_credits);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment