Commit ba3f139f authored by Adam Radford's avatar Adam Radford Committed by James Bottomley

[PATCH] 3ware 5/6/7/8000 driver v1.26.02.000

- Remove deprecated SCSI_IOCTL_SEND_COMMAND interface.
- Remove deprecated /proc/scsi/3w-xxxx interface.
- Convert entire driver to pci_driver format.
- Remove all mdelays, replace w/msleep to fix possible watchdog
  timer issues.
- Make all register accesses macros.
- Remove all prototypes from header file, reorder functions to
  eliminate all prototypes but one.
- Add sysfs 'queue_depth' setting attribute.
- Add sysfs 'stats' attribute.
- Fix spinlocks everywhere, remove tw_lock spinlock.
- Remove all bitfields, add bitmask access macros.
- Remove un-needed scsi_eh_abort entrypoint.  Controller does not
  support aborting invididual IO's, scsi_eh_reset sufficient.
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent d933c291
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -180,7 +180,6 @@ static unsigned char tw_sense_table[][4] = ...@@ -180,7 +180,6 @@ static unsigned char tw_sense_table[][4] =
#define TW_OP_AEN_LISTEN 0x1c #define TW_OP_AEN_LISTEN 0x1c
#define TW_OP_FLUSH_CACHE 0x0e #define TW_OP_FLUSH_CACHE 0x0e
#define TW_CMD_PACKET 0x1d #define TW_CMD_PACKET 0x1d
#define TW_ATA_PASSTHRU 0x1e
#define TW_CMD_PACKET_WITH_DATA 0x1f #define TW_CMD_PACKET_WITH_DATA 0x1f
/* Asynchronous Event Notification (AEN) Codes */ /* Asynchronous Event Notification (AEN) Codes */
...@@ -197,6 +196,11 @@ static unsigned char tw_sense_table[][4] = ...@@ -197,6 +196,11 @@ static unsigned char tw_sense_table[][4] =
#define TW_AEN_SMART_FAIL 0x000F #define TW_AEN_SMART_FAIL 0x000F
#define TW_AEN_SBUF_FAIL 0x0024 #define TW_AEN_SBUF_FAIL 0x0024
/* Phase defines */
#define TW_PHASE_INITIAL 0
#define TW_PHASE_SINGLE 1
#define TW_PHASE_SGLIST 2
/* Misc defines */ /* Misc defines */
#define TW_ALIGNMENT_6000 64 /* 64 bytes */ #define TW_ALIGNMENT_6000 64 /* 64 bytes */
#define TW_ALIGNMENT_7000 4 /* 4 bytes */ #define TW_ALIGNMENT_7000 4 /* 4 bytes */
...@@ -207,7 +211,6 @@ static unsigned char tw_sense_table[][4] = ...@@ -207,7 +211,6 @@ static unsigned char tw_sense_table[][4] =
#define TW_POLL_MAX_RETRIES 20000 #define TW_POLL_MAX_RETRIES 20000
#define TW_MAX_SGL_LENGTH 62 #define TW_MAX_SGL_LENGTH 62
#define TW_ATA_PASS_SGL_MAX 60 #define TW_ATA_PASS_SGL_MAX 60
#define TW_MAX_PASSTHRU_BYTES 4096
#define TW_Q_LENGTH 256 #define TW_Q_LENGTH 256
#define TW_Q_START 0 #define TW_Q_START 0
#define TW_MAX_SLOT 32 #define TW_MAX_SLOT 32
...@@ -221,7 +224,7 @@ static unsigned char tw_sense_table[][4] = ...@@ -221,7 +224,7 @@ static unsigned char tw_sense_table[][4] =
#define TW_IOCTL 0x80 #define TW_IOCTL 0x80
#define TW_UNIT_ONLINE 1 #define TW_UNIT_ONLINE 1
#define TW_IN_INTR 1 #define TW_IN_INTR 1
#define TW_IN_IOCTL 2 #define TW_IN_RESET 2
#define TW_IN_CHRDEV_IOCTL 3 #define TW_IN_CHRDEV_IOCTL 3
#define TW_MAX_SECTORS 256 #define TW_MAX_SECTORS 256
#define TW_AEN_WAIT_TIME 1000 #define TW_AEN_WAIT_TIME 1000
...@@ -231,8 +234,41 @@ static unsigned char tw_sense_table[][4] = ...@@ -231,8 +234,41 @@ static unsigned char tw_sense_table[][4] =
#define TW_IOCTL_TIMEOUT 25 /* 25 seconds */ #define TW_IOCTL_TIMEOUT 25 /* 25 seconds */
#define TW_IOCTL_CHRDEV_TIMEOUT 60 /* 60 seconds */ #define TW_IOCTL_CHRDEV_TIMEOUT 60 /* 60 seconds */
#define TW_IOCTL_CHRDEV_FREE -1 #define TW_IOCTL_CHRDEV_FREE -1
#define TW_DMA_MASK DMA_32BIT_MASK
#define TW_MAX_CDB_LEN 16
/* Bitmask macros to eliminate bitfields */
/* opcode: 5, sgloffset: 3 */
#define TW_OPSGL_IN(x,y) ((x << 5) | (y & 0x1f))
#define TW_SGL_OUT(x) ((x >> 5) & 0x7)
/* reserved_1: 4, response_id: 8, reserved_2: 20 */
#define TW_RESID_OUT(x) ((x >> 4) & 0xff)
/* unit: 4, host_id: 4 */
#define TW_UNITHOST_IN(x,y) ((x << 4) | ( y & 0xf))
#define TW_UNIT_OUT(x) (x & 0xf)
/* Macros */ /* Macros */
#define TW_CONTROL_REG_ADDR(x) (x->base_addr)
#define TW_STATUS_REG_ADDR(x) (x->base_addr + 0x4)
#define TW_COMMAND_QUEUE_REG_ADDR(x) (x->base_addr + 0x8)
#define TW_RESPONSE_QUEUE_REG_ADDR(x) (x->base_addr + 0xC)
#define TW_CLEAR_ALL_INTERRUPTS(x) (outl(TW_STATUS_VALID_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
#define TW_CLEAR_ATTENTION_INTERRUPT(x) (outl(TW_CONTROL_CLEAR_ATTENTION_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
#define TW_CLEAR_HOST_INTERRUPT(x) (outl(TW_CONTROL_CLEAR_HOST_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
#define TW_DISABLE_INTERRUPTS(x) (outl(TW_CONTROL_DISABLE_INTERRUPTS, TW_CONTROL_REG_ADDR(x)))
#define TW_ENABLE_AND_CLEAR_INTERRUPTS(x) (outl(TW_CONTROL_CLEAR_ATTENTION_INTERRUPT | TW_CONTROL_UNMASK_RESPONSE_INTERRUPT | TW_CONTROL_ENABLE_INTERRUPTS, TW_CONTROL_REG_ADDR(x)))
#define TW_MASK_COMMAND_INTERRUPT(x) (outl(TW_CONTROL_MASK_COMMAND_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
#define TW_UNMASK_COMMAND_INTERRUPT(x) (outl(TW_CONTROL_UNMASK_COMMAND_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
#define TW_SOFT_RESET(x) (outl(TW_CONTROL_ISSUE_SOFT_RESET | \
TW_CONTROL_CLEAR_HOST_INTERRUPT | \
TW_CONTROL_CLEAR_ATTENTION_INTERRUPT | \
TW_CONTROL_MASK_COMMAND_INTERRUPT | \
TW_CONTROL_MASK_RESPONSE_INTERRUPT | \
TW_CONTROL_CLEAR_ERROR_STATUS | \
TW_CONTROL_DISABLE_INTERRUPTS, TW_CONTROL_REG_ADDR(x)))
#define TW_STATUS_ERRORS(x) \ #define TW_STATUS_ERRORS(x) \
(((x & TW_STATUS_PCI_ABORT) || \ (((x & TW_STATUS_PCI_ABORT) || \
(x & TW_STATUS_PCI_PARITY_ERROR) || \ (x & TW_STATUS_PCI_PARITY_ERROR) || \
...@@ -258,17 +294,10 @@ typedef unsigned char TW_Sector[512]; ...@@ -258,17 +294,10 @@ typedef unsigned char TW_Sector[512];
/* Command Packet */ /* Command Packet */
typedef struct TW_Command { typedef struct TW_Command {
/* First DWORD */ unsigned char opcode__sgloffset;
struct {
unsigned char opcode:5;
unsigned char sgl_offset:3;
} byte0;
unsigned char size; unsigned char size;
unsigned char request_id; unsigned char request_id;
struct { unsigned char unit__hostid;
unsigned char unit:4;
unsigned char host_id:4;
} byte3;
/* Second DWORD */ /* Second DWORD */
unsigned char status; unsigned char status;
unsigned char flags; unsigned char flags;
...@@ -328,29 +357,10 @@ typedef struct { ...@@ -328,29 +357,10 @@ typedef struct {
/* Response queue */ /* Response queue */
typedef union TAG_TW_Response_Queue { typedef union TAG_TW_Response_Queue {
struct { u32 response_id;
u32 undefined_1: 4;
u32 response_id: 8;
u32 undefined_2: 20;
} u;
u32 value; u32 value;
} TW_Response_Queue; } TW_Response_Queue;
typedef struct TAG_TW_Registers {
u32 base_addr;
u32 control_reg_addr;
u32 status_reg_addr;
u32 command_que_addr;
u32 response_que_addr;
} TW_Registers;
typedef struct TAG_TW_Info {
char *buffer;
int length;
int offset;
int position;
} TW_Info;
typedef int TW_Cmd_State; typedef int TW_Cmd_State;
#define TW_S_INITIAL 0x1 /* Initial state */ #define TW_S_INITIAL 0x1 /* Initial state */
...@@ -364,16 +374,10 @@ typedef int TW_Cmd_State; ...@@ -364,16 +374,10 @@ typedef int TW_Cmd_State;
/* Command header for ATA pass-thru */ /* Command header for ATA pass-thru */
typedef struct TAG_TW_Passthru typedef struct TAG_TW_Passthru
{ {
struct { unsigned char opcode__sgloffset;
unsigned char opcode:5;
unsigned char sgloff:3;
} byte0;
unsigned char size; unsigned char size;
unsigned char request_id; unsigned char request_id;
struct { unsigned char aport__hostid;
unsigned char aport:4;
unsigned char host_id:4;
} byte3;
unsigned char status; unsigned char status;
unsigned char flags; unsigned char flags;
unsigned short param; unsigned short param;
...@@ -389,7 +393,7 @@ typedef struct TAG_TW_Passthru ...@@ -389,7 +393,7 @@ typedef struct TAG_TW_Passthru
} TW_Passthru; } TW_Passthru;
typedef struct TAG_TW_Device_Extension { typedef struct TAG_TW_Device_Extension {
TW_Registers registers; u32 base_addr;
unsigned long *alignment_virtual_address[TW_Q_LENGTH]; unsigned long *alignment_virtual_address[TW_Q_LENGTH];
unsigned long alignment_physical_address[TW_Q_LENGTH]; unsigned long alignment_physical_address[TW_Q_LENGTH];
int is_unit_present[TW_MAX_UNITS]; int is_unit_present[TW_MAX_UNITS];
...@@ -397,11 +401,10 @@ typedef struct TAG_TW_Device_Extension { ...@@ -397,11 +401,10 @@ typedef struct TAG_TW_Device_Extension {
unsigned long *command_packet_virtual_address[TW_Q_LENGTH]; unsigned long *command_packet_virtual_address[TW_Q_LENGTH];
unsigned long command_packet_physical_address[TW_Q_LENGTH]; unsigned long command_packet_physical_address[TW_Q_LENGTH];
struct pci_dev *tw_pci_dev; struct pci_dev *tw_pci_dev;
Scsi_Cmnd *srb[TW_Q_LENGTH]; struct scsi_cmnd *srb[TW_Q_LENGTH];
unsigned char free_queue[TW_Q_LENGTH]; unsigned char free_queue[TW_Q_LENGTH];
unsigned char free_head; unsigned char free_head;
unsigned char free_tail; unsigned char free_tail;
unsigned char free_wrap;
unsigned char pending_queue[TW_Q_LENGTH]; unsigned char pending_queue[TW_Q_LENGTH];
unsigned char pending_head; unsigned char pending_head;
unsigned char pending_tail; unsigned char pending_tail;
...@@ -413,83 +416,21 @@ typedef struct TAG_TW_Device_Extension { ...@@ -413,83 +416,21 @@ typedef struct TAG_TW_Device_Extension {
u32 max_pending_request_count; u32 max_pending_request_count;
u32 max_sgl_entries; u32 max_sgl_entries;
u32 sgl_entries; u32 sgl_entries;
u32 num_aborts;
u32 num_resets; u32 num_resets;
u32 sector_count; u32 sector_count;
u32 max_sector_count; u32 max_sector_count;
u32 aen_count; u32 aen_count;
struct Scsi_Host *host; struct Scsi_Host *host;
spinlock_t tw_lock;
struct semaphore ioctl_sem; struct semaphore ioctl_sem;
int ioctl_size[TW_Q_LENGTH];
unsigned short aen_queue[TW_Q_LENGTH]; unsigned short aen_queue[TW_Q_LENGTH];
unsigned char aen_head; unsigned char aen_head;
unsigned char aen_tail; unsigned char aen_tail;
volatile long flags; /* long req'd for set_bit --RR */ volatile long flags; /* long req'd for set_bit --RR */
unsigned long *ioctl_data[TW_Q_LENGTH];
int reset_print; int reset_print;
char online;
volatile int chrdev_request_id; volatile int chrdev_request_id;
wait_queue_head_t ioctl_wqueue; wait_queue_head_t ioctl_wqueue;
} TW_Device_Extension; } TW_Device_Extension;
#pragma pack() #pragma pack()
/* Function prototypes */
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_read_queue(TW_Device_Extension *tw_dev, int request_id);
int tw_allocate_memory(TW_Device_Extension *tw_dev, int size, int which);
int tw_check_bits(u32 status_reg_value);
int tw_check_errors(TW_Device_Extension *tw_dev);
void tw_clear_all_interrupts(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);
int tw_decode_bits(TW_Device_Extension *tw_dev, u32 status_reg_value, int print_host);
int 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_empty_response_que(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);
void tw_free_device_extension(TW_Device_Extension *tw_dev);
int tw_initconnection(TW_Device_Extension *tw_dev, int message_credits);
int tw_initialize_device_extension(TW_Device_Extension *tw_dev);
int tw_initialize_units(TW_Device_Extension *tw_dev);
int tw_ioctl(TW_Device_Extension *tw_dev, int request_id);
int tw_ioctl_complete(TW_Device_Extension *tw_dev, int request_id);
void tw_mask_command_interrupt(TW_Device_Extension *tw_dev);
int tw_poll_status(TW_Device_Extension *tw_dev, u32 flag, int seconds);
int tw_poll_status_gone(TW_Device_Extension *tw_dev, u32 flag, int seconds);
int tw_post_command_packet(TW_Device_Extension *tw_dev, int request_id);
int tw_reset_device_extension(TW_Device_Extension *tw_dev);
int tw_reset_sequence(TW_Device_Extension *tw_dev);
int tw_scsi_biosparam(struct scsi_device *sdev, struct block_device *bdev,
sector_t capacity, int geom[]);
int tw_scsi_detect(Scsi_Host_Template *tw_host);
int tw_scsi_eh_abort(Scsi_Cmnd *SCpnt);
int tw_scsi_eh_reset(Scsi_Cmnd *SCpnt);
int tw_scsi_queue(Scsi_Cmnd *cmd, void (*done) (Scsi_Cmnd *));
int tw_scsi_release(struct Scsi_Host *tw_host);
int tw_scsiop_inquiry(TW_Device_Extension *tw_dev, int request_id);
int tw_scsiop_inquiry_complete(TW_Device_Extension *tw_dev, int request_id);
int tw_scsiop_mode_sense(TW_Device_Extension *tw_dev, int request_id);
int tw_scsiop_mode_sense_complete(TW_Device_Extension *tw_dev, int request_id);
int tw_scsiop_read_capacity(TW_Device_Extension *tw_dev, int request_id);
int tw_scsiop_read_capacity_complete(TW_Device_Extension *tw_dev, int request_id);
int tw_scsiop_read_write(TW_Device_Extension *tw_dev, int request_id);
int tw_scsiop_request_sense(TW_Device_Extension *tw_dev, int request_id);
int tw_scsiop_synchronize_cache(TW_Device_Extension *tw_dev, int request_id);
int tw_scsiop_test_unit_ready(TW_Device_Extension *tw_dev, int request_id);
int tw_scsiop_test_unit_ready_complete(TW_Device_Extension *tw_dev, int request_id);
int tw_setfeature(TW_Device_Extension *tw_dev, int parm, int param_size,
unsigned char *val);
int tw_setup_irq(TW_Device_Extension *tw_dev);
int tw_shutdown_device(TW_Device_Extension *tw_dev);
int tw_slave_configure(Scsi_Device *SDptr);
void tw_soft_reset(TW_Device_Extension *tw_dev);
int tw_state_request_finish(TW_Device_Extension *tw_dev,int request_id);
int tw_state_request_start(TW_Device_Extension *tw_dev, int *request_id);
void tw_unmask_command_interrupt(TW_Device_Extension *tw_dev);
#endif /* _3W_XXXX_H */ #endif /* _3W_XXXX_H */
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