3ware 9000 driver update for 2.6.13-rc6-git10
adam radford
maintainerPATCH 1/1 3ware 9000 driver update for 2.6.13-rc6-git10
The attached patch updates the driver for the 3ware 9000 series to do the following:
- Add support for 9550SX controllers.
Signed-off-by Adam Radford <[email protected]>
James, Please apply
drivers/scsi/3w-9xxx.c +47 -8
@@ -59,6 +59,7 @@Fix 'handled=1' ISR usage, remove bogus IRQ check. Remove un-needed eh_abort handler. Add support for embedded firmware error strings. +2.26.02.003 - Add support for 9550SX controllers. */ #include <linux/module.h>
@@ -81,7 +82,7 @@#include "3w-9xxx.h" /* Globals */ -#define TW_DRIVER_VERSION "2.26.02.002" +#define TW_DRIVER_VERSION "2.26.02.003"static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT ];static unsigned int twa_device_extension_count;static int twa_major =-1 ;
@@ -891,11 +892,6 @@writel (TW_CONTROL_CLEAR_QUEUE_ERROR ,TW_CONTROL_REG_ADDR (tw_dev)); } -if (status_reg_value &TW_STATUS_SBUF_WRITE_ERROR ) { -TW_PRINTK (tw_dev->host,TW_DRIVER ,0xf ,"SBUF Write Error: clearing" ); -writel (TW_CONTROL_CLEAR_SBUF_WRITE_ERROR ,TW_CONTROL_REG_ADDR (tw_dev)); - } -if (status_reg_value &TW_STATUS_MICROCONTROLLER_ERROR ) {if (tw_dev->reset_print ==0 ) {TW_PRINTK (tw_dev->host,TW_DRIVER ,0x10 ,"Microcontroller Error: clearing" );
@@ -929,6 +925,36 @@return retval; }/* End twa_empty_response_queue() */ +/* This function will clear the pchip/response queue on 9550SX */ +static int twa_empty_response_queue_large (TW_Device_Extension *tw_dev) +{ +u32 status_reg_value, response_que_value; +int count =0 , retval =1 ; + +if (tw_dev->tw_pci_dev->device ==PCI_DEVICE_ID_3WARE_9550SX ) { + status_reg_value =readl (TW_STATUS_REG_ADDR (tw_dev)); + +while (((status_reg_value &TW_STATUS_RESPONSE_QUEUE_EMPTY ) ==0 ) && (count <TW_MAX_RESPONSE_DRAIN )) { + response_que_value =readl (TW_RESPONSE_QUEUE_REG_ADDR_LARGE (tw_dev)); +if ((response_que_value &TW_9550SX_DRAIN_COMPLETED ) ==TW_9550SX_DRAIN_COMPLETED ) { +/* P-chip settle time */ +msleep (500 ); + retval =0 ; + goto out; + } + status_reg_value =readl (TW_STATUS_REG_ADDR (tw_dev)); + count++; + } +if (count ==TW_MAX_RESPONSE_DRAIN ) + goto out; + + retval =0 ; + }else + retval =0 ; +out: +return retval; +}/* End twa_empty_response_queue_large() */ +/* This function passes sense keys from firmware to scsi layer */ static int twa_fill_sense (TW_Device_Extension *tw_dev,int request_id,int copy_sense,int print_host) {
@@ -1612,8 +1638,16 @@int tries =0 , retval =1 , flashed =0 , do_soft_reset = soft_reset;while (tries <TW_MAX_RESET_TRIES ) { -if (do_soft_reset) +if (do_soft_reset) {TW_SOFT_RESET (tw_dev); +/* Clear pchip/response queue on 9550SX */ +if (twa_empty_response_queue_large (tw_dev)) { +TW_PRINTK (tw_dev->host,TW_DRIVER ,0x36 ,"Response queue (large) empty failed during reset sequence" ); + do_soft_reset =1 ; + tries++; +continue ; + } + }/* Make sure controller is in a good state */ if (twa_poll_status (tw_dev,TW_STATUS_MICROCONTROLLER_READY | (do_soft_reset ==1 ?TW_STATUS_ATTENTION_INTERRUPT :0 ),60 )) {
@@ -2016,7 +2050,10 @@ goto out_free_device_extension; } - mem_addr =pci_resource_start (pdev,1 ); +if (pdev->device ==PCI_DEVICE_ID_3WARE_9000 ) + mem_addr =pci_resource_start (pdev,1 ); +else + mem_addr =pci_resource_start (pdev,2 );/* Save base address */ tw_dev->base_addr =ioremap (mem_addr,PAGE_SIZE );
@@ -2130,6 +2167,8 @@static struct pci_device_id twa_pci_tbl[]__devinitdata = { {PCI_VENDOR_ID_3WARE ,PCI_DEVICE_ID_3WARE_9000 ,PCI_ANY_ID ,PCI_ANY_ID ,0 ,0 ,0 }, + {PCI_VENDOR_ID_3WARE ,PCI_DEVICE_ID_3WARE_9550SX , +PCI_ANY_ID ,PCI_ANY_ID ,0 ,0 ,0 }, { } };MODULE_DEVICE_TABLE (pci, twa_pci_tbl);
drivers/scsi/3w-9xxx.h +10 -7
@@ -267,7 +267,6 @@#define TW_CONTROL_CLEAR_PARITY_ERROR 0x00800000#define TW_CONTROL_CLEAR_QUEUE_ERROR 0x00400000#define TW_CONTROL_CLEAR_PCI_ABORT 0x00100000 -#define TW_CONTROL_CLEAR_SBUF_WRITE_ERROR 0x00000008/* Status register bit definitions */ #define TW_STATUS_MAJOR_VERSION_MASK 0xF0000000
@@ -285,9 +284,8 @@#define TW_STATUS_MICROCONTROLLER_READY 0x00002000#define TW_STATUS_COMMAND_QUEUE_EMPTY 0x00001000#define TW_STATUS_EXPECTED_BITS 0x00002000 -#define TW_STATUS_UNEXPECTED_BITS 0x00F00008 -#define TW_STATUS_SBUF_WRITE_ERROR 0x00000008 -#define TW_STATUS_VALID_INTERRUPT 0x00DF0008 +#define TW_STATUS_UNEXPECTED_BITS 0x00F00000 +#define TW_STATUS_VALID_INTERRUPT 0x00DF0000/* RESPONSE QUEUE BIT DEFINITIONS */ #define TW_RESPONSE_ID_MASK 0x00000FF0
@@ -324,9 +322,9 @@/* Compatibility defines */ #define TW_9000_ARCH_ID 0x5 -#define TW_CURRENT_DRIVER_SRL 28 -#define TW_CURRENT_DRIVER_BUILD 9 -#define TW_CURRENT_DRIVER_BRANCH 4 +#define TW_CURRENT_DRIVER_SRL 30 +#define TW_CURRENT_DRIVER_BUILD 80 +#define TW_CURRENT_DRIVER_BRANCH 0/* Phase defines */ #define TW_PHASE_INITIAL 0
@@ -334,6 +332,7 @@#define TW_PHASE_SGLIST 2/* Misc defines */ +#define TW_9550SX_DRAIN_COMPLETED 0xFFFF#define TW_SECTOR_SIZE 512#define TW_ALIGNMENT_9000 4/* 4 bytes */ #define TW_ALIGNMENT_9000_SGL 0x3
@@ -417,6 +416,9 @@#ifndef PCI_DEVICE_ID_3WARE_9000 #define PCI_DEVICE_ID_3WARE_9000 0x1002#endif +#ifndef PCI_DEVICE_ID_3WARE_9550SX +#define PCI_DEVICE_ID_3WARE_9550SX 0x1003 +#endif /* Bitmask macros to eliminate bitfields */
@@ -443,6 +445,7 @@#define TW_STATUS_REG_ADDR (x) ((unsigned char __iomem *)x->base_addr + 0x4)#define TW_COMMAND_QUEUE_REG_ADDR (x) (sizeof(dma_addr_t) > 4 ? ((unsigned char __iomem *)x->base_addr + 0x20) : ((unsigned char __iomem *)x->base_addr + 0x8))#define TW_RESPONSE_QUEUE_REG_ADDR (x) ((unsigned char __iomem *)x->base_addr + 0xC) +#define TW_RESPONSE_QUEUE_REG_ADDR_LARGE (x) ((unsigned char __iomem *)x->base_addr + 0x30)#define TW_CLEAR_ALL_INTERRUPTS (x) (writel(TW_STATUS_VALID_INTERRUPT, TW_CONTROL_REG_ADDR(x)))#define TW_CLEAR_ATTENTION_INTERRUPT (x) (writel(TW_CONTROL_CLEAR_ATTENTION_INTERRUPT, TW_CONTROL_REG_ADDR(x)))#define TW_CLEAR_HOST_INTERRUPT (x) (writel(TW_CONTROL_CLEAR_HOST_INTERRUPT, TW_CONTROL_REG_ADDR(x)))