diff options
Diffstat (limited to 'drivers/scsi/stex.c')
-rw-r--r-- | drivers/scsi/stex.c | 130 |
1 files changed, 84 insertions, 46 deletions
diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c index 185c270bb043..ba6bcdaf2a6a 100644 --- a/drivers/scsi/stex.c +++ b/drivers/scsi/stex.c | |||
@@ -11,8 +11,6 @@ | |||
11 | * Written By: | 11 | * Written By: |
12 | * Ed Lin <promise_linux@promise.com> | 12 | * Ed Lin <promise_linux@promise.com> |
13 | * | 13 | * |
14 | * Version: 3.0.0.1 | ||
15 | * | ||
16 | */ | 14 | */ |
17 | 15 | ||
18 | #include <linux/init.h> | 16 | #include <linux/init.h> |
@@ -37,9 +35,9 @@ | |||
37 | #include <scsi/scsi_tcq.h> | 35 | #include <scsi/scsi_tcq.h> |
38 | 36 | ||
39 | #define DRV_NAME "stex" | 37 | #define DRV_NAME "stex" |
40 | #define ST_DRIVER_VERSION "3.0.0.1" | 38 | #define ST_DRIVER_VERSION "3.1.0.1" |
41 | #define ST_VER_MAJOR 3 | 39 | #define ST_VER_MAJOR 3 |
42 | #define ST_VER_MINOR 0 | 40 | #define ST_VER_MINOR 1 |
43 | #define ST_OEM 0 | 41 | #define ST_OEM 0 |
44 | #define ST_BUILD_VER 1 | 42 | #define ST_BUILD_VER 1 |
45 | 43 | ||
@@ -76,8 +74,10 @@ enum { | |||
76 | MU_STATE_STARTED = 4, | 74 | MU_STATE_STARTED = 4, |
77 | MU_STATE_RESETTING = 5, | 75 | MU_STATE_RESETTING = 5, |
78 | 76 | ||
79 | MU_MAX_DELAY_TIME = 240000, | 77 | MU_MAX_DELAY = 120, |
80 | MU_HANDSHAKE_SIGNATURE = 0x55aaaa55, | 78 | MU_HANDSHAKE_SIGNATURE = 0x55aaaa55, |
79 | MU_HANDSHAKE_SIGNATURE_HALF = 0x5a5a0000, | ||
80 | MU_HARD_RESET_WAIT = 30000, | ||
81 | HMU_PARTNER_TYPE = 2, | 81 | HMU_PARTNER_TYPE = 2, |
82 | 82 | ||
83 | /* firmware returned values */ | 83 | /* firmware returned values */ |
@@ -120,7 +120,8 @@ enum { | |||
120 | 120 | ||
121 | st_shasta = 0, | 121 | st_shasta = 0, |
122 | st_vsc = 1, | 122 | st_vsc = 1, |
123 | st_yosemite = 2, | 123 | st_vsc1 = 2, |
124 | st_yosemite = 3, | ||
124 | 125 | ||
125 | PASSTHRU_REQ_TYPE = 0x00000001, | 126 | PASSTHRU_REQ_TYPE = 0x00000001, |
126 | PASSTHRU_REQ_NO_WAKEUP = 0x00000100, | 127 | PASSTHRU_REQ_NO_WAKEUP = 0x00000100, |
@@ -150,6 +151,8 @@ enum { | |||
150 | MGT_CMD_SIGNATURE = 0xba, | 151 | MGT_CMD_SIGNATURE = 0xba, |
151 | 152 | ||
152 | INQUIRY_EVPD = 0x01, | 153 | INQUIRY_EVPD = 0x01, |
154 | |||
155 | ST_ADDITIONAL_MEM = 0x200000, | ||
153 | }; | 156 | }; |
154 | 157 | ||
155 | /* SCSI inquiry data */ | 158 | /* SCSI inquiry data */ |
@@ -211,7 +214,9 @@ struct handshake_frame { | |||
211 | __le32 partner_ver_minor; | 214 | __le32 partner_ver_minor; |
212 | __le32 partner_ver_oem; | 215 | __le32 partner_ver_oem; |
213 | __le32 partner_ver_build; | 216 | __le32 partner_ver_build; |
214 | u32 reserved1[4]; | 217 | __le32 extra_offset; /* NEW */ |
218 | __le32 extra_size; /* NEW */ | ||
219 | u32 reserved1[2]; | ||
215 | }; | 220 | }; |
216 | 221 | ||
217 | struct req_msg { | 222 | struct req_msg { |
@@ -302,6 +307,7 @@ struct st_hba { | |||
302 | void __iomem *mmio_base; /* iomapped PCI memory space */ | 307 | void __iomem *mmio_base; /* iomapped PCI memory space */ |
303 | void *dma_mem; | 308 | void *dma_mem; |
304 | dma_addr_t dma_handle; | 309 | dma_addr_t dma_handle; |
310 | size_t dma_size; | ||
305 | 311 | ||
306 | struct Scsi_Host *host; | 312 | struct Scsi_Host *host; |
307 | struct pci_dev *pdev; | 313 | struct pci_dev *pdev; |
@@ -507,6 +513,7 @@ static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb) | |||
507 | size_t count = sizeof(struct st_frame); | 513 | size_t count = sizeof(struct st_frame); |
508 | 514 | ||
509 | p = hba->copy_buffer; | 515 | p = hba->copy_buffer; |
516 | stex_internal_copy(ccb->cmd, p, &count, ccb->sg_count, ST_FROM_CMD); | ||
510 | memset(p->base, 0, sizeof(u32)*6); | 517 | memset(p->base, 0, sizeof(u32)*6); |
511 | *(unsigned long *)(p->base) = pci_resource_start(hba->pdev, 0); | 518 | *(unsigned long *)(p->base) = pci_resource_start(hba->pdev, 0); |
512 | p->rom_addr = 0; | 519 | p->rom_addr = 0; |
@@ -901,27 +908,34 @@ static int stex_handshake(struct st_hba *hba) | |||
901 | void __iomem *base = hba->mmio_base; | 908 | void __iomem *base = hba->mmio_base; |
902 | struct handshake_frame *h; | 909 | struct handshake_frame *h; |
903 | dma_addr_t status_phys; | 910 | dma_addr_t status_phys; |
904 | int i; | 911 | u32 data; |
912 | unsigned long before; | ||
905 | 913 | ||
906 | if (readl(base + OMR0) != MU_HANDSHAKE_SIGNATURE) { | 914 | if (readl(base + OMR0) != MU_HANDSHAKE_SIGNATURE) { |
907 | writel(MU_INBOUND_DOORBELL_HANDSHAKE, base + IDBL); | 915 | writel(MU_INBOUND_DOORBELL_HANDSHAKE, base + IDBL); |
908 | readl(base + IDBL); | 916 | readl(base + IDBL); |
909 | for (i = 0; readl(base + OMR0) != MU_HANDSHAKE_SIGNATURE | 917 | before = jiffies; |
910 | && i < MU_MAX_DELAY_TIME; i++) { | 918 | while (readl(base + OMR0) != MU_HANDSHAKE_SIGNATURE) { |
919 | if (time_after(jiffies, before + MU_MAX_DELAY * HZ)) { | ||
920 | printk(KERN_ERR DRV_NAME | ||
921 | "(%s): no handshake signature\n", | ||
922 | pci_name(hba->pdev)); | ||
923 | return -1; | ||
924 | } | ||
911 | rmb(); | 925 | rmb(); |
912 | msleep(1); | 926 | msleep(1); |
913 | } | 927 | } |
914 | |||
915 | if (i == MU_MAX_DELAY_TIME) { | ||
916 | printk(KERN_ERR DRV_NAME | ||
917 | "(%s): no handshake signature\n", | ||
918 | pci_name(hba->pdev)); | ||
919 | return -1; | ||
920 | } | ||
921 | } | 928 | } |
922 | 929 | ||
923 | udelay(10); | 930 | udelay(10); |
924 | 931 | ||
932 | data = readl(base + OMR1); | ||
933 | if ((data & 0xffff0000) == MU_HANDSHAKE_SIGNATURE_HALF) { | ||
934 | data &= 0x0000ffff; | ||
935 | if (hba->host->can_queue > data) | ||
936 | hba->host->can_queue = data; | ||
937 | } | ||
938 | |||
925 | h = (struct handshake_frame *)(hba->dma_mem + MU_REQ_BUFFER_SIZE); | 939 | h = (struct handshake_frame *)(hba->dma_mem + MU_REQ_BUFFER_SIZE); |
926 | h->rb_phy = cpu_to_le32(hba->dma_handle); | 940 | h->rb_phy = cpu_to_le32(hba->dma_handle); |
927 | h->rb_phy_hi = cpu_to_le32((hba->dma_handle >> 16) >> 16); | 941 | h->rb_phy_hi = cpu_to_le32((hba->dma_handle >> 16) >> 16); |
@@ -931,6 +945,11 @@ static int stex_handshake(struct st_hba *hba) | |||
931 | h->status_cnt = cpu_to_le16(MU_STATUS_COUNT); | 945 | h->status_cnt = cpu_to_le16(MU_STATUS_COUNT); |
932 | stex_gettime(&h->hosttime); | 946 | stex_gettime(&h->hosttime); |
933 | h->partner_type = HMU_PARTNER_TYPE; | 947 | h->partner_type = HMU_PARTNER_TYPE; |
948 | if (hba->dma_size > STEX_BUFFER_SIZE) { | ||
949 | h->extra_offset = cpu_to_le32(STEX_BUFFER_SIZE); | ||
950 | h->extra_size = cpu_to_le32(ST_ADDITIONAL_MEM); | ||
951 | } else | ||
952 | h->extra_offset = h->extra_size = 0; | ||
934 | 953 | ||
935 | status_phys = hba->dma_handle + MU_REQ_BUFFER_SIZE; | 954 | status_phys = hba->dma_handle + MU_REQ_BUFFER_SIZE; |
936 | writel(status_phys, base + IMR0); | 955 | writel(status_phys, base + IMR0); |
@@ -944,19 +963,18 @@ static int stex_handshake(struct st_hba *hba) | |||
944 | readl(base + IDBL); /* flush */ | 963 | readl(base + IDBL); /* flush */ |
945 | 964 | ||
946 | udelay(10); | 965 | udelay(10); |
947 | for (i = 0; readl(base + OMR0) != MU_HANDSHAKE_SIGNATURE | 966 | before = jiffies; |
948 | && i < MU_MAX_DELAY_TIME; i++) { | 967 | while (readl(base + OMR0) != MU_HANDSHAKE_SIGNATURE) { |
968 | if (time_after(jiffies, before + MU_MAX_DELAY * HZ)) { | ||
969 | printk(KERN_ERR DRV_NAME | ||
970 | "(%s): no signature after handshake frame\n", | ||
971 | pci_name(hba->pdev)); | ||
972 | return -1; | ||
973 | } | ||
949 | rmb(); | 974 | rmb(); |
950 | msleep(1); | 975 | msleep(1); |
951 | } | 976 | } |
952 | 977 | ||
953 | if (i == MU_MAX_DELAY_TIME) { | ||
954 | printk(KERN_ERR DRV_NAME | ||
955 | "(%s): no signature after handshake frame\n", | ||
956 | pci_name(hba->pdev)); | ||
957 | return -1; | ||
958 | } | ||
959 | |||
960 | writel(0, base + IMR0); | 978 | writel(0, base + IMR0); |
961 | readl(base + IMR0); | 979 | readl(base + IMR0); |
962 | writel(0, base + OMR0); | 980 | writel(0, base + OMR0); |
@@ -1038,9 +1056,9 @@ static void stex_hard_reset(struct st_hba *hba) | |||
1038 | pci_bctl &= ~PCI_BRIDGE_CTL_BUS_RESET; | 1056 | pci_bctl &= ~PCI_BRIDGE_CTL_BUS_RESET; |
1039 | pci_write_config_byte(bus->self, PCI_BRIDGE_CONTROL, pci_bctl); | 1057 | pci_write_config_byte(bus->self, PCI_BRIDGE_CONTROL, pci_bctl); |
1040 | 1058 | ||
1041 | for (i = 0; i < MU_MAX_DELAY_TIME; i++) { | 1059 | for (i = 0; i < MU_HARD_RESET_WAIT; i++) { |
1042 | pci_read_config_word(hba->pdev, PCI_COMMAND, &pci_cmd); | 1060 | pci_read_config_word(hba->pdev, PCI_COMMAND, &pci_cmd); |
1043 | if (pci_cmd & PCI_COMMAND_MASTER) | 1061 | if (pci_cmd != 0xffff && (pci_cmd & PCI_COMMAND_MASTER)) |
1044 | break; | 1062 | break; |
1045 | msleep(1); | 1063 | msleep(1); |
1046 | } | 1064 | } |
@@ -1100,18 +1118,18 @@ static int stex_reset(struct scsi_cmnd *cmd) | |||
1100 | static int stex_biosparam(struct scsi_device *sdev, | 1118 | static int stex_biosparam(struct scsi_device *sdev, |
1101 | struct block_device *bdev, sector_t capacity, int geom[]) | 1119 | struct block_device *bdev, sector_t capacity, int geom[]) |
1102 | { | 1120 | { |
1103 | int heads = 255, sectors = 63, cylinders; | 1121 | int heads = 255, sectors = 63; |
1104 | 1122 | ||
1105 | if (capacity < 0x200000) { | 1123 | if (capacity < 0x200000) { |
1106 | heads = 64; | 1124 | heads = 64; |
1107 | sectors = 32; | 1125 | sectors = 32; |
1108 | } | 1126 | } |
1109 | 1127 | ||
1110 | cylinders = sector_div(capacity, heads * sectors); | 1128 | sector_div(capacity, heads * sectors); |
1111 | 1129 | ||
1112 | geom[0] = heads; | 1130 | geom[0] = heads; |
1113 | geom[1] = sectors; | 1131 | geom[1] = sectors; |
1114 | geom[2] = cylinders; | 1132 | geom[2] = capacity; |
1115 | 1133 | ||
1116 | return 0; | 1134 | return 0; |
1117 | } | 1135 | } |
@@ -1193,8 +1211,13 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1193 | goto out_iounmap; | 1211 | goto out_iounmap; |
1194 | } | 1212 | } |
1195 | 1213 | ||
1214 | hba->cardtype = (unsigned int) id->driver_data; | ||
1215 | if (hba->cardtype == st_vsc && (pdev->subsystem_device & 0xf) == 0x1) | ||
1216 | hba->cardtype = st_vsc1; | ||
1217 | hba->dma_size = (hba->cardtype == st_vsc1) ? | ||
1218 | (STEX_BUFFER_SIZE + ST_ADDITIONAL_MEM) : (STEX_BUFFER_SIZE); | ||
1196 | hba->dma_mem = dma_alloc_coherent(&pdev->dev, | 1219 | hba->dma_mem = dma_alloc_coherent(&pdev->dev, |
1197 | STEX_BUFFER_SIZE, &hba->dma_handle, GFP_KERNEL); | 1220 | hba->dma_size, &hba->dma_handle, GFP_KERNEL); |
1198 | if (!hba->dma_mem) { | 1221 | if (!hba->dma_mem) { |
1199 | err = -ENOMEM; | 1222 | err = -ENOMEM; |
1200 | printk(KERN_ERR DRV_NAME "(%s): dma mem alloc failed\n", | 1223 | printk(KERN_ERR DRV_NAME "(%s): dma mem alloc failed\n", |
@@ -1207,8 +1230,6 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1207 | hba->copy_buffer = hba->dma_mem + MU_BUFFER_SIZE; | 1230 | hba->copy_buffer = hba->dma_mem + MU_BUFFER_SIZE; |
1208 | hba->mu_status = MU_STATE_STARTING; | 1231 | hba->mu_status = MU_STATE_STARTING; |
1209 | 1232 | ||
1210 | hba->cardtype = (unsigned int) id->driver_data; | ||
1211 | |||
1212 | /* firmware uses id/lun pair for a logical drive, but lun would be | 1233 | /* firmware uses id/lun pair for a logical drive, but lun would be |
1213 | always 0 if CONFIG_SCSI_MULTI_LUN not configured, so we use | 1234 | always 0 if CONFIG_SCSI_MULTI_LUN not configured, so we use |
1214 | channel to map lun here */ | 1235 | channel to map lun here */ |
@@ -1233,7 +1254,7 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1233 | if (err) | 1254 | if (err) |
1234 | goto out_free_irq; | 1255 | goto out_free_irq; |
1235 | 1256 | ||
1236 | err = scsi_init_shared_tag_map(host, ST_CAN_QUEUE); | 1257 | err = scsi_init_shared_tag_map(host, host->can_queue); |
1237 | if (err) { | 1258 | if (err) { |
1238 | printk(KERN_ERR DRV_NAME "(%s): init shared queue failed\n", | 1259 | printk(KERN_ERR DRV_NAME "(%s): init shared queue failed\n", |
1239 | pci_name(pdev)); | 1260 | pci_name(pdev)); |
@@ -1256,7 +1277,7 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1256 | out_free_irq: | 1277 | out_free_irq: |
1257 | free_irq(pdev->irq, hba); | 1278 | free_irq(pdev->irq, hba); |
1258 | out_pci_free: | 1279 | out_pci_free: |
1259 | dma_free_coherent(&pdev->dev, STEX_BUFFER_SIZE, | 1280 | dma_free_coherent(&pdev->dev, hba->dma_size, |
1260 | hba->dma_mem, hba->dma_handle); | 1281 | hba->dma_mem, hba->dma_handle); |
1261 | out_iounmap: | 1282 | out_iounmap: |
1262 | iounmap(hba->mmio_base); | 1283 | iounmap(hba->mmio_base); |
@@ -1317,7 +1338,7 @@ static void stex_hba_free(struct st_hba *hba) | |||
1317 | 1338 | ||
1318 | pci_release_regions(hba->pdev); | 1339 | pci_release_regions(hba->pdev); |
1319 | 1340 | ||
1320 | dma_free_coherent(&hba->pdev->dev, STEX_BUFFER_SIZE, | 1341 | dma_free_coherent(&hba->pdev->dev, hba->dma_size, |
1321 | hba->dma_mem, hba->dma_handle); | 1342 | hba->dma_mem, hba->dma_handle); |
1322 | } | 1343 | } |
1323 | 1344 | ||
@@ -1346,15 +1367,32 @@ static void stex_shutdown(struct pci_dev *pdev) | |||
1346 | } | 1367 | } |
1347 | 1368 | ||
1348 | static struct pci_device_id stex_pci_tbl[] = { | 1369 | static struct pci_device_id stex_pci_tbl[] = { |
1349 | { 0x105a, 0x8350, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_shasta }, | 1370 | /* st_shasta */ |
1350 | { 0x105a, 0xc350, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_shasta }, | 1371 | { 0x105a, 0x8350, PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
1351 | { 0x105a, 0xf350, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_shasta }, | 1372 | st_shasta }, /* SuperTrak EX8350/8300/16350/16300 */ |
1352 | { 0x105a, 0x4301, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_shasta }, | 1373 | { 0x105a, 0xc350, PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
1353 | { 0x105a, 0x4302, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_shasta }, | 1374 | st_shasta }, /* SuperTrak EX12350 */ |
1354 | { 0x105a, 0x8301, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_shasta }, | 1375 | { 0x105a, 0x4302, PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
1355 | { 0x105a, 0x8302, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_shasta }, | 1376 | st_shasta }, /* SuperTrak EX4350 */ |
1356 | { 0x1725, 0x7250, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_vsc }, | 1377 | { 0x105a, 0xe350, PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
1357 | { 0x105a, 0x8650, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_yosemite }, | 1378 | st_shasta }, /* SuperTrak EX24350 */ |
1379 | |||
1380 | /* st_vsc */ | ||
1381 | { 0x105a, 0x7250, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_vsc }, | ||
1382 | |||
1383 | /* st_yosemite */ | ||
1384 | { 0x105a, 0x8650, PCI_ANY_ID, 0x4600, 0, 0, | ||
1385 | st_yosemite }, /* SuperTrak EX4650 */ | ||
1386 | { 0x105a, 0x8650, PCI_ANY_ID, 0x4610, 0, 0, | ||
1387 | st_yosemite }, /* SuperTrak EX4650o */ | ||
1388 | { 0x105a, 0x8650, PCI_ANY_ID, 0x8600, 0, 0, | ||
1389 | st_yosemite }, /* SuperTrak EX8650EL */ | ||
1390 | { 0x105a, 0x8650, PCI_ANY_ID, 0x8601, 0, 0, | ||
1391 | st_yosemite }, /* SuperTrak EX8650 */ | ||
1392 | { 0x105a, 0x8650, PCI_ANY_ID, 0x8602, 0, 0, | ||
1393 | st_yosemite }, /* SuperTrak EX8654 */ | ||
1394 | { 0x105a, 0x8650, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
1395 | st_yosemite }, /* generic st_yosemite */ | ||
1358 | { } /* terminate list */ | 1396 | { } /* terminate list */ |
1359 | }; | 1397 | }; |
1360 | MODULE_DEVICE_TABLE(pci, stex_pci_tbl); | 1398 | MODULE_DEVICE_TABLE(pci, stex_pci_tbl); |