diff options
Diffstat (limited to 'drivers/scsi')
100 files changed, 3194 insertions, 2778 deletions
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c index b4912d1cee2a..51c3ebf1c7d1 100644 --- a/drivers/scsi/3w-9xxx.c +++ b/drivers/scsi/3w-9xxx.c | |||
@@ -1838,12 +1838,11 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, | |||
1838 | if (scsi_sg_count(srb)) { | 1838 | if (scsi_sg_count(srb)) { |
1839 | if ((scsi_sg_count(srb) == 1) && | 1839 | if ((scsi_sg_count(srb) == 1) && |
1840 | (scsi_bufflen(srb) < TW_MIN_SGL_LENGTH)) { | 1840 | (scsi_bufflen(srb) < TW_MIN_SGL_LENGTH)) { |
1841 | if (srb->sc_data_direction == DMA_TO_DEVICE || srb->sc_data_direction == DMA_BIDIRECTIONAL) { | 1841 | if (srb->sc_data_direction == DMA_TO_DEVICE || |
1842 | struct scatterlist *sg = scsi_sglist(srb); | 1842 | srb->sc_data_direction == DMA_BIDIRECTIONAL) |
1843 | char *buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset; | 1843 | scsi_sg_copy_to_buffer(srb, |
1844 | memcpy(tw_dev->generic_buffer_virt[request_id], buf, sg->length); | 1844 | tw_dev->generic_buffer_virt[request_id], |
1845 | kunmap_atomic(buf - sg->offset, KM_IRQ0); | 1845 | TW_SECTOR_SIZE); |
1846 | } | ||
1847 | command_packet->sg_list[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]); | 1846 | command_packet->sg_list[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]); |
1848 | command_packet->sg_list[0].length = cpu_to_le32(TW_MIN_SGL_LENGTH); | 1847 | command_packet->sg_list[0].length = cpu_to_le32(TW_MIN_SGL_LENGTH); |
1849 | } else { | 1848 | } else { |
@@ -1915,13 +1914,11 @@ static void twa_scsiop_execute_scsi_complete(TW_Device_Extension *tw_dev, int re | |||
1915 | (cmd->sc_data_direction == DMA_FROM_DEVICE || | 1914 | (cmd->sc_data_direction == DMA_FROM_DEVICE || |
1916 | cmd->sc_data_direction == DMA_BIDIRECTIONAL)) { | 1915 | cmd->sc_data_direction == DMA_BIDIRECTIONAL)) { |
1917 | if (scsi_sg_count(cmd) == 1) { | 1916 | if (scsi_sg_count(cmd) == 1) { |
1918 | struct scatterlist *sg = scsi_sglist(tw_dev->srb[request_id]); | 1917 | unsigned long flags; |
1919 | char *buf; | 1918 | void *buf = tw_dev->generic_buffer_virt[request_id]; |
1920 | unsigned long flags = 0; | 1919 | |
1921 | local_irq_save(flags); | 1920 | local_irq_save(flags); |
1922 | buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset; | 1921 | scsi_sg_copy_from_buffer(cmd, buf, TW_SECTOR_SIZE); |
1923 | memcpy(buf, tw_dev->generic_buffer_virt[request_id], sg->length); | ||
1924 | kunmap_atomic(buf - sg->offset, KM_IRQ0); | ||
1925 | local_irq_restore(flags); | 1922 | local_irq_restore(flags); |
1926 | } | 1923 | } |
1927 | } | 1924 | } |
@@ -2028,8 +2025,6 @@ static int __devinit twa_probe(struct pci_dev *pdev, const struct pci_device_id | |||
2028 | } | 2025 | } |
2029 | tw_dev = (TW_Device_Extension *)host->hostdata; | 2026 | tw_dev = (TW_Device_Extension *)host->hostdata; |
2030 | 2027 | ||
2031 | memset(tw_dev, 0, sizeof(TW_Device_Extension)); | ||
2032 | |||
2033 | /* Save values to device extension */ | 2028 | /* Save values to device extension */ |
2034 | tw_dev->host = host; | 2029 | tw_dev->host = host; |
2035 | tw_dev->tw_pci_dev = pdev; | 2030 | tw_dev->tw_pci_dev = pdev; |
diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c index d09532162217..adb98a297210 100644 --- a/drivers/scsi/3w-xxxx.c +++ b/drivers/scsi/3w-xxxx.c | |||
@@ -1463,18 +1463,10 @@ static void tw_transfer_internal(TW_Device_Extension *tw_dev, int request_id, | |||
1463 | void *data, unsigned int len) | 1463 | void *data, unsigned int len) |
1464 | { | 1464 | { |
1465 | struct scsi_cmnd *cmd = tw_dev->srb[request_id]; | 1465 | struct scsi_cmnd *cmd = tw_dev->srb[request_id]; |
1466 | void *buf; | 1466 | unsigned long flags; |
1467 | unsigned int transfer_len; | ||
1468 | unsigned long flags = 0; | ||
1469 | struct scatterlist *sg = scsi_sglist(cmd); | ||
1470 | 1467 | ||
1471 | local_irq_save(flags); | 1468 | local_irq_save(flags); |
1472 | buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset; | 1469 | scsi_sg_copy_from_buffer(cmd, data, len); |
1473 | transfer_len = min(sg->length, len); | ||
1474 | |||
1475 | memcpy(buf, data, transfer_len); | ||
1476 | |||
1477 | kunmap_atomic(buf - sg->offset, KM_IRQ0); | ||
1478 | local_irq_restore(flags); | 1470 | local_irq_restore(flags); |
1479 | } | 1471 | } |
1480 | 1472 | ||
@@ -2294,8 +2286,6 @@ static int __devinit tw_probe(struct pci_dev *pdev, const struct pci_device_id * | |||
2294 | } | 2286 | } |
2295 | tw_dev = (TW_Device_Extension *)host->hostdata; | 2287 | tw_dev = (TW_Device_Extension *)host->hostdata; |
2296 | 2288 | ||
2297 | memset(tw_dev, 0, sizeof(TW_Device_Extension)); | ||
2298 | |||
2299 | /* Save values to device extension */ | 2289 | /* Save values to device extension */ |
2300 | tw_dev->host = host; | 2290 | tw_dev->host = host; |
2301 | tw_dev->tw_pci_dev = pdev; | 2291 | tw_dev->tw_pci_dev = pdev; |
diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c index 4d3ebb1af490..2d689af24664 100644 --- a/drivers/scsi/BusLogic.c +++ b/drivers/scsi/BusLogic.c | |||
@@ -896,7 +896,7 @@ static int __init BusLogic_InitializeFlashPointProbeInfo(struct BusLogic_HostAda | |||
896 | IRQ_Channel = PCI_Device->irq; | 896 | IRQ_Channel = PCI_Device->irq; |
897 | IO_Address = BaseAddress0 = pci_resource_start(PCI_Device, 0); | 897 | IO_Address = BaseAddress0 = pci_resource_start(PCI_Device, 0); |
898 | PCI_Address = BaseAddress1 = pci_resource_start(PCI_Device, 1); | 898 | PCI_Address = BaseAddress1 = pci_resource_start(PCI_Device, 1); |
899 | #ifndef CONFIG_SCSI_OMIT_FLASHPOINT | 899 | #ifdef CONFIG_SCSI_FLASHPOINT |
900 | if (pci_resource_flags(PCI_Device, 0) & IORESOURCE_MEM) { | 900 | if (pci_resource_flags(PCI_Device, 0) & IORESOURCE_MEM) { |
901 | BusLogic_Error("BusLogic: Base Address0 0x%X not I/O for " "FlashPoint Host Adapter\n", NULL, BaseAddress0); | 901 | BusLogic_Error("BusLogic: Base Address0 0x%X not I/O for " "FlashPoint Host Adapter\n", NULL, BaseAddress0); |
902 | BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, Bus, Device, IO_Address); | 902 | BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, Bus, Device, IO_Address); |
@@ -1006,6 +1006,9 @@ static void __init BusLogic_InitializeProbeInfoList(struct BusLogic_HostAdapter | |||
1006 | } | 1006 | } |
1007 | 1007 | ||
1008 | 1008 | ||
1009 | #else | ||
1010 | #define BusLogic_InitializeProbeInfoList(adapter) \ | ||
1011 | BusLogic_InitializeProbeInfoListISA(adapter) | ||
1009 | #endif /* CONFIG_PCI */ | 1012 | #endif /* CONFIG_PCI */ |
1010 | 1013 | ||
1011 | 1014 | ||
diff --git a/drivers/scsi/BusLogic.h b/drivers/scsi/BusLogic.h index bfbfb5c3a8f6..73f237a1ed94 100644 --- a/drivers/scsi/BusLogic.h +++ b/drivers/scsi/BusLogic.h | |||
@@ -34,23 +34,6 @@ | |||
34 | #endif | 34 | #endif |
35 | 35 | ||
36 | /* | 36 | /* |
37 | FlashPoint support is only available for the Intel x86 Architecture with | ||
38 | CONFIG_PCI set. | ||
39 | */ | ||
40 | |||
41 | #ifndef __i386__ | ||
42 | #undef CONFIG_SCSI_OMIT_FLASHPOINT | ||
43 | #define CONFIG_SCSI_OMIT_FLASHPOINT | ||
44 | #endif | ||
45 | |||
46 | #ifndef CONFIG_PCI | ||
47 | #undef CONFIG_SCSI_OMIT_FLASHPOINT | ||
48 | #define CONFIG_SCSI_OMIT_FLASHPOINT | ||
49 | #define BusLogic_InitializeProbeInfoListISA BusLogic_InitializeProbeInfoList | ||
50 | #endif | ||
51 | |||
52 | |||
53 | /* | ||
54 | Define the maximum number of BusLogic Host Adapters supported by this driver. | 37 | Define the maximum number of BusLogic Host Adapters supported by this driver. |
55 | */ | 38 | */ |
56 | 39 | ||
@@ -178,7 +161,7 @@ static int BusLogic_HostAdapterAddressCount[3] = { 0, BusLogic_MultiMasterAddres | |||
178 | Define macros for testing the Host Adapter Type. | 161 | Define macros for testing the Host Adapter Type. |
179 | */ | 162 | */ |
180 | 163 | ||
181 | #ifndef CONFIG_SCSI_OMIT_FLASHPOINT | 164 | #ifdef CONFIG_SCSI_FLASHPOINT |
182 | 165 | ||
183 | #define BusLogic_MultiMasterHostAdapterP(HostAdapter) \ | 166 | #define BusLogic_MultiMasterHostAdapterP(HostAdapter) \ |
184 | (HostAdapter->HostAdapterType == BusLogic_MultiMaster) | 167 | (HostAdapter->HostAdapterType == BusLogic_MultiMaster) |
@@ -871,7 +854,7 @@ struct BusLogic_CCB { | |||
871 | void (*CallbackFunction) (struct BusLogic_CCB *); /* Bytes 40-43 */ | 854 | void (*CallbackFunction) (struct BusLogic_CCB *); /* Bytes 40-43 */ |
872 | u32 BaseAddress; /* Bytes 44-47 */ | 855 | u32 BaseAddress; /* Bytes 44-47 */ |
873 | enum BusLogic_CompletionCode CompletionCode; /* Byte 48 */ | 856 | enum BusLogic_CompletionCode CompletionCode; /* Byte 48 */ |
874 | #ifndef CONFIG_SCSI_OMIT_FLASHPOINT | 857 | #ifdef CONFIG_SCSI_FLASHPOINT |
875 | unsigned char:8; /* Byte 49 */ | 858 | unsigned char:8; /* Byte 49 */ |
876 | unsigned short OS_Flags; /* Bytes 50-51 */ | 859 | unsigned short OS_Flags; /* Bytes 50-51 */ |
877 | unsigned char Private[48]; /* Bytes 52-99 */ | 860 | unsigned char Private[48]; /* Bytes 52-99 */ |
diff --git a/drivers/scsi/FlashPoint.c b/drivers/scsi/FlashPoint.c index 1c9078191d9e..b374e457e5e2 100644 --- a/drivers/scsi/FlashPoint.c +++ b/drivers/scsi/FlashPoint.c | |||
@@ -16,7 +16,7 @@ | |||
16 | */ | 16 | */ |
17 | 17 | ||
18 | 18 | ||
19 | #ifndef CONFIG_SCSI_OMIT_FLASHPOINT | 19 | #ifdef CONFIG_SCSI_FLASHPOINT |
20 | 20 | ||
21 | #define MAX_CARDS 8 | 21 | #define MAX_CARDS 8 |
22 | #undef BUSTYPE_PCI | 22 | #undef BUSTYPE_PCI |
@@ -7626,7 +7626,7 @@ FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle) | |||
7626 | #define FlashPoint_InterruptPending FlashPoint__InterruptPending | 7626 | #define FlashPoint_InterruptPending FlashPoint__InterruptPending |
7627 | #define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt | 7627 | #define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt |
7628 | 7628 | ||
7629 | #else /* CONFIG_SCSI_OMIT_FLASHPOINT */ | 7629 | #else /* !CONFIG_SCSI_FLASHPOINT */ |
7630 | 7630 | ||
7631 | /* | 7631 | /* |
7632 | Define prototypes for the FlashPoint SCCB Manager Functions. | 7632 | Define prototypes for the FlashPoint SCCB Manager Functions. |
@@ -7641,4 +7641,4 @@ extern bool FlashPoint_InterruptPending(FlashPoint_CardHandle_T); | |||
7641 | extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T); | 7641 | extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T); |
7642 | extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T); | 7642 | extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T); |
7643 | 7643 | ||
7644 | #endif /* CONFIG_SCSI_OMIT_FLASHPOINT */ | 7644 | #endif /* CONFIG_SCSI_FLASHPOINT */ |
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index b9d374082b65..7f78e3ea517d 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig | |||
@@ -588,18 +588,20 @@ config SCSI_BUSLOGIC | |||
588 | <http://www.tldp.org/docs.html#howto>, and the files | 588 | <http://www.tldp.org/docs.html#howto>, and the files |
589 | <file:Documentation/scsi/BusLogic.txt> and | 589 | <file:Documentation/scsi/BusLogic.txt> and |
590 | <file:Documentation/scsi/FlashPoint.txt> for more information. | 590 | <file:Documentation/scsi/FlashPoint.txt> for more information. |
591 | Note that support for FlashPoint is only available for 32-bit | ||
592 | x86 configurations. | ||
591 | 593 | ||
592 | To compile this driver as a module, choose M here: the | 594 | To compile this driver as a module, choose M here: the |
593 | module will be called BusLogic. | 595 | module will be called BusLogic. |
594 | 596 | ||
595 | config SCSI_OMIT_FLASHPOINT | 597 | config SCSI_FLASHPOINT |
596 | bool "Omit FlashPoint support" | 598 | bool "FlashPoint support" |
597 | depends on SCSI_BUSLOGIC | 599 | depends on SCSI_BUSLOGIC && PCI && X86_32 |
598 | help | 600 | help |
599 | This option allows you to omit the FlashPoint support from the | 601 | This option allows you to add FlashPoint support to the |
600 | BusLogic SCSI driver. The FlashPoint SCCB Manager code is | 602 | BusLogic SCSI driver. The FlashPoint SCCB Manager code is |
601 | substantial, so users of MultiMaster Host Adapters may wish to omit | 603 | substantial, so users of MultiMaster Host Adapters may not |
602 | it. | 604 | wish to include it. |
603 | 605 | ||
604 | config SCSI_DMX3191D | 606 | config SCSI_DMX3191D |
605 | tristate "DMX3191D SCSI support" | 607 | tristate "DMX3191D SCSI support" |
diff --git a/drivers/scsi/a2091.c b/drivers/scsi/a2091.c index 5ac3a3e8dfaf..07d572feceed 100644 --- a/drivers/scsi/a2091.c +++ b/drivers/scsi/a2091.c | |||
@@ -179,6 +179,9 @@ int __init a2091_detect(struct scsi_host_template *tpnt) | |||
179 | DMA(instance)->DAWR = DAWR_A2091; | 179 | DMA(instance)->DAWR = DAWR_A2091; |
180 | regs.SASR = &(DMA(instance)->SASR); | 180 | regs.SASR = &(DMA(instance)->SASR); |
181 | regs.SCMD = &(DMA(instance)->SCMD); | 181 | regs.SCMD = &(DMA(instance)->SCMD); |
182 | HDATA(instance)->no_sync = 0xff; | ||
183 | HDATA(instance)->fast = 0; | ||
184 | HDATA(instance)->dma_mode = CTRL_DMA; | ||
182 | wd33c93_init(instance, regs, dma_setup, dma_stop, WD33C93_FS_8_10); | 185 | wd33c93_init(instance, regs, dma_setup, dma_stop, WD33C93_FS_8_10); |
183 | request_irq(IRQ_AMIGA_PORTS, a2091_intr, IRQF_SHARED, "A2091 SCSI", | 186 | request_irq(IRQ_AMIGA_PORTS, a2091_intr, IRQF_SHARED, "A2091 SCSI", |
184 | instance); | 187 | instance); |
diff --git a/drivers/scsi/a3000.c b/drivers/scsi/a3000.c index 3aeec963940b..8b449d8acacd 100644 --- a/drivers/scsi/a3000.c +++ b/drivers/scsi/a3000.c | |||
@@ -178,6 +178,9 @@ int __init a3000_detect(struct scsi_host_template *tpnt) | |||
178 | DMA(a3000_host)->DAWR = DAWR_A3000; | 178 | DMA(a3000_host)->DAWR = DAWR_A3000; |
179 | regs.SASR = &(DMA(a3000_host)->SASR); | 179 | regs.SASR = &(DMA(a3000_host)->SASR); |
180 | regs.SCMD = &(DMA(a3000_host)->SCMD); | 180 | regs.SCMD = &(DMA(a3000_host)->SCMD); |
181 | HDATA(a3000_host)->no_sync = 0xff; | ||
182 | HDATA(a3000_host)->fast = 0; | ||
183 | HDATA(a3000_host)->dma_mode = CTRL_DMA; | ||
181 | wd33c93_init(a3000_host, regs, dma_setup, dma_stop, WD33C93_FS_12_15); | 184 | wd33c93_init(a3000_host, regs, dma_setup, dma_stop, WD33C93_FS_12_15); |
182 | if (request_irq(IRQ_AMIGA_PORTS, a3000_intr, IRQF_SHARED, "A3000 SCSI", | 185 | if (request_irq(IRQ_AMIGA_PORTS, a3000_intr, IRQF_SHARED, "A3000 SCSI", |
183 | a3000_intr)) | 186 | a3000_intr)) |
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index c05092fd3a9d..369fcf78f396 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c | |||
@@ -205,7 +205,7 @@ MODULE_PARM_DESC(check_interval, "Interval in seconds between adapter health" | |||
205 | 205 | ||
206 | int aac_check_reset = 1; | 206 | int aac_check_reset = 1; |
207 | module_param_named(check_reset, aac_check_reset, int, S_IRUGO|S_IWUSR); | 207 | module_param_named(check_reset, aac_check_reset, int, S_IRUGO|S_IWUSR); |
208 | MODULE_PARM_DESC(aac_check_reset, "If adapter fails health check, reset the" | 208 | MODULE_PARM_DESC(check_reset, "If adapter fails health check, reset the" |
209 | " adapter. a value of -1 forces the reset to adapters programmed to" | 209 | " adapter. a value of -1 forces the reset to adapters programmed to" |
210 | " ignore it."); | 210 | " ignore it."); |
211 | 211 | ||
@@ -379,24 +379,6 @@ int aac_get_containers(struct aac_dev *dev) | |||
379 | return status; | 379 | return status; |
380 | } | 380 | } |
381 | 381 | ||
382 | static void aac_internal_transfer(struct scsi_cmnd *scsicmd, void *data, unsigned int offset, unsigned int len) | ||
383 | { | ||
384 | void *buf; | ||
385 | int transfer_len; | ||
386 | struct scatterlist *sg = scsi_sglist(scsicmd); | ||
387 | |||
388 | buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset; | ||
389 | transfer_len = min(sg->length, len + offset); | ||
390 | |||
391 | transfer_len -= offset; | ||
392 | if (buf && transfer_len > 0) | ||
393 | memcpy(buf + offset, data, transfer_len); | ||
394 | |||
395 | flush_kernel_dcache_page(kmap_atomic_to_page(buf - sg->offset)); | ||
396 | kunmap_atomic(buf - sg->offset, KM_IRQ0); | ||
397 | |||
398 | } | ||
399 | |||
400 | static void get_container_name_callback(void *context, struct fib * fibptr) | 382 | static void get_container_name_callback(void *context, struct fib * fibptr) |
401 | { | 383 | { |
402 | struct aac_get_name_resp * get_name_reply; | 384 | struct aac_get_name_resp * get_name_reply; |
@@ -419,14 +401,17 @@ static void get_container_name_callback(void *context, struct fib * fibptr) | |||
419 | while (*sp == ' ') | 401 | while (*sp == ' ') |
420 | ++sp; | 402 | ++sp; |
421 | if (*sp) { | 403 | if (*sp) { |
404 | struct inquiry_data inq; | ||
422 | char d[sizeof(((struct inquiry_data *)NULL)->inqd_pid)]; | 405 | char d[sizeof(((struct inquiry_data *)NULL)->inqd_pid)]; |
423 | int count = sizeof(d); | 406 | int count = sizeof(d); |
424 | char *dp = d; | 407 | char *dp = d; |
425 | do { | 408 | do { |
426 | *dp++ = (*sp) ? *sp++ : ' '; | 409 | *dp++ = (*sp) ? *sp++ : ' '; |
427 | } while (--count > 0); | 410 | } while (--count > 0); |
428 | aac_internal_transfer(scsicmd, d, | 411 | |
429 | offsetof(struct inquiry_data, inqd_pid), sizeof(d)); | 412 | scsi_sg_copy_to_buffer(scsicmd, &inq, sizeof(inq)); |
413 | memcpy(inq.inqd_pid, d, sizeof(d)); | ||
414 | scsi_sg_copy_from_buffer(scsicmd, &inq, sizeof(inq)); | ||
430 | } | 415 | } |
431 | } | 416 | } |
432 | 417 | ||
@@ -811,7 +796,7 @@ static void get_container_serial_callback(void *context, struct fib * fibptr) | |||
811 | sp[2] = 0; | 796 | sp[2] = 0; |
812 | sp[3] = snprintf(sp+4, sizeof(sp)-4, "%08X", | 797 | sp[3] = snprintf(sp+4, sizeof(sp)-4, "%08X", |
813 | le32_to_cpu(get_serial_reply->uid)); | 798 | le32_to_cpu(get_serial_reply->uid)); |
814 | aac_internal_transfer(scsicmd, sp, 0, sizeof(sp)); | 799 | scsi_sg_copy_from_buffer(scsicmd, sp, sizeof(sp)); |
815 | } | 800 | } |
816 | 801 | ||
817 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; | 802 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; |
@@ -1986,8 +1971,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
1986 | arr[4] = 0x0; | 1971 | arr[4] = 0x0; |
1987 | arr[5] = 0x80; | 1972 | arr[5] = 0x80; |
1988 | arr[1] = scsicmd->cmnd[2]; | 1973 | arr[1] = scsicmd->cmnd[2]; |
1989 | aac_internal_transfer(scsicmd, &inq_data, 0, | 1974 | scsi_sg_copy_from_buffer(scsicmd, &inq_data, |
1990 | sizeof(inq_data)); | 1975 | sizeof(inq_data)); |
1991 | scsicmd->result = DID_OK << 16 | | 1976 | scsicmd->result = DID_OK << 16 | |
1992 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; | 1977 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; |
1993 | } else if (scsicmd->cmnd[2] == 0x80) { | 1978 | } else if (scsicmd->cmnd[2] == 0x80) { |
@@ -1995,8 +1980,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
1995 | arr[3] = setinqserial(dev, &arr[4], | 1980 | arr[3] = setinqserial(dev, &arr[4], |
1996 | scmd_id(scsicmd)); | 1981 | scmd_id(scsicmd)); |
1997 | arr[1] = scsicmd->cmnd[2]; | 1982 | arr[1] = scsicmd->cmnd[2]; |
1998 | aac_internal_transfer(scsicmd, &inq_data, 0, | 1983 | scsi_sg_copy_from_buffer(scsicmd, &inq_data, |
1999 | sizeof(inq_data)); | 1984 | sizeof(inq_data)); |
2000 | return aac_get_container_serial(scsicmd); | 1985 | return aac_get_container_serial(scsicmd); |
2001 | } else { | 1986 | } else { |
2002 | /* vpd page not implemented */ | 1987 | /* vpd page not implemented */ |
@@ -2027,7 +2012,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
2027 | if (cid == host->this_id) { | 2012 | if (cid == host->this_id) { |
2028 | setinqstr(dev, (void *) (inq_data.inqd_vid), ARRAY_SIZE(container_types)); | 2013 | setinqstr(dev, (void *) (inq_data.inqd_vid), ARRAY_SIZE(container_types)); |
2029 | inq_data.inqd_pdt = INQD_PDT_PROC; /* Processor device */ | 2014 | inq_data.inqd_pdt = INQD_PDT_PROC; /* Processor device */ |
2030 | aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data)); | 2015 | scsi_sg_copy_from_buffer(scsicmd, &inq_data, |
2016 | sizeof(inq_data)); | ||
2031 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; | 2017 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; |
2032 | scsicmd->scsi_done(scsicmd); | 2018 | scsicmd->scsi_done(scsicmd); |
2033 | return 0; | 2019 | return 0; |
@@ -2036,7 +2022,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
2036 | return -1; | 2022 | return -1; |
2037 | setinqstr(dev, (void *) (inq_data.inqd_vid), fsa_dev_ptr[cid].type); | 2023 | setinqstr(dev, (void *) (inq_data.inqd_vid), fsa_dev_ptr[cid].type); |
2038 | inq_data.inqd_pdt = INQD_PDT_DA; /* Direct/random access device */ | 2024 | inq_data.inqd_pdt = INQD_PDT_DA; /* Direct/random access device */ |
2039 | aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data)); | 2025 | scsi_sg_copy_from_buffer(scsicmd, &inq_data, sizeof(inq_data)); |
2040 | return aac_get_container_name(scsicmd); | 2026 | return aac_get_container_name(scsicmd); |
2041 | } | 2027 | } |
2042 | case SERVICE_ACTION_IN: | 2028 | case SERVICE_ACTION_IN: |
@@ -2047,6 +2033,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
2047 | { | 2033 | { |
2048 | u64 capacity; | 2034 | u64 capacity; |
2049 | char cp[13]; | 2035 | char cp[13]; |
2036 | unsigned int alloc_len; | ||
2050 | 2037 | ||
2051 | dprintk((KERN_DEBUG "READ CAPACITY_16 command.\n")); | 2038 | dprintk((KERN_DEBUG "READ CAPACITY_16 command.\n")); |
2052 | capacity = fsa_dev_ptr[cid].size - 1; | 2039 | capacity = fsa_dev_ptr[cid].size - 1; |
@@ -2063,18 +2050,16 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
2063 | cp[10] = 2; | 2050 | cp[10] = 2; |
2064 | cp[11] = 0; | 2051 | cp[11] = 0; |
2065 | cp[12] = 0; | 2052 | cp[12] = 0; |
2066 | aac_internal_transfer(scsicmd, cp, 0, | ||
2067 | min_t(size_t, scsicmd->cmnd[13], sizeof(cp))); | ||
2068 | if (sizeof(cp) < scsicmd->cmnd[13]) { | ||
2069 | unsigned int len, offset = sizeof(cp); | ||
2070 | 2053 | ||
2071 | memset(cp, 0, offset); | 2054 | alloc_len = ((scsicmd->cmnd[10] << 24) |
2072 | do { | 2055 | + (scsicmd->cmnd[11] << 16) |
2073 | len = min_t(size_t, scsicmd->cmnd[13] - offset, | 2056 | + (scsicmd->cmnd[12] << 8) + scsicmd->cmnd[13]); |
2074 | sizeof(cp)); | 2057 | |
2075 | aac_internal_transfer(scsicmd, cp, offset, len); | 2058 | alloc_len = min_t(size_t, alloc_len, sizeof(cp)); |
2076 | } while ((offset += len) < scsicmd->cmnd[13]); | 2059 | scsi_sg_copy_from_buffer(scsicmd, cp, alloc_len); |
2077 | } | 2060 | if (alloc_len < scsi_bufflen(scsicmd)) |
2061 | scsi_set_resid(scsicmd, | ||
2062 | scsi_bufflen(scsicmd) - alloc_len); | ||
2078 | 2063 | ||
2079 | /* Do not cache partition table for arrays */ | 2064 | /* Do not cache partition table for arrays */ |
2080 | scsicmd->device->removable = 1; | 2065 | scsicmd->device->removable = 1; |
@@ -2104,7 +2089,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
2104 | cp[5] = 0; | 2089 | cp[5] = 0; |
2105 | cp[6] = 2; | 2090 | cp[6] = 2; |
2106 | cp[7] = 0; | 2091 | cp[7] = 0; |
2107 | aac_internal_transfer(scsicmd, cp, 0, sizeof(cp)); | 2092 | scsi_sg_copy_from_buffer(scsicmd, cp, sizeof(cp)); |
2108 | /* Do not cache partition table for arrays */ | 2093 | /* Do not cache partition table for arrays */ |
2109 | scsicmd->device->removable = 1; | 2094 | scsicmd->device->removable = 1; |
2110 | 2095 | ||
@@ -2139,7 +2124,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
2139 | if (mode_buf_length > scsicmd->cmnd[4]) | 2124 | if (mode_buf_length > scsicmd->cmnd[4]) |
2140 | mode_buf_length = scsicmd->cmnd[4]; | 2125 | mode_buf_length = scsicmd->cmnd[4]; |
2141 | } | 2126 | } |
2142 | aac_internal_transfer(scsicmd, mode_buf, 0, mode_buf_length); | 2127 | scsi_sg_copy_from_buffer(scsicmd, mode_buf, mode_buf_length); |
2143 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; | 2128 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; |
2144 | scsicmd->scsi_done(scsicmd); | 2129 | scsicmd->scsi_done(scsicmd); |
2145 | 2130 | ||
@@ -2174,7 +2159,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
2174 | if (mode_buf_length > scsicmd->cmnd[8]) | 2159 | if (mode_buf_length > scsicmd->cmnd[8]) |
2175 | mode_buf_length = scsicmd->cmnd[8]; | 2160 | mode_buf_length = scsicmd->cmnd[8]; |
2176 | } | 2161 | } |
2177 | aac_internal_transfer(scsicmd, mode_buf, 0, mode_buf_length); | 2162 | scsi_sg_copy_from_buffer(scsicmd, mode_buf, mode_buf_length); |
2178 | 2163 | ||
2179 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; | 2164 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; |
2180 | scsicmd->scsi_done(scsicmd); | 2165 | scsicmd->scsi_done(scsicmd); |
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 47434499e82b..23a8e9f8dcb4 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c | |||
@@ -515,10 +515,12 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, | |||
515 | } | 515 | } |
516 | udelay(5); | 516 | udelay(5); |
517 | } | 517 | } |
518 | } else | 518 | } else if (down_interruptible(&fibptr->event_wait) == 0) { |
519 | (void)down_interruptible(&fibptr->event_wait); | 519 | fibptr->done = 2; |
520 | up(&fibptr->event_wait); | ||
521 | } | ||
520 | spin_lock_irqsave(&fibptr->event_lock, flags); | 522 | spin_lock_irqsave(&fibptr->event_lock, flags); |
521 | if (fibptr->done == 0) { | 523 | if ((fibptr->done == 0) || (fibptr->done == 2)) { |
522 | fibptr->done = 2; /* Tell interrupt we aborted */ | 524 | fibptr->done = 2; /* Tell interrupt we aborted */ |
523 | spin_unlock_irqrestore(&fibptr->event_lock, flags); | 525 | spin_unlock_irqrestore(&fibptr->event_lock, flags); |
524 | return -EINTR; | 526 | return -EINTR; |
@@ -594,7 +596,7 @@ void aac_consumer_free(struct aac_dev * dev, struct aac_queue *q, u32 qid) | |||
594 | if (le32_to_cpu(*q->headers.consumer) >= q->entries) | 596 | if (le32_to_cpu(*q->headers.consumer) >= q->entries) |
595 | *q->headers.consumer = cpu_to_le32(1); | 597 | *q->headers.consumer = cpu_to_le32(1); |
596 | else | 598 | else |
597 | *q->headers.consumer = cpu_to_le32(le32_to_cpu(*q->headers.consumer)+1); | 599 | le32_add_cpu(q->headers.consumer, 1); |
598 | 600 | ||
599 | if (wasfull) { | 601 | if (wasfull) { |
600 | switch (qid) { | 602 | switch (qid) { |
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c index 72fccd9f40df..0081aa357c8b 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c | |||
@@ -1413,6 +1413,10 @@ ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev, | |||
1413 | unsigned long flags; | 1413 | unsigned long flags; |
1414 | int nseg; | 1414 | int nseg; |
1415 | 1415 | ||
1416 | nseg = scsi_dma_map(cmd); | ||
1417 | if (nseg < 0) | ||
1418 | return SCSI_MLQUEUE_HOST_BUSY; | ||
1419 | |||
1416 | ahd_lock(ahd, &flags); | 1420 | ahd_lock(ahd, &flags); |
1417 | 1421 | ||
1418 | /* | 1422 | /* |
@@ -1430,6 +1434,7 @@ ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev, | |||
1430 | if ((scb = ahd_get_scb(ahd, col_idx)) == NULL) { | 1434 | if ((scb = ahd_get_scb(ahd, col_idx)) == NULL) { |
1431 | ahd->flags |= AHD_RESOURCE_SHORTAGE; | 1435 | ahd->flags |= AHD_RESOURCE_SHORTAGE; |
1432 | ahd_unlock(ahd, &flags); | 1436 | ahd_unlock(ahd, &flags); |
1437 | scsi_dma_unmap(cmd); | ||
1433 | return SCSI_MLQUEUE_HOST_BUSY; | 1438 | return SCSI_MLQUEUE_HOST_BUSY; |
1434 | } | 1439 | } |
1435 | 1440 | ||
@@ -1485,8 +1490,6 @@ ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev, | |||
1485 | ahd_set_sense_residual(scb, 0); | 1490 | ahd_set_sense_residual(scb, 0); |
1486 | scb->sg_count = 0; | 1491 | scb->sg_count = 0; |
1487 | 1492 | ||
1488 | nseg = scsi_dma_map(cmd); | ||
1489 | BUG_ON(nseg < 0); | ||
1490 | if (nseg > 0) { | 1493 | if (nseg > 0) { |
1491 | void *sg = scb->sg_list; | 1494 | void *sg = scb->sg_list; |
1492 | struct scatterlist *cur_seg; | 1495 | struct scatterlist *cur_seg; |
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index 282aff6f852e..42ad48e09f02 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c | |||
@@ -1398,12 +1398,18 @@ ahc_linux_run_command(struct ahc_softc *ahc, struct ahc_linux_device *dev, | |||
1398 | return SCSI_MLQUEUE_DEVICE_BUSY; | 1398 | return SCSI_MLQUEUE_DEVICE_BUSY; |
1399 | } | 1399 | } |
1400 | 1400 | ||
1401 | nseg = scsi_dma_map(cmd); | ||
1402 | if (nseg < 0) | ||
1403 | return SCSI_MLQUEUE_HOST_BUSY; | ||
1404 | |||
1401 | /* | 1405 | /* |
1402 | * Get an scb to use. | 1406 | * Get an scb to use. |
1403 | */ | 1407 | */ |
1404 | scb = ahc_get_scb(ahc); | 1408 | scb = ahc_get_scb(ahc); |
1405 | if (!scb) | 1409 | if (!scb) { |
1410 | scsi_dma_unmap(cmd); | ||
1406 | return SCSI_MLQUEUE_HOST_BUSY; | 1411 | return SCSI_MLQUEUE_HOST_BUSY; |
1412 | } | ||
1407 | 1413 | ||
1408 | scb->io_ctx = cmd; | 1414 | scb->io_ctx = cmd; |
1409 | scb->platform_data->dev = dev; | 1415 | scb->platform_data->dev = dev; |
@@ -1464,8 +1470,6 @@ ahc_linux_run_command(struct ahc_softc *ahc, struct ahc_linux_device *dev, | |||
1464 | ahc_set_sense_residual(scb, 0); | 1470 | ahc_set_sense_residual(scb, 0); |
1465 | scb->sg_count = 0; | 1471 | scb->sg_count = 0; |
1466 | 1472 | ||
1467 | nseg = scsi_dma_map(cmd); | ||
1468 | BUG_ON(nseg < 0); | ||
1469 | if (nseg > 0) { | 1473 | if (nseg > 0) { |
1470 | struct ahc_dma_seg *sg; | 1474 | struct ahc_dma_seg *sg; |
1471 | struct scatterlist *cur_seg; | 1475 | struct scatterlist *cur_seg; |
diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y b/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y index 6066998ed562..702e2dbd11fb 100644 --- a/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y +++ b/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y | |||
@@ -1837,7 +1837,7 @@ type_check(symbol_t *symbol, expression_t *expression, int opcode) | |||
1837 | int and_op; | 1837 | int and_op; |
1838 | 1838 | ||
1839 | and_op = FALSE; | 1839 | and_op = FALSE; |
1840 | if (opcode == AIC_OP_AND || opcode == AIC_OP_JNZ || AIC_OP_JZ) | 1840 | if (opcode == AIC_OP_AND || opcode == AIC_OP_JNZ || opcode == AIC_OP_JZ) |
1841 | and_op = TRUE; | 1841 | and_op = TRUE; |
1842 | 1842 | ||
1843 | /* | 1843 | /* |
diff --git a/drivers/scsi/aic94xx/aic94xx.h b/drivers/scsi/aic94xx/aic94xx.h index eb8efdcefe48..2ef459e9cda1 100644 --- a/drivers/scsi/aic94xx/aic94xx.h +++ b/drivers/scsi/aic94xx/aic94xx.h | |||
@@ -58,7 +58,6 @@ | |||
58 | 58 | ||
59 | extern struct kmem_cache *asd_dma_token_cache; | 59 | extern struct kmem_cache *asd_dma_token_cache; |
60 | extern struct kmem_cache *asd_ascb_cache; | 60 | extern struct kmem_cache *asd_ascb_cache; |
61 | extern char sas_addr_str[2*SAS_ADDR_SIZE + 1]; | ||
62 | 61 | ||
63 | static inline void asd_stringify_sas_addr(char *p, const u8 *sas_addr) | 62 | static inline void asd_stringify_sas_addr(char *p, const u8 *sas_addr) |
64 | { | 63 | { |
@@ -68,21 +67,6 @@ static inline void asd_stringify_sas_addr(char *p, const u8 *sas_addr) | |||
68 | *p = '\0'; | 67 | *p = '\0'; |
69 | } | 68 | } |
70 | 69 | ||
71 | static inline void asd_destringify_sas_addr(u8 *sas_addr, const char *p) | ||
72 | { | ||
73 | int i; | ||
74 | for (i = 0; i < SAS_ADDR_SIZE; i++) { | ||
75 | u8 h, l; | ||
76 | if (!*p) | ||
77 | break; | ||
78 | h = isdigit(*p) ? *p-'0' : *p-'A'+10; | ||
79 | p++; | ||
80 | l = isdigit(*p) ? *p-'0' : *p-'A'+10; | ||
81 | p++; | ||
82 | sas_addr[i] = (h<<4) | l; | ||
83 | } | ||
84 | } | ||
85 | |||
86 | struct asd_ha_struct; | 70 | struct asd_ha_struct; |
87 | struct asd_ascb; | 71 | struct asd_ascb; |
88 | 72 | ||
diff --git a/drivers/scsi/aic94xx/aic94xx_dev.c b/drivers/scsi/aic94xx/aic94xx_dev.c index 72042cae7768..2e2ddec9c0b6 100644 --- a/drivers/scsi/aic94xx/aic94xx_dev.c +++ b/drivers/scsi/aic94xx/aic94xx_dev.c | |||
@@ -35,7 +35,7 @@ | |||
35 | #define SET_DDB(_ddb, _ha) set_bit(_ddb, (_ha)->hw_prof.ddb_bitmap) | 35 | #define SET_DDB(_ddb, _ha) set_bit(_ddb, (_ha)->hw_prof.ddb_bitmap) |
36 | #define CLEAR_DDB(_ddb, _ha) clear_bit(_ddb, (_ha)->hw_prof.ddb_bitmap) | 36 | #define CLEAR_DDB(_ddb, _ha) clear_bit(_ddb, (_ha)->hw_prof.ddb_bitmap) |
37 | 37 | ||
38 | static inline int asd_get_ddb(struct asd_ha_struct *asd_ha) | 38 | static int asd_get_ddb(struct asd_ha_struct *asd_ha) |
39 | { | 39 | { |
40 | int ddb, i; | 40 | int ddb, i; |
41 | 41 | ||
@@ -71,7 +71,7 @@ out: | |||
71 | #define NCQ_DATA_SCB_PTR offsetof(struct asd_ddb_stp_sata_target_port, ncq_data_scb_ptr) | 71 | #define NCQ_DATA_SCB_PTR offsetof(struct asd_ddb_stp_sata_target_port, ncq_data_scb_ptr) |
72 | #define ITNL_TIMEOUT offsetof(struct asd_ddb_ssp_smp_target_port, itnl_timeout) | 72 | #define ITNL_TIMEOUT offsetof(struct asd_ddb_ssp_smp_target_port, itnl_timeout) |
73 | 73 | ||
74 | static inline void asd_free_ddb(struct asd_ha_struct *asd_ha, int ddb) | 74 | static void asd_free_ddb(struct asd_ha_struct *asd_ha, int ddb) |
75 | { | 75 | { |
76 | if (!ddb || ddb >= 0xFFFF) | 76 | if (!ddb || ddb >= 0xFFFF) |
77 | return; | 77 | return; |
@@ -79,7 +79,7 @@ static inline void asd_free_ddb(struct asd_ha_struct *asd_ha, int ddb) | |||
79 | CLEAR_DDB(ddb, asd_ha); | 79 | CLEAR_DDB(ddb, asd_ha); |
80 | } | 80 | } |
81 | 81 | ||
82 | static inline void asd_set_ddb_type(struct domain_device *dev) | 82 | static void asd_set_ddb_type(struct domain_device *dev) |
83 | { | 83 | { |
84 | struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha; | 84 | struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha; |
85 | int ddb = (int) (unsigned long) dev->lldd_dev; | 85 | int ddb = (int) (unsigned long) dev->lldd_dev; |
@@ -109,7 +109,7 @@ static int asd_init_sata_tag_ddb(struct domain_device *dev) | |||
109 | return 0; | 109 | return 0; |
110 | } | 110 | } |
111 | 111 | ||
112 | static inline int asd_init_sata(struct domain_device *dev) | 112 | static int asd_init_sata(struct domain_device *dev) |
113 | { | 113 | { |
114 | struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha; | 114 | struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha; |
115 | int ddb = (int) (unsigned long) dev->lldd_dev; | 115 | int ddb = (int) (unsigned long) dev->lldd_dev; |
diff --git a/drivers/scsi/aic94xx/aic94xx_dump.c b/drivers/scsi/aic94xx/aic94xx_dump.c index 3d8c4ff1f2ef..67eeba3bdb06 100644 --- a/drivers/scsi/aic94xx/aic94xx_dump.c +++ b/drivers/scsi/aic94xx/aic94xx_dump.c | |||
@@ -738,6 +738,8 @@ static void asd_dump_lseq_state(struct asd_ha_struct *asd_ha, int lseq) | |||
738 | PRINT_LMIP_dword(asd_ha, lseq, DEV_PRES_TIMER_TERM_TS); | 738 | PRINT_LMIP_dword(asd_ha, lseq, DEV_PRES_TIMER_TERM_TS); |
739 | } | 739 | } |
740 | 740 | ||
741 | #if 0 | ||
742 | |||
741 | /** | 743 | /** |
742 | * asd_dump_ddb_site -- dump a CSEQ DDB site | 744 | * asd_dump_ddb_site -- dump a CSEQ DDB site |
743 | * @asd_ha: pointer to host adapter structure | 745 | * @asd_ha: pointer to host adapter structure |
@@ -880,6 +882,8 @@ void asd_dump_scb_sites(struct asd_ha_struct *asd_ha) | |||
880 | } | 882 | } |
881 | } | 883 | } |
882 | 884 | ||
885 | #endif /* 0 */ | ||
886 | |||
883 | /** | 887 | /** |
884 | * ads_dump_seq_state -- dump CSEQ and LSEQ states | 888 | * ads_dump_seq_state -- dump CSEQ and LSEQ states |
885 | * @asd_ha: pointer to host adapter structure | 889 | * @asd_ha: pointer to host adapter structure |
@@ -922,7 +926,9 @@ void asd_dump_frame_rcvd(struct asd_phy *phy, | |||
922 | spin_unlock_irqrestore(&phy->sas_phy.frame_rcvd_lock, flags); | 926 | spin_unlock_irqrestore(&phy->sas_phy.frame_rcvd_lock, flags); |
923 | } | 927 | } |
924 | 928 | ||
925 | static inline void asd_dump_scb(struct asd_ascb *ascb, int ind) | 929 | #if 0 |
930 | |||
931 | static void asd_dump_scb(struct asd_ascb *ascb, int ind) | ||
926 | { | 932 | { |
927 | asd_printk("scb%d: vaddr: 0x%p, dma_handle: 0x%llx, next: 0x%llx, " | 933 | asd_printk("scb%d: vaddr: 0x%p, dma_handle: 0x%llx, next: 0x%llx, " |
928 | "index:%d, opcode:0x%02x\n", | 934 | "index:%d, opcode:0x%02x\n", |
@@ -956,4 +962,6 @@ void asd_dump_scb_list(struct asd_ascb *ascb, int num) | |||
956 | } | 962 | } |
957 | } | 963 | } |
958 | 964 | ||
965 | #endif /* 0 */ | ||
966 | |||
959 | #endif /* ASD_DEBUG */ | 967 | #endif /* ASD_DEBUG */ |
diff --git a/drivers/scsi/aic94xx/aic94xx_dump.h b/drivers/scsi/aic94xx/aic94xx_dump.h index 0c388e7da6bb..191a753d42a7 100644 --- a/drivers/scsi/aic94xx/aic94xx_dump.h +++ b/drivers/scsi/aic94xx/aic94xx_dump.h | |||
@@ -29,24 +29,15 @@ | |||
29 | 29 | ||
30 | #ifdef ASD_DEBUG | 30 | #ifdef ASD_DEBUG |
31 | 31 | ||
32 | void asd_dump_ddb_0(struct asd_ha_struct *asd_ha); | ||
33 | void asd_dump_target_ddb(struct asd_ha_struct *asd_ha, u16 site_no); | ||
34 | void asd_dump_scb_sites(struct asd_ha_struct *asd_ha); | ||
35 | void asd_dump_seq_state(struct asd_ha_struct *asd_ha, u8 lseq_mask); | 32 | void asd_dump_seq_state(struct asd_ha_struct *asd_ha, u8 lseq_mask); |
36 | void asd_dump_frame_rcvd(struct asd_phy *phy, | 33 | void asd_dump_frame_rcvd(struct asd_phy *phy, |
37 | struct done_list_struct *dl); | 34 | struct done_list_struct *dl); |
38 | void asd_dump_scb_list(struct asd_ascb *ascb, int num); | ||
39 | #else /* ASD_DEBUG */ | 35 | #else /* ASD_DEBUG */ |
40 | 36 | ||
41 | static inline void asd_dump_ddb_0(struct asd_ha_struct *asd_ha) { } | ||
42 | static inline void asd_dump_target_ddb(struct asd_ha_struct *asd_ha, | ||
43 | u16 site_no) { } | ||
44 | static inline void asd_dump_scb_sites(struct asd_ha_struct *asd_ha) { } | ||
45 | static inline void asd_dump_seq_state(struct asd_ha_struct *asd_ha, | 37 | static inline void asd_dump_seq_state(struct asd_ha_struct *asd_ha, |
46 | u8 lseq_mask) { } | 38 | u8 lseq_mask) { } |
47 | static inline void asd_dump_frame_rcvd(struct asd_phy *phy, | 39 | static inline void asd_dump_frame_rcvd(struct asd_phy *phy, |
48 | struct done_list_struct *dl) { } | 40 | struct done_list_struct *dl) { } |
49 | static inline void asd_dump_scb_list(struct asd_ascb *ascb, int num) { } | ||
50 | #endif /* ASD_DEBUG */ | 41 | #endif /* ASD_DEBUG */ |
51 | 42 | ||
52 | #endif /* _AIC94XX_DUMP_H_ */ | 43 | #endif /* _AIC94XX_DUMP_H_ */ |
diff --git a/drivers/scsi/aic94xx/aic94xx_hwi.c b/drivers/scsi/aic94xx/aic94xx_hwi.c index 098b5f39cd31..83a78222896d 100644 --- a/drivers/scsi/aic94xx/aic94xx_hwi.c +++ b/drivers/scsi/aic94xx/aic94xx_hwi.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/pci.h> | 27 | #include <linux/pci.h> |
28 | #include <linux/delay.h> | 28 | #include <linux/delay.h> |
29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
30 | #include <linux/firmware.h> | ||
30 | 31 | ||
31 | #include "aic94xx.h" | 32 | #include "aic94xx.h" |
32 | #include "aic94xx_reg.h" | 33 | #include "aic94xx_reg.h" |
@@ -38,16 +39,14 @@ u32 MBAR0_SWB_SIZE; | |||
38 | 39 | ||
39 | /* ---------- Initialization ---------- */ | 40 | /* ---------- Initialization ---------- */ |
40 | 41 | ||
41 | static void asd_get_user_sas_addr(struct asd_ha_struct *asd_ha) | 42 | static int asd_get_user_sas_addr(struct asd_ha_struct *asd_ha) |
42 | { | 43 | { |
43 | extern char sas_addr_str[]; | 44 | /* adapter came with a sas address */ |
44 | /* If the user has specified a WWN it overrides other settings | 45 | if (asd_ha->hw_prof.sas_addr[0]) |
45 | */ | 46 | return 0; |
46 | if (sas_addr_str[0] != '\0') | 47 | |
47 | asd_destringify_sas_addr(asd_ha->hw_prof.sas_addr, | 48 | return sas_request_addr(asd_ha->sas_ha.core.shost, |
48 | sas_addr_str); | 49 | asd_ha->hw_prof.sas_addr); |
49 | else if (asd_ha->hw_prof.sas_addr[0] != 0) | ||
50 | asd_stringify_sas_addr(sas_addr_str, asd_ha->hw_prof.sas_addr); | ||
51 | } | 50 | } |
52 | 51 | ||
53 | static void asd_propagate_sas_addr(struct asd_ha_struct *asd_ha) | 52 | static void asd_propagate_sas_addr(struct asd_ha_struct *asd_ha) |
@@ -251,7 +250,7 @@ static int asd_init_scbs(struct asd_ha_struct *asd_ha) | |||
251 | return 0; | 250 | return 0; |
252 | } | 251 | } |
253 | 252 | ||
254 | static inline void asd_get_max_scb_ddb(struct asd_ha_struct *asd_ha) | 253 | static void asd_get_max_scb_ddb(struct asd_ha_struct *asd_ha) |
255 | { | 254 | { |
256 | asd_ha->hw_prof.max_scbs = asd_get_cmdctx_size(asd_ha)/ASD_SCB_SIZE; | 255 | asd_ha->hw_prof.max_scbs = asd_get_cmdctx_size(asd_ha)/ASD_SCB_SIZE; |
257 | asd_ha->hw_prof.max_ddbs = asd_get_devctx_size(asd_ha)/ASD_DDB_SIZE; | 256 | asd_ha->hw_prof.max_ddbs = asd_get_devctx_size(asd_ha)/ASD_DDB_SIZE; |
@@ -657,8 +656,7 @@ int asd_init_hw(struct asd_ha_struct *asd_ha) | |||
657 | 656 | ||
658 | asd_init_ctxmem(asd_ha); | 657 | asd_init_ctxmem(asd_ha); |
659 | 658 | ||
660 | asd_get_user_sas_addr(asd_ha); | 659 | if (asd_get_user_sas_addr(asd_ha)) { |
661 | if (!asd_ha->hw_prof.sas_addr[0]) { | ||
662 | asd_printk("No SAS Address provided for %s\n", | 660 | asd_printk("No SAS Address provided for %s\n", |
663 | pci_name(asd_ha->pcidev)); | 661 | pci_name(asd_ha->pcidev)); |
664 | err = -ENODEV; | 662 | err = -ENODEV; |
@@ -773,7 +771,7 @@ static void asd_dl_tasklet_handler(unsigned long data) | |||
773 | * asd_process_donelist_isr -- schedule processing of done list entries | 771 | * asd_process_donelist_isr -- schedule processing of done list entries |
774 | * @asd_ha: pointer to host adapter structure | 772 | * @asd_ha: pointer to host adapter structure |
775 | */ | 773 | */ |
776 | static inline void asd_process_donelist_isr(struct asd_ha_struct *asd_ha) | 774 | static void asd_process_donelist_isr(struct asd_ha_struct *asd_ha) |
777 | { | 775 | { |
778 | tasklet_schedule(&asd_ha->seq.dl_tasklet); | 776 | tasklet_schedule(&asd_ha->seq.dl_tasklet); |
779 | } | 777 | } |
@@ -782,7 +780,7 @@ static inline void asd_process_donelist_isr(struct asd_ha_struct *asd_ha) | |||
782 | * asd_com_sas_isr -- process device communication interrupt (COMINT) | 780 | * asd_com_sas_isr -- process device communication interrupt (COMINT) |
783 | * @asd_ha: pointer to host adapter structure | 781 | * @asd_ha: pointer to host adapter structure |
784 | */ | 782 | */ |
785 | static inline void asd_com_sas_isr(struct asd_ha_struct *asd_ha) | 783 | static void asd_com_sas_isr(struct asd_ha_struct *asd_ha) |
786 | { | 784 | { |
787 | u32 comstat = asd_read_reg_dword(asd_ha, COMSTAT); | 785 | u32 comstat = asd_read_reg_dword(asd_ha, COMSTAT); |
788 | 786 | ||
@@ -821,7 +819,7 @@ static inline void asd_com_sas_isr(struct asd_ha_struct *asd_ha) | |||
821 | asd_chip_reset(asd_ha); | 819 | asd_chip_reset(asd_ha); |
822 | } | 820 | } |
823 | 821 | ||
824 | static inline void asd_arp2_err(struct asd_ha_struct *asd_ha, u32 dchstatus) | 822 | static void asd_arp2_err(struct asd_ha_struct *asd_ha, u32 dchstatus) |
825 | { | 823 | { |
826 | static const char *halt_code[256] = { | 824 | static const char *halt_code[256] = { |
827 | "UNEXPECTED_INTERRUPT0", | 825 | "UNEXPECTED_INTERRUPT0", |
@@ -908,7 +906,7 @@ static inline void asd_arp2_err(struct asd_ha_struct *asd_ha, u32 dchstatus) | |||
908 | * asd_dch_sas_isr -- process device channel interrupt (DEVINT) | 906 | * asd_dch_sas_isr -- process device channel interrupt (DEVINT) |
909 | * @asd_ha: pointer to host adapter structure | 907 | * @asd_ha: pointer to host adapter structure |
910 | */ | 908 | */ |
911 | static inline void asd_dch_sas_isr(struct asd_ha_struct *asd_ha) | 909 | static void asd_dch_sas_isr(struct asd_ha_struct *asd_ha) |
912 | { | 910 | { |
913 | u32 dchstatus = asd_read_reg_dword(asd_ha, DCHSTATUS); | 911 | u32 dchstatus = asd_read_reg_dword(asd_ha, DCHSTATUS); |
914 | 912 | ||
@@ -923,7 +921,7 @@ static inline void asd_dch_sas_isr(struct asd_ha_struct *asd_ha) | |||
923 | * ads_rbi_exsi_isr -- process external system interface interrupt (INITERR) | 921 | * ads_rbi_exsi_isr -- process external system interface interrupt (INITERR) |
924 | * @asd_ha: pointer to host adapter structure | 922 | * @asd_ha: pointer to host adapter structure |
925 | */ | 923 | */ |
926 | static inline void asd_rbi_exsi_isr(struct asd_ha_struct *asd_ha) | 924 | static void asd_rbi_exsi_isr(struct asd_ha_struct *asd_ha) |
927 | { | 925 | { |
928 | u32 stat0r = asd_read_reg_dword(asd_ha, ASISTAT0R); | 926 | u32 stat0r = asd_read_reg_dword(asd_ha, ASISTAT0R); |
929 | 927 | ||
@@ -971,7 +969,7 @@ static inline void asd_rbi_exsi_isr(struct asd_ha_struct *asd_ha) | |||
971 | * | 969 | * |
972 | * Asserted on PCIX errors: target abort, etc. | 970 | * Asserted on PCIX errors: target abort, etc. |
973 | */ | 971 | */ |
974 | static inline void asd_hst_pcix_isr(struct asd_ha_struct *asd_ha) | 972 | static void asd_hst_pcix_isr(struct asd_ha_struct *asd_ha) |
975 | { | 973 | { |
976 | u16 status; | 974 | u16 status; |
977 | u32 pcix_status; | 975 | u32 pcix_status; |
@@ -1044,8 +1042,8 @@ irqreturn_t asd_hw_isr(int irq, void *dev_id) | |||
1044 | 1042 | ||
1045 | /* ---------- SCB handling ---------- */ | 1043 | /* ---------- SCB handling ---------- */ |
1046 | 1044 | ||
1047 | static inline struct asd_ascb *asd_ascb_alloc(struct asd_ha_struct *asd_ha, | 1045 | static struct asd_ascb *asd_ascb_alloc(struct asd_ha_struct *asd_ha, |
1048 | gfp_t gfp_flags) | 1046 | gfp_t gfp_flags) |
1049 | { | 1047 | { |
1050 | extern struct kmem_cache *asd_ascb_cache; | 1048 | extern struct kmem_cache *asd_ascb_cache; |
1051 | struct asd_seq_data *seq = &asd_ha->seq; | 1049 | struct asd_seq_data *seq = &asd_ha->seq; |
@@ -1144,8 +1142,8 @@ struct asd_ascb *asd_ascb_alloc_list(struct asd_ha_struct | |||
1144 | * | 1142 | * |
1145 | * LOCKING: called with the pending list lock held. | 1143 | * LOCKING: called with the pending list lock held. |
1146 | */ | 1144 | */ |
1147 | static inline void asd_swap_head_scb(struct asd_ha_struct *asd_ha, | 1145 | static void asd_swap_head_scb(struct asd_ha_struct *asd_ha, |
1148 | struct asd_ascb *ascb) | 1146 | struct asd_ascb *ascb) |
1149 | { | 1147 | { |
1150 | struct asd_seq_data *seq = &asd_ha->seq; | 1148 | struct asd_seq_data *seq = &asd_ha->seq; |
1151 | struct asd_ascb *last = list_entry(ascb->list.prev, | 1149 | struct asd_ascb *last = list_entry(ascb->list.prev, |
@@ -1171,7 +1169,7 @@ static inline void asd_swap_head_scb(struct asd_ha_struct *asd_ha, | |||
1171 | * intended to be called from asd_post_ascb_list(), just prior to | 1169 | * intended to be called from asd_post_ascb_list(), just prior to |
1172 | * posting the SCBs to the sequencer. | 1170 | * posting the SCBs to the sequencer. |
1173 | */ | 1171 | */ |
1174 | static inline void asd_start_scb_timers(struct list_head *list) | 1172 | static void asd_start_scb_timers(struct list_head *list) |
1175 | { | 1173 | { |
1176 | struct asd_ascb *ascb; | 1174 | struct asd_ascb *ascb; |
1177 | list_for_each_entry(ascb, list, list) { | 1175 | list_for_each_entry(ascb, list, list) { |
diff --git a/drivers/scsi/aic94xx/aic94xx_hwi.h b/drivers/scsi/aic94xx/aic94xx_hwi.h index abc757559c1a..8c1c28239e93 100644 --- a/drivers/scsi/aic94xx/aic94xx_hwi.h +++ b/drivers/scsi/aic94xx/aic94xx_hwi.h | |||
@@ -391,8 +391,6 @@ void asd_build_control_phy(struct asd_ascb *ascb, int phy_id, u8 subfunc); | |||
391 | void asd_control_led(struct asd_ha_struct *asd_ha, int phy_id, int op); | 391 | void asd_control_led(struct asd_ha_struct *asd_ha, int phy_id, int op); |
392 | void asd_turn_led(struct asd_ha_struct *asd_ha, int phy_id, int op); | 392 | void asd_turn_led(struct asd_ha_struct *asd_ha, int phy_id, int op); |
393 | int asd_enable_phys(struct asd_ha_struct *asd_ha, const u8 phy_mask); | 393 | int asd_enable_phys(struct asd_ha_struct *asd_ha, const u8 phy_mask); |
394 | void asd_build_initiate_link_adm_task(struct asd_ascb *ascb, int phy_id, | ||
395 | u8 subfunc); | ||
396 | 394 | ||
397 | void asd_ascb_timedout(unsigned long data); | 395 | void asd_ascb_timedout(unsigned long data); |
398 | int asd_chip_hardrst(struct asd_ha_struct *asd_ha); | 396 | int asd_chip_hardrst(struct asd_ha_struct *asd_ha); |
diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c index 88d1e731b65e..90f5e0a6f2e3 100644 --- a/drivers/scsi/aic94xx/aic94xx_init.c +++ b/drivers/scsi/aic94xx/aic94xx_init.c | |||
@@ -56,8 +56,6 @@ MODULE_PARM_DESC(collector, "\n" | |||
56 | "\tThe aic94xx SAS LLDD supports both modes.\n" | 56 | "\tThe aic94xx SAS LLDD supports both modes.\n" |
57 | "\tDefault: 0 (Direct Mode).\n"); | 57 | "\tDefault: 0 (Direct Mode).\n"); |
58 | 58 | ||
59 | char sas_addr_str[2*SAS_ADDR_SIZE + 1] = ""; | ||
60 | |||
61 | static struct scsi_transport_template *aic94xx_transport_template; | 59 | static struct scsi_transport_template *aic94xx_transport_template; |
62 | static int asd_scan_finished(struct Scsi_Host *, unsigned long); | 60 | static int asd_scan_finished(struct Scsi_Host *, unsigned long); |
63 | static void asd_scan_start(struct Scsi_Host *); | 61 | static void asd_scan_start(struct Scsi_Host *); |
@@ -547,7 +545,7 @@ static struct asd_pcidev_struct { | |||
547 | }, | 545 | }, |
548 | }; | 546 | }; |
549 | 547 | ||
550 | static inline int asd_create_ha_caches(struct asd_ha_struct *asd_ha) | 548 | static int asd_create_ha_caches(struct asd_ha_struct *asd_ha) |
551 | { | 549 | { |
552 | asd_ha->scb_pool = dma_pool_create(ASD_DRIVER_NAME "_scb_pool", | 550 | asd_ha->scb_pool = dma_pool_create(ASD_DRIVER_NAME "_scb_pool", |
553 | &asd_ha->pcidev->dev, | 551 | &asd_ha->pcidev->dev, |
@@ -565,7 +563,7 @@ static inline int asd_create_ha_caches(struct asd_ha_struct *asd_ha) | |||
565 | * asd_free_edbs -- free empty data buffers | 563 | * asd_free_edbs -- free empty data buffers |
566 | * asd_ha: pointer to host adapter structure | 564 | * asd_ha: pointer to host adapter structure |
567 | */ | 565 | */ |
568 | static inline void asd_free_edbs(struct asd_ha_struct *asd_ha) | 566 | static void asd_free_edbs(struct asd_ha_struct *asd_ha) |
569 | { | 567 | { |
570 | struct asd_seq_data *seq = &asd_ha->seq; | 568 | struct asd_seq_data *seq = &asd_ha->seq; |
571 | int i; | 569 | int i; |
@@ -576,7 +574,7 @@ static inline void asd_free_edbs(struct asd_ha_struct *asd_ha) | |||
576 | seq->edb_arr = NULL; | 574 | seq->edb_arr = NULL; |
577 | } | 575 | } |
578 | 576 | ||
579 | static inline void asd_free_escbs(struct asd_ha_struct *asd_ha) | 577 | static void asd_free_escbs(struct asd_ha_struct *asd_ha) |
580 | { | 578 | { |
581 | struct asd_seq_data *seq = &asd_ha->seq; | 579 | struct asd_seq_data *seq = &asd_ha->seq; |
582 | int i; | 580 | int i; |
@@ -591,7 +589,7 @@ static inline void asd_free_escbs(struct asd_ha_struct *asd_ha) | |||
591 | seq->escb_arr = NULL; | 589 | seq->escb_arr = NULL; |
592 | } | 590 | } |
593 | 591 | ||
594 | static inline void asd_destroy_ha_caches(struct asd_ha_struct *asd_ha) | 592 | static void asd_destroy_ha_caches(struct asd_ha_struct *asd_ha) |
595 | { | 593 | { |
596 | int i; | 594 | int i; |
597 | 595 | ||
diff --git a/drivers/scsi/aic94xx/aic94xx_reg.c b/drivers/scsi/aic94xx/aic94xx_reg.c index f210dac3203d..56b17c22526e 100644 --- a/drivers/scsi/aic94xx/aic94xx_reg.c +++ b/drivers/scsi/aic94xx/aic94xx_reg.c | |||
@@ -32,8 +32,8 @@ | |||
32 | * Offset comes before value to remind that the operation of | 32 | * Offset comes before value to remind that the operation of |
33 | * this function is *offs = val. | 33 | * this function is *offs = val. |
34 | */ | 34 | */ |
35 | static inline void asd_write_byte(struct asd_ha_struct *asd_ha, | 35 | static void asd_write_byte(struct asd_ha_struct *asd_ha, |
36 | unsigned long offs, u8 val) | 36 | unsigned long offs, u8 val) |
37 | { | 37 | { |
38 | if (unlikely(asd_ha->iospace)) | 38 | if (unlikely(asd_ha->iospace)) |
39 | outb(val, | 39 | outb(val, |
@@ -43,8 +43,8 @@ static inline void asd_write_byte(struct asd_ha_struct *asd_ha, | |||
43 | wmb(); | 43 | wmb(); |
44 | } | 44 | } |
45 | 45 | ||
46 | static inline void asd_write_word(struct asd_ha_struct *asd_ha, | 46 | static void asd_write_word(struct asd_ha_struct *asd_ha, |
47 | unsigned long offs, u16 val) | 47 | unsigned long offs, u16 val) |
48 | { | 48 | { |
49 | if (unlikely(asd_ha->iospace)) | 49 | if (unlikely(asd_ha->iospace)) |
50 | outw(val, | 50 | outw(val, |
@@ -54,8 +54,8 @@ static inline void asd_write_word(struct asd_ha_struct *asd_ha, | |||
54 | wmb(); | 54 | wmb(); |
55 | } | 55 | } |
56 | 56 | ||
57 | static inline void asd_write_dword(struct asd_ha_struct *asd_ha, | 57 | static void asd_write_dword(struct asd_ha_struct *asd_ha, |
58 | unsigned long offs, u32 val) | 58 | unsigned long offs, u32 val) |
59 | { | 59 | { |
60 | if (unlikely(asd_ha->iospace)) | 60 | if (unlikely(asd_ha->iospace)) |
61 | outl(val, | 61 | outl(val, |
@@ -67,8 +67,7 @@ static inline void asd_write_dword(struct asd_ha_struct *asd_ha, | |||
67 | 67 | ||
68 | /* Reading from device address space. | 68 | /* Reading from device address space. |
69 | */ | 69 | */ |
70 | static inline u8 asd_read_byte(struct asd_ha_struct *asd_ha, | 70 | static u8 asd_read_byte(struct asd_ha_struct *asd_ha, unsigned long offs) |
71 | unsigned long offs) | ||
72 | { | 71 | { |
73 | u8 val; | 72 | u8 val; |
74 | if (unlikely(asd_ha->iospace)) | 73 | if (unlikely(asd_ha->iospace)) |
@@ -80,8 +79,8 @@ static inline u8 asd_read_byte(struct asd_ha_struct *asd_ha, | |||
80 | return val; | 79 | return val; |
81 | } | 80 | } |
82 | 81 | ||
83 | static inline u16 asd_read_word(struct asd_ha_struct *asd_ha, | 82 | static u16 asd_read_word(struct asd_ha_struct *asd_ha, |
84 | unsigned long offs) | 83 | unsigned long offs) |
85 | { | 84 | { |
86 | u16 val; | 85 | u16 val; |
87 | if (unlikely(asd_ha->iospace)) | 86 | if (unlikely(asd_ha->iospace)) |
@@ -93,8 +92,8 @@ static inline u16 asd_read_word(struct asd_ha_struct *asd_ha, | |||
93 | return val; | 92 | return val; |
94 | } | 93 | } |
95 | 94 | ||
96 | static inline u32 asd_read_dword(struct asd_ha_struct *asd_ha, | 95 | static u32 asd_read_dword(struct asd_ha_struct *asd_ha, |
97 | unsigned long offs) | 96 | unsigned long offs) |
98 | { | 97 | { |
99 | u32 val; | 98 | u32 val; |
100 | if (unlikely(asd_ha->iospace)) | 99 | if (unlikely(asd_ha->iospace)) |
@@ -124,22 +123,22 @@ static inline u32 asd_mem_offs_swb(void) | |||
124 | /* We know that the register wanted is in the range | 123 | /* We know that the register wanted is in the range |
125 | * of the sliding window. | 124 | * of the sliding window. |
126 | */ | 125 | */ |
127 | #define ASD_READ_SW(ww, type, ord) \ | 126 | #define ASD_READ_SW(ww, type, ord) \ |
128 | static inline type asd_read_##ww##_##ord (struct asd_ha_struct *asd_ha,\ | 127 | static type asd_read_##ww##_##ord(struct asd_ha_struct *asd_ha, \ |
129 | u32 reg) \ | 128 | u32 reg) \ |
130 | { \ | 129 | { \ |
131 | struct asd_ha_addrspace *io_handle = &asd_ha->io_handle[0]; \ | 130 | struct asd_ha_addrspace *io_handle = &asd_ha->io_handle[0]; \ |
132 | u32 map_offs=(reg - io_handle-> ww##_base )+asd_mem_offs_##ww ();\ | 131 | u32 map_offs = (reg - io_handle->ww##_base) + asd_mem_offs_##ww();\ |
133 | return asd_read_##ord (asd_ha, (unsigned long) map_offs); \ | 132 | return asd_read_##ord(asd_ha, (unsigned long)map_offs); \ |
134 | } | 133 | } |
135 | 134 | ||
136 | #define ASD_WRITE_SW(ww, type, ord) \ | 135 | #define ASD_WRITE_SW(ww, type, ord) \ |
137 | static inline void asd_write_##ww##_##ord (struct asd_ha_struct *asd_ha,\ | 136 | static void asd_write_##ww##_##ord(struct asd_ha_struct *asd_ha, \ |
138 | u32 reg, type val) \ | 137 | u32 reg, type val) \ |
139 | { \ | 138 | { \ |
140 | struct asd_ha_addrspace *io_handle = &asd_ha->io_handle[0]; \ | 139 | struct asd_ha_addrspace *io_handle = &asd_ha->io_handle[0]; \ |
141 | u32 map_offs=(reg - io_handle-> ww##_base )+asd_mem_offs_##ww ();\ | 140 | u32 map_offs = (reg - io_handle->ww##_base) + asd_mem_offs_##ww();\ |
142 | asd_write_##ord (asd_ha, (unsigned long) map_offs, val); \ | 141 | asd_write_##ord(asd_ha, (unsigned long)map_offs, val); \ |
143 | } | 142 | } |
144 | 143 | ||
145 | ASD_READ_SW(swa, u8, byte); | 144 | ASD_READ_SW(swa, u8, byte); |
@@ -186,7 +185,7 @@ ASD_WRITE_SW(swc, u32, dword); | |||
186 | * @asd_ha: pointer to host adapter structure | 185 | * @asd_ha: pointer to host adapter structure |
187 | * @reg: register desired to be within range of the new window | 186 | * @reg: register desired to be within range of the new window |
188 | */ | 187 | */ |
189 | static inline void asd_move_swb(struct asd_ha_struct *asd_ha, u32 reg) | 188 | static void asd_move_swb(struct asd_ha_struct *asd_ha, u32 reg) |
190 | { | 189 | { |
191 | u32 base = reg & ~(MBAR0_SWB_SIZE-1); | 190 | u32 base = reg & ~(MBAR0_SWB_SIZE-1); |
192 | pci_write_config_dword(asd_ha->pcidev, PCI_CONF_MBAR0_SWB, base); | 191 | pci_write_config_dword(asd_ha->pcidev, PCI_CONF_MBAR0_SWB, base); |
diff --git a/drivers/scsi/aic94xx/aic94xx_scb.c b/drivers/scsi/aic94xx/aic94xx_scb.c index ab350504ca5a..46643319c520 100644 --- a/drivers/scsi/aic94xx/aic94xx_scb.c +++ b/drivers/scsi/aic94xx/aic94xx_scb.c | |||
@@ -50,7 +50,7 @@ | |||
50 | | CURRENT_SPINUP_HOLD | CURRENT_GTO_TIMEOUT \ | 50 | | CURRENT_SPINUP_HOLD | CURRENT_GTO_TIMEOUT \ |
51 | | CURRENT_OOB_ERROR) | 51 | | CURRENT_OOB_ERROR) |
52 | 52 | ||
53 | static inline void get_lrate_mode(struct asd_phy *phy, u8 oob_mode) | 53 | static void get_lrate_mode(struct asd_phy *phy, u8 oob_mode) |
54 | { | 54 | { |
55 | struct sas_phy *sas_phy = phy->sas_phy.phy; | 55 | struct sas_phy *sas_phy = phy->sas_phy.phy; |
56 | 56 | ||
@@ -81,7 +81,7 @@ static inline void get_lrate_mode(struct asd_phy *phy, u8 oob_mode) | |||
81 | phy->sas_phy.oob_mode = SATA_OOB_MODE; | 81 | phy->sas_phy.oob_mode = SATA_OOB_MODE; |
82 | } | 82 | } |
83 | 83 | ||
84 | static inline void asd_phy_event_tasklet(struct asd_ascb *ascb, | 84 | static void asd_phy_event_tasklet(struct asd_ascb *ascb, |
85 | struct done_list_struct *dl) | 85 | struct done_list_struct *dl) |
86 | { | 86 | { |
87 | struct asd_ha_struct *asd_ha = ascb->ha; | 87 | struct asd_ha_struct *asd_ha = ascb->ha; |
@@ -125,8 +125,7 @@ static inline void asd_phy_event_tasklet(struct asd_ascb *ascb, | |||
125 | } | 125 | } |
126 | 126 | ||
127 | /* If phys are enabled sparsely, this will do the right thing. */ | 127 | /* If phys are enabled sparsely, this will do the right thing. */ |
128 | static inline unsigned ord_phy(struct asd_ha_struct *asd_ha, | 128 | static unsigned ord_phy(struct asd_ha_struct *asd_ha, struct asd_phy *phy) |
129 | struct asd_phy *phy) | ||
130 | { | 129 | { |
131 | u8 enabled_mask = asd_ha->hw_prof.enabled_phys; | 130 | u8 enabled_mask = asd_ha->hw_prof.enabled_phys; |
132 | int i, k = 0; | 131 | int i, k = 0; |
@@ -151,7 +150,7 @@ static inline unsigned ord_phy(struct asd_ha_struct *asd_ha, | |||
151 | * LOCKING: the frame_rcvd_lock needs to be held since this parses the frame | 150 | * LOCKING: the frame_rcvd_lock needs to be held since this parses the frame |
152 | * buffer. | 151 | * buffer. |
153 | */ | 152 | */ |
154 | static inline void asd_get_attached_sas_addr(struct asd_phy *phy, u8 *sas_addr) | 153 | static void asd_get_attached_sas_addr(struct asd_phy *phy, u8 *sas_addr) |
155 | { | 154 | { |
156 | if (phy->sas_phy.frame_rcvd[0] == 0x34 | 155 | if (phy->sas_phy.frame_rcvd[0] == 0x34 |
157 | && phy->sas_phy.oob_mode == SATA_OOB_MODE) { | 156 | && phy->sas_phy.oob_mode == SATA_OOB_MODE) { |
@@ -232,9 +231,9 @@ static void asd_deform_port(struct asd_ha_struct *asd_ha, struct asd_phy *phy) | |||
232 | spin_unlock_irqrestore(&asd_ha->asd_ports_lock, flags); | 231 | spin_unlock_irqrestore(&asd_ha->asd_ports_lock, flags); |
233 | } | 232 | } |
234 | 233 | ||
235 | static inline void asd_bytes_dmaed_tasklet(struct asd_ascb *ascb, | 234 | static void asd_bytes_dmaed_tasklet(struct asd_ascb *ascb, |
236 | struct done_list_struct *dl, | 235 | struct done_list_struct *dl, |
237 | int edb_id, int phy_id) | 236 | int edb_id, int phy_id) |
238 | { | 237 | { |
239 | unsigned long flags; | 238 | unsigned long flags; |
240 | int edb_el = edb_id + ascb->edb_index; | 239 | int edb_el = edb_id + ascb->edb_index; |
@@ -255,9 +254,9 @@ static inline void asd_bytes_dmaed_tasklet(struct asd_ascb *ascb, | |||
255 | sas_ha->notify_port_event(&phy->sas_phy, PORTE_BYTES_DMAED); | 254 | sas_ha->notify_port_event(&phy->sas_phy, PORTE_BYTES_DMAED); |
256 | } | 255 | } |
257 | 256 | ||
258 | static inline void asd_link_reset_err_tasklet(struct asd_ascb *ascb, | 257 | static void asd_link_reset_err_tasklet(struct asd_ascb *ascb, |
259 | struct done_list_struct *dl, | 258 | struct done_list_struct *dl, |
260 | int phy_id) | 259 | int phy_id) |
261 | { | 260 | { |
262 | struct asd_ha_struct *asd_ha = ascb->ha; | 261 | struct asd_ha_struct *asd_ha = ascb->ha; |
263 | struct sas_ha_struct *sas_ha = &asd_ha->sas_ha; | 262 | struct sas_ha_struct *sas_ha = &asd_ha->sas_ha; |
@@ -308,9 +307,9 @@ out: | |||
308 | ; | 307 | ; |
309 | } | 308 | } |
310 | 309 | ||
311 | static inline void asd_primitive_rcvd_tasklet(struct asd_ascb *ascb, | 310 | static void asd_primitive_rcvd_tasklet(struct asd_ascb *ascb, |
312 | struct done_list_struct *dl, | 311 | struct done_list_struct *dl, |
313 | int phy_id) | 312 | int phy_id) |
314 | { | 313 | { |
315 | unsigned long flags; | 314 | unsigned long flags; |
316 | struct sas_ha_struct *sas_ha = &ascb->ha->sas_ha; | 315 | struct sas_ha_struct *sas_ha = &ascb->ha->sas_ha; |
@@ -715,7 +714,7 @@ out: | |||
715 | asd_ascb_free(ascb); | 714 | asd_ascb_free(ascb); |
716 | } | 715 | } |
717 | 716 | ||
718 | static inline void set_speed_mask(u8 *speed_mask, struct asd_phy_desc *pd) | 717 | static void set_speed_mask(u8 *speed_mask, struct asd_phy_desc *pd) |
719 | { | 718 | { |
720 | /* disable all speeds, then enable defaults */ | 719 | /* disable all speeds, then enable defaults */ |
721 | *speed_mask = SAS_SPEED_60_DIS | SAS_SPEED_30_DIS | SAS_SPEED_15_DIS | 720 | *speed_mask = SAS_SPEED_60_DIS | SAS_SPEED_30_DIS | SAS_SPEED_15_DIS |
@@ -820,6 +819,8 @@ void asd_build_control_phy(struct asd_ascb *ascb, int phy_id, u8 subfunc) | |||
820 | 819 | ||
821 | /* ---------- INITIATE LINK ADM TASK ---------- */ | 820 | /* ---------- INITIATE LINK ADM TASK ---------- */ |
822 | 821 | ||
822 | #if 0 | ||
823 | |||
823 | static void link_adm_tasklet_complete(struct asd_ascb *ascb, | 824 | static void link_adm_tasklet_complete(struct asd_ascb *ascb, |
824 | struct done_list_struct *dl) | 825 | struct done_list_struct *dl) |
825 | { | 826 | { |
@@ -852,6 +853,8 @@ void asd_build_initiate_link_adm_task(struct asd_ascb *ascb, int phy_id, | |||
852 | ascb->tasklet_complete = link_adm_tasklet_complete; | 853 | ascb->tasklet_complete = link_adm_tasklet_complete; |
853 | } | 854 | } |
854 | 855 | ||
856 | #endif /* 0 */ | ||
857 | |||
855 | /* ---------- SCB timer ---------- */ | 858 | /* ---------- SCB timer ---------- */ |
856 | 859 | ||
857 | /** | 860 | /** |
diff --git a/drivers/scsi/aic94xx/aic94xx_sds.c b/drivers/scsi/aic94xx/aic94xx_sds.c index 2a4c933eb89c..4446e3d584dc 100644 --- a/drivers/scsi/aic94xx/aic94xx_sds.c +++ b/drivers/scsi/aic94xx/aic94xx_sds.c | |||
@@ -590,8 +590,8 @@ static int asd_reset_flash(struct asd_ha_struct *asd_ha) | |||
590 | return err; | 590 | return err; |
591 | } | 591 | } |
592 | 592 | ||
593 | static inline int asd_read_flash_seg(struct asd_ha_struct *asd_ha, | 593 | static int asd_read_flash_seg(struct asd_ha_struct *asd_ha, |
594 | void *buffer, u32 offs, int size) | 594 | void *buffer, u32 offs, int size) |
595 | { | 595 | { |
596 | asd_read_reg_string(asd_ha, buffer, asd_ha->hw_prof.flash.bar+offs, | 596 | asd_read_reg_string(asd_ha, buffer, asd_ha->hw_prof.flash.bar+offs, |
597 | size); | 597 | size); |
diff --git a/drivers/scsi/aic94xx/aic94xx_seq.c b/drivers/scsi/aic94xx/aic94xx_seq.c index c750fbf7013b..f4272ac4c685 100644 --- a/drivers/scsi/aic94xx/aic94xx_seq.c +++ b/drivers/scsi/aic94xx/aic94xx_seq.c | |||
@@ -60,7 +60,7 @@ static u16 last_scb_site_no; | |||
60 | * | 60 | * |
61 | * Return 0 on success, negative on failure. | 61 | * Return 0 on success, negative on failure. |
62 | */ | 62 | */ |
63 | int asd_pause_cseq(struct asd_ha_struct *asd_ha) | 63 | static int asd_pause_cseq(struct asd_ha_struct *asd_ha) |
64 | { | 64 | { |
65 | int count = PAUSE_TRIES; | 65 | int count = PAUSE_TRIES; |
66 | u32 arp2ctl; | 66 | u32 arp2ctl; |
@@ -87,7 +87,7 @@ int asd_pause_cseq(struct asd_ha_struct *asd_ha) | |||
87 | * | 87 | * |
88 | * Return 0 on success, negative on error. | 88 | * Return 0 on success, negative on error. |
89 | */ | 89 | */ |
90 | int asd_unpause_cseq(struct asd_ha_struct *asd_ha) | 90 | static int asd_unpause_cseq(struct asd_ha_struct *asd_ha) |
91 | { | 91 | { |
92 | u32 arp2ctl; | 92 | u32 arp2ctl; |
93 | int count = PAUSE_TRIES; | 93 | int count = PAUSE_TRIES; |
@@ -115,7 +115,7 @@ int asd_unpause_cseq(struct asd_ha_struct *asd_ha) | |||
115 | * | 115 | * |
116 | * Return 0 on success, negative on error. | 116 | * Return 0 on success, negative on error. |
117 | */ | 117 | */ |
118 | static inline int asd_seq_pause_lseq(struct asd_ha_struct *asd_ha, int lseq) | 118 | static int asd_seq_pause_lseq(struct asd_ha_struct *asd_ha, int lseq) |
119 | { | 119 | { |
120 | u32 arp2ctl; | 120 | u32 arp2ctl; |
121 | int count = PAUSE_TRIES; | 121 | int count = PAUSE_TRIES; |
@@ -143,7 +143,7 @@ static inline int asd_seq_pause_lseq(struct asd_ha_struct *asd_ha, int lseq) | |||
143 | * | 143 | * |
144 | * Return 0 on success, negative on failure. | 144 | * Return 0 on success, negative on failure. |
145 | */ | 145 | */ |
146 | int asd_pause_lseq(struct asd_ha_struct *asd_ha, u8 lseq_mask) | 146 | static int asd_pause_lseq(struct asd_ha_struct *asd_ha, u8 lseq_mask) |
147 | { | 147 | { |
148 | int lseq; | 148 | int lseq; |
149 | int err = 0; | 149 | int err = 0; |
@@ -164,7 +164,7 @@ int asd_pause_lseq(struct asd_ha_struct *asd_ha, u8 lseq_mask) | |||
164 | * | 164 | * |
165 | * Return 0 on success, negative on error. | 165 | * Return 0 on success, negative on error. |
166 | */ | 166 | */ |
167 | static inline int asd_seq_unpause_lseq(struct asd_ha_struct *asd_ha, int lseq) | 167 | static int asd_seq_unpause_lseq(struct asd_ha_struct *asd_ha, int lseq) |
168 | { | 168 | { |
169 | u32 arp2ctl; | 169 | u32 arp2ctl; |
170 | int count = PAUSE_TRIES; | 170 | int count = PAUSE_TRIES; |
@@ -186,27 +186,6 @@ static inline int asd_seq_unpause_lseq(struct asd_ha_struct *asd_ha, int lseq) | |||
186 | } | 186 | } |
187 | 187 | ||
188 | 188 | ||
189 | /** | ||
190 | * asd_unpause_lseq - unpause the link sequencer(s) | ||
191 | * @asd_ha: pointer to host adapter structure | ||
192 | * @lseq_mask: mask of link sequencers of interest | ||
193 | * | ||
194 | * Return 0 on success, negative on failure. | ||
195 | */ | ||
196 | int asd_unpause_lseq(struct asd_ha_struct *asd_ha, u8 lseq_mask) | ||
197 | { | ||
198 | int lseq; | ||
199 | int err = 0; | ||
200 | |||
201 | for_each_sequencer(lseq_mask, lseq_mask, lseq) { | ||
202 | err = asd_seq_unpause_lseq(asd_ha, lseq); | ||
203 | if (err) | ||
204 | return err; | ||
205 | } | ||
206 | |||
207 | return err; | ||
208 | } | ||
209 | |||
210 | /* ---------- Downloading CSEQ/LSEQ microcode ---------- */ | 189 | /* ---------- Downloading CSEQ/LSEQ microcode ---------- */ |
211 | 190 | ||
212 | static int asd_verify_cseq(struct asd_ha_struct *asd_ha, const u8 *_prog, | 191 | static int asd_verify_cseq(struct asd_ha_struct *asd_ha, const u8 *_prog, |
diff --git a/drivers/scsi/aic94xx/aic94xx_seq.h b/drivers/scsi/aic94xx/aic94xx_seq.h index 2ea6a0d52208..ad787c55525f 100644 --- a/drivers/scsi/aic94xx/aic94xx_seq.h +++ b/drivers/scsi/aic94xx/aic94xx_seq.h | |||
@@ -58,10 +58,6 @@ struct sequencer_file_header { | |||
58 | } __attribute__((packed)); | 58 | } __attribute__((packed)); |
59 | 59 | ||
60 | #ifdef __KERNEL__ | 60 | #ifdef __KERNEL__ |
61 | int asd_pause_cseq(struct asd_ha_struct *asd_ha); | ||
62 | int asd_unpause_cseq(struct asd_ha_struct *asd_ha); | ||
63 | int asd_pause_lseq(struct asd_ha_struct *asd_ha, u8 lseq_mask); | ||
64 | int asd_unpause_lseq(struct asd_ha_struct *asd_ha, u8 lseq_mask); | ||
65 | int asd_init_seqs(struct asd_ha_struct *asd_ha); | 61 | int asd_init_seqs(struct asd_ha_struct *asd_ha); |
66 | int asd_start_seqs(struct asd_ha_struct *asd_ha); | 62 | int asd_start_seqs(struct asd_ha_struct *asd_ha); |
67 | int asd_release_firmware(void); | 63 | int asd_release_firmware(void); |
diff --git a/drivers/scsi/aic94xx/aic94xx_task.c b/drivers/scsi/aic94xx/aic94xx_task.c index 008df9ab92a5..326765c9caf8 100644 --- a/drivers/scsi/aic94xx/aic94xx_task.c +++ b/drivers/scsi/aic94xx/aic94xx_task.c | |||
@@ -33,7 +33,7 @@ static void asd_unbuild_ata_ascb(struct asd_ascb *a); | |||
33 | static void asd_unbuild_smp_ascb(struct asd_ascb *a); | 33 | static void asd_unbuild_smp_ascb(struct asd_ascb *a); |
34 | static void asd_unbuild_ssp_ascb(struct asd_ascb *a); | 34 | static void asd_unbuild_ssp_ascb(struct asd_ascb *a); |
35 | 35 | ||
36 | static inline void asd_can_dequeue(struct asd_ha_struct *asd_ha, int num) | 36 | static void asd_can_dequeue(struct asd_ha_struct *asd_ha, int num) |
37 | { | 37 | { |
38 | unsigned long flags; | 38 | unsigned long flags; |
39 | 39 | ||
@@ -51,9 +51,9 @@ static const u8 data_dir_flags[] = { | |||
51 | [PCI_DMA_NONE] = DATA_DIR_NONE, /* NO TRANSFER */ | 51 | [PCI_DMA_NONE] = DATA_DIR_NONE, /* NO TRANSFER */ |
52 | }; | 52 | }; |
53 | 53 | ||
54 | static inline int asd_map_scatterlist(struct sas_task *task, | 54 | static int asd_map_scatterlist(struct sas_task *task, |
55 | struct sg_el *sg_arr, | 55 | struct sg_el *sg_arr, |
56 | gfp_t gfp_flags) | 56 | gfp_t gfp_flags) |
57 | { | 57 | { |
58 | struct asd_ascb *ascb = task->lldd_task; | 58 | struct asd_ascb *ascb = task->lldd_task; |
59 | struct asd_ha_struct *asd_ha = ascb->ha; | 59 | struct asd_ha_struct *asd_ha = ascb->ha; |
@@ -131,7 +131,7 @@ err_unmap: | |||
131 | return res; | 131 | return res; |
132 | } | 132 | } |
133 | 133 | ||
134 | static inline void asd_unmap_scatterlist(struct asd_ascb *ascb) | 134 | static void asd_unmap_scatterlist(struct asd_ascb *ascb) |
135 | { | 135 | { |
136 | struct asd_ha_struct *asd_ha = ascb->ha; | 136 | struct asd_ha_struct *asd_ha = ascb->ha; |
137 | struct sas_task *task = ascb->uldd_task; | 137 | struct sas_task *task = ascb->uldd_task; |
@@ -527,7 +527,7 @@ static void asd_unbuild_ssp_ascb(struct asd_ascb *a) | |||
527 | 527 | ||
528 | /* ---------- Execute Task ---------- */ | 528 | /* ---------- Execute Task ---------- */ |
529 | 529 | ||
530 | static inline int asd_can_queue(struct asd_ha_struct *asd_ha, int num) | 530 | static int asd_can_queue(struct asd_ha_struct *asd_ha, int num) |
531 | { | 531 | { |
532 | int res = 0; | 532 | int res = 0; |
533 | unsigned long flags; | 533 | unsigned long flags; |
diff --git a/drivers/scsi/aic94xx/aic94xx_tmf.c b/drivers/scsi/aic94xx/aic94xx_tmf.c index b9ac8f703a1d..633ff40c736a 100644 --- a/drivers/scsi/aic94xx/aic94xx_tmf.c +++ b/drivers/scsi/aic94xx/aic94xx_tmf.c | |||
@@ -336,7 +336,7 @@ static void asd_tmf_tasklet_complete(struct asd_ascb *ascb, | |||
336 | asd_ascb_free(ascb); | 336 | asd_ascb_free(ascb); |
337 | } | 337 | } |
338 | 338 | ||
339 | static inline int asd_clear_nexus(struct sas_task *task) | 339 | static int asd_clear_nexus(struct sas_task *task) |
340 | { | 340 | { |
341 | int res = TMF_RESP_FUNC_FAILED; | 341 | int res = TMF_RESP_FUNC_FAILED; |
342 | int leftover; | 342 | int leftover; |
diff --git a/drivers/scsi/arm/acornscsi.c b/drivers/scsi/arm/acornscsi.c index 3bedf2466bd1..8e53f02cc311 100644 --- a/drivers/scsi/arm/acornscsi.c +++ b/drivers/scsi/arm/acornscsi.c | |||
@@ -2983,7 +2983,6 @@ static struct scsi_host_template acornscsi_template = { | |||
2983 | .this_id = 7, | 2983 | .this_id = 7, |
2984 | .sg_tablesize = SG_ALL, | 2984 | .sg_tablesize = SG_ALL, |
2985 | .cmd_per_lun = 2, | 2985 | .cmd_per_lun = 2, |
2986 | .unchecked_isa_dma = 0, | ||
2987 | .use_clustering = DISABLE_CLUSTERING, | 2986 | .use_clustering = DISABLE_CLUSTERING, |
2988 | .proc_name = "acornscsi", | 2987 | .proc_name = "acornscsi", |
2989 | }; | 2988 | }; |
diff --git a/drivers/scsi/arm/cumana_1.c b/drivers/scsi/arm/cumana_1.c index 49d838e90a24..a3398fe70a9c 100644 --- a/drivers/scsi/arm/cumana_1.c +++ b/drivers/scsi/arm/cumana_1.c | |||
@@ -222,7 +222,6 @@ static struct scsi_host_template cumanascsi_template = { | |||
222 | .this_id = 7, | 222 | .this_id = 7, |
223 | .sg_tablesize = SG_ALL, | 223 | .sg_tablesize = SG_ALL, |
224 | .cmd_per_lun = 2, | 224 | .cmd_per_lun = 2, |
225 | .unchecked_isa_dma = 0, | ||
226 | .use_clustering = DISABLE_CLUSTERING, | 225 | .use_clustering = DISABLE_CLUSTERING, |
227 | .proc_name = "CumanaSCSI-1", | 226 | .proc_name = "CumanaSCSI-1", |
228 | }; | 227 | }; |
diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c index 7aad15436d24..92d1cb1b21cb 100644 --- a/drivers/scsi/ch.c +++ b/drivers/scsi/ch.c | |||
@@ -113,7 +113,7 @@ static const struct { | |||
113 | unsigned char asc; | 113 | unsigned char asc; |
114 | unsigned char ascq; | 114 | unsigned char ascq; |
115 | int errno; | 115 | int errno; |
116 | } err[] = { | 116 | } ch_err[] = { |
117 | /* Just filled in what looks right. Hav'nt checked any standard paper for | 117 | /* Just filled in what looks right. Hav'nt checked any standard paper for |
118 | these errno assignments, so they may be wrong... */ | 118 | these errno assignments, so they may be wrong... */ |
119 | { | 119 | { |
@@ -155,11 +155,11 @@ static int ch_find_errno(struct scsi_sense_hdr *sshdr) | |||
155 | /* Check to see if additional sense information is available */ | 155 | /* Check to see if additional sense information is available */ |
156 | if (scsi_sense_valid(sshdr) && | 156 | if (scsi_sense_valid(sshdr) && |
157 | sshdr->asc != 0) { | 157 | sshdr->asc != 0) { |
158 | for (i = 0; err[i].errno != 0; i++) { | 158 | for (i = 0; ch_err[i].errno != 0; i++) { |
159 | if (err[i].sense == sshdr->sense_key && | 159 | if (ch_err[i].sense == sshdr->sense_key && |
160 | err[i].asc == sshdr->asc && | 160 | ch_err[i].asc == sshdr->asc && |
161 | err[i].ascq == sshdr->ascq) { | 161 | ch_err[i].ascq == sshdr->ascq) { |
162 | errno = -err[i].errno; | 162 | errno = -ch_err[i].errno; |
163 | break; | 163 | break; |
164 | } | 164 | } |
165 | } | 165 | } |
@@ -721,8 +721,8 @@ static long ch_ioctl(struct file *file, | |||
721 | case CHIOGELEM: | 721 | case CHIOGELEM: |
722 | { | 722 | { |
723 | struct changer_get_element cge; | 723 | struct changer_get_element cge; |
724 | u_char cmd[12]; | 724 | u_char ch_cmd[12]; |
725 | u_char *buffer; | 725 | u_char *buffer; |
726 | unsigned int elem; | 726 | unsigned int elem; |
727 | int result,i; | 727 | int result,i; |
728 | 728 | ||
@@ -739,17 +739,18 @@ static long ch_ioctl(struct file *file, | |||
739 | mutex_lock(&ch->lock); | 739 | mutex_lock(&ch->lock); |
740 | 740 | ||
741 | voltag_retry: | 741 | voltag_retry: |
742 | memset(cmd,0,sizeof(cmd)); | 742 | memset(ch_cmd, 0, sizeof(ch_cmd)); |
743 | cmd[0] = READ_ELEMENT_STATUS; | 743 | ch_cmd[0] = READ_ELEMENT_STATUS; |
744 | cmd[1] = (ch->device->lun << 5) | | 744 | ch_cmd[1] = (ch->device->lun << 5) | |
745 | (ch->voltags ? 0x10 : 0) | | 745 | (ch->voltags ? 0x10 : 0) | |
746 | ch_elem_to_typecode(ch,elem); | 746 | ch_elem_to_typecode(ch,elem); |
747 | cmd[2] = (elem >> 8) & 0xff; | 747 | ch_cmd[2] = (elem >> 8) & 0xff; |
748 | cmd[3] = elem & 0xff; | 748 | ch_cmd[3] = elem & 0xff; |
749 | cmd[5] = 1; | 749 | ch_cmd[5] = 1; |
750 | cmd[9] = 255; | 750 | ch_cmd[9] = 255; |
751 | 751 | ||
752 | if (0 == (result = ch_do_scsi(ch, cmd, buffer, 256, DMA_FROM_DEVICE))) { | 752 | result = ch_do_scsi(ch, ch_cmd, buffer, 256, DMA_FROM_DEVICE); |
753 | if (!result) { | ||
753 | cge.cge_status = buffer[18]; | 754 | cge.cge_status = buffer[18]; |
754 | cge.cge_flags = 0; | 755 | cge.cge_flags = 0; |
755 | if (buffer[18] & CESTATUS_EXCEPT) { | 756 | if (buffer[18] & CESTATUS_EXCEPT) { |
diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c index e351db6c0077..075e2397273c 100644 --- a/drivers/scsi/dc395x.c +++ b/drivers/scsi/dc395x.c | |||
@@ -4761,7 +4761,6 @@ static struct scsi_host_template dc395x_driver_template = { | |||
4761 | .cmd_per_lun = DC395x_MAX_CMD_PER_LUN, | 4761 | .cmd_per_lun = DC395x_MAX_CMD_PER_LUN, |
4762 | .eh_abort_handler = dc395x_eh_abort, | 4762 | .eh_abort_handler = dc395x_eh_abort, |
4763 | .eh_bus_reset_handler = dc395x_eh_bus_reset, | 4763 | .eh_bus_reset_handler = dc395x_eh_bus_reset, |
4764 | .unchecked_isa_dma = 0, | ||
4765 | .use_clustering = DISABLE_CLUSTERING, | 4764 | .use_clustering = DISABLE_CLUSTERING, |
4766 | }; | 4765 | }; |
4767 | 4766 | ||
diff --git a/drivers/scsi/eata_pio.c b/drivers/scsi/eata_pio.c index b5a60926e556..952505c006df 100644 --- a/drivers/scsi/eata_pio.c +++ b/drivers/scsi/eata_pio.c | |||
@@ -815,8 +815,6 @@ static int register_pio_HBA(long base, struct get_conf *gc, struct pci_dev *pdev | |||
815 | else | 815 | else |
816 | hd->primary = 1; | 816 | hd->primary = 1; |
817 | 817 | ||
818 | sh->unchecked_isa_dma = 0; /* We can only do PIO */ | ||
819 | |||
820 | hd->next = NULL; /* build a linked list of all HBAs */ | 818 | hd->next = NULL; /* build a linked list of all HBAs */ |
821 | hd->prev = last_HBA; | 819 | hd->prev = last_HBA; |
822 | if (hd->prev != NULL) | 820 | if (hd->prev != NULL) |
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index 0b2080d33575..c6d6e7c6559a 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c | |||
@@ -85,10 +85,10 @@ | |||
85 | 85 | ||
86 | /* The meaning of the Scsi_Pointer members in this driver is as follows: | 86 | /* The meaning of the Scsi_Pointer members in this driver is as follows: |
87 | * ptr: Chaining | 87 | * ptr: Chaining |
88 | * this_residual: gdth_bufflen | 88 | * this_residual: unused |
89 | * buffer: gdth_sglist | 89 | * buffer: unused |
90 | * dma_handle: unused | 90 | * dma_handle: unused |
91 | * buffers_residual: gdth_sg_count | 91 | * buffers_residual: unused |
92 | * Status: unused | 92 | * Status: unused |
93 | * Message: unused | 93 | * Message: unused |
94 | * have_data_in: unused | 94 | * have_data_in: unused |
@@ -372,47 +372,6 @@ static const struct file_operations gdth_fops = { | |||
372 | .release = gdth_close, | 372 | .release = gdth_close, |
373 | }; | 373 | }; |
374 | 374 | ||
375 | /* | ||
376 | * gdth scsi_command access wrappers. | ||
377 | * below 6 functions are used throughout the driver to access scsi_command's | ||
378 | * io parameters. The reason we do not use the regular accessors from | ||
379 | * scsi_cmnd.h is because of gdth_execute(). Since it is unrecommended for | ||
380 | * llds to directly set scsi_cmnd's IO members. This driver will use SCp | ||
381 | * members for IO parameters, and will copy scsi_cmnd's members to Scp | ||
382 | * members in queuecommand. For internal commands through gdth_execute() | ||
383 | * SCp's members will be set directly. | ||
384 | */ | ||
385 | static inline unsigned gdth_bufflen(struct scsi_cmnd *cmd) | ||
386 | { | ||
387 | return (unsigned)cmd->SCp.this_residual; | ||
388 | } | ||
389 | |||
390 | static inline void gdth_set_bufflen(struct scsi_cmnd *cmd, unsigned bufflen) | ||
391 | { | ||
392 | cmd->SCp.this_residual = bufflen; | ||
393 | } | ||
394 | |||
395 | static inline unsigned gdth_sg_count(struct scsi_cmnd *cmd) | ||
396 | { | ||
397 | return (unsigned)cmd->SCp.buffers_residual; | ||
398 | } | ||
399 | |||
400 | static inline void gdth_set_sg_count(struct scsi_cmnd *cmd, unsigned sg_count) | ||
401 | { | ||
402 | cmd->SCp.buffers_residual = sg_count; | ||
403 | } | ||
404 | |||
405 | static inline struct scatterlist *gdth_sglist(struct scsi_cmnd *cmd) | ||
406 | { | ||
407 | return cmd->SCp.buffer; | ||
408 | } | ||
409 | |||
410 | static inline void gdth_set_sglist(struct scsi_cmnd *cmd, | ||
411 | struct scatterlist *sglist) | ||
412 | { | ||
413 | cmd->SCp.buffer = sglist; | ||
414 | } | ||
415 | |||
416 | #include "gdth_proc.h" | 375 | #include "gdth_proc.h" |
417 | #include "gdth_proc.c" | 376 | #include "gdth_proc.c" |
418 | 377 | ||
@@ -591,125 +550,111 @@ static int __init gdth_search_isa(ulong32 bios_adr) | |||
591 | #endif /* CONFIG_ISA */ | 550 | #endif /* CONFIG_ISA */ |
592 | 551 | ||
593 | #ifdef CONFIG_PCI | 552 | #ifdef CONFIG_PCI |
594 | static void gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt, | 553 | static bool gdth_pci_registered; |
595 | ushort vendor, ushort dev); | ||
596 | 554 | ||
597 | static int __init gdth_search_pci(gdth_pci_str *pcistr) | 555 | static bool gdth_search_vortex(ushort device) |
598 | { | 556 | { |
599 | ushort device, cnt; | 557 | if (device <= PCI_DEVICE_ID_VORTEX_GDT6555) |
600 | 558 | return true; | |
601 | TRACE(("gdth_search_pci()\n")); | 559 | if (device >= PCI_DEVICE_ID_VORTEX_GDT6x17RP && |
602 | 560 | device <= PCI_DEVICE_ID_VORTEX_GDTMAXRP) | |
603 | cnt = 0; | 561 | return true; |
604 | for (device = 0; device <= PCI_DEVICE_ID_VORTEX_GDT6555; ++device) | 562 | if (device == PCI_DEVICE_ID_VORTEX_GDTNEWRX || |
605 | gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_VORTEX, device); | 563 | device == PCI_DEVICE_ID_VORTEX_GDTNEWRX2) |
606 | for (device = PCI_DEVICE_ID_VORTEX_GDT6x17RP; | 564 | return true; |
607 | device <= PCI_DEVICE_ID_VORTEX_GDTMAXRP; ++device) | 565 | return false; |
608 | gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_VORTEX, device); | ||
609 | gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_VORTEX, | ||
610 | PCI_DEVICE_ID_VORTEX_GDTNEWRX); | ||
611 | gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_VORTEX, | ||
612 | PCI_DEVICE_ID_VORTEX_GDTNEWRX2); | ||
613 | gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_INTEL, | ||
614 | PCI_DEVICE_ID_INTEL_SRC); | ||
615 | gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_INTEL, | ||
616 | PCI_DEVICE_ID_INTEL_SRC_XSCALE); | ||
617 | return cnt; | ||
618 | } | 566 | } |
619 | 567 | ||
568 | static int gdth_pci_probe_one(gdth_pci_str *pcistr, gdth_ha_str **ha_out); | ||
569 | static int gdth_pci_init_one(struct pci_dev *pdev, | ||
570 | const struct pci_device_id *ent); | ||
571 | static void gdth_pci_remove_one(struct pci_dev *pdev); | ||
572 | static void gdth_remove_one(gdth_ha_str *ha); | ||
573 | |||
620 | /* Vortex only makes RAID controllers. | 574 | /* Vortex only makes RAID controllers. |
621 | * We do not really want to specify all 550 ids here, so wildcard match. | 575 | * We do not really want to specify all 550 ids here, so wildcard match. |
622 | */ | 576 | */ |
623 | static struct pci_device_id gdthtable[] __maybe_unused = { | 577 | static const struct pci_device_id gdthtable[] = { |
624 | {PCI_VENDOR_ID_VORTEX,PCI_ANY_ID,PCI_ANY_ID, PCI_ANY_ID}, | 578 | { PCI_VDEVICE(VORTEX, PCI_ANY_ID) }, |
625 | {PCI_VENDOR_ID_INTEL,PCI_DEVICE_ID_INTEL_SRC,PCI_ANY_ID,PCI_ANY_ID}, | 579 | { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_SRC) }, |
626 | {PCI_VENDOR_ID_INTEL,PCI_DEVICE_ID_INTEL_SRC_XSCALE,PCI_ANY_ID,PCI_ANY_ID}, | 580 | { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_SRC_XSCALE) }, |
627 | {0} | 581 | { } /* terminate list */ |
582 | }; | ||
583 | MODULE_DEVICE_TABLE(pci, gdthtable); | ||
584 | |||
585 | static struct pci_driver gdth_pci_driver = { | ||
586 | .name = "gdth", | ||
587 | .id_table = gdthtable, | ||
588 | .probe = gdth_pci_init_one, | ||
589 | .remove = gdth_pci_remove_one, | ||
628 | }; | 590 | }; |
629 | MODULE_DEVICE_TABLE(pci,gdthtable); | ||
630 | 591 | ||
631 | static void __init gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt, | 592 | static void gdth_pci_remove_one(struct pci_dev *pdev) |
632 | ushort vendor, ushort device) | ||
633 | { | 593 | { |
634 | ulong base0, base1, base2; | 594 | gdth_ha_str *ha = pci_get_drvdata(pdev); |
635 | struct pci_dev *pdev; | 595 | |
596 | pci_set_drvdata(pdev, NULL); | ||
597 | |||
598 | list_del(&ha->list); | ||
599 | gdth_remove_one(ha); | ||
600 | |||
601 | pci_disable_device(pdev); | ||
602 | } | ||
603 | |||
604 | static int gdth_pci_init_one(struct pci_dev *pdev, | ||
605 | const struct pci_device_id *ent) | ||
606 | { | ||
607 | ushort vendor = pdev->vendor; | ||
608 | ushort device = pdev->device; | ||
609 | ulong base0, base1, base2; | ||
610 | int rc; | ||
611 | gdth_pci_str gdth_pcistr; | ||
612 | gdth_ha_str *ha = NULL; | ||
636 | 613 | ||
637 | TRACE(("gdth_search_dev() cnt %d vendor %x device %x\n", | 614 | TRACE(("gdth_search_dev() cnt %d vendor %x device %x\n", |
638 | *cnt, vendor, device)); | 615 | gdth_ctr_count, vendor, device)); |
639 | 616 | ||
640 | pdev = NULL; | 617 | memset(&gdth_pcistr, 0, sizeof(gdth_pcistr)); |
641 | while ((pdev = pci_get_device(vendor, device, pdev)) | 618 | |
642 | != NULL) { | 619 | if (vendor == PCI_VENDOR_ID_VORTEX && !gdth_search_vortex(device)) |
643 | if (pci_enable_device(pdev)) | 620 | return -ENODEV; |
644 | continue; | 621 | |
645 | if (*cnt >= MAXHA) { | 622 | rc = pci_enable_device(pdev); |
646 | pci_dev_put(pdev); | 623 | if (rc) |
647 | return; | 624 | return rc; |
648 | } | 625 | |
626 | if (gdth_ctr_count >= MAXHA) | ||
627 | return -EBUSY; | ||
649 | 628 | ||
650 | /* GDT PCI controller found, resources are already in pdev */ | 629 | /* GDT PCI controller found, resources are already in pdev */ |
651 | pcistr[*cnt].pdev = pdev; | 630 | gdth_pcistr.pdev = pdev; |
652 | pcistr[*cnt].irq = pdev->irq; | ||
653 | base0 = pci_resource_flags(pdev, 0); | 631 | base0 = pci_resource_flags(pdev, 0); |
654 | base1 = pci_resource_flags(pdev, 1); | 632 | base1 = pci_resource_flags(pdev, 1); |
655 | base2 = pci_resource_flags(pdev, 2); | 633 | base2 = pci_resource_flags(pdev, 2); |
656 | if (device <= PCI_DEVICE_ID_VORTEX_GDT6000B || /* GDT6000/B */ | 634 | if (device <= PCI_DEVICE_ID_VORTEX_GDT6000B || /* GDT6000/B */ |
657 | device >= PCI_DEVICE_ID_VORTEX_GDT6x17RP) { /* MPR */ | 635 | device >= PCI_DEVICE_ID_VORTEX_GDT6x17RP) { /* MPR */ |
658 | if (!(base0 & IORESOURCE_MEM)) | 636 | if (!(base0 & IORESOURCE_MEM)) |
659 | continue; | 637 | return -ENODEV; |
660 | pcistr[*cnt].dpmem = pci_resource_start(pdev, 0); | 638 | gdth_pcistr.dpmem = pci_resource_start(pdev, 0); |
661 | } else { /* GDT6110, GDT6120, .. */ | 639 | } else { /* GDT6110, GDT6120, .. */ |
662 | if (!(base0 & IORESOURCE_MEM) || | 640 | if (!(base0 & IORESOURCE_MEM) || |
663 | !(base2 & IORESOURCE_MEM) || | 641 | !(base2 & IORESOURCE_MEM) || |
664 | !(base1 & IORESOURCE_IO)) | 642 | !(base1 & IORESOURCE_IO)) |
665 | continue; | 643 | return -ENODEV; |
666 | pcistr[*cnt].dpmem = pci_resource_start(pdev, 2); | 644 | gdth_pcistr.dpmem = pci_resource_start(pdev, 2); |
667 | pcistr[*cnt].io_mm = pci_resource_start(pdev, 0); | 645 | gdth_pcistr.io = pci_resource_start(pdev, 1); |
668 | pcistr[*cnt].io = pci_resource_start(pdev, 1); | ||
669 | } | 646 | } |
670 | TRACE2(("Controller found at %d/%d, irq %d, dpmem 0x%lx\n", | 647 | TRACE2(("Controller found at %d/%d, irq %d, dpmem 0x%lx\n", |
671 | pcistr[*cnt].pdev->bus->number, | 648 | gdth_pcistr.pdev->bus->number, |
672 | PCI_SLOT(pcistr[*cnt].pdev->devfn), | 649 | PCI_SLOT(gdth_pcistr.pdev->devfn), |
673 | pcistr[*cnt].irq, pcistr[*cnt].dpmem)); | 650 | gdth_pcistr.irq, |
674 | (*cnt)++; | 651 | gdth_pcistr.dpmem)); |
675 | } | ||
676 | } | ||
677 | 652 | ||
678 | static void __init gdth_sort_pci(gdth_pci_str *pcistr, int cnt) | 653 | rc = gdth_pci_probe_one(&gdth_pcistr, &ha); |
679 | { | 654 | if (rc) |
680 | gdth_pci_str temp; | 655 | return rc; |
681 | int i, changed; | ||
682 | |||
683 | TRACE(("gdth_sort_pci() cnt %d\n",cnt)); | ||
684 | if (cnt == 0) | ||
685 | return; | ||
686 | 656 | ||
687 | do { | 657 | return 0; |
688 | changed = FALSE; | ||
689 | for (i = 0; i < cnt-1; ++i) { | ||
690 | if (!reverse_scan) { | ||
691 | if ((pcistr[i].pdev->bus->number > pcistr[i+1].pdev->bus->number) || | ||
692 | (pcistr[i].pdev->bus->number == pcistr[i+1].pdev->bus->number && | ||
693 | PCI_SLOT(pcistr[i].pdev->devfn) > | ||
694 | PCI_SLOT(pcistr[i+1].pdev->devfn))) { | ||
695 | temp = pcistr[i]; | ||
696 | pcistr[i] = pcistr[i+1]; | ||
697 | pcistr[i+1] = temp; | ||
698 | changed = TRUE; | ||
699 | } | ||
700 | } else { | ||
701 | if ((pcistr[i].pdev->bus->number < pcistr[i+1].pdev->bus->number) || | ||
702 | (pcistr[i].pdev->bus->number == pcistr[i+1].pdev->bus->number && | ||
703 | PCI_SLOT(pcistr[i].pdev->devfn) < | ||
704 | PCI_SLOT(pcistr[i+1].pdev->devfn))) { | ||
705 | temp = pcistr[i]; | ||
706 | pcistr[i] = pcistr[i+1]; | ||
707 | pcistr[i+1] = temp; | ||
708 | changed = TRUE; | ||
709 | } | ||
710 | } | ||
711 | } | ||
712 | } while (changed); | ||
713 | } | 658 | } |
714 | #endif /* CONFIG_PCI */ | 659 | #endif /* CONFIG_PCI */ |
715 | 660 | ||
@@ -909,7 +854,8 @@ static int __init gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha) | |||
909 | #endif /* CONFIG_ISA */ | 854 | #endif /* CONFIG_ISA */ |
910 | 855 | ||
911 | #ifdef CONFIG_PCI | 856 | #ifdef CONFIG_PCI |
912 | static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | 857 | static int gdth_init_pci(struct pci_dev *pdev, gdth_pci_str *pcistr, |
858 | gdth_ha_str *ha) | ||
913 | { | 859 | { |
914 | register gdt6_dpram_str __iomem *dp6_ptr; | 860 | register gdt6_dpram_str __iomem *dp6_ptr; |
915 | register gdt6c_dpram_str __iomem *dp6c_ptr; | 861 | register gdt6c_dpram_str __iomem *dp6c_ptr; |
@@ -921,14 +867,14 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
921 | 867 | ||
922 | TRACE(("gdth_init_pci()\n")); | 868 | TRACE(("gdth_init_pci()\n")); |
923 | 869 | ||
924 | if (pcistr->pdev->vendor == PCI_VENDOR_ID_INTEL) | 870 | if (pdev->vendor == PCI_VENDOR_ID_INTEL) |
925 | ha->oem_id = OEM_ID_INTEL; | 871 | ha->oem_id = OEM_ID_INTEL; |
926 | else | 872 | else |
927 | ha->oem_id = OEM_ID_ICP; | 873 | ha->oem_id = OEM_ID_ICP; |
928 | ha->brd_phys = (pcistr->pdev->bus->number << 8) | (pcistr->pdev->devfn & 0xf8); | 874 | ha->brd_phys = (pdev->bus->number << 8) | (pdev->devfn & 0xf8); |
929 | ha->stype = (ulong32)pcistr->pdev->device; | 875 | ha->stype = (ulong32)pdev->device; |
930 | ha->irq = pcistr->irq; | 876 | ha->irq = pdev->irq; |
931 | ha->pdev = pcistr->pdev; | 877 | ha->pdev = pdev; |
932 | 878 | ||
933 | if (ha->pdev->device <= PCI_DEVICE_ID_VORTEX_GDT6000B) { /* GDT6000/B */ | 879 | if (ha->pdev->device <= PCI_DEVICE_ID_VORTEX_GDT6000B) { /* GDT6000/B */ |
934 | TRACE2(("init_pci() dpmem %lx irq %d\n",pcistr->dpmem,ha->irq)); | 880 | TRACE2(("init_pci() dpmem %lx irq %d\n",pcistr->dpmem,ha->irq)); |
@@ -956,8 +902,7 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
956 | continue; | 902 | continue; |
957 | } | 903 | } |
958 | iounmap(ha->brd); | 904 | iounmap(ha->brd); |
959 | pci_write_config_dword(pcistr->pdev, | 905 | pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, i); |
960 | PCI_BASE_ADDRESS_0, i); | ||
961 | ha->brd = ioremap(i, sizeof(gdt6_dpram_str)); | 906 | ha->brd = ioremap(i, sizeof(gdt6_dpram_str)); |
962 | if (ha->brd == NULL) { | 907 | if (ha->brd == NULL) { |
963 | printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); | 908 | printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); |
@@ -1066,8 +1011,7 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1066 | continue; | 1011 | continue; |
1067 | } | 1012 | } |
1068 | iounmap(ha->brd); | 1013 | iounmap(ha->brd); |
1069 | pci_write_config_dword(pcistr->pdev, | 1014 | pci_write_config_dword(pdev, PCI_BASE_ADDRESS_2, i); |
1070 | PCI_BASE_ADDRESS_2, i); | ||
1071 | ha->brd = ioremap(i, sizeof(gdt6c_dpram_str)); | 1015 | ha->brd = ioremap(i, sizeof(gdt6c_dpram_str)); |
1072 | if (ha->brd == NULL) { | 1016 | if (ha->brd == NULL) { |
1073 | printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); | 1017 | printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); |
@@ -1159,16 +1103,16 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1159 | } | 1103 | } |
1160 | 1104 | ||
1161 | /* manipulate config. space to enable DPMEM, start RP controller */ | 1105 | /* manipulate config. space to enable DPMEM, start RP controller */ |
1162 | pci_read_config_word(pcistr->pdev, PCI_COMMAND, &command); | 1106 | pci_read_config_word(pdev, PCI_COMMAND, &command); |
1163 | command |= 6; | 1107 | command |= 6; |
1164 | pci_write_config_word(pcistr->pdev, PCI_COMMAND, command); | 1108 | pci_write_config_word(pdev, PCI_COMMAND, command); |
1165 | if (pci_resource_start(pcistr->pdev, 8) == 1UL) | 1109 | if (pci_resource_start(pdev, 8) == 1UL) |
1166 | pci_resource_start(pcistr->pdev, 8) = 0UL; | 1110 | pci_resource_start(pdev, 8) = 0UL; |
1167 | i = 0xFEFF0001UL; | 1111 | i = 0xFEFF0001UL; |
1168 | pci_write_config_dword(pcistr->pdev, PCI_ROM_ADDRESS, i); | 1112 | pci_write_config_dword(pdev, PCI_ROM_ADDRESS, i); |
1169 | gdth_delay(1); | 1113 | gdth_delay(1); |
1170 | pci_write_config_dword(pcistr->pdev, PCI_ROM_ADDRESS, | 1114 | pci_write_config_dword(pdev, PCI_ROM_ADDRESS, |
1171 | pci_resource_start(pcistr->pdev, 8)); | 1115 | pci_resource_start(pdev, 8)); |
1172 | 1116 | ||
1173 | dp6m_ptr = ha->brd; | 1117 | dp6m_ptr = ha->brd; |
1174 | 1118 | ||
@@ -1195,8 +1139,7 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1195 | continue; | 1139 | continue; |
1196 | } | 1140 | } |
1197 | iounmap(ha->brd); | 1141 | iounmap(ha->brd); |
1198 | pci_write_config_dword(pcistr->pdev, | 1142 | pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, i); |
1199 | PCI_BASE_ADDRESS_0, i); | ||
1200 | ha->brd = ioremap(i, sizeof(gdt6m_dpram_str)); | 1143 | ha->brd = ioremap(i, sizeof(gdt6m_dpram_str)); |
1201 | if (ha->brd == NULL) { | 1144 | if (ha->brd == NULL) { |
1202 | printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); | 1145 | printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); |
@@ -2353,12 +2296,12 @@ static void gdth_next(gdth_ha_str *ha) | |||
2353 | static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp, | 2296 | static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp, |
2354 | char *buffer, ushort count) | 2297 | char *buffer, ushort count) |
2355 | { | 2298 | { |
2356 | ushort cpcount,i, max_sg = gdth_sg_count(scp); | 2299 | ushort cpcount,i, max_sg = scsi_sg_count(scp); |
2357 | ushort cpsum,cpnow; | 2300 | ushort cpsum,cpnow; |
2358 | struct scatterlist *sl; | 2301 | struct scatterlist *sl; |
2359 | char *address; | 2302 | char *address; |
2360 | 2303 | ||
2361 | cpcount = min_t(ushort, count, gdth_bufflen(scp)); | 2304 | cpcount = min_t(ushort, count, scsi_bufflen(scp)); |
2362 | 2305 | ||
2363 | if (cpcount) { | 2306 | if (cpcount) { |
2364 | cpsum=0; | 2307 | cpsum=0; |
@@ -2366,7 +2309,7 @@ static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp, | |||
2366 | unsigned long flags; | 2309 | unsigned long flags; |
2367 | cpnow = (ushort)sl->length; | 2310 | cpnow = (ushort)sl->length; |
2368 | TRACE(("copy_internal() now %d sum %d count %d %d\n", | 2311 | TRACE(("copy_internal() now %d sum %d count %d %d\n", |
2369 | cpnow, cpsum, cpcount, gdth_bufflen(scp))); | 2312 | cpnow, cpsum, cpcount, scsi_bufflen(scp))); |
2370 | if (cpsum+cpnow > cpcount) | 2313 | if (cpsum+cpnow > cpcount) |
2371 | cpnow = cpcount - cpsum; | 2314 | cpnow = cpcount - cpsum; |
2372 | cpsum += cpnow; | 2315 | cpsum += cpnow; |
@@ -2589,10 +2532,10 @@ static int gdth_fill_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, ushort hdrive) | |||
2589 | cmdp->u.cache.BlockCnt = blockcnt; | 2532 | cmdp->u.cache.BlockCnt = blockcnt; |
2590 | } | 2533 | } |
2591 | 2534 | ||
2592 | if (gdth_bufflen(scp)) { | 2535 | if (scsi_bufflen(scp)) { |
2593 | cmndinfo->dma_dir = (read_write == 1 ? | 2536 | cmndinfo->dma_dir = (read_write == 1 ? |
2594 | PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); | 2537 | PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); |
2595 | sgcnt = pci_map_sg(ha->pdev, gdth_sglist(scp), gdth_sg_count(scp), | 2538 | sgcnt = pci_map_sg(ha->pdev, scsi_sglist(scp), scsi_sg_count(scp), |
2596 | cmndinfo->dma_dir); | 2539 | cmndinfo->dma_dir); |
2597 | if (mode64) { | 2540 | if (mode64) { |
2598 | struct scatterlist *sl; | 2541 | struct scatterlist *sl; |
@@ -2739,7 +2682,7 @@ static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar b) | |||
2739 | cmdp->u.raw64.lun = l; | 2682 | cmdp->u.raw64.lun = l; |
2740 | cmdp->u.raw64.bus = b; | 2683 | cmdp->u.raw64.bus = b; |
2741 | cmdp->u.raw64.priority = 0; | 2684 | cmdp->u.raw64.priority = 0; |
2742 | cmdp->u.raw64.sdlen = gdth_bufflen(scp); | 2685 | cmdp->u.raw64.sdlen = scsi_bufflen(scp); |
2743 | cmdp->u.raw64.sense_len = 16; | 2686 | cmdp->u.raw64.sense_len = 16; |
2744 | cmdp->u.raw64.sense_data = sense_paddr; | 2687 | cmdp->u.raw64.sense_data = sense_paddr; |
2745 | cmdp->u.raw64.direction = | 2688 | cmdp->u.raw64.direction = |
@@ -2756,7 +2699,7 @@ static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar b) | |||
2756 | cmdp->u.raw.bus = b; | 2699 | cmdp->u.raw.bus = b; |
2757 | cmdp->u.raw.priority = 0; | 2700 | cmdp->u.raw.priority = 0; |
2758 | cmdp->u.raw.link_p = 0; | 2701 | cmdp->u.raw.link_p = 0; |
2759 | cmdp->u.raw.sdlen = gdth_bufflen(scp); | 2702 | cmdp->u.raw.sdlen = scsi_bufflen(scp); |
2760 | cmdp->u.raw.sense_len = 16; | 2703 | cmdp->u.raw.sense_len = 16; |
2761 | cmdp->u.raw.sense_data = sense_paddr; | 2704 | cmdp->u.raw.sense_data = sense_paddr; |
2762 | cmdp->u.raw.direction = | 2705 | cmdp->u.raw.direction = |
@@ -2765,9 +2708,9 @@ static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar b) | |||
2765 | cmdp->u.raw.sg_ranz = 0; | 2708 | cmdp->u.raw.sg_ranz = 0; |
2766 | } | 2709 | } |
2767 | 2710 | ||
2768 | if (gdth_bufflen(scp)) { | 2711 | if (scsi_bufflen(scp)) { |
2769 | cmndinfo->dma_dir = PCI_DMA_BIDIRECTIONAL; | 2712 | cmndinfo->dma_dir = PCI_DMA_BIDIRECTIONAL; |
2770 | sgcnt = pci_map_sg(ha->pdev, gdth_sglist(scp), gdth_sg_count(scp), | 2713 | sgcnt = pci_map_sg(ha->pdev, scsi_sglist(scp), scsi_sg_count(scp), |
2771 | cmndinfo->dma_dir); | 2714 | cmndinfo->dma_dir); |
2772 | if (mode64) { | 2715 | if (mode64) { |
2773 | struct scatterlist *sl; | 2716 | struct scatterlist *sl; |
@@ -3388,8 +3331,8 @@ static int gdth_sync_event(gdth_ha_str *ha, int service, unchar index, | |||
3388 | /* retry */ | 3331 | /* retry */ |
3389 | return 2; | 3332 | return 2; |
3390 | } | 3333 | } |
3391 | if (gdth_bufflen(scp)) | 3334 | if (scsi_bufflen(scp)) |
3392 | pci_unmap_sg(ha->pdev, gdth_sglist(scp), gdth_sg_count(scp), | 3335 | pci_unmap_sg(ha->pdev, scsi_sglist(scp), scsi_sg_count(scp), |
3393 | cmndinfo->dma_dir); | 3336 | cmndinfo->dma_dir); |
3394 | 3337 | ||
3395 | if (cmndinfo->sense_paddr) | 3338 | if (cmndinfo->sense_paddr) |
@@ -4031,10 +3974,6 @@ static int gdth_queuecommand(struct scsi_cmnd *scp, | |||
4031 | gdth_update_timeout(scp, scp->timeout_per_command * 6); | 3974 | gdth_update_timeout(scp, scp->timeout_per_command * 6); |
4032 | cmndinfo->priority = DEFAULT_PRI; | 3975 | cmndinfo->priority = DEFAULT_PRI; |
4033 | 3976 | ||
4034 | gdth_set_bufflen(scp, scsi_bufflen(scp)); | ||
4035 | gdth_set_sg_count(scp, scsi_sg_count(scp)); | ||
4036 | gdth_set_sglist(scp, scsi_sglist(scp)); | ||
4037 | |||
4038 | return __gdth_queuecommand(ha, scp, cmndinfo); | 3977 | return __gdth_queuecommand(ha, scp, cmndinfo); |
4039 | } | 3978 | } |
4040 | 3979 | ||
@@ -4955,12 +4894,16 @@ static int __init gdth_eisa_probe_one(ushort eisa_slot) | |||
4955 | #endif /* CONFIG_EISA */ | 4894 | #endif /* CONFIG_EISA */ |
4956 | 4895 | ||
4957 | #ifdef CONFIG_PCI | 4896 | #ifdef CONFIG_PCI |
4958 | static int __init gdth_pci_probe_one(gdth_pci_str *pcistr, int ctr) | 4897 | static int gdth_pci_probe_one(gdth_pci_str *pcistr, |
4898 | gdth_ha_str **ha_out) | ||
4959 | { | 4899 | { |
4960 | struct Scsi_Host *shp; | 4900 | struct Scsi_Host *shp; |
4961 | gdth_ha_str *ha; | 4901 | gdth_ha_str *ha; |
4962 | dma_addr_t scratch_dma_handle = 0; | 4902 | dma_addr_t scratch_dma_handle = 0; |
4963 | int error, i; | 4903 | int error, i; |
4904 | struct pci_dev *pdev = pcistr->pdev; | ||
4905 | |||
4906 | *ha_out = NULL; | ||
4964 | 4907 | ||
4965 | shp = scsi_host_alloc(&gdth_template, sizeof(gdth_ha_str)); | 4908 | shp = scsi_host_alloc(&gdth_template, sizeof(gdth_ha_str)); |
4966 | if (!shp) | 4909 | if (!shp) |
@@ -4968,13 +4911,13 @@ static int __init gdth_pci_probe_one(gdth_pci_str *pcistr, int ctr) | |||
4968 | ha = shost_priv(shp); | 4911 | ha = shost_priv(shp); |
4969 | 4912 | ||
4970 | error = -ENODEV; | 4913 | error = -ENODEV; |
4971 | if (!gdth_init_pci(&pcistr[ctr],ha)) | 4914 | if (!gdth_init_pci(pdev, pcistr, ha)) |
4972 | goto out_host_put; | 4915 | goto out_host_put; |
4973 | 4916 | ||
4974 | /* controller found and initialized */ | 4917 | /* controller found and initialized */ |
4975 | printk("Configuring GDT-PCI HA at %d/%d IRQ %u\n", | 4918 | printk("Configuring GDT-PCI HA at %d/%d IRQ %u\n", |
4976 | pcistr[ctr].pdev->bus->number, | 4919 | pdev->bus->number, |
4977 | PCI_SLOT(pcistr[ctr].pdev->devfn), | 4920 | PCI_SLOT(pdev->devfn), |
4978 | ha->irq); | 4921 | ha->irq); |
4979 | 4922 | ||
4980 | error = request_irq(ha->irq, gdth_interrupt, | 4923 | error = request_irq(ha->irq, gdth_interrupt, |
@@ -5019,7 +4962,7 @@ static int __init gdth_pci_probe_one(gdth_pci_str *pcistr, int ctr) | |||
5019 | 4962 | ||
5020 | ha->scratch_busy = FALSE; | 4963 | ha->scratch_busy = FALSE; |
5021 | ha->req_first = NULL; | 4964 | ha->req_first = NULL; |
5022 | ha->tid_cnt = pcistr[ctr].pdev->device >= 0x200 ? MAXID : MAX_HDRIVES; | 4965 | ha->tid_cnt = pdev->device >= 0x200 ? MAXID : MAX_HDRIVES; |
5023 | if (max_ids > 0 && max_ids < ha->tid_cnt) | 4966 | if (max_ids > 0 && max_ids < ha->tid_cnt) |
5024 | ha->tid_cnt = max_ids; | 4967 | ha->tid_cnt = max_ids; |
5025 | for (i = 0; i < GDTH_MAXCMDS; ++i) | 4968 | for (i = 0; i < GDTH_MAXCMDS; ++i) |
@@ -5039,16 +4982,16 @@ static int __init gdth_pci_probe_one(gdth_pci_str *pcistr, int ctr) | |||
5039 | /* 64-bit DMA only supported from FW >= x.43 */ | 4982 | /* 64-bit DMA only supported from FW >= x.43 */ |
5040 | if (!(ha->cache_feat & ha->raw_feat & ha->screen_feat & GDT_64BIT) || | 4983 | if (!(ha->cache_feat & ha->raw_feat & ha->screen_feat & GDT_64BIT) || |
5041 | !ha->dma64_support) { | 4984 | !ha->dma64_support) { |
5042 | if (pci_set_dma_mask(pcistr[ctr].pdev, DMA_32BIT_MASK)) { | 4985 | if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { |
5043 | printk(KERN_WARNING "GDT-PCI %d: " | 4986 | printk(KERN_WARNING "GDT-PCI %d: " |
5044 | "Unable to set 32-bit DMA\n", ha->hanum); | 4987 | "Unable to set 32-bit DMA\n", ha->hanum); |
5045 | goto out_free_coal_stat; | 4988 | goto out_free_coal_stat; |
5046 | } | 4989 | } |
5047 | } else { | 4990 | } else { |
5048 | shp->max_cmd_len = 16; | 4991 | shp->max_cmd_len = 16; |
5049 | if (!pci_set_dma_mask(pcistr[ctr].pdev, DMA_64BIT_MASK)) { | 4992 | if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) { |
5050 | printk("GDT-PCI %d: 64-bit DMA enabled\n", ha->hanum); | 4993 | printk("GDT-PCI %d: 64-bit DMA enabled\n", ha->hanum); |
5051 | } else if (pci_set_dma_mask(pcistr[ctr].pdev, DMA_32BIT_MASK)) { | 4994 | } else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { |
5052 | printk(KERN_WARNING "GDT-PCI %d: " | 4995 | printk(KERN_WARNING "GDT-PCI %d: " |
5053 | "Unable to set 64/32-bit DMA\n", ha->hanum); | 4996 | "Unable to set 64/32-bit DMA\n", ha->hanum); |
5054 | goto out_free_coal_stat; | 4997 | goto out_free_coal_stat; |
@@ -5062,13 +5005,17 @@ static int __init gdth_pci_probe_one(gdth_pci_str *pcistr, int ctr) | |||
5062 | spin_lock_init(&ha->smp_lock); | 5005 | spin_lock_init(&ha->smp_lock); |
5063 | gdth_enable_int(ha); | 5006 | gdth_enable_int(ha); |
5064 | 5007 | ||
5065 | error = scsi_add_host(shp, &pcistr[ctr].pdev->dev); | 5008 | error = scsi_add_host(shp, &pdev->dev); |
5066 | if (error) | 5009 | if (error) |
5067 | goto out_free_coal_stat; | 5010 | goto out_free_coal_stat; |
5068 | list_add_tail(&ha->list, &gdth_instances); | 5011 | list_add_tail(&ha->list, &gdth_instances); |
5069 | 5012 | ||
5013 | pci_set_drvdata(ha->pdev, ha); | ||
5014 | |||
5070 | scsi_scan_host(shp); | 5015 | scsi_scan_host(shp); |
5071 | 5016 | ||
5017 | *ha_out = ha; | ||
5018 | |||
5072 | return 0; | 5019 | return 0; |
5073 | 5020 | ||
5074 | out_free_coal_stat: | 5021 | out_free_coal_stat: |
@@ -5185,16 +5132,8 @@ static int __init gdth_init(void) | |||
5185 | 5132 | ||
5186 | #ifdef CONFIG_PCI | 5133 | #ifdef CONFIG_PCI |
5187 | /* scanning for PCI controllers */ | 5134 | /* scanning for PCI controllers */ |
5188 | { | 5135 | if (pci_register_driver(&gdth_pci_driver) == 0) |
5189 | gdth_pci_str pcistr[MAXHA]; | 5136 | gdth_pci_registered = true; |
5190 | int cnt,ctr; | ||
5191 | |||
5192 | cnt = gdth_search_pci(pcistr); | ||
5193 | printk("GDT-HA: Found %d PCI Storage RAID Controllers\n", cnt); | ||
5194 | gdth_sort_pci(pcistr,cnt); | ||
5195 | for (ctr = 0; ctr < cnt; ++ctr) | ||
5196 | gdth_pci_probe_one(pcistr, ctr); | ||
5197 | } | ||
5198 | #endif /* CONFIG_PCI */ | 5137 | #endif /* CONFIG_PCI */ |
5199 | 5138 | ||
5200 | TRACE2(("gdth_detect() %d controller detected\n", gdth_ctr_count)); | 5139 | TRACE2(("gdth_detect() %d controller detected\n", gdth_ctr_count)); |
@@ -5227,6 +5166,11 @@ static void __exit gdth_exit(void) | |||
5227 | del_timer_sync(&gdth_timer); | 5166 | del_timer_sync(&gdth_timer); |
5228 | #endif | 5167 | #endif |
5229 | 5168 | ||
5169 | #ifdef CONFIG_PCI | ||
5170 | if (gdth_pci_registered) | ||
5171 | pci_unregister_driver(&gdth_pci_driver); | ||
5172 | #endif | ||
5173 | |||
5230 | list_for_each_entry(ha, &gdth_instances, list) | 5174 | list_for_each_entry(ha, &gdth_instances, list) |
5231 | gdth_remove_one(ha); | 5175 | gdth_remove_one(ha); |
5232 | } | 5176 | } |
diff --git a/drivers/scsi/gdth.h b/drivers/scsi/gdth.h index 26e4e92515e0..ca92476727cf 100644 --- a/drivers/scsi/gdth.h +++ b/drivers/scsi/gdth.h | |||
@@ -839,8 +839,6 @@ typedef struct { | |||
839 | struct pci_dev *pdev; | 839 | struct pci_dev *pdev; |
840 | ulong dpmem; /* DPRAM address */ | 840 | ulong dpmem; /* DPRAM address */ |
841 | ulong io; /* IO address */ | 841 | ulong io; /* IO address */ |
842 | ulong io_mm; /* IO address mem. mapped */ | ||
843 | unchar irq; /* IRQ */ | ||
844 | } gdth_pci_str; | 842 | } gdth_pci_str; |
845 | 843 | ||
846 | 844 | ||
diff --git a/drivers/scsi/gvp11.c b/drivers/scsi/gvp11.c index 91f85226d08f..ca7363752401 100644 --- a/drivers/scsi/gvp11.c +++ b/drivers/scsi/gvp11.c | |||
@@ -322,6 +322,9 @@ int __init gvp11_detect(struct scsi_host_template *tpnt) | |||
322 | */ | 322 | */ |
323 | regs.SASR = &(DMA(instance)->SASR); | 323 | regs.SASR = &(DMA(instance)->SASR); |
324 | regs.SCMD = &(DMA(instance)->SCMD); | 324 | regs.SCMD = &(DMA(instance)->SCMD); |
325 | HDATA(instance)->no_sync = 0xff; | ||
326 | HDATA(instance)->fast = 0; | ||
327 | HDATA(instance)->dma_mode = CTRL_DMA; | ||
325 | wd33c93_init(instance, regs, dma_setup, dma_stop, | 328 | wd33c93_init(instance, regs, dma_setup, dma_stop, |
326 | (epc & GVP_SCSICLKMASK) ? WD33C93_FS_8_10 | 329 | (epc & GVP_SCSICLKMASK) ? WD33C93_FS_8_10 |
327 | : WD33C93_FS_12_15); | 330 | : WD33C93_FS_12_15); |
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index ed7e0a1fc34d..1592640a87b5 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c | |||
@@ -347,7 +347,6 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) | |||
347 | shost->unchecked_isa_dma = sht->unchecked_isa_dma; | 347 | shost->unchecked_isa_dma = sht->unchecked_isa_dma; |
348 | shost->use_clustering = sht->use_clustering; | 348 | shost->use_clustering = sht->use_clustering; |
349 | shost->ordered_tag = sht->ordered_tag; | 349 | shost->ordered_tag = sht->ordered_tag; |
350 | shost->active_mode = sht->supported_mode; | ||
351 | 350 | ||
352 | if (sht->supported_mode == MODE_UNKNOWN) | 351 | if (sht->supported_mode == MODE_UNKNOWN) |
353 | /* means we didn't set it ... default to INITIATOR */ | 352 | /* means we didn't set it ... default to INITIATOR */ |
diff --git a/drivers/scsi/hptiop.c b/drivers/scsi/hptiop.c index ff149ad6bc4e..beecda991682 100644 --- a/drivers/scsi/hptiop.c +++ b/drivers/scsi/hptiop.c | |||
@@ -338,7 +338,8 @@ static int iop_get_config_mv(struct hptiop_hba *hba, | |||
338 | req->header.size = | 338 | req->header.size = |
339 | cpu_to_le32(sizeof(struct hpt_iop_request_get_config)); | 339 | cpu_to_le32(sizeof(struct hpt_iop_request_get_config)); |
340 | req->header.result = cpu_to_le32(IOP_RESULT_PENDING); | 340 | req->header.result = cpu_to_le32(IOP_RESULT_PENDING); |
341 | req->header.context = cpu_to_le64(IOP_REQUEST_TYPE_GET_CONFIG<<5); | 341 | req->header.context = cpu_to_le32(IOP_REQUEST_TYPE_GET_CONFIG<<5); |
342 | req->header.context_hi32 = 0; | ||
342 | 343 | ||
343 | if (iop_send_sync_request_mv(hba, 0, 20000)) { | 344 | if (iop_send_sync_request_mv(hba, 0, 20000)) { |
344 | dprintk("Get config send cmd failed\n"); | 345 | dprintk("Get config send cmd failed\n"); |
@@ -392,7 +393,8 @@ static int iop_set_config_mv(struct hptiop_hba *hba, | |||
392 | req->header.size = | 393 | req->header.size = |
393 | cpu_to_le32(sizeof(struct hpt_iop_request_set_config)); | 394 | cpu_to_le32(sizeof(struct hpt_iop_request_set_config)); |
394 | req->header.result = cpu_to_le32(IOP_RESULT_PENDING); | 395 | req->header.result = cpu_to_le32(IOP_RESULT_PENDING); |
395 | req->header.context = cpu_to_le64(IOP_REQUEST_TYPE_SET_CONFIG<<5); | 396 | req->header.context = cpu_to_le32(IOP_REQUEST_TYPE_SET_CONFIG<<5); |
397 | req->header.context_hi32 = 0; | ||
396 | 398 | ||
397 | if (iop_send_sync_request_mv(hba, 0, 20000)) { | 399 | if (iop_send_sync_request_mv(hba, 0, 20000)) { |
398 | dprintk("Set config send cmd failed\n"); | 400 | dprintk("Set config send cmd failed\n"); |
@@ -903,7 +905,6 @@ static struct scsi_host_template driver_template = { | |||
903 | .eh_device_reset_handler = hptiop_reset, | 905 | .eh_device_reset_handler = hptiop_reset, |
904 | .eh_bus_reset_handler = hptiop_reset, | 906 | .eh_bus_reset_handler = hptiop_reset, |
905 | .info = hptiop_info, | 907 | .info = hptiop_info, |
906 | .unchecked_isa_dma = 0, | ||
907 | .emulated = 0, | 908 | .emulated = 0, |
908 | .use_clustering = ENABLE_CLUSTERING, | 909 | .use_clustering = ENABLE_CLUSTERING, |
909 | .proc_name = driver_name, | 910 | .proc_name = driver_name, |
diff --git a/drivers/scsi/initio.c b/drivers/scsi/initio.c index 0cc8868ea35d..dbae3fdb8506 100644 --- a/drivers/scsi/initio.c +++ b/drivers/scsi/initio.c | |||
@@ -2581,8 +2581,8 @@ static void initio_build_scb(struct initio_host * host, struct scsi_ctrl_blk * c | |||
2581 | /* Map the sense buffer into bus memory */ | 2581 | /* Map the sense buffer into bus memory */ |
2582 | dma_addr = dma_map_single(&host->pci_dev->dev, cmnd->sense_buffer, | 2582 | dma_addr = dma_map_single(&host->pci_dev->dev, cmnd->sense_buffer, |
2583 | SENSE_SIZE, DMA_FROM_DEVICE); | 2583 | SENSE_SIZE, DMA_FROM_DEVICE); |
2584 | cblk->senseptr = cpu_to_le32((u32)dma_addr); | 2584 | cblk->senseptr = (u32)dma_addr; |
2585 | cblk->senselen = cpu_to_le32(SENSE_SIZE); | 2585 | cblk->senselen = SENSE_SIZE; |
2586 | cmnd->SCp.ptr = (char *)(unsigned long)dma_addr; | 2586 | cmnd->SCp.ptr = (char *)(unsigned long)dma_addr; |
2587 | cblk->cdblen = cmnd->cmd_len; | 2587 | cblk->cdblen = cmnd->cmd_len; |
2588 | 2588 | ||
@@ -2606,7 +2606,7 @@ static void initio_build_scb(struct initio_host * host, struct scsi_ctrl_blk * c | |||
2606 | dma_addr = dma_map_single(&host->pci_dev->dev, &cblk->sglist[0], | 2606 | dma_addr = dma_map_single(&host->pci_dev->dev, &cblk->sglist[0], |
2607 | sizeof(struct sg_entry) * TOTAL_SG_ENTRY, | 2607 | sizeof(struct sg_entry) * TOTAL_SG_ENTRY, |
2608 | DMA_BIDIRECTIONAL); | 2608 | DMA_BIDIRECTIONAL); |
2609 | cblk->bufptr = cpu_to_le32((u32)dma_addr); | 2609 | cblk->bufptr = (u32)dma_addr; |
2610 | cmnd->SCp.dma_handle = dma_addr; | 2610 | cmnd->SCp.dma_handle = dma_addr; |
2611 | 2611 | ||
2612 | cblk->sglen = nseg; | 2612 | cblk->sglen = nseg; |
@@ -2616,7 +2616,8 @@ static void initio_build_scb(struct initio_host * host, struct scsi_ctrl_blk * c | |||
2616 | sg = &cblk->sglist[0]; | 2616 | sg = &cblk->sglist[0]; |
2617 | scsi_for_each_sg(cmnd, sglist, cblk->sglen, i) { | 2617 | scsi_for_each_sg(cmnd, sglist, cblk->sglen, i) { |
2618 | sg->data = cpu_to_le32((u32)sg_dma_address(sglist)); | 2618 | sg->data = cpu_to_le32((u32)sg_dma_address(sglist)); |
2619 | total_len += sg->len = cpu_to_le32((u32)sg_dma_len(sglist)); | 2619 | sg->len = cpu_to_le32((u32)sg_dma_len(sglist)); |
2620 | total_len += sg_dma_len(sglist); | ||
2620 | ++sg; | 2621 | ++sg; |
2621 | } | 2622 | } |
2622 | 2623 | ||
diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c index 7ed568f180ae..7c615c70ec5c 100644 --- a/drivers/scsi/ips.c +++ b/drivers/scsi/ips.c | |||
@@ -2377,7 +2377,7 @@ ips_get_bios_version(ips_ha_t * ha, int intr) | |||
2377 | if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55) | 2377 | if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55) |
2378 | return; | 2378 | return; |
2379 | 2379 | ||
2380 | outl(cpu_to_le32(1), ha->io_addr + IPS_REG_FLAP); | 2380 | outl(1, ha->io_addr + IPS_REG_FLAP); |
2381 | if (ha->pcidev->revision == IPS_REVID_TROMBONE64) | 2381 | if (ha->pcidev->revision == IPS_REVID_TROMBONE64) |
2382 | udelay(25); /* 25 us */ | 2382 | udelay(25); /* 25 us */ |
2383 | 2383 | ||
@@ -2385,21 +2385,21 @@ ips_get_bios_version(ips_ha_t * ha, int intr) | |||
2385 | return; | 2385 | return; |
2386 | 2386 | ||
2387 | /* Get Major version */ | 2387 | /* Get Major version */ |
2388 | outl(cpu_to_le32(0x1FF), ha->io_addr + IPS_REG_FLAP); | 2388 | outl(0x1FF, ha->io_addr + IPS_REG_FLAP); |
2389 | if (ha->pcidev->revision == IPS_REVID_TROMBONE64) | 2389 | if (ha->pcidev->revision == IPS_REVID_TROMBONE64) |
2390 | udelay(25); /* 25 us */ | 2390 | udelay(25); /* 25 us */ |
2391 | 2391 | ||
2392 | major = inb(ha->io_addr + IPS_REG_FLDP); | 2392 | major = inb(ha->io_addr + IPS_REG_FLDP); |
2393 | 2393 | ||
2394 | /* Get Minor version */ | 2394 | /* Get Minor version */ |
2395 | outl(cpu_to_le32(0x1FE), ha->io_addr + IPS_REG_FLAP); | 2395 | outl(0x1FE, ha->io_addr + IPS_REG_FLAP); |
2396 | if (ha->pcidev->revision == IPS_REVID_TROMBONE64) | 2396 | if (ha->pcidev->revision == IPS_REVID_TROMBONE64) |
2397 | udelay(25); /* 25 us */ | 2397 | udelay(25); /* 25 us */ |
2398 | 2398 | ||
2399 | minor = inb(ha->io_addr + IPS_REG_FLDP); | 2399 | minor = inb(ha->io_addr + IPS_REG_FLDP); |
2400 | 2400 | ||
2401 | /* Get SubMinor version */ | 2401 | /* Get SubMinor version */ |
2402 | outl(cpu_to_le32(0x1FD), ha->io_addr + IPS_REG_FLAP); | 2402 | outl(0x1FD, ha->io_addr + IPS_REG_FLAP); |
2403 | if (ha->pcidev->revision == IPS_REVID_TROMBONE64) | 2403 | if (ha->pcidev->revision == IPS_REVID_TROMBONE64) |
2404 | udelay(25); /* 25 us */ | 2404 | udelay(25); /* 25 us */ |
2405 | 2405 | ||
@@ -3502,27 +3502,11 @@ ips_send_wait(ips_ha_t * ha, ips_scb_t * scb, int timeout, int intr) | |||
3502 | static void | 3502 | static void |
3503 | ips_scmd_buf_write(struct scsi_cmnd *scmd, void *data, unsigned int count) | 3503 | ips_scmd_buf_write(struct scsi_cmnd *scmd, void *data, unsigned int count) |
3504 | { | 3504 | { |
3505 | int i; | 3505 | unsigned long flags; |
3506 | unsigned int min_cnt, xfer_cnt; | ||
3507 | char *cdata = (char *) data; | ||
3508 | unsigned char *buffer; | ||
3509 | unsigned long flags; | ||
3510 | struct scatterlist *sg = scsi_sglist(scmd); | ||
3511 | |||
3512 | for (i = 0, xfer_cnt = 0; | ||
3513 | (i < scsi_sg_count(scmd)) && (xfer_cnt < count); i++) { | ||
3514 | min_cnt = min(count - xfer_cnt, sg[i].length); | ||
3515 | |||
3516 | /* kmap_atomic() ensures addressability of the data buffer.*/ | ||
3517 | /* local_irq_save() protects the KM_IRQ0 address slot. */ | ||
3518 | local_irq_save(flags); | ||
3519 | buffer = kmap_atomic(sg_page(&sg[i]), KM_IRQ0) + sg[i].offset; | ||
3520 | memcpy(buffer, &cdata[xfer_cnt], min_cnt); | ||
3521 | kunmap_atomic(buffer - sg[i].offset, KM_IRQ0); | ||
3522 | local_irq_restore(flags); | ||
3523 | 3506 | ||
3524 | xfer_cnt += min_cnt; | 3507 | local_irq_save(flags); |
3525 | } | 3508 | scsi_sg_copy_from_buffer(scmd, data, count); |
3509 | local_irq_restore(flags); | ||
3526 | } | 3510 | } |
3527 | 3511 | ||
3528 | /****************************************************************************/ | 3512 | /****************************************************************************/ |
@@ -3535,27 +3519,11 @@ ips_scmd_buf_write(struct scsi_cmnd *scmd, void *data, unsigned int count) | |||
3535 | static void | 3519 | static void |
3536 | ips_scmd_buf_read(struct scsi_cmnd *scmd, void *data, unsigned int count) | 3520 | ips_scmd_buf_read(struct scsi_cmnd *scmd, void *data, unsigned int count) |
3537 | { | 3521 | { |
3538 | int i; | 3522 | unsigned long flags; |
3539 | unsigned int min_cnt, xfer_cnt; | ||
3540 | char *cdata = (char *) data; | ||
3541 | unsigned char *buffer; | ||
3542 | unsigned long flags; | ||
3543 | struct scatterlist *sg = scsi_sglist(scmd); | ||
3544 | |||
3545 | for (i = 0, xfer_cnt = 0; | ||
3546 | (i < scsi_sg_count(scmd)) && (xfer_cnt < count); i++) { | ||
3547 | min_cnt = min(count - xfer_cnt, sg[i].length); | ||
3548 | |||
3549 | /* kmap_atomic() ensures addressability of the data buffer.*/ | ||
3550 | /* local_irq_save() protects the KM_IRQ0 address slot. */ | ||
3551 | local_irq_save(flags); | ||
3552 | buffer = kmap_atomic(sg_page(&sg[i]), KM_IRQ0) + sg[i].offset; | ||
3553 | memcpy(&cdata[xfer_cnt], buffer, min_cnt); | ||
3554 | kunmap_atomic(buffer - sg[i].offset, KM_IRQ0); | ||
3555 | local_irq_restore(flags); | ||
3556 | 3523 | ||
3557 | xfer_cnt += min_cnt; | 3524 | local_irq_save(flags); |
3558 | } | 3525 | scsi_sg_copy_to_buffer(scmd, data, count); |
3526 | local_irq_restore(flags); | ||
3559 | } | 3527 | } |
3560 | 3528 | ||
3561 | /****************************************************************************/ | 3529 | /****************************************************************************/ |
@@ -3696,9 +3664,7 @@ ips_send_cmd(ips_ha_t * ha, ips_scb_t * scb) | |||
3696 | scb->cmd.basic_io.sg_count = scb->sg_len; | 3664 | scb->cmd.basic_io.sg_count = scb->sg_len; |
3697 | 3665 | ||
3698 | if (scb->cmd.basic_io.lba) | 3666 | if (scb->cmd.basic_io.lba) |
3699 | scb->cmd.basic_io.lba = | 3667 | le32_add_cpu(&scb->cmd.basic_io.lba, |
3700 | cpu_to_le32(le32_to_cpu | ||
3701 | (scb->cmd.basic_io.lba) + | ||
3702 | le16_to_cpu(scb->cmd.basic_io. | 3668 | le16_to_cpu(scb->cmd.basic_io. |
3703 | sector_count)); | 3669 | sector_count)); |
3704 | else | 3670 | else |
@@ -3744,9 +3710,7 @@ ips_send_cmd(ips_ha_t * ha, ips_scb_t * scb) | |||
3744 | scb->cmd.basic_io.sg_count = scb->sg_len; | 3710 | scb->cmd.basic_io.sg_count = scb->sg_len; |
3745 | 3711 | ||
3746 | if (scb->cmd.basic_io.lba) | 3712 | if (scb->cmd.basic_io.lba) |
3747 | scb->cmd.basic_io.lba = | 3713 | le32_add_cpu(&scb->cmd.basic_io.lba, |
3748 | cpu_to_le32(le32_to_cpu | ||
3749 | (scb->cmd.basic_io.lba) + | ||
3750 | le16_to_cpu(scb->cmd.basic_io. | 3714 | le16_to_cpu(scb->cmd.basic_io. |
3751 | sector_count)); | 3715 | sector_count)); |
3752 | else | 3716 | else |
@@ -4888,7 +4852,7 @@ ips_init_copperhead(ips_ha_t * ha) | |||
4888 | return (0); | 4852 | return (0); |
4889 | 4853 | ||
4890 | /* setup CCCR */ | 4854 | /* setup CCCR */ |
4891 | outl(cpu_to_le32(0x1010), ha->io_addr + IPS_REG_CCCR); | 4855 | outl(0x1010, ha->io_addr + IPS_REG_CCCR); |
4892 | 4856 | ||
4893 | /* Enable busmastering */ | 4857 | /* Enable busmastering */ |
4894 | outb(IPS_BIT_EBM, ha->io_addr + IPS_REG_SCPR); | 4858 | outb(IPS_BIT_EBM, ha->io_addr + IPS_REG_SCPR); |
@@ -5270,12 +5234,12 @@ ips_statinit(ips_ha_t * ha) | |||
5270 | ha->adapt->p_status_tail = ha->adapt->status; | 5234 | ha->adapt->p_status_tail = ha->adapt->status; |
5271 | 5235 | ||
5272 | phys_status_start = ha->adapt->hw_status_start; | 5236 | phys_status_start = ha->adapt->hw_status_start; |
5273 | outl(cpu_to_le32(phys_status_start), ha->io_addr + IPS_REG_SQSR); | 5237 | outl(phys_status_start, ha->io_addr + IPS_REG_SQSR); |
5274 | outl(cpu_to_le32(phys_status_start + IPS_STATUS_Q_SIZE), | 5238 | outl(phys_status_start + IPS_STATUS_Q_SIZE, |
5275 | ha->io_addr + IPS_REG_SQER); | 5239 | ha->io_addr + IPS_REG_SQER); |
5276 | outl(cpu_to_le32(phys_status_start + IPS_STATUS_SIZE), | 5240 | outl(phys_status_start + IPS_STATUS_SIZE, |
5277 | ha->io_addr + IPS_REG_SQHR); | 5241 | ha->io_addr + IPS_REG_SQHR); |
5278 | outl(cpu_to_le32(phys_status_start), ha->io_addr + IPS_REG_SQTR); | 5242 | outl(phys_status_start, ha->io_addr + IPS_REG_SQTR); |
5279 | 5243 | ||
5280 | ha->adapt->hw_status_tail = phys_status_start; | 5244 | ha->adapt->hw_status_tail = phys_status_start; |
5281 | } | 5245 | } |
@@ -5332,7 +5296,7 @@ ips_statupd_copperhead(ips_ha_t * ha) | |||
5332 | ha->adapt->hw_status_tail = ha->adapt->hw_status_start; | 5296 | ha->adapt->hw_status_tail = ha->adapt->hw_status_start; |
5333 | } | 5297 | } |
5334 | 5298 | ||
5335 | outl(cpu_to_le32(ha->adapt->hw_status_tail), | 5299 | outl(ha->adapt->hw_status_tail, |
5336 | ha->io_addr + IPS_REG_SQTR); | 5300 | ha->io_addr + IPS_REG_SQTR); |
5337 | 5301 | ||
5338 | return (ha->adapt->p_status_tail->value); | 5302 | return (ha->adapt->p_status_tail->value); |
@@ -5434,8 +5398,8 @@ ips_issue_copperhead(ips_ha_t * ha, ips_scb_t * scb) | |||
5434 | } /* end if */ | 5398 | } /* end if */ |
5435 | } /* end while */ | 5399 | } /* end while */ |
5436 | 5400 | ||
5437 | outl(cpu_to_le32(scb->scb_busaddr), ha->io_addr + IPS_REG_CCSAR); | 5401 | outl(scb->scb_busaddr, ha->io_addr + IPS_REG_CCSAR); |
5438 | outw(cpu_to_le32(IPS_BIT_START_CMD), ha->io_addr + IPS_REG_CCCR); | 5402 | outw(IPS_BIT_START_CMD, ha->io_addr + IPS_REG_CCCR); |
5439 | 5403 | ||
5440 | return (IPS_SUCCESS); | 5404 | return (IPS_SUCCESS); |
5441 | } | 5405 | } |
@@ -5520,7 +5484,7 @@ ips_issue_i2o(ips_ha_t * ha, ips_scb_t * scb) | |||
5520 | ips_name, ha->host_num, scb->cmd.basic_io.command_id); | 5484 | ips_name, ha->host_num, scb->cmd.basic_io.command_id); |
5521 | } | 5485 | } |
5522 | 5486 | ||
5523 | outl(cpu_to_le32(scb->scb_busaddr), ha->io_addr + IPS_REG_I2O_INMSGQ); | 5487 | outl(scb->scb_busaddr, ha->io_addr + IPS_REG_I2O_INMSGQ); |
5524 | 5488 | ||
5525 | return (IPS_SUCCESS); | 5489 | return (IPS_SUCCESS); |
5526 | } | 5490 | } |
@@ -6412,7 +6376,7 @@ ips_program_bios(ips_ha_t * ha, char *buffer, uint32_t buffersize, | |||
6412 | 6376 | ||
6413 | for (i = 0; i < buffersize; i++) { | 6377 | for (i = 0; i < buffersize; i++) { |
6414 | /* write a byte */ | 6378 | /* write a byte */ |
6415 | outl(cpu_to_le32(i + offset), ha->io_addr + IPS_REG_FLAP); | 6379 | outl(i + offset, ha->io_addr + IPS_REG_FLAP); |
6416 | if (ha->pcidev->revision == IPS_REVID_TROMBONE64) | 6380 | if (ha->pcidev->revision == IPS_REVID_TROMBONE64) |
6417 | udelay(25); /* 25 us */ | 6381 | udelay(25); /* 25 us */ |
6418 | 6382 | ||
@@ -6597,7 +6561,7 @@ ips_verify_bios(ips_ha_t * ha, char *buffer, uint32_t buffersize, | |||
6597 | if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55) | 6561 | if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55) |
6598 | return (1); | 6562 | return (1); |
6599 | 6563 | ||
6600 | outl(cpu_to_le32(1), ha->io_addr + IPS_REG_FLAP); | 6564 | outl(1, ha->io_addr + IPS_REG_FLAP); |
6601 | if (ha->pcidev->revision == IPS_REVID_TROMBONE64) | 6565 | if (ha->pcidev->revision == IPS_REVID_TROMBONE64) |
6602 | udelay(25); /* 25 us */ | 6566 | udelay(25); /* 25 us */ |
6603 | if (inb(ha->io_addr + IPS_REG_FLDP) != 0xAA) | 6567 | if (inb(ha->io_addr + IPS_REG_FLDP) != 0xAA) |
@@ -6606,7 +6570,7 @@ ips_verify_bios(ips_ha_t * ha, char *buffer, uint32_t buffersize, | |||
6606 | checksum = 0xff; | 6570 | checksum = 0xff; |
6607 | for (i = 2; i < buffersize; i++) { | 6571 | for (i = 2; i < buffersize; i++) { |
6608 | 6572 | ||
6609 | outl(cpu_to_le32(i + offset), ha->io_addr + IPS_REG_FLAP); | 6573 | outl(i + offset, ha->io_addr + IPS_REG_FLAP); |
6610 | if (ha->pcidev->revision == IPS_REVID_TROMBONE64) | 6574 | if (ha->pcidev->revision == IPS_REVID_TROMBONE64) |
6611 | udelay(25); /* 25 us */ | 6575 | udelay(25); /* 25 us */ |
6612 | 6576 | ||
@@ -6842,7 +6806,6 @@ ips_register_scsi(int index) | |||
6842 | sh->sg_tablesize = sh->hostt->sg_tablesize; | 6806 | sh->sg_tablesize = sh->hostt->sg_tablesize; |
6843 | sh->can_queue = sh->hostt->can_queue; | 6807 | sh->can_queue = sh->hostt->can_queue; |
6844 | sh->cmd_per_lun = sh->hostt->cmd_per_lun; | 6808 | sh->cmd_per_lun = sh->hostt->cmd_per_lun; |
6845 | sh->unchecked_isa_dma = sh->hostt->unchecked_isa_dma; | ||
6846 | sh->use_clustering = sh->hostt->use_clustering; | 6809 | sh->use_clustering = sh->hostt->use_clustering; |
6847 | sh->max_sectors = 128; | 6810 | sh->max_sectors = 128; |
6848 | 6811 | ||
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 8a178674cb18..72b9b2a0eba3 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c | |||
@@ -528,6 +528,7 @@ iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
528 | struct iscsi_session *session = conn->session; | 528 | struct iscsi_session *session = conn->session; |
529 | struct scsi_cmnd *sc = ctask->sc; | 529 | struct scsi_cmnd *sc = ctask->sc; |
530 | int datasn = be32_to_cpu(rhdr->datasn); | 530 | int datasn = be32_to_cpu(rhdr->datasn); |
531 | unsigned total_in_length = scsi_in(sc)->length; | ||
531 | 532 | ||
532 | iscsi_update_cmdsn(session, (struct iscsi_nopin*)rhdr); | 533 | iscsi_update_cmdsn(session, (struct iscsi_nopin*)rhdr); |
533 | if (tcp_conn->in.datalen == 0) | 534 | if (tcp_conn->in.datalen == 0) |
@@ -542,10 +543,10 @@ iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
542 | tcp_ctask->exp_datasn++; | 543 | tcp_ctask->exp_datasn++; |
543 | 544 | ||
544 | tcp_ctask->data_offset = be32_to_cpu(rhdr->offset); | 545 | tcp_ctask->data_offset = be32_to_cpu(rhdr->offset); |
545 | if (tcp_ctask->data_offset + tcp_conn->in.datalen > scsi_bufflen(sc)) { | 546 | if (tcp_ctask->data_offset + tcp_conn->in.datalen > total_in_length) { |
546 | debug_tcp("%s: data_offset(%d) + data_len(%d) > total_length_in(%d)\n", | 547 | debug_tcp("%s: data_offset(%d) + data_len(%d) > total_length_in(%d)\n", |
547 | __FUNCTION__, tcp_ctask->data_offset, | 548 | __FUNCTION__, tcp_ctask->data_offset, |
548 | tcp_conn->in.datalen, scsi_bufflen(sc)); | 549 | tcp_conn->in.datalen, total_in_length); |
549 | return ISCSI_ERR_DATA_OFFSET; | 550 | return ISCSI_ERR_DATA_OFFSET; |
550 | } | 551 | } |
551 | 552 | ||
@@ -558,8 +559,8 @@ iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
558 | 559 | ||
559 | if (res_count > 0 && | 560 | if (res_count > 0 && |
560 | (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW || | 561 | (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW || |
561 | res_count <= scsi_bufflen(sc))) | 562 | res_count <= total_in_length)) |
562 | scsi_set_resid(sc, res_count); | 563 | scsi_in(sc)->resid = res_count; |
563 | else | 564 | else |
564 | sc->result = (DID_BAD_TARGET << 16) | | 565 | sc->result = (DID_BAD_TARGET << 16) | |
565 | rhdr->cmd_status; | 566 | rhdr->cmd_status; |
@@ -670,11 +671,11 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
670 | r2t->data_length, session->max_burst); | 671 | r2t->data_length, session->max_burst); |
671 | 672 | ||
672 | r2t->data_offset = be32_to_cpu(rhdr->data_offset); | 673 | r2t->data_offset = be32_to_cpu(rhdr->data_offset); |
673 | if (r2t->data_offset + r2t->data_length > scsi_bufflen(ctask->sc)) { | 674 | if (r2t->data_offset + r2t->data_length > scsi_out(ctask->sc)->length) { |
674 | iscsi_conn_printk(KERN_ERR, conn, | 675 | iscsi_conn_printk(KERN_ERR, conn, |
675 | "invalid R2T with data len %u at offset %u " | 676 | "invalid R2T with data len %u at offset %u " |
676 | "and total length %d\n", r2t->data_length, | 677 | "and total length %d\n", r2t->data_length, |
677 | r2t->data_offset, scsi_bufflen(ctask->sc)); | 678 | r2t->data_offset, scsi_out(ctask->sc)->length); |
678 | __kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t, | 679 | __kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t, |
679 | sizeof(void*)); | 680 | sizeof(void*)); |
680 | return ISCSI_ERR_DATALEN; | 681 | return ISCSI_ERR_DATALEN; |
@@ -771,6 +772,7 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr) | |||
771 | if (tcp_conn->in.datalen) { | 772 | if (tcp_conn->in.datalen) { |
772 | struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; | 773 | struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; |
773 | struct hash_desc *rx_hash = NULL; | 774 | struct hash_desc *rx_hash = NULL; |
775 | struct scsi_data_buffer *sdb = scsi_in(ctask->sc); | ||
774 | 776 | ||
775 | /* | 777 | /* |
776 | * Setup copy of Data-In into the Scsi_Cmnd | 778 | * Setup copy of Data-In into the Scsi_Cmnd |
@@ -788,8 +790,8 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr) | |||
788 | tcp_ctask->data_offset, | 790 | tcp_ctask->data_offset, |
789 | tcp_conn->in.datalen); | 791 | tcp_conn->in.datalen); |
790 | return iscsi_segment_seek_sg(&tcp_conn->in.segment, | 792 | return iscsi_segment_seek_sg(&tcp_conn->in.segment, |
791 | scsi_sglist(ctask->sc), | 793 | sdb->table.sgl, |
792 | scsi_sg_count(ctask->sc), | 794 | sdb->table.nents, |
793 | tcp_ctask->data_offset, | 795 | tcp_ctask->data_offset, |
794 | tcp_conn->in.datalen, | 796 | tcp_conn->in.datalen, |
795 | iscsi_tcp_process_data_in, | 797 | iscsi_tcp_process_data_in, |
@@ -1332,7 +1334,8 @@ iscsi_tcp_ctask_init(struct iscsi_cmd_task *ctask) | |||
1332 | return 0; | 1334 | return 0; |
1333 | 1335 | ||
1334 | /* If we have immediate data, attach a payload */ | 1336 | /* If we have immediate data, attach a payload */ |
1335 | err = iscsi_tcp_send_data_prep(conn, scsi_sglist(sc), scsi_sg_count(sc), | 1337 | err = iscsi_tcp_send_data_prep(conn, scsi_out(sc)->table.sgl, |
1338 | scsi_out(sc)->table.nents, | ||
1336 | 0, ctask->imm_count); | 1339 | 0, ctask->imm_count); |
1337 | if (err) | 1340 | if (err) |
1338 | return err; | 1341 | return err; |
@@ -1386,6 +1389,7 @@ iscsi_tcp_ctask_xmit(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
1386 | { | 1389 | { |
1387 | struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; | 1390 | struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; |
1388 | struct scsi_cmnd *sc = ctask->sc; | 1391 | struct scsi_cmnd *sc = ctask->sc; |
1392 | struct scsi_data_buffer *sdb = scsi_out(sc); | ||
1389 | int rc = 0; | 1393 | int rc = 0; |
1390 | 1394 | ||
1391 | flush: | 1395 | flush: |
@@ -1412,9 +1416,8 @@ flush: | |||
1412 | ctask->itt, tcp_ctask->sent, ctask->data_count); | 1416 | ctask->itt, tcp_ctask->sent, ctask->data_count); |
1413 | 1417 | ||
1414 | iscsi_tcp_send_hdr_prep(conn, hdr, sizeof(*hdr)); | 1418 | iscsi_tcp_send_hdr_prep(conn, hdr, sizeof(*hdr)); |
1415 | rc = iscsi_tcp_send_data_prep(conn, scsi_sglist(sc), | 1419 | rc = iscsi_tcp_send_data_prep(conn, sdb->table.sgl, |
1416 | scsi_sg_count(sc), | 1420 | sdb->table.nents, tcp_ctask->sent, |
1417 | tcp_ctask->sent, | ||
1418 | ctask->data_count); | 1421 | ctask->data_count); |
1419 | if (rc) | 1422 | if (rc) |
1420 | goto fail; | 1423 | goto fail; |
@@ -1460,8 +1463,8 @@ flush: | |||
1460 | iscsi_tcp_send_hdr_prep(conn, &r2t->dtask.hdr, | 1463 | iscsi_tcp_send_hdr_prep(conn, &r2t->dtask.hdr, |
1461 | sizeof(struct iscsi_hdr)); | 1464 | sizeof(struct iscsi_hdr)); |
1462 | 1465 | ||
1463 | rc = iscsi_tcp_send_data_prep(conn, scsi_sglist(sc), | 1466 | rc = iscsi_tcp_send_data_prep(conn, sdb->table.sgl, |
1464 | scsi_sg_count(sc), | 1467 | sdb->table.nents, |
1465 | r2t->data_offset + r2t->sent, | 1468 | r2t->data_offset + r2t->sent, |
1466 | r2t->data_count); | 1469 | r2t->data_count); |
1467 | if (rc) | 1470 | if (rc) |
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index bdd7de7da39a..010c1b9b178c 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c | |||
@@ -137,6 +137,70 @@ static int iscsi_add_hdr(struct iscsi_cmd_task *ctask, unsigned len) | |||
137 | return 0; | 137 | return 0; |
138 | } | 138 | } |
139 | 139 | ||
140 | /* | ||
141 | * make an extended cdb AHS | ||
142 | */ | ||
143 | static int iscsi_prep_ecdb_ahs(struct iscsi_cmd_task *ctask) | ||
144 | { | ||
145 | struct scsi_cmnd *cmd = ctask->sc; | ||
146 | unsigned rlen, pad_len; | ||
147 | unsigned short ahslength; | ||
148 | struct iscsi_ecdb_ahdr *ecdb_ahdr; | ||
149 | int rc; | ||
150 | |||
151 | ecdb_ahdr = iscsi_next_hdr(ctask); | ||
152 | rlen = cmd->cmd_len - ISCSI_CDB_SIZE; | ||
153 | |||
154 | BUG_ON(rlen > sizeof(ecdb_ahdr->ecdb)); | ||
155 | ahslength = rlen + sizeof(ecdb_ahdr->reserved); | ||
156 | |||
157 | pad_len = iscsi_padding(rlen); | ||
158 | |||
159 | rc = iscsi_add_hdr(ctask, sizeof(ecdb_ahdr->ahslength) + | ||
160 | sizeof(ecdb_ahdr->ahstype) + ahslength + pad_len); | ||
161 | if (rc) | ||
162 | return rc; | ||
163 | |||
164 | if (pad_len) | ||
165 | memset(&ecdb_ahdr->ecdb[rlen], 0, pad_len); | ||
166 | |||
167 | ecdb_ahdr->ahslength = cpu_to_be16(ahslength); | ||
168 | ecdb_ahdr->ahstype = ISCSI_AHSTYPE_CDB; | ||
169 | ecdb_ahdr->reserved = 0; | ||
170 | memcpy(ecdb_ahdr->ecdb, cmd->cmnd + ISCSI_CDB_SIZE, rlen); | ||
171 | |||
172 | debug_scsi("iscsi_prep_ecdb_ahs: varlen_cdb_len %d " | ||
173 | "rlen %d pad_len %d ahs_length %d iscsi_headers_size %u\n", | ||
174 | cmd->cmd_len, rlen, pad_len, ahslength, ctask->hdr_len); | ||
175 | |||
176 | return 0; | ||
177 | } | ||
178 | |||
179 | static int iscsi_prep_bidi_ahs(struct iscsi_cmd_task *ctask) | ||
180 | { | ||
181 | struct scsi_cmnd *sc = ctask->sc; | ||
182 | struct iscsi_rlength_ahdr *rlen_ahdr; | ||
183 | int rc; | ||
184 | |||
185 | rlen_ahdr = iscsi_next_hdr(ctask); | ||
186 | rc = iscsi_add_hdr(ctask, sizeof(*rlen_ahdr)); | ||
187 | if (rc) | ||
188 | return rc; | ||
189 | |||
190 | rlen_ahdr->ahslength = | ||
191 | cpu_to_be16(sizeof(rlen_ahdr->read_length) + | ||
192 | sizeof(rlen_ahdr->reserved)); | ||
193 | rlen_ahdr->ahstype = ISCSI_AHSTYPE_RLENGTH; | ||
194 | rlen_ahdr->reserved = 0; | ||
195 | rlen_ahdr->read_length = cpu_to_be32(scsi_in(sc)->length); | ||
196 | |||
197 | debug_scsi("bidi-in rlen_ahdr->read_length(%d) " | ||
198 | "rlen_ahdr->ahslength(%d)\n", | ||
199 | be32_to_cpu(rlen_ahdr->read_length), | ||
200 | be16_to_cpu(rlen_ahdr->ahslength)); | ||
201 | return 0; | ||
202 | } | ||
203 | |||
140 | /** | 204 | /** |
141 | * iscsi_prep_scsi_cmd_pdu - prep iscsi scsi cmd pdu | 205 | * iscsi_prep_scsi_cmd_pdu - prep iscsi scsi cmd pdu |
142 | * @ctask: iscsi cmd task | 206 | * @ctask: iscsi cmd task |
@@ -150,7 +214,7 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask) | |||
150 | struct iscsi_session *session = conn->session; | 214 | struct iscsi_session *session = conn->session; |
151 | struct iscsi_cmd *hdr = ctask->hdr; | 215 | struct iscsi_cmd *hdr = ctask->hdr; |
152 | struct scsi_cmnd *sc = ctask->sc; | 216 | struct scsi_cmnd *sc = ctask->sc; |
153 | unsigned hdrlength; | 217 | unsigned hdrlength, cmd_len; |
154 | int rc; | 218 | int rc; |
155 | 219 | ||
156 | ctask->hdr_len = 0; | 220 | ctask->hdr_len = 0; |
@@ -161,17 +225,30 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask) | |||
161 | hdr->flags = ISCSI_ATTR_SIMPLE; | 225 | hdr->flags = ISCSI_ATTR_SIMPLE; |
162 | int_to_scsilun(sc->device->lun, (struct scsi_lun *)hdr->lun); | 226 | int_to_scsilun(sc->device->lun, (struct scsi_lun *)hdr->lun); |
163 | hdr->itt = build_itt(ctask->itt, session->age); | 227 | hdr->itt = build_itt(ctask->itt, session->age); |
164 | hdr->data_length = cpu_to_be32(scsi_bufflen(sc)); | ||
165 | hdr->cmdsn = cpu_to_be32(session->cmdsn); | 228 | hdr->cmdsn = cpu_to_be32(session->cmdsn); |
166 | session->cmdsn++; | 229 | session->cmdsn++; |
167 | hdr->exp_statsn = cpu_to_be32(conn->exp_statsn); | 230 | hdr->exp_statsn = cpu_to_be32(conn->exp_statsn); |
168 | memcpy(hdr->cdb, sc->cmnd, sc->cmd_len); | 231 | cmd_len = sc->cmd_len; |
169 | if (sc->cmd_len < MAX_COMMAND_SIZE) | 232 | if (cmd_len < ISCSI_CDB_SIZE) |
170 | memset(&hdr->cdb[sc->cmd_len], 0, | 233 | memset(&hdr->cdb[cmd_len], 0, ISCSI_CDB_SIZE - cmd_len); |
171 | MAX_COMMAND_SIZE - sc->cmd_len); | 234 | else if (cmd_len > ISCSI_CDB_SIZE) { |
235 | rc = iscsi_prep_ecdb_ahs(ctask); | ||
236 | if (rc) | ||
237 | return rc; | ||
238 | cmd_len = ISCSI_CDB_SIZE; | ||
239 | } | ||
240 | memcpy(hdr->cdb, sc->cmnd, cmd_len); | ||
172 | 241 | ||
173 | ctask->imm_count = 0; | 242 | ctask->imm_count = 0; |
243 | if (scsi_bidi_cmnd(sc)) { | ||
244 | hdr->flags |= ISCSI_FLAG_CMD_READ; | ||
245 | rc = iscsi_prep_bidi_ahs(ctask); | ||
246 | if (rc) | ||
247 | return rc; | ||
248 | } | ||
174 | if (sc->sc_data_direction == DMA_TO_DEVICE) { | 249 | if (sc->sc_data_direction == DMA_TO_DEVICE) { |
250 | unsigned out_len = scsi_out(sc)->length; | ||
251 | hdr->data_length = cpu_to_be32(out_len); | ||
175 | hdr->flags |= ISCSI_FLAG_CMD_WRITE; | 252 | hdr->flags |= ISCSI_FLAG_CMD_WRITE; |
176 | /* | 253 | /* |
177 | * Write counters: | 254 | * Write counters: |
@@ -192,19 +269,19 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask) | |||
192 | ctask->unsol_datasn = 0; | 269 | ctask->unsol_datasn = 0; |
193 | 270 | ||
194 | if (session->imm_data_en) { | 271 | if (session->imm_data_en) { |
195 | if (scsi_bufflen(sc) >= session->first_burst) | 272 | if (out_len >= session->first_burst) |
196 | ctask->imm_count = min(session->first_burst, | 273 | ctask->imm_count = min(session->first_burst, |
197 | conn->max_xmit_dlength); | 274 | conn->max_xmit_dlength); |
198 | else | 275 | else |
199 | ctask->imm_count = min(scsi_bufflen(sc), | 276 | ctask->imm_count = min(out_len, |
200 | conn->max_xmit_dlength); | 277 | conn->max_xmit_dlength); |
201 | hton24(hdr->dlength, ctask->imm_count); | 278 | hton24(hdr->dlength, ctask->imm_count); |
202 | } else | 279 | } else |
203 | zero_data(hdr->dlength); | 280 | zero_data(hdr->dlength); |
204 | 281 | ||
205 | if (!session->initial_r2t_en) { | 282 | if (!session->initial_r2t_en) { |
206 | ctask->unsol_count = min((session->first_burst), | 283 | ctask->unsol_count = min(session->first_burst, out_len) |
207 | (scsi_bufflen(sc))) - ctask->imm_count; | 284 | - ctask->imm_count; |
208 | ctask->unsol_offset = ctask->imm_count; | 285 | ctask->unsol_offset = ctask->imm_count; |
209 | } | 286 | } |
210 | 287 | ||
@@ -214,6 +291,7 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask) | |||
214 | } else { | 291 | } else { |
215 | hdr->flags |= ISCSI_FLAG_CMD_FINAL; | 292 | hdr->flags |= ISCSI_FLAG_CMD_FINAL; |
216 | zero_data(hdr->dlength); | 293 | zero_data(hdr->dlength); |
294 | hdr->data_length = cpu_to_be32(scsi_in(sc)->length); | ||
217 | 295 | ||
218 | if (sc->sc_data_direction == DMA_FROM_DEVICE) | 296 | if (sc->sc_data_direction == DMA_FROM_DEVICE) |
219 | hdr->flags |= ISCSI_FLAG_CMD_READ; | 297 | hdr->flags |= ISCSI_FLAG_CMD_READ; |
@@ -232,10 +310,12 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask) | |||
232 | return EIO; | 310 | return EIO; |
233 | 311 | ||
234 | conn->scsicmd_pdus_cnt++; | 312 | conn->scsicmd_pdus_cnt++; |
235 | debug_scsi("iscsi prep [%s cid %d sc %p cdb 0x%x itt 0x%x len %d " | 313 | debug_scsi("iscsi prep [%s cid %d sc %p cdb 0x%x itt 0x%x " |
236 | "cmdsn %d win %d]\n", | 314 | "len %d bidi_len %d cmdsn %d win %d]\n", |
237 | sc->sc_data_direction == DMA_TO_DEVICE ? "write" : "read", | 315 | scsi_bidi_cmnd(sc) ? "bidirectional" : |
238 | conn->id, sc, sc->cmnd[0], ctask->itt, scsi_bufflen(sc), | 316 | sc->sc_data_direction == DMA_TO_DEVICE ? "write" : "read", |
317 | conn->id, sc, sc->cmnd[0], ctask->itt, | ||
318 | scsi_bufflen(sc), scsi_bidi_cmnd(sc) ? scsi_in(sc)->length : 0, | ||
239 | session->cmdsn, session->max_cmdsn - session->exp_cmdsn + 1); | 319 | session->cmdsn, session->max_cmdsn - session->exp_cmdsn + 1); |
240 | return 0; | 320 | return 0; |
241 | } | 321 | } |
@@ -298,7 +378,12 @@ static void fail_command(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, | |||
298 | conn->session->tt->cleanup_cmd_task(conn, ctask); | 378 | conn->session->tt->cleanup_cmd_task(conn, ctask); |
299 | 379 | ||
300 | sc->result = err; | 380 | sc->result = err; |
301 | scsi_set_resid(sc, scsi_bufflen(sc)); | 381 | if (!scsi_bidi_cmnd(sc)) |
382 | scsi_set_resid(sc, scsi_bufflen(sc)); | ||
383 | else { | ||
384 | scsi_out(sc)->resid = scsi_out(sc)->length; | ||
385 | scsi_in(sc)->resid = scsi_in(sc)->length; | ||
386 | } | ||
302 | if (conn->ctask == ctask) | 387 | if (conn->ctask == ctask) |
303 | conn->ctask = NULL; | 388 | conn->ctask = NULL; |
304 | /* release ref from queuecommand */ | 389 | /* release ref from queuecommand */ |
@@ -433,6 +518,18 @@ invalid_datalen: | |||
433 | min_t(uint16_t, senselen, SCSI_SENSE_BUFFERSIZE)); | 518 | min_t(uint16_t, senselen, SCSI_SENSE_BUFFERSIZE)); |
434 | } | 519 | } |
435 | 520 | ||
521 | if (rhdr->flags & (ISCSI_FLAG_CMD_BIDI_UNDERFLOW | | ||
522 | ISCSI_FLAG_CMD_BIDI_OVERFLOW)) { | ||
523 | int res_count = be32_to_cpu(rhdr->bi_residual_count); | ||
524 | |||
525 | if (scsi_bidi_cmnd(sc) && res_count > 0 && | ||
526 | (rhdr->flags & ISCSI_FLAG_CMD_BIDI_OVERFLOW || | ||
527 | res_count <= scsi_in(sc)->length)) | ||
528 | scsi_in(sc)->resid = res_count; | ||
529 | else | ||
530 | sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status; | ||
531 | } | ||
532 | |||
436 | if (rhdr->flags & (ISCSI_FLAG_CMD_UNDERFLOW | | 533 | if (rhdr->flags & (ISCSI_FLAG_CMD_UNDERFLOW | |
437 | ISCSI_FLAG_CMD_OVERFLOW)) { | 534 | ISCSI_FLAG_CMD_OVERFLOW)) { |
438 | int res_count = be32_to_cpu(rhdr->residual_count); | 535 | int res_count = be32_to_cpu(rhdr->residual_count); |
@@ -440,13 +537,11 @@ invalid_datalen: | |||
440 | if (res_count > 0 && | 537 | if (res_count > 0 && |
441 | (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW || | 538 | (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW || |
442 | res_count <= scsi_bufflen(sc))) | 539 | res_count <= scsi_bufflen(sc))) |
540 | /* write side for bidi or uni-io set_resid */ | ||
443 | scsi_set_resid(sc, res_count); | 541 | scsi_set_resid(sc, res_count); |
444 | else | 542 | else |
445 | sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status; | 543 | sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status; |
446 | } else if (rhdr->flags & (ISCSI_FLAG_CMD_BIDI_UNDERFLOW | | 544 | } |
447 | ISCSI_FLAG_CMD_BIDI_OVERFLOW)) | ||
448 | sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status; | ||
449 | |||
450 | out: | 545 | out: |
451 | debug_scsi("done [sc %lx res %d itt 0x%x]\n", | 546 | debug_scsi("done [sc %lx res %d itt 0x%x]\n", |
452 | (long)sc, sc->result, ctask->itt); | 547 | (long)sc, sc->result, ctask->itt); |
@@ -1102,7 +1197,12 @@ reject: | |||
1102 | fault: | 1197 | fault: |
1103 | spin_unlock(&session->lock); | 1198 | spin_unlock(&session->lock); |
1104 | debug_scsi("iscsi: cmd 0x%x is not queued (%d)\n", sc->cmnd[0], reason); | 1199 | debug_scsi("iscsi: cmd 0x%x is not queued (%d)\n", sc->cmnd[0], reason); |
1105 | scsi_set_resid(sc, scsi_bufflen(sc)); | 1200 | if (!scsi_bidi_cmnd(sc)) |
1201 | scsi_set_resid(sc, scsi_bufflen(sc)); | ||
1202 | else { | ||
1203 | scsi_out(sc)->resid = scsi_out(sc)->length; | ||
1204 | scsi_in(sc)->resid = scsi_in(sc)->length; | ||
1205 | } | ||
1106 | sc->scsi_done(sc); | 1206 | sc->scsi_done(sc); |
1107 | spin_lock(host->host_lock); | 1207 | spin_lock(host->host_lock); |
1108 | return 0; | 1208 | return 0; |
diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index a4811e4106df..744f06d04a36 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c | |||
@@ -691,7 +691,7 @@ static int sas_discover_sata_dev(struct domain_device *dev) | |||
691 | /* incomplete response */ | 691 | /* incomplete response */ |
692 | SAS_DPRINTK("sending SET FEATURE/PUP_STBY_SPIN_UP to " | 692 | SAS_DPRINTK("sending SET FEATURE/PUP_STBY_SPIN_UP to " |
693 | "dev %llx\n", SAS_ADDR(dev->sas_addr)); | 693 | "dev %llx\n", SAS_ADDR(dev->sas_addr)); |
694 | if (!le16_to_cpu(identify_x[83] & (1<<6))) | 694 | if (!(identify_x[83] & cpu_to_le16(1<<6))) |
695 | goto cont1; | 695 | goto cont1; |
696 | res = sas_issue_ata_cmd(dev, ATA_SET_FEATURES, | 696 | res = sas_issue_ata_cmd(dev, ATA_SET_FEATURES, |
697 | ATA_FEATURE_PUP_STBY_SPIN_UP, | 697 | ATA_FEATURE_PUP_STBY_SPIN_UP, |
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c index 1f8241563c6c..601ec5b6a7f6 100644 --- a/drivers/scsi/libsas/sas_scsi_host.c +++ b/drivers/scsi/libsas/sas_scsi_host.c | |||
@@ -24,6 +24,8 @@ | |||
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include <linux/kthread.h> | 26 | #include <linux/kthread.h> |
27 | #include <linux/firmware.h> | ||
28 | #include <linux/ctype.h> | ||
27 | 29 | ||
28 | #include "sas_internal.h" | 30 | #include "sas_internal.h" |
29 | 31 | ||
@@ -1064,6 +1066,45 @@ void sas_target_destroy(struct scsi_target *starget) | |||
1064 | return; | 1066 | return; |
1065 | } | 1067 | } |
1066 | 1068 | ||
1069 | static void sas_parse_addr(u8 *sas_addr, const char *p) | ||
1070 | { | ||
1071 | int i; | ||
1072 | for (i = 0; i < SAS_ADDR_SIZE; i++) { | ||
1073 | u8 h, l; | ||
1074 | if (!*p) | ||
1075 | break; | ||
1076 | h = isdigit(*p) ? *p-'0' : toupper(*p)-'A'+10; | ||
1077 | p++; | ||
1078 | l = isdigit(*p) ? *p-'0' : toupper(*p)-'A'+10; | ||
1079 | p++; | ||
1080 | sas_addr[i] = (h<<4) | l; | ||
1081 | } | ||
1082 | } | ||
1083 | |||
1084 | #define SAS_STRING_ADDR_SIZE 16 | ||
1085 | |||
1086 | int sas_request_addr(struct Scsi_Host *shost, u8 *addr) | ||
1087 | { | ||
1088 | int res; | ||
1089 | const struct firmware *fw; | ||
1090 | |||
1091 | res = request_firmware(&fw, "sas_addr", &shost->shost_gendev); | ||
1092 | if (res) | ||
1093 | return res; | ||
1094 | |||
1095 | if (fw->size < SAS_STRING_ADDR_SIZE) { | ||
1096 | res = -ENODEV; | ||
1097 | goto out; | ||
1098 | } | ||
1099 | |||
1100 | sas_parse_addr(addr, fw->data); | ||
1101 | |||
1102 | out: | ||
1103 | release_firmware(fw); | ||
1104 | return res; | ||
1105 | } | ||
1106 | EXPORT_SYMBOL_GPL(sas_request_addr); | ||
1107 | |||
1067 | EXPORT_SYMBOL_GPL(sas_queuecommand); | 1108 | EXPORT_SYMBOL_GPL(sas_queuecommand); |
1068 | EXPORT_SYMBOL_GPL(sas_target_alloc); | 1109 | EXPORT_SYMBOL_GPL(sas_target_alloc); |
1069 | EXPORT_SYMBOL_GPL(sas_slave_configure); | 1110 | EXPORT_SYMBOL_GPL(sas_slave_configure); |
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 2ab2d24dcc15..ec0b0f6e5e1a 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h | |||
@@ -23,7 +23,7 @@ | |||
23 | 23 | ||
24 | struct lpfc_sli2_slim; | 24 | struct lpfc_sli2_slim; |
25 | 25 | ||
26 | #define LPFC_MAX_TARGET 256 /* max number of targets supported */ | 26 | #define LPFC_MAX_TARGET 4096 /* max number of targets supported */ |
27 | #define LPFC_MAX_DISC_THREADS 64 /* max outstanding discovery els | 27 | #define LPFC_MAX_DISC_THREADS 64 /* max outstanding discovery els |
28 | requests */ | 28 | requests */ |
29 | #define LPFC_MAX_NS_RETRY 3 /* Number of retry attempts to contact | 29 | #define LPFC_MAX_NS_RETRY 3 /* Number of retry attempts to contact |
@@ -268,7 +268,6 @@ struct lpfc_vport { | |||
268 | #define FC_NLP_MORE 0x40 /* More node to process in node tbl */ | 268 | #define FC_NLP_MORE 0x40 /* More node to process in node tbl */ |
269 | #define FC_OFFLINE_MODE 0x80 /* Interface is offline for diag */ | 269 | #define FC_OFFLINE_MODE 0x80 /* Interface is offline for diag */ |
270 | #define FC_FABRIC 0x100 /* We are fabric attached */ | 270 | #define FC_FABRIC 0x100 /* We are fabric attached */ |
271 | #define FC_ESTABLISH_LINK 0x200 /* Reestablish Link */ | ||
272 | #define FC_RSCN_DISCOVERY 0x400 /* Auth all devices after RSCN */ | 271 | #define FC_RSCN_DISCOVERY 0x400 /* Auth all devices after RSCN */ |
273 | #define FC_SCSI_SCAN_TMO 0x4000 /* scsi scan timer running */ | 272 | #define FC_SCSI_SCAN_TMO 0x4000 /* scsi scan timer running */ |
274 | #define FC_ABORT_DISCOVERY 0x8000 /* we want to abort discovery */ | 273 | #define FC_ABORT_DISCOVERY 0x8000 /* we want to abort discovery */ |
@@ -433,8 +432,6 @@ struct lpfc_hba { | |||
433 | 432 | ||
434 | uint32_t fc_eventTag; /* event tag for link attention */ | 433 | uint32_t fc_eventTag; /* event tag for link attention */ |
435 | 434 | ||
436 | |||
437 | struct timer_list fc_estabtmo; /* link establishment timer */ | ||
438 | /* These fields used to be binfo */ | 435 | /* These fields used to be binfo */ |
439 | uint32_t fc_pref_DID; /* preferred D_ID */ | 436 | uint32_t fc_pref_DID; /* preferred D_ID */ |
440 | uint8_t fc_pref_ALPA; /* preferred AL_PA */ | 437 | uint8_t fc_pref_ALPA; /* preferred AL_PA */ |
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index b12a841703ca..74c9fc204211 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c | |||
@@ -1954,7 +1954,9 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr, | |||
1954 | (phba->sysfs_mbox.mbox->mb.mbxCommand != | 1954 | (phba->sysfs_mbox.mbox->mb.mbxCommand != |
1955 | MBX_DUMP_MEMORY && | 1955 | MBX_DUMP_MEMORY && |
1956 | phba->sysfs_mbox.mbox->mb.mbxCommand != | 1956 | phba->sysfs_mbox.mbox->mb.mbxCommand != |
1957 | MBX_RESTART)) { | 1957 | MBX_RESTART && |
1958 | phba->sysfs_mbox.mbox->mb.mbxCommand != | ||
1959 | MBX_WRITE_VPARMS)) { | ||
1958 | sysfs_mbox_idle(phba); | 1960 | sysfs_mbox_idle(phba); |
1959 | spin_unlock_irq(&phba->hbalock); | 1961 | spin_unlock_irq(&phba->hbalock); |
1960 | return -EPERM; | 1962 | return -EPERM; |
@@ -1962,7 +1964,11 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr, | |||
1962 | 1964 | ||
1963 | phba->sysfs_mbox.mbox->vport = vport; | 1965 | phba->sysfs_mbox.mbox->vport = vport; |
1964 | 1966 | ||
1965 | if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) { | 1967 | /* Don't allow mailbox commands to be sent when blocked |
1968 | * or when in the middle of discovery | ||
1969 | */ | ||
1970 | if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO || | ||
1971 | vport->fc_flag & FC_NDISC_ACTIVE) { | ||
1966 | sysfs_mbox_idle(phba); | 1972 | sysfs_mbox_idle(phba); |
1967 | spin_unlock_irq(&phba->hbalock); | 1973 | spin_unlock_irq(&phba->hbalock); |
1968 | return -EAGAIN; | 1974 | return -EAGAIN; |
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index 3d0ccd9b341d..153afae567b5 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c | |||
@@ -63,7 +63,7 @@ lpfc_ct_ignore_hbq_buffer(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq, | |||
63 | { | 63 | { |
64 | if (!mp) { | 64 | if (!mp) { |
65 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, | 65 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, |
66 | "0146 Ignoring unsolicted CT No HBQ " | 66 | "0146 Ignoring unsolicited CT No HBQ " |
67 | "status = x%x\n", | 67 | "status = x%x\n", |
68 | piocbq->iocb.ulpStatus); | 68 | piocbq->iocb.ulpStatus); |
69 | } | 69 | } |
@@ -438,7 +438,7 @@ lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint32_t Size) | |||
438 | (!(vport->ct_flags & FC_CT_RFF_ID)) || | 438 | (!(vport->ct_flags & FC_CT_RFF_ID)) || |
439 | (!vport->cfg_restrict_login)) { | 439 | (!vport->cfg_restrict_login)) { |
440 | ndlp = lpfc_setup_disc_node(vport, Did); | 440 | ndlp = lpfc_setup_disc_node(vport, Did); |
441 | if (ndlp) { | 441 | if (ndlp && NLP_CHK_NODE_ACT(ndlp)) { |
442 | lpfc_debugfs_disc_trc(vport, | 442 | lpfc_debugfs_disc_trc(vport, |
443 | LPFC_DISC_TRC_CT, | 443 | LPFC_DISC_TRC_CT, |
444 | "Parse GID_FTrsp: " | 444 | "Parse GID_FTrsp: " |
@@ -543,7 +543,7 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
543 | struct lpfc_dmabuf *outp; | 543 | struct lpfc_dmabuf *outp; |
544 | struct lpfc_sli_ct_request *CTrsp; | 544 | struct lpfc_sli_ct_request *CTrsp; |
545 | struct lpfc_nodelist *ndlp; | 545 | struct lpfc_nodelist *ndlp; |
546 | int rc, retry; | 546 | int rc; |
547 | 547 | ||
548 | /* First save ndlp, before we overwrite it */ | 548 | /* First save ndlp, before we overwrite it */ |
549 | ndlp = cmdiocb->context_un.ndlp; | 549 | ndlp = cmdiocb->context_un.ndlp; |
@@ -563,45 +563,29 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
563 | if (vport->load_flag & FC_UNLOADING) | 563 | if (vport->load_flag & FC_UNLOADING) |
564 | goto out; | 564 | goto out; |
565 | 565 | ||
566 | if (lpfc_els_chk_latt(vport) || lpfc_error_lost_link(irsp)) { | 566 | if (lpfc_els_chk_latt(vport)) { |
567 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, | 567 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, |
568 | "0216 Link event during NS query\n"); | 568 | "0216 Link event during NS query\n"); |
569 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); | 569 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); |
570 | goto out; | 570 | goto out; |
571 | } | 571 | } |
572 | 572 | if (lpfc_error_lost_link(irsp)) { | |
573 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, | ||
574 | "0226 NS query failed due to link event\n"); | ||
575 | goto out; | ||
576 | } | ||
573 | if (irsp->ulpStatus) { | 577 | if (irsp->ulpStatus) { |
574 | /* Check for retry */ | 578 | /* Check for retry */ |
575 | if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) { | 579 | if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) { |
576 | retry = 1; | 580 | if (irsp->ulpStatus != IOSTAT_LOCAL_REJECT || |
577 | if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT) { | 581 | irsp->un.ulpWord[4] != IOERR_NO_RESOURCES) |
578 | switch (irsp->un.ulpWord[4]) { | ||
579 | case IOERR_NO_RESOURCES: | ||
580 | /* We don't increment the retry | ||
581 | * count for this case. | ||
582 | */ | ||
583 | break; | ||
584 | case IOERR_LINK_DOWN: | ||
585 | case IOERR_SLI_ABORTED: | ||
586 | case IOERR_SLI_DOWN: | ||
587 | retry = 0; | ||
588 | break; | ||
589 | default: | ||
590 | vport->fc_ns_retry++; | ||
591 | } | ||
592 | } | ||
593 | else | ||
594 | vport->fc_ns_retry++; | 582 | vport->fc_ns_retry++; |
595 | 583 | ||
596 | if (retry) { | 584 | /* CT command is being retried */ |
597 | /* CT command is being retried */ | 585 | rc = lpfc_ns_cmd(vport, SLI_CTNS_GID_FT, |
598 | rc = lpfc_ns_cmd(vport, SLI_CTNS_GID_FT, | ||
599 | vport->fc_ns_retry, 0); | 586 | vport->fc_ns_retry, 0); |
600 | if (rc == 0) { | 587 | if (rc == 0) |
601 | /* success */ | 588 | goto out; |
602 | goto out; | ||
603 | } | ||
604 | } | ||
605 | } | 589 | } |
606 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); | 590 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); |
607 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | 591 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, |
@@ -780,7 +764,7 @@ lpfc_cmpl_ct_cmd_gff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
780 | 764 | ||
781 | /* This is a target port, unregistered port, or the GFF_ID failed */ | 765 | /* This is a target port, unregistered port, or the GFF_ID failed */ |
782 | ndlp = lpfc_setup_disc_node(vport, did); | 766 | ndlp = lpfc_setup_disc_node(vport, did); |
783 | if (ndlp) { | 767 | if (ndlp && NLP_CHK_NODE_ACT(ndlp)) { |
784 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, | 768 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, |
785 | "0242 Process x%x GFF " | 769 | "0242 Process x%x GFF " |
786 | "NameServer Rsp Data: x%x x%x x%x\n", | 770 | "NameServer Rsp Data: x%x x%x x%x\n", |
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index 783d1eea13ef..90272e65957a 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c | |||
@@ -503,6 +503,8 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size) | |||
503 | ndlp->nlp_sid); | 503 | ndlp->nlp_sid); |
504 | if (ndlp->nlp_type & NLP_FCP_INITIATOR) | 504 | if (ndlp->nlp_type & NLP_FCP_INITIATOR) |
505 | len += snprintf(buf+len, size-len, "FCP_INITIATOR "); | 505 | len += snprintf(buf+len, size-len, "FCP_INITIATOR "); |
506 | len += snprintf(buf+len, size-len, "usgmap:%x ", | ||
507 | ndlp->nlp_usg_map); | ||
506 | len += snprintf(buf+len, size-len, "refcnt:%x", | 508 | len += snprintf(buf+len, size-len, "refcnt:%x", |
507 | atomic_read(&ndlp->kref.refcount)); | 509 | atomic_read(&ndlp->kref.refcount)); |
508 | len += snprintf(buf+len, size-len, "\n"); | 510 | len += snprintf(buf+len, size-len, "\n"); |
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index cbb68a942255..886c5f1b11d2 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -719,9 +719,9 @@ lpfc_els_abort_flogi(struct lpfc_hba *phba) | |||
719 | if (icmd->ulpCommand == CMD_ELS_REQUEST64_CR && | 719 | if (icmd->ulpCommand == CMD_ELS_REQUEST64_CR && |
720 | icmd->un.elsreq64.bdl.ulpIoTag32) { | 720 | icmd->un.elsreq64.bdl.ulpIoTag32) { |
721 | ndlp = (struct lpfc_nodelist *)(iocb->context1); | 721 | ndlp = (struct lpfc_nodelist *)(iocb->context1); |
722 | if (ndlp && (ndlp->nlp_DID == Fabric_DID)) { | 722 | if (ndlp && NLP_CHK_NODE_ACT(ndlp) && |
723 | (ndlp->nlp_DID == Fabric_DID)) | ||
723 | lpfc_sli_issue_abort_iotag(phba, pring, iocb); | 724 | lpfc_sli_issue_abort_iotag(phba, pring, iocb); |
724 | } | ||
725 | } | 725 | } |
726 | } | 726 | } |
727 | spin_unlock_irq(&phba->hbalock); | 727 | spin_unlock_irq(&phba->hbalock); |
@@ -829,7 +829,7 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp, | |||
829 | struct fc_rport *rport; | 829 | struct fc_rport *rport; |
830 | struct serv_parm *sp; | 830 | struct serv_parm *sp; |
831 | uint8_t name[sizeof(struct lpfc_name)]; | 831 | uint8_t name[sizeof(struct lpfc_name)]; |
832 | uint32_t rc; | 832 | uint32_t rc, keepDID = 0; |
833 | 833 | ||
834 | /* Fabric nodes can have the same WWPN so we don't bother searching | 834 | /* Fabric nodes can have the same WWPN so we don't bother searching |
835 | * by WWPN. Just return the ndlp that was given to us. | 835 | * by WWPN. Just return the ndlp that was given to us. |
@@ -858,11 +858,17 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp, | |||
858 | return ndlp; | 858 | return ndlp; |
859 | lpfc_nlp_init(vport, new_ndlp, ndlp->nlp_DID); | 859 | lpfc_nlp_init(vport, new_ndlp, ndlp->nlp_DID); |
860 | } else if (!NLP_CHK_NODE_ACT(new_ndlp)) { | 860 | } else if (!NLP_CHK_NODE_ACT(new_ndlp)) { |
861 | rc = memcmp(&ndlp->nlp_portname, name, | ||
862 | sizeof(struct lpfc_name)); | ||
863 | if (!rc) | ||
864 | return ndlp; | ||
861 | new_ndlp = lpfc_enable_node(vport, new_ndlp, | 865 | new_ndlp = lpfc_enable_node(vport, new_ndlp, |
862 | NLP_STE_UNUSED_NODE); | 866 | NLP_STE_UNUSED_NODE); |
863 | if (!new_ndlp) | 867 | if (!new_ndlp) |
864 | return ndlp; | 868 | return ndlp; |
865 | } | 869 | keepDID = new_ndlp->nlp_DID; |
870 | } else | ||
871 | keepDID = new_ndlp->nlp_DID; | ||
866 | 872 | ||
867 | lpfc_unreg_rpi(vport, new_ndlp); | 873 | lpfc_unreg_rpi(vport, new_ndlp); |
868 | new_ndlp->nlp_DID = ndlp->nlp_DID; | 874 | new_ndlp->nlp_DID = ndlp->nlp_DID; |
@@ -893,12 +899,24 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp, | |||
893 | } | 899 | } |
894 | new_ndlp->nlp_type = ndlp->nlp_type; | 900 | new_ndlp->nlp_type = ndlp->nlp_type; |
895 | } | 901 | } |
902 | /* We shall actually free the ndlp with both nlp_DID and | ||
903 | * nlp_portname fields equals 0 to avoid any ndlp on the | ||
904 | * nodelist never to be used. | ||
905 | */ | ||
906 | if (ndlp->nlp_DID == 0) { | ||
907 | spin_lock_irq(&phba->ndlp_lock); | ||
908 | NLP_SET_FREE_REQ(ndlp); | ||
909 | spin_unlock_irq(&phba->ndlp_lock); | ||
910 | } | ||
896 | 911 | ||
912 | /* Two ndlps cannot have the same did on the nodelist */ | ||
913 | ndlp->nlp_DID = keepDID; | ||
897 | lpfc_drop_node(vport, ndlp); | 914 | lpfc_drop_node(vport, ndlp); |
898 | } | 915 | } |
899 | else { | 916 | else { |
900 | lpfc_unreg_rpi(vport, ndlp); | 917 | lpfc_unreg_rpi(vport, ndlp); |
901 | ndlp->nlp_DID = 0; /* Two ndlps cannot have the same did */ | 918 | /* Two ndlps cannot have the same did */ |
919 | ndlp->nlp_DID = keepDID; | ||
902 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); | 920 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
903 | } | 921 | } |
904 | return new_ndlp; | 922 | return new_ndlp; |
@@ -2091,7 +2109,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
2091 | } | 2109 | } |
2092 | 2110 | ||
2093 | phba->fc_stat.elsXmitRetry++; | 2111 | phba->fc_stat.elsXmitRetry++; |
2094 | if (ndlp && delay) { | 2112 | if (ndlp && NLP_CHK_NODE_ACT(ndlp) && delay) { |
2095 | phba->fc_stat.elsDelayRetry++; | 2113 | phba->fc_stat.elsDelayRetry++; |
2096 | ndlp->nlp_retry = cmdiocb->retry; | 2114 | ndlp->nlp_retry = cmdiocb->retry; |
2097 | 2115 | ||
@@ -2121,7 +2139,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
2121 | lpfc_issue_els_fdisc(vport, ndlp, cmdiocb->retry); | 2139 | lpfc_issue_els_fdisc(vport, ndlp, cmdiocb->retry); |
2122 | return 1; | 2140 | return 1; |
2123 | case ELS_CMD_PLOGI: | 2141 | case ELS_CMD_PLOGI: |
2124 | if (ndlp) { | 2142 | if (ndlp && NLP_CHK_NODE_ACT(ndlp)) { |
2125 | ndlp->nlp_prev_state = ndlp->nlp_state; | 2143 | ndlp->nlp_prev_state = ndlp->nlp_state; |
2126 | lpfc_nlp_set_state(vport, ndlp, | 2144 | lpfc_nlp_set_state(vport, ndlp, |
2127 | NLP_STE_PLOGI_ISSUE); | 2145 | NLP_STE_PLOGI_ISSUE); |
@@ -2302,7 +2320,7 @@ lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
2302 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 2320 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
2303 | kfree(mp); | 2321 | kfree(mp); |
2304 | mempool_free(pmb, phba->mbox_mem_pool); | 2322 | mempool_free(pmb, phba->mbox_mem_pool); |
2305 | if (ndlp) { | 2323 | if (ndlp && NLP_CHK_NODE_ACT(ndlp)) { |
2306 | lpfc_nlp_put(ndlp); | 2324 | lpfc_nlp_put(ndlp); |
2307 | /* This is the end of the default RPI cleanup logic for this | 2325 | /* This is the end of the default RPI cleanup logic for this |
2308 | * ndlp. If no other discovery threads are using this ndlp. | 2326 | * ndlp. If no other discovery threads are using this ndlp. |
@@ -2335,7 +2353,8 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
2335 | * function can have cmdiocb->contest1 (ndlp) field set to NULL. | 2353 | * function can have cmdiocb->contest1 (ndlp) field set to NULL. |
2336 | */ | 2354 | */ |
2337 | pcmd = (uint8_t *) (((struct lpfc_dmabuf *) cmdiocb->context2)->virt); | 2355 | pcmd = (uint8_t *) (((struct lpfc_dmabuf *) cmdiocb->context2)->virt); |
2338 | if (ndlp && (*((uint32_t *) (pcmd)) == ELS_CMD_LS_RJT)) { | 2356 | if (ndlp && NLP_CHK_NODE_ACT(ndlp) && |
2357 | (*((uint32_t *) (pcmd)) == ELS_CMD_LS_RJT)) { | ||
2339 | /* A LS_RJT associated with Default RPI cleanup has its own | 2358 | /* A LS_RJT associated with Default RPI cleanup has its own |
2340 | * seperate code path. | 2359 | * seperate code path. |
2341 | */ | 2360 | */ |
@@ -2344,7 +2363,7 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
2344 | } | 2363 | } |
2345 | 2364 | ||
2346 | /* Check to see if link went down during discovery */ | 2365 | /* Check to see if link went down during discovery */ |
2347 | if (!ndlp || lpfc_els_chk_latt(vport)) { | 2366 | if (!ndlp || !NLP_CHK_NODE_ACT(ndlp) || lpfc_els_chk_latt(vport)) { |
2348 | if (mbox) { | 2367 | if (mbox) { |
2349 | mp = (struct lpfc_dmabuf *) mbox->context1; | 2368 | mp = (struct lpfc_dmabuf *) mbox->context1; |
2350 | if (mp) { | 2369 | if (mp) { |
@@ -2353,7 +2372,8 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
2353 | } | 2372 | } |
2354 | mempool_free(mbox, phba->mbox_mem_pool); | 2373 | mempool_free(mbox, phba->mbox_mem_pool); |
2355 | } | 2374 | } |
2356 | if (ndlp && (ndlp->nlp_flag & NLP_RM_DFLT_RPI)) | 2375 | if (ndlp && NLP_CHK_NODE_ACT(ndlp) && |
2376 | (ndlp->nlp_flag & NLP_RM_DFLT_RPI)) | ||
2357 | if (lpfc_nlp_not_used(ndlp)) { | 2377 | if (lpfc_nlp_not_used(ndlp)) { |
2358 | ndlp = NULL; | 2378 | ndlp = NULL; |
2359 | /* Indicate the node has already released, | 2379 | /* Indicate the node has already released, |
@@ -2443,7 +2463,7 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
2443 | mempool_free(mbox, phba->mbox_mem_pool); | 2463 | mempool_free(mbox, phba->mbox_mem_pool); |
2444 | } | 2464 | } |
2445 | out: | 2465 | out: |
2446 | if (ndlp) { | 2466 | if (ndlp && NLP_CHK_NODE_ACT(ndlp)) { |
2447 | spin_lock_irq(shost->host_lock); | 2467 | spin_lock_irq(shost->host_lock); |
2448 | ndlp->nlp_flag &= ~(NLP_ACC_REGLOGIN | NLP_RM_DFLT_RPI); | 2468 | ndlp->nlp_flag &= ~(NLP_ACC_REGLOGIN | NLP_RM_DFLT_RPI); |
2449 | spin_unlock_irq(shost->host_lock); | 2469 | spin_unlock_irq(shost->host_lock); |
@@ -3139,6 +3159,8 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
3139 | /* Another thread is walking fc_rscn_id_list on this vport */ | 3159 | /* Another thread is walking fc_rscn_id_list on this vport */ |
3140 | spin_unlock_irq(shost->host_lock); | 3160 | spin_unlock_irq(shost->host_lock); |
3141 | vport->fc_flag |= FC_RSCN_DISCOVERY; | 3161 | vport->fc_flag |= FC_RSCN_DISCOVERY; |
3162 | /* Send back ACC */ | ||
3163 | lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL); | ||
3142 | return 0; | 3164 | return 0; |
3143 | } | 3165 | } |
3144 | /* Indicate we are walking fc_rscn_id_list on this vport */ | 3166 | /* Indicate we are walking fc_rscn_id_list on this vport */ |
@@ -3928,7 +3950,7 @@ lpfc_els_timeout_handler(struct lpfc_vport *vport) | |||
3928 | else { | 3950 | else { |
3929 | struct lpfc_nodelist *ndlp; | 3951 | struct lpfc_nodelist *ndlp; |
3930 | ndlp = __lpfc_findnode_rpi(vport, cmd->ulpContext); | 3952 | ndlp = __lpfc_findnode_rpi(vport, cmd->ulpContext); |
3931 | if (ndlp) | 3953 | if (ndlp && NLP_CHK_NODE_ACT(ndlp)) |
3932 | remote_ID = ndlp->nlp_DID; | 3954 | remote_ID = ndlp->nlp_DID; |
3933 | } | 3955 | } |
3934 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | 3956 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, |
@@ -4097,21 +4119,22 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
4097 | newnode = 1; | 4119 | newnode = 1; |
4098 | if ((did & Fabric_DID_MASK) == Fabric_DID_MASK) | 4120 | if ((did & Fabric_DID_MASK) == Fabric_DID_MASK) |
4099 | ndlp->nlp_type |= NLP_FABRIC; | 4121 | ndlp->nlp_type |= NLP_FABRIC; |
4100 | } else { | 4122 | } else if (!NLP_CHK_NODE_ACT(ndlp)) { |
4101 | if (!NLP_CHK_NODE_ACT(ndlp)) { | 4123 | ndlp = lpfc_enable_node(vport, ndlp, |
4102 | ndlp = lpfc_enable_node(vport, ndlp, | 4124 | NLP_STE_UNUSED_NODE); |
4103 | NLP_STE_UNUSED_NODE); | 4125 | if (!ndlp) |
4104 | if (!ndlp) | 4126 | goto dropit; |
4105 | goto dropit; | 4127 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
4106 | } | 4128 | newnode = 1; |
4107 | if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) { | 4129 | if ((did & Fabric_DID_MASK) == Fabric_DID_MASK) |
4108 | /* This is simular to the new node path */ | 4130 | ndlp->nlp_type |= NLP_FABRIC; |
4109 | ndlp = lpfc_nlp_get(ndlp); | 4131 | } else if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) { |
4110 | if (!ndlp) | 4132 | /* This is similar to the new node path */ |
4111 | goto dropit; | 4133 | ndlp = lpfc_nlp_get(ndlp); |
4112 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); | 4134 | if (!ndlp) |
4113 | newnode = 1; | 4135 | goto dropit; |
4114 | } | 4136 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
4137 | newnode = 1; | ||
4115 | } | 4138 | } |
4116 | 4139 | ||
4117 | phba->fc_stat.elsRcvFrame++; | 4140 | phba->fc_stat.elsRcvFrame++; |
@@ -4451,7 +4474,6 @@ lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport) | |||
4451 | return; | 4474 | return; |
4452 | } | 4475 | } |
4453 | lpfc_nlp_init(vport, ndlp, NameServer_DID); | 4476 | lpfc_nlp_init(vport, ndlp, NameServer_DID); |
4454 | ndlp->nlp_type |= NLP_FABRIC; | ||
4455 | } else if (!NLP_CHK_NODE_ACT(ndlp)) { | 4477 | } else if (!NLP_CHK_NODE_ACT(ndlp)) { |
4456 | ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE); | 4478 | ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE); |
4457 | if (!ndlp) { | 4479 | if (!ndlp) { |
@@ -4465,6 +4487,7 @@ lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport) | |||
4465 | return; | 4487 | return; |
4466 | } | 4488 | } |
4467 | } | 4489 | } |
4490 | ndlp->nlp_type |= NLP_FABRIC; | ||
4468 | 4491 | ||
4469 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE); | 4492 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE); |
4470 | 4493 | ||
@@ -4481,8 +4504,8 @@ lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport) | |||
4481 | if (ndlp_fdmi) { | 4504 | if (ndlp_fdmi) { |
4482 | lpfc_nlp_init(vport, ndlp_fdmi, FDMI_DID); | 4505 | lpfc_nlp_init(vport, ndlp_fdmi, FDMI_DID); |
4483 | ndlp_fdmi->nlp_type |= NLP_FABRIC; | 4506 | ndlp_fdmi->nlp_type |= NLP_FABRIC; |
4484 | ndlp_fdmi->nlp_state = | 4507 | lpfc_nlp_set_state(vport, ndlp_fdmi, |
4485 | NLP_STE_PLOGI_ISSUE; | 4508 | NLP_STE_PLOGI_ISSUE); |
4486 | lpfc_issue_els_plogi(vport, ndlp_fdmi->nlp_DID, | 4509 | lpfc_issue_els_plogi(vport, ndlp_fdmi->nlp_DID, |
4487 | 0); | 4510 | 0); |
4488 | } | 4511 | } |
@@ -5074,39 +5097,3 @@ void lpfc_fabric_abort_hba(struct lpfc_hba *phba) | |||
5074 | (piocb->iocb_cmpl) (phba, piocb, piocb); | 5097 | (piocb->iocb_cmpl) (phba, piocb, piocb); |
5075 | } | 5098 | } |
5076 | } | 5099 | } |
5077 | |||
5078 | |||
5079 | #if 0 | ||
5080 | void lpfc_fabric_abort_flogi(struct lpfc_hba *phba) | ||
5081 | { | ||
5082 | LIST_HEAD(completions); | ||
5083 | struct lpfc_iocbq *tmp_iocb, *piocb; | ||
5084 | IOCB_t *cmd; | ||
5085 | struct lpfc_nodelist *ndlp; | ||
5086 | |||
5087 | spin_lock_irq(&phba->hbalock); | ||
5088 | list_for_each_entry_safe(piocb, tmp_iocb, &phba->fabric_iocb_list, | ||
5089 | list) { | ||
5090 | |||
5091 | cmd = &piocb->iocb; | ||
5092 | ndlp = (struct lpfc_nodelist *) piocb->context1; | ||
5093 | if (cmd->ulpCommand == CMD_ELS_REQUEST64_CR && | ||
5094 | ndlp != NULL && | ||
5095 | ndlp->nlp_DID == Fabric_DID) | ||
5096 | list_move_tail(&piocb->list, &completions); | ||
5097 | } | ||
5098 | spin_unlock_irq(&phba->hbalock); | ||
5099 | |||
5100 | while (!list_empty(&completions)) { | ||
5101 | piocb = list_get_first(&completions, struct lpfc_iocbq, list); | ||
5102 | list_del_init(&piocb->list); | ||
5103 | |||
5104 | cmd = &piocb->iocb; | ||
5105 | cmd->ulpStatus = IOSTAT_LOCAL_REJECT; | ||
5106 | cmd->un.ulpWord[4] = IOERR_SLI_ABORTED; | ||
5107 | (piocb->iocb_cmpl) (phba, piocb, piocb); | ||
5108 | } | ||
5109 | } | ||
5110 | #endif /* 0 */ | ||
5111 | |||
5112 | |||
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 976653440fba..7cb68feb04fd 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -69,7 +69,7 @@ lpfc_terminate_rport_io(struct fc_rport *rport) | |||
69 | rdata = rport->dd_data; | 69 | rdata = rport->dd_data; |
70 | ndlp = rdata->pnode; | 70 | ndlp = rdata->pnode; |
71 | 71 | ||
72 | if (!ndlp) { | 72 | if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) { |
73 | if (rport->roles & FC_RPORT_ROLE_FCP_TARGET) | 73 | if (rport->roles & FC_RPORT_ROLE_FCP_TARGET) |
74 | printk(KERN_ERR "Cannot find remote node" | 74 | printk(KERN_ERR "Cannot find remote node" |
75 | " to terminate I/O Data x%x\n", | 75 | " to terminate I/O Data x%x\n", |
@@ -114,7 +114,7 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport) | |||
114 | 114 | ||
115 | rdata = rport->dd_data; | 115 | rdata = rport->dd_data; |
116 | ndlp = rdata->pnode; | 116 | ndlp = rdata->pnode; |
117 | if (!ndlp) | 117 | if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) |
118 | return; | 118 | return; |
119 | 119 | ||
120 | vport = ndlp->vport; | 120 | vport = ndlp->vport; |
@@ -243,8 +243,8 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp) | |||
243 | if (warn_on) { | 243 | if (warn_on) { |
244 | lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, | 244 | lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, |
245 | "0203 Devloss timeout on " | 245 | "0203 Devloss timeout on " |
246 | "WWPN %x:%x:%x:%x:%x:%x:%x:%x " | 246 | "WWPN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x " |
247 | "NPort x%x Data: x%x x%x x%x\n", | 247 | "NPort x%06x Data: x%x x%x x%x\n", |
248 | *name, *(name+1), *(name+2), *(name+3), | 248 | *name, *(name+1), *(name+2), *(name+3), |
249 | *(name+4), *(name+5), *(name+6), *(name+7), | 249 | *(name+4), *(name+5), *(name+6), *(name+7), |
250 | ndlp->nlp_DID, ndlp->nlp_flag, | 250 | ndlp->nlp_DID, ndlp->nlp_flag, |
@@ -252,8 +252,8 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp) | |||
252 | } else { | 252 | } else { |
253 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, | 253 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, |
254 | "0204 Devloss timeout on " | 254 | "0204 Devloss timeout on " |
255 | "WWPN %x:%x:%x:%x:%x:%x:%x:%x " | 255 | "WWPN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x " |
256 | "NPort x%x Data: x%x x%x x%x\n", | 256 | "NPort x%06x Data: x%x x%x x%x\n", |
257 | *name, *(name+1), *(name+2), *(name+3), | 257 | *name, *(name+1), *(name+2), *(name+3), |
258 | *(name+4), *(name+5), *(name+6), *(name+7), | 258 | *(name+4), *(name+5), *(name+6), *(name+7), |
259 | ndlp->nlp_DID, ndlp->nlp_flag, | 259 | ndlp->nlp_DID, ndlp->nlp_flag, |
@@ -399,7 +399,10 @@ lpfc_work_done(struct lpfc_hba *phba) | |||
399 | vport = vports[i]; | 399 | vport = vports[i]; |
400 | if (vport == NULL) | 400 | if (vport == NULL) |
401 | break; | 401 | break; |
402 | spin_lock_irq(&vport->work_port_lock); | ||
402 | work_port_events = vport->work_port_events; | 403 | work_port_events = vport->work_port_events; |
404 | vport->work_port_events &= ~work_port_events; | ||
405 | spin_unlock_irq(&vport->work_port_lock); | ||
403 | if (work_port_events & WORKER_DISC_TMO) | 406 | if (work_port_events & WORKER_DISC_TMO) |
404 | lpfc_disc_timeout_handler(vport); | 407 | lpfc_disc_timeout_handler(vport); |
405 | if (work_port_events & WORKER_ELS_TMO) | 408 | if (work_port_events & WORKER_ELS_TMO) |
@@ -416,9 +419,6 @@ lpfc_work_done(struct lpfc_hba *phba) | |||
416 | lpfc_ramp_down_queue_handler(phba); | 419 | lpfc_ramp_down_queue_handler(phba); |
417 | if (work_port_events & WORKER_RAMP_UP_QUEUE) | 420 | if (work_port_events & WORKER_RAMP_UP_QUEUE) |
418 | lpfc_ramp_up_queue_handler(phba); | 421 | lpfc_ramp_up_queue_handler(phba); |
419 | spin_lock_irq(&vport->work_port_lock); | ||
420 | vport->work_port_events &= ~work_port_events; | ||
421 | spin_unlock_irq(&vport->work_port_lock); | ||
422 | } | 422 | } |
423 | lpfc_destroy_vport_work_array(phba, vports); | 423 | lpfc_destroy_vport_work_array(phba, vports); |
424 | 424 | ||
@@ -430,10 +430,10 @@ lpfc_work_done(struct lpfc_hba *phba) | |||
430 | if (pring->flag & LPFC_STOP_IOCB_EVENT) { | 430 | if (pring->flag & LPFC_STOP_IOCB_EVENT) { |
431 | pring->flag |= LPFC_DEFERRED_RING_EVENT; | 431 | pring->flag |= LPFC_DEFERRED_RING_EVENT; |
432 | } else { | 432 | } else { |
433 | pring->flag &= ~LPFC_DEFERRED_RING_EVENT; | ||
433 | lpfc_sli_handle_slow_ring_event(phba, pring, | 434 | lpfc_sli_handle_slow_ring_event(phba, pring, |
434 | (status & | 435 | (status & |
435 | HA_RXMASK)); | 436 | HA_RXMASK)); |
436 | pring->flag &= ~LPFC_DEFERRED_RING_EVENT; | ||
437 | } | 437 | } |
438 | /* | 438 | /* |
439 | * Turn on Ring interrupts | 439 | * Turn on Ring interrupts |
@@ -519,7 +519,9 @@ lpfc_do_work(void *p) | |||
519 | schedule(); | 519 | schedule(); |
520 | } | 520 | } |
521 | } | 521 | } |
522 | spin_lock_irq(&phba->hbalock); | ||
522 | phba->work_wait = NULL; | 523 | phba->work_wait = NULL; |
524 | spin_unlock_irq(&phba->hbalock); | ||
523 | return 0; | 525 | return 0; |
524 | } | 526 | } |
525 | 527 | ||
@@ -809,11 +811,9 @@ out: | |||
809 | mempool_free(pmb, phba->mbox_mem_pool); | 811 | mempool_free(pmb, phba->mbox_mem_pool); |
810 | 812 | ||
811 | spin_lock_irq(shost->host_lock); | 813 | spin_lock_irq(shost->host_lock); |
812 | vport->fc_flag &= ~(FC_ABORT_DISCOVERY | FC_ESTABLISH_LINK); | 814 | vport->fc_flag &= ~FC_ABORT_DISCOVERY; |
813 | spin_unlock_irq(shost->host_lock); | 815 | spin_unlock_irq(shost->host_lock); |
814 | 816 | ||
815 | del_timer_sync(&phba->fc_estabtmo); | ||
816 | |||
817 | lpfc_can_disctmo(vport); | 817 | lpfc_can_disctmo(vport); |
818 | 818 | ||
819 | /* turn on Link Attention interrupts */ | 819 | /* turn on Link Attention interrupts */ |
@@ -1340,10 +1340,14 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
1340 | i++) { | 1340 | i++) { |
1341 | if (vports[i]->port_type == LPFC_PHYSICAL_PORT) | 1341 | if (vports[i]->port_type == LPFC_PHYSICAL_PORT) |
1342 | continue; | 1342 | continue; |
1343 | if (phba->fc_topology == TOPOLOGY_LOOP) { | ||
1344 | lpfc_vport_set_state(vports[i], | ||
1345 | FC_VPORT_LINKDOWN); | ||
1346 | continue; | ||
1347 | } | ||
1343 | if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) | 1348 | if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) |
1344 | lpfc_initial_fdisc(vports[i]); | 1349 | lpfc_initial_fdisc(vports[i]); |
1345 | else if (phba->sli3_options & | 1350 | else { |
1346 | LPFC_SLI3_NPIV_ENABLED) { | ||
1347 | lpfc_vport_set_state(vports[i], | 1351 | lpfc_vport_set_state(vports[i], |
1348 | FC_VPORT_NO_FABRIC_SUPP); | 1352 | FC_VPORT_NO_FABRIC_SUPP); |
1349 | lpfc_printf_vlog(vport, KERN_ERR, | 1353 | lpfc_printf_vlog(vport, KERN_ERR, |
@@ -2190,10 +2194,6 @@ lpfc_matchdid(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
2190 | if (did == Bcast_DID) | 2194 | if (did == Bcast_DID) |
2191 | return 0; | 2195 | return 0; |
2192 | 2196 | ||
2193 | if (ndlp->nlp_DID == 0) { | ||
2194 | return 0; | ||
2195 | } | ||
2196 | |||
2197 | /* First check for Direct match */ | 2197 | /* First check for Direct match */ |
2198 | if (ndlp->nlp_DID == did) | 2198 | if (ndlp->nlp_DID == did) |
2199 | return 1; | 2199 | return 1; |
@@ -2301,7 +2301,8 @@ lpfc_setup_disc_node(struct lpfc_vport *vport, uint32_t did) | |||
2301 | return ndlp; | 2301 | return ndlp; |
2302 | } | 2302 | } |
2303 | 2303 | ||
2304 | if (vport->fc_flag & FC_RSCN_MODE) { | 2304 | if ((vport->fc_flag & FC_RSCN_MODE) && |
2305 | !(vport->fc_flag & FC_NDISC_ACTIVE)) { | ||
2305 | if (lpfc_rscn_payload_check(vport, did)) { | 2306 | if (lpfc_rscn_payload_check(vport, did)) { |
2306 | /* If we've already recieved a PLOGI from this NPort | 2307 | /* If we've already recieved a PLOGI from this NPort |
2307 | * we don't need to try to discover it again. | 2308 | * we don't need to try to discover it again. |
@@ -2947,24 +2948,6 @@ __lpfc_find_node(struct lpfc_vport *vport, node_filter filter, void *param) | |||
2947 | return NULL; | 2948 | return NULL; |
2948 | } | 2949 | } |
2949 | 2950 | ||
2950 | #if 0 | ||
2951 | /* | ||
2952 | * Search node lists for a remote port matching filter criteria | ||
2953 | * Caller needs to hold host_lock before calling this routine. | ||
2954 | */ | ||
2955 | struct lpfc_nodelist * | ||
2956 | lpfc_find_node(struct lpfc_vport *vport, node_filter filter, void *param) | ||
2957 | { | ||
2958 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
2959 | struct lpfc_nodelist *ndlp; | ||
2960 | |||
2961 | spin_lock_irq(shost->host_lock); | ||
2962 | ndlp = __lpfc_find_node(vport, filter, param); | ||
2963 | spin_unlock_irq(shost->host_lock); | ||
2964 | return ndlp; | ||
2965 | } | ||
2966 | #endif /* 0 */ | ||
2967 | |||
2968 | /* | 2951 | /* |
2969 | * This routine looks up the ndlp lists for the given RPI. If rpi found it | 2952 | * This routine looks up the ndlp lists for the given RPI. If rpi found it |
2970 | * returns the node list element pointer else return NULL. | 2953 | * returns the node list element pointer else return NULL. |
@@ -2975,20 +2958,6 @@ __lpfc_findnode_rpi(struct lpfc_vport *vport, uint16_t rpi) | |||
2975 | return __lpfc_find_node(vport, lpfc_filter_by_rpi, &rpi); | 2958 | return __lpfc_find_node(vport, lpfc_filter_by_rpi, &rpi); |
2976 | } | 2959 | } |
2977 | 2960 | ||
2978 | #if 0 | ||
2979 | struct lpfc_nodelist * | ||
2980 | lpfc_findnode_rpi(struct lpfc_vport *vport, uint16_t rpi) | ||
2981 | { | ||
2982 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
2983 | struct lpfc_nodelist *ndlp; | ||
2984 | |||
2985 | spin_lock_irq(shost->host_lock); | ||
2986 | ndlp = __lpfc_findnode_rpi(vport, rpi); | ||
2987 | spin_unlock_irq(shost->host_lock); | ||
2988 | return ndlp; | ||
2989 | } | ||
2990 | #endif /* 0 */ | ||
2991 | |||
2992 | /* | 2961 | /* |
2993 | * This routine looks up the ndlp lists for the given WWPN. If WWPN found it | 2962 | * This routine looks up the ndlp lists for the given WWPN. If WWPN found it |
2994 | * returns the node element list pointer else return NULL. | 2963 | * returns the node element list pointer else return NULL. |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 22843751c2ca..fa757b251f82 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -559,8 +559,10 @@ lpfc_hb_timeout(unsigned long ptr) | |||
559 | phba->pport->work_port_events |= WORKER_HB_TMO; | 559 | phba->pport->work_port_events |= WORKER_HB_TMO; |
560 | spin_unlock_irqrestore(&phba->pport->work_port_lock, iflag); | 560 | spin_unlock_irqrestore(&phba->pport->work_port_lock, iflag); |
561 | 561 | ||
562 | spin_lock_irqsave(&phba->hbalock, iflag); | ||
562 | if (phba->work_wait) | 563 | if (phba->work_wait) |
563 | wake_up(phba->work_wait); | 564 | wake_up(phba->work_wait); |
565 | spin_unlock_irqrestore(&phba->hbalock, iflag); | ||
564 | return; | 566 | return; |
565 | } | 567 | } |
566 | 568 | ||
@@ -714,12 +716,10 @@ lpfc_handle_eratt(struct lpfc_hba *phba) | |||
714 | struct lpfc_vport *vport = phba->pport; | 716 | struct lpfc_vport *vport = phba->pport; |
715 | struct lpfc_sli *psli = &phba->sli; | 717 | struct lpfc_sli *psli = &phba->sli; |
716 | struct lpfc_sli_ring *pring; | 718 | struct lpfc_sli_ring *pring; |
717 | struct lpfc_vport **vports; | ||
718 | uint32_t event_data; | 719 | uint32_t event_data; |
719 | unsigned long temperature; | 720 | unsigned long temperature; |
720 | struct temp_event temp_event_data; | 721 | struct temp_event temp_event_data; |
721 | struct Scsi_Host *shost; | 722 | struct Scsi_Host *shost; |
722 | int i; | ||
723 | 723 | ||
724 | /* If the pci channel is offline, ignore possible errors, | 724 | /* If the pci channel is offline, ignore possible errors, |
725 | * since we cannot communicate with the pci card anyway. */ | 725 | * since we cannot communicate with the pci card anyway. */ |
@@ -729,25 +729,14 @@ lpfc_handle_eratt(struct lpfc_hba *phba) | |||
729 | if (!phba->cfg_enable_hba_reset) | 729 | if (!phba->cfg_enable_hba_reset) |
730 | return; | 730 | return; |
731 | 731 | ||
732 | if (phba->work_hs & HS_FFER6 || | 732 | if (phba->work_hs & HS_FFER6) { |
733 | phba->work_hs & HS_FFER5) { | ||
734 | /* Re-establishing Link */ | 733 | /* Re-establishing Link */ |
735 | lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT, | 734 | lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT, |
736 | "1301 Re-establishing Link " | 735 | "1301 Re-establishing Link " |
737 | "Data: x%x x%x x%x\n", | 736 | "Data: x%x x%x x%x\n", |
738 | phba->work_hs, | 737 | phba->work_hs, |
739 | phba->work_status[0], phba->work_status[1]); | 738 | phba->work_status[0], phba->work_status[1]); |
740 | vports = lpfc_create_vport_work_array(phba); | 739 | |
741 | if (vports != NULL) | ||
742 | for(i = 0; | ||
743 | i <= phba->max_vpi && vports[i] != NULL; | ||
744 | i++){ | ||
745 | shost = lpfc_shost_from_vport(vports[i]); | ||
746 | spin_lock_irq(shost->host_lock); | ||
747 | vports[i]->fc_flag |= FC_ESTABLISH_LINK; | ||
748 | spin_unlock_irq(shost->host_lock); | ||
749 | } | ||
750 | lpfc_destroy_vport_work_array(phba, vports); | ||
751 | spin_lock_irq(&phba->hbalock); | 740 | spin_lock_irq(&phba->hbalock); |
752 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; | 741 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; |
753 | spin_unlock_irq(&phba->hbalock); | 742 | spin_unlock_irq(&phba->hbalock); |
@@ -761,7 +750,6 @@ lpfc_handle_eratt(struct lpfc_hba *phba) | |||
761 | pring = &psli->ring[psli->fcp_ring]; | 750 | pring = &psli->ring[psli->fcp_ring]; |
762 | lpfc_sli_abort_iocb_ring(phba, pring); | 751 | lpfc_sli_abort_iocb_ring(phba, pring); |
763 | 752 | ||
764 | |||
765 | /* | 753 | /* |
766 | * There was a firmware error. Take the hba offline and then | 754 | * There was a firmware error. Take the hba offline and then |
767 | * attempt to restart it. | 755 | * attempt to restart it. |
@@ -770,7 +758,6 @@ lpfc_handle_eratt(struct lpfc_hba *phba) | |||
770 | lpfc_offline(phba); | 758 | lpfc_offline(phba); |
771 | lpfc_sli_brdrestart(phba); | 759 | lpfc_sli_brdrestart(phba); |
772 | if (lpfc_online(phba) == 0) { /* Initialize the HBA */ | 760 | if (lpfc_online(phba) == 0) { /* Initialize the HBA */ |
773 | mod_timer(&phba->fc_estabtmo, jiffies + HZ * 60); | ||
774 | lpfc_unblock_mgmt_io(phba); | 761 | lpfc_unblock_mgmt_io(phba); |
775 | return; | 762 | return; |
776 | } | 763 | } |
@@ -1454,6 +1441,13 @@ lpfc_cleanup(struct lpfc_vport *vport) | |||
1454 | NLP_SET_FREE_REQ(ndlp); | 1441 | NLP_SET_FREE_REQ(ndlp); |
1455 | spin_unlock_irq(&phba->ndlp_lock); | 1442 | spin_unlock_irq(&phba->ndlp_lock); |
1456 | 1443 | ||
1444 | if (vport->port_type != LPFC_PHYSICAL_PORT && | ||
1445 | ndlp->nlp_DID == Fabric_DID) { | ||
1446 | /* Just free up ndlp with Fabric_DID for vports */ | ||
1447 | lpfc_nlp_put(ndlp); | ||
1448 | continue; | ||
1449 | } | ||
1450 | |||
1457 | if (ndlp->nlp_type & NLP_FABRIC) | 1451 | if (ndlp->nlp_type & NLP_FABRIC) |
1458 | lpfc_disc_state_machine(vport, ndlp, NULL, | 1452 | lpfc_disc_state_machine(vport, ndlp, NULL, |
1459 | NLP_EVT_DEVICE_RECOVERY); | 1453 | NLP_EVT_DEVICE_RECOVERY); |
@@ -1491,31 +1485,6 @@ lpfc_cleanup(struct lpfc_vport *vport) | |||
1491 | return; | 1485 | return; |
1492 | } | 1486 | } |
1493 | 1487 | ||
1494 | static void | ||
1495 | lpfc_establish_link_tmo(unsigned long ptr) | ||
1496 | { | ||
1497 | struct lpfc_hba *phba = (struct lpfc_hba *) ptr; | ||
1498 | struct lpfc_vport **vports; | ||
1499 | unsigned long iflag; | ||
1500 | int i; | ||
1501 | |||
1502 | /* Re-establishing Link, timer expired */ | ||
1503 | lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT, | ||
1504 | "1300 Re-establishing Link, timer expired " | ||
1505 | "Data: x%x x%x\n", | ||
1506 | phba->pport->fc_flag, phba->pport->port_state); | ||
1507 | vports = lpfc_create_vport_work_array(phba); | ||
1508 | if (vports != NULL) | ||
1509 | for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) { | ||
1510 | struct Scsi_Host *shost; | ||
1511 | shost = lpfc_shost_from_vport(vports[i]); | ||
1512 | spin_lock_irqsave(shost->host_lock, iflag); | ||
1513 | vports[i]->fc_flag &= ~FC_ESTABLISH_LINK; | ||
1514 | spin_unlock_irqrestore(shost->host_lock, iflag); | ||
1515 | } | ||
1516 | lpfc_destroy_vport_work_array(phba, vports); | ||
1517 | } | ||
1518 | |||
1519 | void | 1488 | void |
1520 | lpfc_stop_vport_timers(struct lpfc_vport *vport) | 1489 | lpfc_stop_vport_timers(struct lpfc_vport *vport) |
1521 | { | 1490 | { |
@@ -1529,7 +1498,6 @@ static void | |||
1529 | lpfc_stop_phba_timers(struct lpfc_hba *phba) | 1498 | lpfc_stop_phba_timers(struct lpfc_hba *phba) |
1530 | { | 1499 | { |
1531 | del_timer_sync(&phba->fcp_poll_timer); | 1500 | del_timer_sync(&phba->fcp_poll_timer); |
1532 | del_timer_sync(&phba->fc_estabtmo); | ||
1533 | lpfc_stop_vport_timers(phba->pport); | 1501 | lpfc_stop_vport_timers(phba->pport); |
1534 | del_timer_sync(&phba->sli.mbox_tmo); | 1502 | del_timer_sync(&phba->sli.mbox_tmo); |
1535 | del_timer_sync(&phba->fabric_block_timer); | 1503 | del_timer_sync(&phba->fabric_block_timer); |
@@ -2005,10 +1973,6 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
2005 | phba->max_vpi = LPFC_MAX_VPI; | 1973 | phba->max_vpi = LPFC_MAX_VPI; |
2006 | 1974 | ||
2007 | /* Initialize timers used by driver */ | 1975 | /* Initialize timers used by driver */ |
2008 | init_timer(&phba->fc_estabtmo); | ||
2009 | phba->fc_estabtmo.function = lpfc_establish_link_tmo; | ||
2010 | phba->fc_estabtmo.data = (unsigned long)phba; | ||
2011 | |||
2012 | init_timer(&phba->hb_tmofunc); | 1976 | init_timer(&phba->hb_tmofunc); |
2013 | phba->hb_tmofunc.function = lpfc_hb_timeout; | 1977 | phba->hb_tmofunc.function = lpfc_hb_timeout; |
2014 | phba->hb_tmofunc.data = (unsigned long)phba; | 1978 | phba->hb_tmofunc.data = (unsigned long)phba; |
@@ -2406,6 +2370,7 @@ static pci_ers_result_t lpfc_io_slot_reset(struct pci_dev *pdev) | |||
2406 | struct Scsi_Host *shost = pci_get_drvdata(pdev); | 2370 | struct Scsi_Host *shost = pci_get_drvdata(pdev); |
2407 | struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; | 2371 | struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; |
2408 | struct lpfc_sli *psli = &phba->sli; | 2372 | struct lpfc_sli *psli = &phba->sli; |
2373 | int error, retval; | ||
2409 | 2374 | ||
2410 | dev_printk(KERN_INFO, &pdev->dev, "recovering from a slot reset.\n"); | 2375 | dev_printk(KERN_INFO, &pdev->dev, "recovering from a slot reset.\n"); |
2411 | if (pci_enable_device_mem(pdev)) { | 2376 | if (pci_enable_device_mem(pdev)) { |
@@ -2416,15 +2381,40 @@ static pci_ers_result_t lpfc_io_slot_reset(struct pci_dev *pdev) | |||
2416 | 2381 | ||
2417 | pci_set_master(pdev); | 2382 | pci_set_master(pdev); |
2418 | 2383 | ||
2419 | /* Re-establishing Link */ | ||
2420 | spin_lock_irq(shost->host_lock); | ||
2421 | phba->pport->fc_flag |= FC_ESTABLISH_LINK; | ||
2422 | spin_unlock_irq(shost->host_lock); | ||
2423 | |||
2424 | spin_lock_irq(&phba->hbalock); | 2384 | spin_lock_irq(&phba->hbalock); |
2425 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; | 2385 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; |
2426 | spin_unlock_irq(&phba->hbalock); | 2386 | spin_unlock_irq(&phba->hbalock); |
2427 | 2387 | ||
2388 | /* Enable configured interrupt method */ | ||
2389 | phba->intr_type = NONE; | ||
2390 | if (phba->cfg_use_msi == 2) { | ||
2391 | error = lpfc_enable_msix(phba); | ||
2392 | if (!error) | ||
2393 | phba->intr_type = MSIX; | ||
2394 | } | ||
2395 | |||
2396 | /* Fallback to MSI if MSI-X initialization failed */ | ||
2397 | if (phba->cfg_use_msi >= 1 && phba->intr_type == NONE) { | ||
2398 | retval = pci_enable_msi(phba->pcidev); | ||
2399 | if (!retval) | ||
2400 | phba->intr_type = MSI; | ||
2401 | else | ||
2402 | lpfc_printf_log(phba, KERN_INFO, LOG_INIT, | ||
2403 | "0470 Enable MSI failed, continuing " | ||
2404 | "with IRQ\n"); | ||
2405 | } | ||
2406 | |||
2407 | /* MSI-X is the only case the doesn't need to call request_irq */ | ||
2408 | if (phba->intr_type != MSIX) { | ||
2409 | retval = request_irq(phba->pcidev->irq, lpfc_intr_handler, | ||
2410 | IRQF_SHARED, LPFC_DRIVER_NAME, phba); | ||
2411 | if (retval) { | ||
2412 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
2413 | "0471 Enable interrupt handler " | ||
2414 | "failed\n"); | ||
2415 | } else if (phba->intr_type != MSI) | ||
2416 | phba->intr_type = INTx; | ||
2417 | } | ||
2428 | 2418 | ||
2429 | /* Take device offline; this will perform cleanup */ | 2419 | /* Take device offline; this will perform cleanup */ |
2430 | lpfc_offline(phba); | 2420 | lpfc_offline(phba); |
@@ -2445,9 +2435,7 @@ static void lpfc_io_resume(struct pci_dev *pdev) | |||
2445 | struct Scsi_Host *shost = pci_get_drvdata(pdev); | 2435 | struct Scsi_Host *shost = pci_get_drvdata(pdev); |
2446 | struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; | 2436 | struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; |
2447 | 2437 | ||
2448 | if (lpfc_online(phba) == 0) { | 2438 | lpfc_online(phba); |
2449 | mod_timer(&phba->fc_estabtmo, jiffies + HZ * 60); | ||
2450 | } | ||
2451 | } | 2439 | } |
2452 | 2440 | ||
2453 | static struct pci_device_id lpfc_id_table[] = { | 2441 | static struct pci_device_id lpfc_id_table[] = { |
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index d513813f6697..d08c4c890744 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c | |||
@@ -451,7 +451,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
451 | spin_unlock_irq(shost->host_lock); | 451 | spin_unlock_irq(shost->host_lock); |
452 | 452 | ||
453 | if ((ndlp->nlp_flag & NLP_ADISC_SND) && | 453 | if ((ndlp->nlp_flag & NLP_ADISC_SND) && |
454 | (vport->num_disc_nodes)) { | 454 | (vport->num_disc_nodes)) { |
455 | /* Check to see if there are more | 455 | /* Check to see if there are more |
456 | * ADISCs to be sent | 456 | * ADISCs to be sent |
457 | */ | 457 | */ |
@@ -469,20 +469,23 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
469 | lpfc_end_rscn(vport); | 469 | lpfc_end_rscn(vport); |
470 | } | 470 | } |
471 | } | 471 | } |
472 | else if (vport->num_disc_nodes) { | 472 | } |
473 | /* Check to see if there are more | 473 | } else if ((ndlp->nlp_state == NLP_STE_PLOGI_ISSUE) && |
474 | * PLOGIs to be sent | 474 | (ndlp->nlp_flag & NLP_NPR_2B_DISC) && |
475 | */ | 475 | (vport->num_disc_nodes)) { |
476 | lpfc_more_plogi(vport); | 476 | spin_lock_irq(shost->host_lock); |
477 | 477 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; | |
478 | if (vport->num_disc_nodes == 0) { | 478 | spin_unlock_irq(shost->host_lock); |
479 | spin_lock_irq(shost->host_lock); | 479 | /* Check to see if there are more |
480 | vport->fc_flag &= ~FC_NDISC_ACTIVE; | 480 | * PLOGIs to be sent |
481 | spin_unlock_irq(shost->host_lock); | 481 | */ |
482 | lpfc_can_disctmo(vport); | 482 | lpfc_more_plogi(vport); |
483 | lpfc_end_rscn(vport); | 483 | if (vport->num_disc_nodes == 0) { |
484 | } | 484 | spin_lock_irq(shost->host_lock); |
485 | } | 485 | vport->fc_flag &= ~FC_NDISC_ACTIVE; |
486 | spin_unlock_irq(shost->host_lock); | ||
487 | lpfc_can_disctmo(vport); | ||
488 | lpfc_end_rscn(vport); | ||
486 | } | 489 | } |
487 | } | 490 | } |
488 | 491 | ||
@@ -869,8 +872,11 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport, | |||
869 | 872 | ||
870 | lp = (uint32_t *) prsp->virt; | 873 | lp = (uint32_t *) prsp->virt; |
871 | sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); | 874 | sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); |
872 | if (wwn_to_u64(sp->portName.u.wwn) == 0 || | 875 | |
873 | wwn_to_u64(sp->nodeName.u.wwn) == 0) { | 876 | /* Some switches have FDMI servers returning 0 for WWN */ |
877 | if ((ndlp->nlp_DID != FDMI_DID) && | ||
878 | (wwn_to_u64(sp->portName.u.wwn) == 0 || | ||
879 | wwn_to_u64(sp->nodeName.u.wwn) == 0)) { | ||
874 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | 880 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, |
875 | "0142 PLOGI RSP: Invalid WWN.\n"); | 881 | "0142 PLOGI RSP: Invalid WWN.\n"); |
876 | goto out; | 882 | goto out; |
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 70255c11d3ad..0910a9ab76a5 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
@@ -169,6 +169,9 @@ lpfc_ramp_up_queue_handler(struct lpfc_hba *phba) | |||
169 | for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) { | 169 | for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) { |
170 | shost = lpfc_shost_from_vport(vports[i]); | 170 | shost = lpfc_shost_from_vport(vports[i]); |
171 | shost_for_each_device(sdev, shost) { | 171 | shost_for_each_device(sdev, shost) { |
172 | if (vports[i]->cfg_lun_queue_depth <= | ||
173 | sdev->queue_depth) | ||
174 | continue; | ||
172 | if (sdev->ordered_tags) | 175 | if (sdev->ordered_tags) |
173 | scsi_adjust_queue_depth(sdev, | 176 | scsi_adjust_queue_depth(sdev, |
174 | MSG_ORDERED_TAG, | 177 | MSG_ORDERED_TAG, |
@@ -578,14 +581,14 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
578 | lpfc_cmd->result == IOERR_NO_RESOURCES || | 581 | lpfc_cmd->result == IOERR_NO_RESOURCES || |
579 | lpfc_cmd->result == RJT_LOGIN_REQUIRED) { | 582 | lpfc_cmd->result == RJT_LOGIN_REQUIRED) { |
580 | cmd->result = ScsiResult(DID_REQUEUE, 0); | 583 | cmd->result = ScsiResult(DID_REQUEUE, 0); |
581 | break; | 584 | break; |
582 | } /* else: fall through */ | 585 | } /* else: fall through */ |
583 | default: | 586 | default: |
584 | cmd->result = ScsiResult(DID_ERROR, 0); | 587 | cmd->result = ScsiResult(DID_ERROR, 0); |
585 | break; | 588 | break; |
586 | } | 589 | } |
587 | 590 | ||
588 | if ((pnode == NULL ) | 591 | if (!pnode || !NLP_CHK_NODE_ACT(pnode) |
589 | || (pnode->nlp_state != NLP_STE_MAPPED_NODE)) | 592 | || (pnode->nlp_state != NLP_STE_MAPPED_NODE)) |
590 | cmd->result = ScsiResult(DID_BUS_BUSY, SAM_STAT_BUSY); | 593 | cmd->result = ScsiResult(DID_BUS_BUSY, SAM_STAT_BUSY); |
591 | } else { | 594 | } else { |
@@ -606,6 +609,9 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
606 | result = cmd->result; | 609 | result = cmd->result; |
607 | sdev = cmd->device; | 610 | sdev = cmd->device; |
608 | lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd); | 611 | lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd); |
612 | spin_lock_irqsave(sdev->host->host_lock, flags); | ||
613 | lpfc_cmd->pCmd = NULL; /* This must be done before scsi_done */ | ||
614 | spin_unlock_irqrestore(sdev->host->host_lock, flags); | ||
609 | cmd->scsi_done(cmd); | 615 | cmd->scsi_done(cmd); |
610 | 616 | ||
611 | if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) { | 617 | if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) { |
@@ -614,7 +620,6 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
614 | * wake up the thread. | 620 | * wake up the thread. |
615 | */ | 621 | */ |
616 | spin_lock_irqsave(sdev->host->host_lock, flags); | 622 | spin_lock_irqsave(sdev->host->host_lock, flags); |
617 | lpfc_cmd->pCmd = NULL; | ||
618 | if (lpfc_cmd->waitq) | 623 | if (lpfc_cmd->waitq) |
619 | wake_up(lpfc_cmd->waitq); | 624 | wake_up(lpfc_cmd->waitq); |
620 | spin_unlock_irqrestore(sdev->host->host_lock, flags); | 625 | spin_unlock_irqrestore(sdev->host->host_lock, flags); |
@@ -626,7 +631,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
626 | if (!result) | 631 | if (!result) |
627 | lpfc_rampup_queue_depth(vport, sdev); | 632 | lpfc_rampup_queue_depth(vport, sdev); |
628 | 633 | ||
629 | if (!result && pnode != NULL && | 634 | if (!result && pnode && NLP_CHK_NODE_ACT(pnode) && |
630 | ((jiffies - pnode->last_ramp_up_time) > | 635 | ((jiffies - pnode->last_ramp_up_time) > |
631 | LPFC_Q_RAMP_UP_INTERVAL * HZ) && | 636 | LPFC_Q_RAMP_UP_INTERVAL * HZ) && |
632 | ((jiffies - pnode->last_q_full_time) > | 637 | ((jiffies - pnode->last_q_full_time) > |
@@ -654,7 +659,8 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
654 | * Check for queue full. If the lun is reporting queue full, then | 659 | * Check for queue full. If the lun is reporting queue full, then |
655 | * back off the lun queue depth to prevent target overloads. | 660 | * back off the lun queue depth to prevent target overloads. |
656 | */ | 661 | */ |
657 | if (result == SAM_STAT_TASK_SET_FULL && pnode != NULL) { | 662 | if (result == SAM_STAT_TASK_SET_FULL && pnode && |
663 | NLP_CHK_NODE_ACT(pnode)) { | ||
658 | pnode->last_q_full_time = jiffies; | 664 | pnode->last_q_full_time = jiffies; |
659 | 665 | ||
660 | shost_for_each_device(tmp_sdev, sdev->host) { | 666 | shost_for_each_device(tmp_sdev, sdev->host) { |
@@ -684,7 +690,6 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
684 | * wake up the thread. | 690 | * wake up the thread. |
685 | */ | 691 | */ |
686 | spin_lock_irqsave(sdev->host->host_lock, flags); | 692 | spin_lock_irqsave(sdev->host->host_lock, flags); |
687 | lpfc_cmd->pCmd = NULL; | ||
688 | if (lpfc_cmd->waitq) | 693 | if (lpfc_cmd->waitq) |
689 | wake_up(lpfc_cmd->waitq); | 694 | wake_up(lpfc_cmd->waitq); |
690 | spin_unlock_irqrestore(sdev->host->host_lock, flags); | 695 | spin_unlock_irqrestore(sdev->host->host_lock, flags); |
@@ -704,6 +709,9 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, | |||
704 | int datadir = scsi_cmnd->sc_data_direction; | 709 | int datadir = scsi_cmnd->sc_data_direction; |
705 | char tag[2]; | 710 | char tag[2]; |
706 | 711 | ||
712 | if (!pnode || !NLP_CHK_NODE_ACT(pnode)) | ||
713 | return; | ||
714 | |||
707 | lpfc_cmd->fcp_rsp->rspSnsLen = 0; | 715 | lpfc_cmd->fcp_rsp->rspSnsLen = 0; |
708 | /* clear task management bits */ | 716 | /* clear task management bits */ |
709 | lpfc_cmd->fcp_cmnd->fcpCntl2 = 0; | 717 | lpfc_cmd->fcp_cmnd->fcpCntl2 = 0; |
@@ -785,9 +793,9 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_vport *vport, | |||
785 | struct lpfc_rport_data *rdata = lpfc_cmd->rdata; | 793 | struct lpfc_rport_data *rdata = lpfc_cmd->rdata; |
786 | struct lpfc_nodelist *ndlp = rdata->pnode; | 794 | struct lpfc_nodelist *ndlp = rdata->pnode; |
787 | 795 | ||
788 | if ((ndlp == NULL) || (ndlp->nlp_state != NLP_STE_MAPPED_NODE)) { | 796 | if (!ndlp || !NLP_CHK_NODE_ACT(ndlp) || |
797 | ndlp->nlp_state != NLP_STE_MAPPED_NODE) | ||
789 | return 0; | 798 | return 0; |
790 | } | ||
791 | 799 | ||
792 | piocbq = &(lpfc_cmd->cur_iocbq); | 800 | piocbq = &(lpfc_cmd->cur_iocbq); |
793 | piocbq->vport = vport; | 801 | piocbq->vport = vport; |
@@ -842,7 +850,7 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf *lpfc_cmd, struct lpfc_vport *vport, | |||
842 | struct lpfc_iocbq *iocbqrsp; | 850 | struct lpfc_iocbq *iocbqrsp; |
843 | int ret; | 851 | int ret; |
844 | 852 | ||
845 | if (!rdata->pnode) | 853 | if (!rdata->pnode || !NLP_CHK_NODE_ACT(rdata->pnode)) |
846 | return FAILED; | 854 | return FAILED; |
847 | 855 | ||
848 | lpfc_cmd->rdata = rdata; | 856 | lpfc_cmd->rdata = rdata; |
@@ -959,7 +967,7 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *)) | |||
959 | * Catch race where our node has transitioned, but the | 967 | * Catch race where our node has transitioned, but the |
960 | * transport is still transitioning. | 968 | * transport is still transitioning. |
961 | */ | 969 | */ |
962 | if (!ndlp) { | 970 | if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) { |
963 | cmnd->result = ScsiResult(DID_BUS_BUSY, 0); | 971 | cmnd->result = ScsiResult(DID_BUS_BUSY, 0); |
964 | goto out_fail_command; | 972 | goto out_fail_command; |
965 | } | 973 | } |
@@ -1146,7 +1154,7 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd) | |||
1146 | * target is rediscovered or devloss timeout expires. | 1154 | * target is rediscovered or devloss timeout expires. |
1147 | */ | 1155 | */ |
1148 | while (1) { | 1156 | while (1) { |
1149 | if (!pnode) | 1157 | if (!pnode || !NLP_CHK_NODE_ACT(pnode)) |
1150 | goto out; | 1158 | goto out; |
1151 | 1159 | ||
1152 | if (pnode->nlp_state != NLP_STE_MAPPED_NODE) { | 1160 | if (pnode->nlp_state != NLP_STE_MAPPED_NODE) { |
@@ -1162,7 +1170,7 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd) | |||
1162 | goto out; | 1170 | goto out; |
1163 | } | 1171 | } |
1164 | pnode = rdata->pnode; | 1172 | pnode = rdata->pnode; |
1165 | if (!pnode) | 1173 | if (!pnode || !NLP_CHK_NODE_ACT(pnode)) |
1166 | goto out; | 1174 | goto out; |
1167 | } | 1175 | } |
1168 | if (pnode->nlp_state == NLP_STE_MAPPED_NODE) | 1176 | if (pnode->nlp_state == NLP_STE_MAPPED_NODE) |
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index fc0d9501aba6..70a0a9eab211 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -2648,7 +2648,6 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba) | |||
2648 | spin_unlock_irq(&phba->pport->work_port_lock); | 2648 | spin_unlock_irq(&phba->pport->work_port_lock); |
2649 | spin_lock_irq(&phba->hbalock); | 2649 | spin_lock_irq(&phba->hbalock); |
2650 | phba->link_state = LPFC_LINK_UNKNOWN; | 2650 | phba->link_state = LPFC_LINK_UNKNOWN; |
2651 | phba->pport->fc_flag |= FC_ESTABLISH_LINK; | ||
2652 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; | 2651 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; |
2653 | spin_unlock_irq(&phba->hbalock); | 2652 | spin_unlock_irq(&phba->hbalock); |
2654 | 2653 | ||
@@ -2669,8 +2668,7 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba) | |||
2669 | lpfc_offline_prep(phba); | 2668 | lpfc_offline_prep(phba); |
2670 | lpfc_offline(phba); | 2669 | lpfc_offline(phba); |
2671 | lpfc_sli_brdrestart(phba); | 2670 | lpfc_sli_brdrestart(phba); |
2672 | if (lpfc_online(phba) == 0) /* Initialize the HBA */ | 2671 | lpfc_online(phba); |
2673 | mod_timer(&phba->fc_estabtmo, jiffies + HZ * 60); | ||
2674 | lpfc_unblock_mgmt_io(phba); | 2672 | lpfc_unblock_mgmt_io(phba); |
2675 | return; | 2673 | return; |
2676 | } | 2674 | } |
@@ -2687,28 +2685,41 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) | |||
2687 | unsigned long drvr_flag = 0; | 2685 | unsigned long drvr_flag = 0; |
2688 | volatile uint32_t word0, ldata; | 2686 | volatile uint32_t word0, ldata; |
2689 | void __iomem *to_slim; | 2687 | void __iomem *to_slim; |
2688 | int processing_queue = 0; | ||
2689 | |||
2690 | spin_lock_irqsave(&phba->hbalock, drvr_flag); | ||
2691 | if (!pmbox) { | ||
2692 | /* processing mbox queue from intr_handler */ | ||
2693 | processing_queue = 1; | ||
2694 | phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; | ||
2695 | pmbox = lpfc_mbox_get(phba); | ||
2696 | if (!pmbox) { | ||
2697 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); | ||
2698 | return MBX_SUCCESS; | ||
2699 | } | ||
2700 | } | ||
2690 | 2701 | ||
2691 | if (pmbox->mbox_cmpl && pmbox->mbox_cmpl != lpfc_sli_def_mbox_cmpl && | 2702 | if (pmbox->mbox_cmpl && pmbox->mbox_cmpl != lpfc_sli_def_mbox_cmpl && |
2692 | pmbox->mbox_cmpl != lpfc_sli_wake_mbox_wait) { | 2703 | pmbox->mbox_cmpl != lpfc_sli_wake_mbox_wait) { |
2693 | if(!pmbox->vport) { | 2704 | if(!pmbox->vport) { |
2705 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); | ||
2694 | lpfc_printf_log(phba, KERN_ERR, | 2706 | lpfc_printf_log(phba, KERN_ERR, |
2695 | LOG_MBOX | LOG_VPORT, | 2707 | LOG_MBOX | LOG_VPORT, |
2696 | "1806 Mbox x%x failed. No vport\n", | 2708 | "1806 Mbox x%x failed. No vport\n", |
2697 | pmbox->mb.mbxCommand); | 2709 | pmbox->mb.mbxCommand); |
2698 | dump_stack(); | 2710 | dump_stack(); |
2699 | return MBX_NOT_FINISHED; | 2711 | goto out_not_finished; |
2700 | } | 2712 | } |
2701 | } | 2713 | } |
2702 | 2714 | ||
2703 | |||
2704 | /* If the PCI channel is in offline state, do not post mbox. */ | 2715 | /* If the PCI channel is in offline state, do not post mbox. */ |
2705 | if (unlikely(pci_channel_offline(phba->pcidev))) | 2716 | if (unlikely(pci_channel_offline(phba->pcidev))) { |
2706 | return MBX_NOT_FINISHED; | 2717 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); |
2718 | goto out_not_finished; | ||
2719 | } | ||
2707 | 2720 | ||
2708 | spin_lock_irqsave(&phba->hbalock, drvr_flag); | ||
2709 | psli = &phba->sli; | 2721 | psli = &phba->sli; |
2710 | 2722 | ||
2711 | |||
2712 | mb = &pmbox->mb; | 2723 | mb = &pmbox->mb; |
2713 | status = MBX_SUCCESS; | 2724 | status = MBX_SUCCESS; |
2714 | 2725 | ||
@@ -2717,14 +2728,14 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) | |||
2717 | 2728 | ||
2718 | /* Mbox command <mbxCommand> cannot issue */ | 2729 | /* Mbox command <mbxCommand> cannot issue */ |
2719 | LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag); | 2730 | LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag); |
2720 | return MBX_NOT_FINISHED; | 2731 | goto out_not_finished; |
2721 | } | 2732 | } |
2722 | 2733 | ||
2723 | if (mb->mbxCommand != MBX_KILL_BOARD && flag & MBX_NOWAIT && | 2734 | if (mb->mbxCommand != MBX_KILL_BOARD && flag & MBX_NOWAIT && |
2724 | !(readl(phba->HCregaddr) & HC_MBINT_ENA)) { | 2735 | !(readl(phba->HCregaddr) & HC_MBINT_ENA)) { |
2725 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); | 2736 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); |
2726 | LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag); | 2737 | LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag); |
2727 | return MBX_NOT_FINISHED; | 2738 | goto out_not_finished; |
2728 | } | 2739 | } |
2729 | 2740 | ||
2730 | if (psli->sli_flag & LPFC_SLI_MBOX_ACTIVE) { | 2741 | if (psli->sli_flag & LPFC_SLI_MBOX_ACTIVE) { |
@@ -2738,14 +2749,14 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) | |||
2738 | 2749 | ||
2739 | /* Mbox command <mbxCommand> cannot issue */ | 2750 | /* Mbox command <mbxCommand> cannot issue */ |
2740 | LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag); | 2751 | LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag); |
2741 | return MBX_NOT_FINISHED; | 2752 | goto out_not_finished; |
2742 | } | 2753 | } |
2743 | 2754 | ||
2744 | if (!(psli->sli_flag & LPFC_SLI2_ACTIVE)) { | 2755 | if (!(psli->sli_flag & LPFC_SLI2_ACTIVE)) { |
2745 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); | 2756 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); |
2746 | /* Mbox command <mbxCommand> cannot issue */ | 2757 | /* Mbox command <mbxCommand> cannot issue */ |
2747 | LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag); | 2758 | LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag); |
2748 | return MBX_NOT_FINISHED; | 2759 | goto out_not_finished; |
2749 | } | 2760 | } |
2750 | 2761 | ||
2751 | /* Another mailbox command is still being processed, queue this | 2762 | /* Another mailbox command is still being processed, queue this |
@@ -2792,7 +2803,7 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) | |||
2792 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); | 2803 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); |
2793 | /* Mbox command <mbxCommand> cannot issue */ | 2804 | /* Mbox command <mbxCommand> cannot issue */ |
2794 | LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag); | 2805 | LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag); |
2795 | return MBX_NOT_FINISHED; | 2806 | goto out_not_finished; |
2796 | } | 2807 | } |
2797 | /* timeout active mbox command */ | 2808 | /* timeout active mbox command */ |
2798 | mod_timer(&psli->mbox_tmo, (jiffies + | 2809 | mod_timer(&psli->mbox_tmo, (jiffies + |
@@ -2900,7 +2911,7 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) | |||
2900 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; | 2911 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; |
2901 | spin_unlock_irqrestore(&phba->hbalock, | 2912 | spin_unlock_irqrestore(&phba->hbalock, |
2902 | drvr_flag); | 2913 | drvr_flag); |
2903 | return MBX_NOT_FINISHED; | 2914 | goto out_not_finished; |
2904 | } | 2915 | } |
2905 | 2916 | ||
2906 | /* Check if we took a mbox interrupt while we were | 2917 | /* Check if we took a mbox interrupt while we were |
@@ -2967,6 +2978,13 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) | |||
2967 | 2978 | ||
2968 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); | 2979 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); |
2969 | return status; | 2980 | return status; |
2981 | |||
2982 | out_not_finished: | ||
2983 | if (processing_queue) { | ||
2984 | pmbox->mb.mbxStatus = MBX_NOT_FINISHED; | ||
2985 | lpfc_mbox_cmpl_put(phba, pmbox); | ||
2986 | } | ||
2987 | return MBX_NOT_FINISHED; | ||
2970 | } | 2988 | } |
2971 | 2989 | ||
2972 | /* | 2990 | /* |
@@ -3463,26 +3481,21 @@ lpfc_sli_hba_down(struct lpfc_hba *phba) | |||
3463 | phba->pport->work_port_events &= ~WORKER_MBOX_TMO; | 3481 | phba->pport->work_port_events &= ~WORKER_MBOX_TMO; |
3464 | spin_unlock(&phba->pport->work_port_lock); | 3482 | spin_unlock(&phba->pport->work_port_lock); |
3465 | 3483 | ||
3484 | /* Return any pending or completed mbox cmds */ | ||
3485 | list_splice_init(&phba->sli.mboxq, &completions); | ||
3466 | if (psli->mbox_active) { | 3486 | if (psli->mbox_active) { |
3467 | list_add_tail(&psli->mbox_active->list, &completions); | 3487 | list_add_tail(&psli->mbox_active->list, &completions); |
3468 | psli->mbox_active = NULL; | 3488 | psli->mbox_active = NULL; |
3469 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; | 3489 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; |
3470 | } | 3490 | } |
3471 | |||
3472 | /* Return any pending or completed mbox cmds */ | ||
3473 | list_splice_init(&phba->sli.mboxq, &completions); | ||
3474 | list_splice_init(&phba->sli.mboxq_cmpl, &completions); | 3491 | list_splice_init(&phba->sli.mboxq_cmpl, &completions); |
3475 | INIT_LIST_HEAD(&psli->mboxq); | ||
3476 | INIT_LIST_HEAD(&psli->mboxq_cmpl); | ||
3477 | |||
3478 | spin_unlock_irqrestore(&phba->hbalock, flags); | 3492 | spin_unlock_irqrestore(&phba->hbalock, flags); |
3479 | 3493 | ||
3480 | while (!list_empty(&completions)) { | 3494 | while (!list_empty(&completions)) { |
3481 | list_remove_head(&completions, pmb, LPFC_MBOXQ_t, list); | 3495 | list_remove_head(&completions, pmb, LPFC_MBOXQ_t, list); |
3482 | pmb->mb.mbxStatus = MBX_NOT_FINISHED; | 3496 | pmb->mb.mbxStatus = MBX_NOT_FINISHED; |
3483 | if (pmb->mbox_cmpl) { | 3497 | if (pmb->mbox_cmpl) |
3484 | pmb->mbox_cmpl(phba,pmb); | 3498 | pmb->mbox_cmpl(phba,pmb); |
3485 | } | ||
3486 | } | 3499 | } |
3487 | return 1; | 3500 | return 1; |
3488 | } | 3501 | } |
@@ -3613,6 +3626,15 @@ lpfc_sli_abort_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
3613 | irsp->ulpStatus, irsp->un.ulpWord[4]); | 3626 | irsp->ulpStatus, irsp->un.ulpWord[4]); |
3614 | 3627 | ||
3615 | /* | 3628 | /* |
3629 | * If the iocb is not found in Firmware queue the iocb | ||
3630 | * might have completed already. Do not free it again. | ||
3631 | */ | ||
3632 | if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT) { | ||
3633 | spin_unlock_irq(&phba->hbalock); | ||
3634 | lpfc_sli_release_iocbq(phba, cmdiocb); | ||
3635 | return; | ||
3636 | } | ||
3637 | /* | ||
3616 | * make sure we have the right iocbq before taking it | 3638 | * make sure we have the right iocbq before taking it |
3617 | * off the txcmplq and try to call completion routine. | 3639 | * off the txcmplq and try to call completion routine. |
3618 | */ | 3640 | */ |
@@ -4174,6 +4196,7 @@ lpfc_intr_handler(int irq, void *dev_id) | |||
4174 | phba->pport->stopped = 1; | 4196 | phba->pport->stopped = 1; |
4175 | } | 4197 | } |
4176 | 4198 | ||
4199 | spin_lock(&phba->hbalock); | ||
4177 | if ((work_ha_copy & HA_MBATT) && | 4200 | if ((work_ha_copy & HA_MBATT) && |
4178 | (phba->sli.mbox_active)) { | 4201 | (phba->sli.mbox_active)) { |
4179 | pmb = phba->sli.mbox_active; | 4202 | pmb = phba->sli.mbox_active; |
@@ -4184,6 +4207,7 @@ lpfc_intr_handler(int irq, void *dev_id) | |||
4184 | /* First check out the status word */ | 4207 | /* First check out the status word */ |
4185 | lpfc_sli_pcimem_bcopy(mbox, pmbox, sizeof(uint32_t)); | 4208 | lpfc_sli_pcimem_bcopy(mbox, pmbox, sizeof(uint32_t)); |
4186 | if (pmbox->mbxOwner != OWN_HOST) { | 4209 | if (pmbox->mbxOwner != OWN_HOST) { |
4210 | spin_unlock(&phba->hbalock); | ||
4187 | /* | 4211 | /* |
4188 | * Stray Mailbox Interrupt, mbxCommand <cmd> | 4212 | * Stray Mailbox Interrupt, mbxCommand <cmd> |
4189 | * mbxStatus <status> | 4213 | * mbxStatus <status> |
@@ -4199,10 +4223,10 @@ lpfc_intr_handler(int irq, void *dev_id) | |||
4199 | /* clear mailbox attention bit */ | 4223 | /* clear mailbox attention bit */ |
4200 | work_ha_copy &= ~HA_MBATT; | 4224 | work_ha_copy &= ~HA_MBATT; |
4201 | } else { | 4225 | } else { |
4226 | phba->sli.mbox_active = NULL; | ||
4227 | spin_unlock(&phba->hbalock); | ||
4202 | phba->last_completion_time = jiffies; | 4228 | phba->last_completion_time = jiffies; |
4203 | del_timer(&phba->sli.mbox_tmo); | 4229 | del_timer(&phba->sli.mbox_tmo); |
4204 | |||
4205 | phba->sli.mbox_active = NULL; | ||
4206 | if (pmb->mbox_cmpl) { | 4230 | if (pmb->mbox_cmpl) { |
4207 | lpfc_sli_pcimem_bcopy(mbox, pmbox, | 4231 | lpfc_sli_pcimem_bcopy(mbox, pmbox, |
4208 | MAILBOX_CMD_SIZE); | 4232 | MAILBOX_CMD_SIZE); |
@@ -4237,10 +4261,15 @@ lpfc_intr_handler(int irq, void *dev_id) | |||
4237 | pmb->context1 = mp; | 4261 | pmb->context1 = mp; |
4238 | pmb->context2 = ndlp; | 4262 | pmb->context2 = ndlp; |
4239 | pmb->vport = vport; | 4263 | pmb->vport = vport; |
4240 | spin_lock(&phba->hbalock); | 4264 | rc = lpfc_sli_issue_mbox(phba, |
4241 | phba->sli.sli_flag &= | 4265 | pmb, |
4242 | ~LPFC_SLI_MBOX_ACTIVE; | 4266 | MBX_NOWAIT); |
4243 | spin_unlock(&phba->hbalock); | 4267 | if (rc != MBX_BUSY) |
4268 | lpfc_printf_log(phba, | ||
4269 | KERN_ERR, | ||
4270 | LOG_MBOX | LOG_SLI, | ||
4271 | "0306 rc should have" | ||
4272 | "been MBX_BUSY"); | ||
4244 | goto send_current_mbox; | 4273 | goto send_current_mbox; |
4245 | } | 4274 | } |
4246 | } | 4275 | } |
@@ -4250,25 +4279,20 @@ lpfc_intr_handler(int irq, void *dev_id) | |||
4250 | spin_unlock(&phba->pport->work_port_lock); | 4279 | spin_unlock(&phba->pport->work_port_lock); |
4251 | lpfc_mbox_cmpl_put(phba, pmb); | 4280 | lpfc_mbox_cmpl_put(phba, pmb); |
4252 | } | 4281 | } |
4253 | } | 4282 | } else |
4283 | spin_unlock(&phba->hbalock); | ||
4254 | if ((work_ha_copy & HA_MBATT) && | 4284 | if ((work_ha_copy & HA_MBATT) && |
4255 | (phba->sli.mbox_active == NULL)) { | 4285 | (phba->sli.mbox_active == NULL)) { |
4256 | send_next_mbox: | ||
4257 | spin_lock(&phba->hbalock); | ||
4258 | phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; | ||
4259 | pmb = lpfc_mbox_get(phba); | ||
4260 | spin_unlock(&phba->hbalock); | ||
4261 | send_current_mbox: | 4286 | send_current_mbox: |
4262 | /* Process next mailbox command if there is one */ | 4287 | /* Process next mailbox command if there is one */ |
4263 | if (pmb != NULL) { | 4288 | do { |
4264 | rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); | 4289 | rc = lpfc_sli_issue_mbox(phba, NULL, |
4265 | if (rc == MBX_NOT_FINISHED) { | 4290 | MBX_NOWAIT); |
4266 | pmb->mb.mbxStatus = MBX_NOT_FINISHED; | 4291 | } while (rc == MBX_NOT_FINISHED); |
4267 | lpfc_mbox_cmpl_put(phba, pmb); | 4292 | if (rc != MBX_SUCCESS) |
4268 | goto send_next_mbox; | 4293 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | |
4269 | } | 4294 | LOG_SLI, "0349 rc should be " |
4270 | } | 4295 | "MBX_SUCCESS"); |
4271 | |||
4272 | } | 4296 | } |
4273 | 4297 | ||
4274 | spin_lock(&phba->hbalock); | 4298 | spin_lock(&phba->hbalock); |
diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index ca540d1d041e..b22b893019f4 100644 --- a/drivers/scsi/lpfc/lpfc_version.h +++ b/drivers/scsi/lpfc/lpfc_version.h | |||
@@ -18,7 +18,7 @@ | |||
18 | * included with this package. * | 18 | * included with this package. * |
19 | *******************************************************************/ | 19 | *******************************************************************/ |
20 | 20 | ||
21 | #define LPFC_DRIVER_VERSION "8.2.5" | 21 | #define LPFC_DRIVER_VERSION "8.2.6" |
22 | 22 | ||
23 | #define LPFC_DRIVER_NAME "lpfc" | 23 | #define LPFC_DRIVER_NAME "lpfc" |
24 | 24 | ||
diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c index 86d05beb00b8..6feaf59b0b1b 100644 --- a/drivers/scsi/lpfc/lpfc_vport.c +++ b/drivers/scsi/lpfc/lpfc_vport.c | |||
@@ -538,7 +538,8 @@ lpfc_vport_delete(struct fc_vport *fc_vport) | |||
538 | /* Otherwise, we will perform fabric logo as needed */ | 538 | /* Otherwise, we will perform fabric logo as needed */ |
539 | if (ndlp && NLP_CHK_NODE_ACT(ndlp) && | 539 | if (ndlp && NLP_CHK_NODE_ACT(ndlp) && |
540 | ndlp->nlp_state == NLP_STE_UNMAPPED_NODE && | 540 | ndlp->nlp_state == NLP_STE_UNMAPPED_NODE && |
541 | phba->link_state >= LPFC_LINK_UP) { | 541 | phba->link_state >= LPFC_LINK_UP && |
542 | phba->fc_topology != TOPOLOGY_LOOP) { | ||
542 | if (vport->cfg_enable_da_id) { | 543 | if (vport->cfg_enable_da_id) { |
543 | timeout = msecs_to_jiffies(phba->fc_ratov * 2000); | 544 | timeout = msecs_to_jiffies(phba->fc_ratov * 2000); |
544 | if (!lpfc_ns_cmd(vport, SLI_CTNS_DA_ID, 0, 0)) | 545 | if (!lpfc_ns_cmd(vport, SLI_CTNS_DA_ID, 0, 0)) |
diff --git a/drivers/scsi/mac_scsi.c b/drivers/scsi/mac_scsi.c index 3b09ab21d701..0248919bc2df 100644 --- a/drivers/scsi/mac_scsi.c +++ b/drivers/scsi/mac_scsi.c | |||
@@ -592,7 +592,6 @@ static struct scsi_host_template driver_template = { | |||
592 | .this_id = 7, | 592 | .this_id = 7, |
593 | .sg_tablesize = SG_ALL, | 593 | .sg_tablesize = SG_ALL, |
594 | .cmd_per_lun = CMD_PER_LUN, | 594 | .cmd_per_lun = CMD_PER_LUN, |
595 | .unchecked_isa_dma = 0, | ||
596 | .use_clustering = DISABLE_CLUSTERING | 595 | .use_clustering = DISABLE_CLUSTERING |
597 | }; | 596 | }; |
598 | 597 | ||
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c index 77a62a1b12c3..b937e9cddb23 100644 --- a/drivers/scsi/megaraid/megaraid_sas.c +++ b/drivers/scsi/megaraid/megaraid_sas.c | |||
@@ -68,6 +68,8 @@ static struct pci_device_id megasas_pci_table[] = { | |||
68 | /* xscale IOP */ | 68 | /* xscale IOP */ |
69 | {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078R)}, | 69 | {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078R)}, |
70 | /* ppc IOP */ | 70 | /* ppc IOP */ |
71 | {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078DE)}, | ||
72 | /* ppc IOP */ | ||
71 | {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_VERDE_ZCR)}, | 73 | {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_VERDE_ZCR)}, |
72 | /* xscale IOP, vega */ | 74 | /* xscale IOP, vega */ |
73 | {PCI_DEVICE(PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_PERC5)}, | 75 | {PCI_DEVICE(PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_PERC5)}, |
@@ -488,12 +490,13 @@ megasas_make_sgl64(struct megasas_instance *instance, struct scsi_cmnd *scp, | |||
488 | 490 | ||
489 | /** | 491 | /** |
490 | * megasas_get_frame_count - Computes the number of frames | 492 | * megasas_get_frame_count - Computes the number of frames |
493 | * @frame_type : type of frame- io or pthru frame | ||
491 | * @sge_count : number of sg elements | 494 | * @sge_count : number of sg elements |
492 | * | 495 | * |
493 | * Returns the number of frames required for numnber of sge's (sge_count) | 496 | * Returns the number of frames required for numnber of sge's (sge_count) |
494 | */ | 497 | */ |
495 | 498 | ||
496 | static u32 megasas_get_frame_count(u8 sge_count) | 499 | static u32 megasas_get_frame_count(u8 sge_count, u8 frame_type) |
497 | { | 500 | { |
498 | int num_cnt; | 501 | int num_cnt; |
499 | int sge_bytes; | 502 | int sge_bytes; |
@@ -504,13 +507,22 @@ static u32 megasas_get_frame_count(u8 sge_count) | |||
504 | sizeof(struct megasas_sge32); | 507 | sizeof(struct megasas_sge32); |
505 | 508 | ||
506 | /* | 509 | /* |
507 | * Main frame can contain 2 SGEs for 64-bit SGLs and | 510 | * Main frame can contain 2 SGEs for 64-bit SGLs and |
508 | * 3 SGEs for 32-bit SGLs | 511 | * 3 SGEs for 32-bit SGLs for ldio & |
509 | */ | 512 | * 1 SGEs for 64-bit SGLs and |
510 | if (IS_DMA64) | 513 | * 2 SGEs for 32-bit SGLs for pthru frame |
511 | num_cnt = sge_count - 2; | 514 | */ |
512 | else | 515 | if (unlikely(frame_type == PTHRU_FRAME)) { |
513 | num_cnt = sge_count - 3; | 516 | if (IS_DMA64) |
517 | num_cnt = sge_count - 1; | ||
518 | else | ||
519 | num_cnt = sge_count - 2; | ||
520 | } else { | ||
521 | if (IS_DMA64) | ||
522 | num_cnt = sge_count - 2; | ||
523 | else | ||
524 | num_cnt = sge_count - 3; | ||
525 | } | ||
514 | 526 | ||
515 | if(num_cnt>0){ | 527 | if(num_cnt>0){ |
516 | sge_bytes = sge_sz * num_cnt; | 528 | sge_bytes = sge_sz * num_cnt; |
@@ -592,7 +604,8 @@ megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp, | |||
592 | * Compute the total number of frames this command consumes. FW uses | 604 | * Compute the total number of frames this command consumes. FW uses |
593 | * this number to pull sufficient number of frames from host memory. | 605 | * this number to pull sufficient number of frames from host memory. |
594 | */ | 606 | */ |
595 | cmd->frame_count = megasas_get_frame_count(pthru->sge_count); | 607 | cmd->frame_count = megasas_get_frame_count(pthru->sge_count, |
608 | PTHRU_FRAME); | ||
596 | 609 | ||
597 | return cmd->frame_count; | 610 | return cmd->frame_count; |
598 | } | 611 | } |
@@ -709,7 +722,7 @@ megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp, | |||
709 | * Compute the total number of frames this command consumes. FW uses | 722 | * Compute the total number of frames this command consumes. FW uses |
710 | * this number to pull sufficient number of frames from host memory. | 723 | * this number to pull sufficient number of frames from host memory. |
711 | */ | 724 | */ |
712 | cmd->frame_count = megasas_get_frame_count(ldio->sge_count); | 725 | cmd->frame_count = megasas_get_frame_count(ldio->sge_count, IO_FRAME); |
713 | 726 | ||
714 | return cmd->frame_count; | 727 | return cmd->frame_count; |
715 | } | 728 | } |
@@ -1460,7 +1473,7 @@ megasas_transition_to_ready(struct megasas_instance* instance) | |||
1460 | instance->instancet->disable_intr(instance->reg_set); | 1473 | instance->instancet->disable_intr(instance->reg_set); |
1461 | writel(MFI_RESET_FLAGS, &instance->reg_set->inbound_doorbell); | 1474 | writel(MFI_RESET_FLAGS, &instance->reg_set->inbound_doorbell); |
1462 | 1475 | ||
1463 | max_wait = 10; | 1476 | max_wait = 60; |
1464 | cur_state = MFI_STATE_OPERATIONAL; | 1477 | cur_state = MFI_STATE_OPERATIONAL; |
1465 | break; | 1478 | break; |
1466 | 1479 | ||
@@ -1980,7 +1993,8 @@ static int megasas_init_mfi(struct megasas_instance *instance) | |||
1980 | 1993 | ||
1981 | switch(instance->pdev->device) | 1994 | switch(instance->pdev->device) |
1982 | { | 1995 | { |
1983 | case PCI_DEVICE_ID_LSI_SAS1078R: | 1996 | case PCI_DEVICE_ID_LSI_SAS1078R: |
1997 | case PCI_DEVICE_ID_LSI_SAS1078DE: | ||
1984 | instance->instancet = &megasas_instance_template_ppc; | 1998 | instance->instancet = &megasas_instance_template_ppc; |
1985 | break; | 1999 | break; |
1986 | case PCI_DEVICE_ID_LSI_SAS1064R: | 2000 | case PCI_DEVICE_ID_LSI_SAS1064R: |
@@ -2909,7 +2923,6 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance, | |||
2909 | void *sense = NULL; | 2923 | void *sense = NULL; |
2910 | dma_addr_t sense_handle; | 2924 | dma_addr_t sense_handle; |
2911 | u32 *sense_ptr; | 2925 | u32 *sense_ptr; |
2912 | unsigned long *sense_buff; | ||
2913 | 2926 | ||
2914 | memset(kbuff_arr, 0, sizeof(kbuff_arr)); | 2927 | memset(kbuff_arr, 0, sizeof(kbuff_arr)); |
2915 | 2928 | ||
@@ -3014,14 +3027,14 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance, | |||
3014 | */ | 3027 | */ |
3015 | if (ioc->sense_len) { | 3028 | if (ioc->sense_len) { |
3016 | /* | 3029 | /* |
3017 | * sense_buff points to the location that has the user | 3030 | * sense_ptr points to the location that has the user |
3018 | * sense buffer address | 3031 | * sense buffer address |
3019 | */ | 3032 | */ |
3020 | sense_buff = (unsigned long *) ((unsigned long)ioc->frame.raw + | 3033 | sense_ptr = (u32 *) ((unsigned long)ioc->frame.raw + |
3021 | ioc->sense_off); | 3034 | ioc->sense_off); |
3022 | 3035 | ||
3023 | if (copy_to_user((void __user *)(unsigned long)(*sense_buff), | 3036 | if (copy_to_user((void __user *)((unsigned long)(*sense_ptr)), |
3024 | sense, ioc->sense_len)) { | 3037 | sense, ioc->sense_len)) { |
3025 | printk(KERN_ERR "megasas: Failed to copy out to user " | 3038 | printk(KERN_ERR "megasas: Failed to copy out to user " |
3026 | "sense data\n"); | 3039 | "sense data\n"); |
3027 | error = -EFAULT; | 3040 | error = -EFAULT; |
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 6466bdf548c2..3a997eb457bf 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h | |||
@@ -26,6 +26,7 @@ | |||
26 | * Device IDs | 26 | * Device IDs |
27 | */ | 27 | */ |
28 | #define PCI_DEVICE_ID_LSI_SAS1078R 0x0060 | 28 | #define PCI_DEVICE_ID_LSI_SAS1078R 0x0060 |
29 | #define PCI_DEVICE_ID_LSI_SAS1078DE 0x007C | ||
29 | #define PCI_DEVICE_ID_LSI_VERDE_ZCR 0x0413 | 30 | #define PCI_DEVICE_ID_LSI_VERDE_ZCR 0x0413 |
30 | 31 | ||
31 | /* | 32 | /* |
@@ -542,6 +543,10 @@ struct megasas_ctrl_info { | |||
542 | 543 | ||
543 | #define MEGASAS_FW_BUSY 1 | 544 | #define MEGASAS_FW_BUSY 1 |
544 | 545 | ||
546 | /* Frame Type */ | ||
547 | #define IO_FRAME 0 | ||
548 | #define PTHRU_FRAME 1 | ||
549 | |||
545 | /* | 550 | /* |
546 | * When SCSI mid-layer calls driver's reset routine, driver waits for | 551 | * When SCSI mid-layer calls driver's reset routine, driver waits for |
547 | * MEGASAS_RESET_WAIT_TIME seconds for all outstanding IO to complete. Note | 552 | * MEGASAS_RESET_WAIT_TIME seconds for all outstanding IO to complete. Note |
diff --git a/drivers/scsi/mvme147.c b/drivers/scsi/mvme147.c index be41aadccae5..d722235111a8 100644 --- a/drivers/scsi/mvme147.c +++ b/drivers/scsi/mvme147.c | |||
@@ -82,6 +82,9 @@ int mvme147_detect(struct scsi_host_template *tpnt) | |||
82 | mvme147_host->irq = MVME147_IRQ_SCSI_PORT; | 82 | mvme147_host->irq = MVME147_IRQ_SCSI_PORT; |
83 | regs.SASR = (volatile unsigned char *)0xfffe4000; | 83 | regs.SASR = (volatile unsigned char *)0xfffe4000; |
84 | regs.SCMD = (volatile unsigned char *)0xfffe4001; | 84 | regs.SCMD = (volatile unsigned char *)0xfffe4001; |
85 | HDATA(mvme147_host)->no_sync = 0xff; | ||
86 | HDATA(mvme147_host)->fast = 0; | ||
87 | HDATA(mvme147_host)->dma_mode = CTRL_DMA; | ||
85 | wd33c93_init(mvme147_host, regs, dma_setup, dma_stop, WD33C93_FS_8_10); | 88 | wd33c93_init(mvme147_host, regs, dma_setup, dma_stop, WD33C93_FS_8_10); |
86 | 89 | ||
87 | if (request_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr, 0, "MVME147 SCSI PORT", mvme147_intr)) | 90 | if (request_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr, 0, "MVME147 SCSI PORT", mvme147_intr)) |
diff --git a/drivers/scsi/ps3rom.c b/drivers/scsi/ps3rom.c index fad6cb5cba28..ce48e2d0193c 100644 --- a/drivers/scsi/ps3rom.c +++ b/drivers/scsi/ps3rom.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <scsi/scsi_dbg.h> | 26 | #include <scsi/scsi_dbg.h> |
27 | #include <scsi/scsi_device.h> | 27 | #include <scsi/scsi_device.h> |
28 | #include <scsi/scsi_host.h> | 28 | #include <scsi/scsi_host.h> |
29 | #include <scsi/scsi_eh.h> | ||
29 | 30 | ||
30 | #include <asm/lv1call.h> | 31 | #include <asm/lv1call.h> |
31 | #include <asm/ps3stor.h> | 32 | #include <asm/ps3stor.h> |
@@ -90,78 +91,6 @@ static int ps3rom_slave_configure(struct scsi_device *scsi_dev) | |||
90 | return 0; | 91 | return 0; |
91 | } | 92 | } |
92 | 93 | ||
93 | /* | ||
94 | * copy data from device into scatter/gather buffer | ||
95 | */ | ||
96 | static int fill_from_dev_buffer(struct scsi_cmnd *cmd, const void *buf) | ||
97 | { | ||
98 | int k, req_len, act_len, len, active; | ||
99 | void *kaddr; | ||
100 | struct scatterlist *sgpnt; | ||
101 | unsigned int buflen; | ||
102 | |||
103 | buflen = scsi_bufflen(cmd); | ||
104 | if (!buflen) | ||
105 | return 0; | ||
106 | |||
107 | if (!scsi_sglist(cmd)) | ||
108 | return -1; | ||
109 | |||
110 | active = 1; | ||
111 | req_len = act_len = 0; | ||
112 | scsi_for_each_sg(cmd, sgpnt, scsi_sg_count(cmd), k) { | ||
113 | if (active) { | ||
114 | kaddr = kmap_atomic(sg_page(sgpnt), KM_IRQ0); | ||
115 | len = sgpnt->length; | ||
116 | if ((req_len + len) > buflen) { | ||
117 | active = 0; | ||
118 | len = buflen - req_len; | ||
119 | } | ||
120 | memcpy(kaddr + sgpnt->offset, buf + req_len, len); | ||
121 | flush_kernel_dcache_page(sg_page(sgpnt)); | ||
122 | kunmap_atomic(kaddr, KM_IRQ0); | ||
123 | act_len += len; | ||
124 | } | ||
125 | req_len += sgpnt->length; | ||
126 | } | ||
127 | scsi_set_resid(cmd, buflen - act_len); | ||
128 | return 0; | ||
129 | } | ||
130 | |||
131 | /* | ||
132 | * copy data from scatter/gather into device's buffer | ||
133 | */ | ||
134 | static int fetch_to_dev_buffer(struct scsi_cmnd *cmd, void *buf) | ||
135 | { | ||
136 | int k, req_len, len, fin; | ||
137 | void *kaddr; | ||
138 | struct scatterlist *sgpnt; | ||
139 | unsigned int buflen; | ||
140 | |||
141 | buflen = scsi_bufflen(cmd); | ||
142 | if (!buflen) | ||
143 | return 0; | ||
144 | |||
145 | if (!scsi_sglist(cmd)) | ||
146 | return -1; | ||
147 | |||
148 | req_len = fin = 0; | ||
149 | scsi_for_each_sg(cmd, sgpnt, scsi_sg_count(cmd), k) { | ||
150 | kaddr = kmap_atomic(sg_page(sgpnt), KM_IRQ0); | ||
151 | len = sgpnt->length; | ||
152 | if ((req_len + len) > buflen) { | ||
153 | len = buflen - req_len; | ||
154 | fin = 1; | ||
155 | } | ||
156 | memcpy(buf + req_len, kaddr + sgpnt->offset, len); | ||
157 | kunmap_atomic(kaddr, KM_IRQ0); | ||
158 | if (fin) | ||
159 | return req_len + len; | ||
160 | req_len += sgpnt->length; | ||
161 | } | ||
162 | return req_len; | ||
163 | } | ||
164 | |||
165 | static int ps3rom_atapi_request(struct ps3_storage_device *dev, | 94 | static int ps3rom_atapi_request(struct ps3_storage_device *dev, |
166 | struct scsi_cmnd *cmd) | 95 | struct scsi_cmnd *cmd) |
167 | { | 96 | { |
@@ -195,9 +124,7 @@ static int ps3rom_atapi_request(struct ps3_storage_device *dev, | |||
195 | else | 124 | else |
196 | atapi_cmnd.proto = PIO_DATA_OUT_PROTO; | 125 | atapi_cmnd.proto = PIO_DATA_OUT_PROTO; |
197 | atapi_cmnd.in_out = DIR_WRITE; | 126 | atapi_cmnd.in_out = DIR_WRITE; |
198 | res = fetch_to_dev_buffer(cmd, dev->bounce_buf); | 127 | scsi_sg_copy_to_buffer(cmd, dev->bounce_buf, dev->bounce_size); |
199 | if (res < 0) | ||
200 | return DID_ERROR << 16; | ||
201 | break; | 128 | break; |
202 | 129 | ||
203 | default: | 130 | default: |
@@ -269,9 +196,7 @@ static int ps3rom_write_request(struct ps3_storage_device *dev, | |||
269 | dev_dbg(&dev->sbd.core, "%s:%u: write %u sectors starting at %u\n", | 196 | dev_dbg(&dev->sbd.core, "%s:%u: write %u sectors starting at %u\n", |
270 | __func__, __LINE__, sectors, start_sector); | 197 | __func__, __LINE__, sectors, start_sector); |
271 | 198 | ||
272 | res = fetch_to_dev_buffer(cmd, dev->bounce_buf); | 199 | scsi_sg_copy_to_buffer(cmd, dev->bounce_buf, dev->bounce_size); |
273 | if (res < 0) | ||
274 | return DID_ERROR << 16; | ||
275 | 200 | ||
276 | res = lv1_storage_write(dev->sbd.dev_id, | 201 | res = lv1_storage_write(dev->sbd.dev_id, |
277 | dev->regions[dev->region_idx].id, start_sector, | 202 | dev->regions[dev->region_idx].id, start_sector, |
@@ -381,11 +306,13 @@ static irqreturn_t ps3rom_interrupt(int irq, void *data) | |||
381 | if (!status) { | 306 | if (!status) { |
382 | /* OK, completed */ | 307 | /* OK, completed */ |
383 | if (cmd->sc_data_direction == DMA_FROM_DEVICE) { | 308 | if (cmd->sc_data_direction == DMA_FROM_DEVICE) { |
384 | res = fill_from_dev_buffer(cmd, dev->bounce_buf); | 309 | int len; |
385 | if (res) { | 310 | |
386 | cmd->result = DID_ERROR << 16; | 311 | len = scsi_sg_copy_from_buffer(cmd, |
387 | goto done; | 312 | dev->bounce_buf, |
388 | } | 313 | dev->bounce_size); |
314 | |||
315 | scsi_set_resid(cmd, scsi_bufflen(cmd) - len); | ||
389 | } | 316 | } |
390 | cmd->result = DID_OK << 16; | 317 | cmd->result = DID_OK << 16; |
391 | goto done; | 318 | goto done; |
@@ -404,11 +331,7 @@ static irqreturn_t ps3rom_interrupt(int irq, void *data) | |||
404 | goto done; | 331 | goto done; |
405 | } | 332 | } |
406 | 333 | ||
407 | cmd->sense_buffer[0] = 0x70; | 334 | scsi_build_sense_buffer(0, cmd->sense_buffer, sense_key, asc, ascq); |
408 | cmd->sense_buffer[2] = sense_key; | ||
409 | cmd->sense_buffer[7] = 16 - 6; | ||
410 | cmd->sense_buffer[12] = asc; | ||
411 | cmd->sense_buffer[13] = ascq; | ||
412 | cmd->result = SAM_STAT_CHECK_CONDITION; | 335 | cmd->result = SAM_STAT_CHECK_CONDITION; |
413 | 336 | ||
414 | done: | 337 | done: |
@@ -427,7 +350,7 @@ static struct scsi_host_template ps3rom_host_template = { | |||
427 | .cmd_per_lun = 1, | 350 | .cmd_per_lun = 1, |
428 | .emulated = 1, /* only sg driver uses this */ | 351 | .emulated = 1, /* only sg driver uses this */ |
429 | .max_sectors = PS3ROM_MAX_SECTORS, | 352 | .max_sectors = PS3ROM_MAX_SECTORS, |
430 | .use_clustering = DISABLE_CLUSTERING, | 353 | .use_clustering = ENABLE_CLUSTERING, |
431 | .module = THIS_MODULE, | 354 | .module = THIS_MODULE, |
432 | }; | 355 | }; |
433 | 356 | ||
diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c index 68c0d09ffe78..09ab3eac1c1a 100644 --- a/drivers/scsi/qla1280.c +++ b/drivers/scsi/qla1280.c | |||
@@ -333,7 +333,6 @@ | |||
333 | 333 | ||
334 | #include <linux/module.h> | 334 | #include <linux/module.h> |
335 | 335 | ||
336 | #include <linux/version.h> | ||
337 | #include <linux/types.h> | 336 | #include <linux/types.h> |
338 | #include <linux/string.h> | 337 | #include <linux/string.h> |
339 | #include <linux/errno.h> | 338 | #include <linux/errno.h> |
@@ -367,10 +366,6 @@ | |||
367 | #include <asm/sn/io.h> | 366 | #include <asm/sn/io.h> |
368 | #endif | 367 | #endif |
369 | 368 | ||
370 | #if LINUX_VERSION_CODE < 0x020600 | ||
371 | #error "Kernels older than 2.6.0 are no longer supported" | ||
372 | #endif | ||
373 | |||
374 | 369 | ||
375 | /* | 370 | /* |
376 | * Compile time Options: | 371 | * Compile time Options: |
diff --git a/drivers/scsi/qla2xxx/Kconfig b/drivers/scsi/qla2xxx/Kconfig index 8c865b9e02b5..6208d562890d 100644 --- a/drivers/scsi/qla2xxx/Kconfig +++ b/drivers/scsi/qla2xxx/Kconfig | |||
@@ -16,7 +16,8 @@ config SCSI_QLA_FC | |||
16 | 22xx ql2200_fw.bin | 16 | 22xx ql2200_fw.bin |
17 | 2300, 2312, 6312 ql2300_fw.bin | 17 | 2300, 2312, 6312 ql2300_fw.bin |
18 | 2322, 6322 ql2322_fw.bin | 18 | 2322, 6322 ql2322_fw.bin |
19 | 24xx ql2400_fw.bin | 19 | 24xx, 54xx ql2400_fw.bin |
20 | 25xx ql2500_fw.bin | ||
20 | 21 | ||
21 | Upon request, the driver caches the firmware image until | 22 | Upon request, the driver caches the firmware image until |
22 | the driver is unloaded. | 23 | the driver is unloaded. |
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 4894dc886b62..413d8cd6a324 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -849,20 +849,20 @@ static void | |||
849 | qla2x00_get_host_speed(struct Scsi_Host *shost) | 849 | qla2x00_get_host_speed(struct Scsi_Host *shost) |
850 | { | 850 | { |
851 | scsi_qla_host_t *ha = to_qla_parent(shost_priv(shost)); | 851 | scsi_qla_host_t *ha = to_qla_parent(shost_priv(shost)); |
852 | uint32_t speed = 0; | 852 | u32 speed = FC_PORTSPEED_UNKNOWN; |
853 | 853 | ||
854 | switch (ha->link_data_rate) { | 854 | switch (ha->link_data_rate) { |
855 | case PORT_SPEED_1GB: | 855 | case PORT_SPEED_1GB: |
856 | speed = 1; | 856 | speed = FC_PORTSPEED_1GBIT; |
857 | break; | 857 | break; |
858 | case PORT_SPEED_2GB: | 858 | case PORT_SPEED_2GB: |
859 | speed = 2; | 859 | speed = FC_PORTSPEED_2GBIT; |
860 | break; | 860 | break; |
861 | case PORT_SPEED_4GB: | 861 | case PORT_SPEED_4GB: |
862 | speed = 4; | 862 | speed = FC_PORTSPEED_4GBIT; |
863 | break; | 863 | break; |
864 | case PORT_SPEED_8GB: | 864 | case PORT_SPEED_8GB: |
865 | speed = 8; | 865 | speed = FC_PORTSPEED_8GBIT; |
866 | break; | 866 | break; |
867 | } | 867 | } |
868 | fc_host_speed(shost) = speed; | 868 | fc_host_speed(shost) = speed; |
@@ -900,7 +900,8 @@ qla2x00_get_starget_node_name(struct scsi_target *starget) | |||
900 | u64 node_name = 0; | 900 | u64 node_name = 0; |
901 | 901 | ||
902 | list_for_each_entry(fcport, &ha->fcports, list) { | 902 | list_for_each_entry(fcport, &ha->fcports, list) { |
903 | if (starget->id == fcport->os_target_id) { | 903 | if (fcport->rport && |
904 | starget->id == fcport->rport->scsi_target_id) { | ||
904 | node_name = wwn_to_u64(fcport->node_name); | 905 | node_name = wwn_to_u64(fcport->node_name); |
905 | break; | 906 | break; |
906 | } | 907 | } |
@@ -918,7 +919,8 @@ qla2x00_get_starget_port_name(struct scsi_target *starget) | |||
918 | u64 port_name = 0; | 919 | u64 port_name = 0; |
919 | 920 | ||
920 | list_for_each_entry(fcport, &ha->fcports, list) { | 921 | list_for_each_entry(fcport, &ha->fcports, list) { |
921 | if (starget->id == fcport->os_target_id) { | 922 | if (fcport->rport && |
923 | starget->id == fcport->rport->scsi_target_id) { | ||
922 | port_name = wwn_to_u64(fcport->port_name); | 924 | port_name = wwn_to_u64(fcport->port_name); |
923 | break; | 925 | break; |
924 | } | 926 | } |
@@ -936,7 +938,8 @@ qla2x00_get_starget_port_id(struct scsi_target *starget) | |||
936 | uint32_t port_id = ~0U; | 938 | uint32_t port_id = ~0U; |
937 | 939 | ||
938 | list_for_each_entry(fcport, &ha->fcports, list) { | 940 | list_for_each_entry(fcport, &ha->fcports, list) { |
939 | if (starget->id == fcport->os_target_id) { | 941 | if (fcport->rport && |
942 | starget->id == fcport->rport->scsi_target_id) { | ||
940 | port_id = fcport->d_id.b.domain << 16 | | 943 | port_id = fcport->d_id.b.domain << 16 | |
941 | fcport->d_id.b.area << 8 | fcport->d_id.b.al_pa; | 944 | fcport->d_id.b.area << 8 | fcport->d_id.b.al_pa; |
942 | break; | 945 | break; |
@@ -1196,6 +1199,7 @@ struct fc_function_template qla2xxx_transport_functions = { | |||
1196 | .show_host_node_name = 1, | 1199 | .show_host_node_name = 1, |
1197 | .show_host_port_name = 1, | 1200 | .show_host_port_name = 1, |
1198 | .show_host_supported_classes = 1, | 1201 | .show_host_supported_classes = 1, |
1202 | .show_host_supported_speeds = 1, | ||
1199 | 1203 | ||
1200 | .get_host_port_id = qla2x00_get_host_port_id, | 1204 | .get_host_port_id = qla2x00_get_host_port_id, |
1201 | .show_host_port_id = 1, | 1205 | .show_host_port_id = 1, |
@@ -1276,9 +1280,23 @@ struct fc_function_template qla2xxx_transport_vport_functions = { | |||
1276 | void | 1280 | void |
1277 | qla2x00_init_host_attr(scsi_qla_host_t *ha) | 1281 | qla2x00_init_host_attr(scsi_qla_host_t *ha) |
1278 | { | 1282 | { |
1283 | u32 speed = FC_PORTSPEED_UNKNOWN; | ||
1284 | |||
1279 | fc_host_node_name(ha->host) = wwn_to_u64(ha->node_name); | 1285 | fc_host_node_name(ha->host) = wwn_to_u64(ha->node_name); |
1280 | fc_host_port_name(ha->host) = wwn_to_u64(ha->port_name); | 1286 | fc_host_port_name(ha->host) = wwn_to_u64(ha->port_name); |
1281 | fc_host_supported_classes(ha->host) = FC_COS_CLASS3; | 1287 | fc_host_supported_classes(ha->host) = FC_COS_CLASS3; |
1282 | fc_host_max_npiv_vports(ha->host) = ha->max_npiv_vports;; | 1288 | fc_host_max_npiv_vports(ha->host) = ha->max_npiv_vports;; |
1283 | fc_host_npiv_vports_inuse(ha->host) = ha->cur_vport_count; | 1289 | fc_host_npiv_vports_inuse(ha->host) = ha->cur_vport_count; |
1290 | |||
1291 | if (IS_QLA25XX(ha)) | ||
1292 | speed = FC_PORTSPEED_8GBIT | FC_PORTSPEED_4GBIT | | ||
1293 | FC_PORTSPEED_2GBIT | FC_PORTSPEED_1GBIT; | ||
1294 | else if (IS_QLA24XX_TYPE(ha)) | ||
1295 | speed = FC_PORTSPEED_4GBIT | FC_PORTSPEED_2GBIT | | ||
1296 | FC_PORTSPEED_1GBIT; | ||
1297 | else if (IS_QLA23XX(ha)) | ||
1298 | speed = FC_PORTSPEED_2GBIT | FC_PORTSPEED_1GBIT; | ||
1299 | else | ||
1300 | speed = FC_PORTSPEED_1GBIT; | ||
1301 | fc_host_supported_speeds(ha->host) = speed; | ||
1284 | } | 1302 | } |
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index d88e98c476b0..9d12d9f26209 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -1410,125 +1410,3 @@ qla2x00_dump_buffer(uint8_t * b, uint32_t size) | |||
1410 | if (cnt % 16) | 1410 | if (cnt % 16) |
1411 | printk("\n"); | 1411 | printk("\n"); |
1412 | } | 1412 | } |
1413 | |||
1414 | /************************************************************************** | ||
1415 | * qla2x00_print_scsi_cmd | ||
1416 | * Dumps out info about the scsi cmd and srb. | ||
1417 | * Input | ||
1418 | * cmd : struct scsi_cmnd | ||
1419 | **************************************************************************/ | ||
1420 | void | ||
1421 | qla2x00_print_scsi_cmd(struct scsi_cmnd * cmd) | ||
1422 | { | ||
1423 | int i; | ||
1424 | struct scsi_qla_host *ha; | ||
1425 | srb_t *sp; | ||
1426 | |||
1427 | ha = shost_priv(cmd->device->host); | ||
1428 | |||
1429 | sp = (srb_t *) cmd->SCp.ptr; | ||
1430 | printk("SCSI Command @=0x%p, Handle=0x%p\n", cmd, cmd->host_scribble); | ||
1431 | printk(" chan=0x%02x, target=0x%02x, lun=0x%02x, cmd_len=0x%02x\n", | ||
1432 | cmd->device->channel, cmd->device->id, cmd->device->lun, | ||
1433 | cmd->cmd_len); | ||
1434 | printk(" CDB: "); | ||
1435 | for (i = 0; i < cmd->cmd_len; i++) { | ||
1436 | printk("0x%02x ", cmd->cmnd[i]); | ||
1437 | } | ||
1438 | printk("\n seg_cnt=%d, allowed=%d, retries=%d\n", | ||
1439 | scsi_sg_count(cmd), cmd->allowed, cmd->retries); | ||
1440 | printk(" request buffer=0x%p, request buffer len=0x%x\n", | ||
1441 | scsi_sglist(cmd), scsi_bufflen(cmd)); | ||
1442 | printk(" tag=%d, transfersize=0x%x\n", | ||
1443 | cmd->tag, cmd->transfersize); | ||
1444 | printk(" serial_number=%lx, SP=%p\n", cmd->serial_number, sp); | ||
1445 | printk(" data direction=%d\n", cmd->sc_data_direction); | ||
1446 | |||
1447 | if (!sp) | ||
1448 | return; | ||
1449 | |||
1450 | printk(" sp flags=0x%x\n", sp->flags); | ||
1451 | } | ||
1452 | |||
1453 | #if defined(QL_DEBUG_ROUTINES) | ||
1454 | /* | ||
1455 | * qla2x00_formatted_dump_buffer | ||
1456 | * Prints string plus buffer. | ||
1457 | * | ||
1458 | * Input: | ||
1459 | * string = Null terminated string (no newline at end). | ||
1460 | * buffer = buffer address. | ||
1461 | * wd_size = word size 8, 16, 32 or 64 bits | ||
1462 | * count = number of words. | ||
1463 | */ | ||
1464 | void | ||
1465 | qla2x00_formatted_dump_buffer(char *string, uint8_t * buffer, | ||
1466 | uint8_t wd_size, uint32_t count) | ||
1467 | { | ||
1468 | uint32_t cnt; | ||
1469 | uint16_t *buf16; | ||
1470 | uint32_t *buf32; | ||
1471 | |||
1472 | if (strcmp(string, "") != 0) | ||
1473 | printk("%s\n",string); | ||
1474 | |||
1475 | switch (wd_size) { | ||
1476 | case 8: | ||
1477 | printk(" 0 1 2 3 4 5 6 7 " | ||
1478 | "8 9 Ah Bh Ch Dh Eh Fh\n"); | ||
1479 | printk("-----------------------------------------" | ||
1480 | "-------------------------------------\n"); | ||
1481 | |||
1482 | for (cnt = 1; cnt <= count; cnt++, buffer++) { | ||
1483 | printk("%02x",*buffer); | ||
1484 | if (cnt % 16 == 0) | ||
1485 | printk("\n"); | ||
1486 | else | ||
1487 | printk(" "); | ||
1488 | } | ||
1489 | if (cnt % 16 != 0) | ||
1490 | printk("\n"); | ||
1491 | break; | ||
1492 | case 16: | ||
1493 | printk(" 0 2 4 6 8 Ah " | ||
1494 | " Ch Eh\n"); | ||
1495 | printk("-----------------------------------------" | ||
1496 | "-------------\n"); | ||
1497 | |||
1498 | buf16 = (uint16_t *) buffer; | ||
1499 | for (cnt = 1; cnt <= count; cnt++, buf16++) { | ||
1500 | printk("%4x",*buf16); | ||
1501 | |||
1502 | if (cnt % 8 == 0) | ||
1503 | printk("\n"); | ||
1504 | else if (*buf16 < 10) | ||
1505 | printk(" "); | ||
1506 | else | ||
1507 | printk(" "); | ||
1508 | } | ||
1509 | if (cnt % 8 != 0) | ||
1510 | printk("\n"); | ||
1511 | break; | ||
1512 | case 32: | ||
1513 | printk(" 0 4 8 Ch\n"); | ||
1514 | printk("------------------------------------------\n"); | ||
1515 | |||
1516 | buf32 = (uint32_t *) buffer; | ||
1517 | for (cnt = 1; cnt <= count; cnt++, buf32++) { | ||
1518 | printk("%8x", *buf32); | ||
1519 | |||
1520 | if (cnt % 4 == 0) | ||
1521 | printk("\n"); | ||
1522 | else if (*buf32 < 10) | ||
1523 | printk(" "); | ||
1524 | else | ||
1525 | printk(" "); | ||
1526 | } | ||
1527 | if (cnt % 4 != 0) | ||
1528 | printk("\n"); | ||
1529 | break; | ||
1530 | default: | ||
1531 | break; | ||
1532 | } | ||
1533 | } | ||
1534 | #endif | ||
diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h index 524598afc81c..2e9c0c097f5e 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.h +++ b/drivers/scsi/qla2xxx/qla_dbg.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -22,19 +22,7 @@ | |||
22 | /* #define QL_DEBUG_LEVEL_13 */ /* Output fdmi function trace msgs */ | 22 | /* #define QL_DEBUG_LEVEL_13 */ /* Output fdmi function trace msgs */ |
23 | /* #define QL_DEBUG_LEVEL_14 */ /* Output RSCN trace msgs */ | 23 | /* #define QL_DEBUG_LEVEL_14 */ /* Output RSCN trace msgs */ |
24 | /* #define QL_DEBUG_LEVEL_15 */ /* Output NPIV trace msgs */ | 24 | /* #define QL_DEBUG_LEVEL_15 */ /* Output NPIV trace msgs */ |
25 | /* | 25 | /* #define QL_DEBUG_LEVEL_16 */ /* Output ISP84XX trace msgs */ |
26 | * Local Macro Definitions. | ||
27 | */ | ||
28 | #if defined(QL_DEBUG_LEVEL_1) || defined(QL_DEBUG_LEVEL_2) || \ | ||
29 | defined(QL_DEBUG_LEVEL_3) || defined(QL_DEBUG_LEVEL_4) || \ | ||
30 | defined(QL_DEBUG_LEVEL_5) || defined(QL_DEBUG_LEVEL_6) || \ | ||
31 | defined(QL_DEBUG_LEVEL_7) || defined(QL_DEBUG_LEVEL_8) || \ | ||
32 | defined(QL_DEBUG_LEVEL_9) || defined(QL_DEBUG_LEVEL_10) || \ | ||
33 | defined(QL_DEBUG_LEVEL_11) || defined(QL_DEBUG_LEVEL_12) || \ | ||
34 | defined(QL_DEBUG_LEVEL_13) || defined(QL_DEBUG_LEVEL_14) || \ | ||
35 | defined(QL_DEBUG_LEVEL_15) | ||
36 | #define QL_DEBUG_ROUTINES | ||
37 | #endif | ||
38 | 26 | ||
39 | /* | 27 | /* |
40 | * Macros use for debugging the driver. | 28 | * Macros use for debugging the driver. |
@@ -54,6 +42,7 @@ | |||
54 | #define DEBUG2_9_10(x) do { if (ql2xextended_error_logging) { x; } } while (0) | 42 | #define DEBUG2_9_10(x) do { if (ql2xextended_error_logging) { x; } } while (0) |
55 | #define DEBUG2_11(x) do { if (ql2xextended_error_logging) { x; } } while (0) | 43 | #define DEBUG2_11(x) do { if (ql2xextended_error_logging) { x; } } while (0) |
56 | #define DEBUG2_13(x) do { if (ql2xextended_error_logging) { x; } } while (0) | 44 | #define DEBUG2_13(x) do { if (ql2xextended_error_logging) { x; } } while (0) |
45 | #define DEBUG2_16(x) do { if (ql2xextended_error_logging) { x; } } while (0) | ||
57 | 46 | ||
58 | #if defined(QL_DEBUG_LEVEL_3) | 47 | #if defined(QL_DEBUG_LEVEL_3) |
59 | #define DEBUG3(x) do {x;} while (0) | 48 | #define DEBUG3(x) do {x;} while (0) |
@@ -133,6 +122,12 @@ | |||
133 | #define DEBUG15(x) do {} while (0) | 122 | #define DEBUG15(x) do {} while (0) |
134 | #endif | 123 | #endif |
135 | 124 | ||
125 | #if defined(QL_DEBUG_LEVEL_16) | ||
126 | #define DEBUG16(x) do {x;} while (0) | ||
127 | #else | ||
128 | #define DEBUG16(x) do {} while (0) | ||
129 | #endif | ||
130 | |||
136 | /* | 131 | /* |
137 | * Firmware Dump structure definition | 132 | * Firmware Dump structure definition |
138 | */ | 133 | */ |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 3750319f4968..094d95f0764c 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/workqueue.h> | 24 | #include <linux/workqueue.h> |
25 | #include <linux/firmware.h> | 25 | #include <linux/firmware.h> |
26 | #include <linux/aer.h> | 26 | #include <linux/aer.h> |
27 | #include <linux/mutex.h> | ||
27 | #include <asm/semaphore.h> | 28 | #include <asm/semaphore.h> |
28 | 29 | ||
29 | #include <scsi/scsi.h> | 30 | #include <scsi/scsi.h> |
@@ -192,9 +193,6 @@ typedef struct srb { | |||
192 | 193 | ||
193 | uint16_t flags; | 194 | uint16_t flags; |
194 | 195 | ||
195 | /* Single transfer DMA context */ | ||
196 | dma_addr_t dma_handle; | ||
197 | |||
198 | uint32_t request_sense_length; | 196 | uint32_t request_sense_length; |
199 | uint8_t *request_sense_ptr; | 197 | uint8_t *request_sense_ptr; |
200 | } srb_t; | 198 | } srb_t; |
@@ -1542,8 +1540,6 @@ typedef struct fc_port { | |||
1542 | atomic_t state; | 1540 | atomic_t state; |
1543 | uint32_t flags; | 1541 | uint32_t flags; |
1544 | 1542 | ||
1545 | unsigned int os_target_id; | ||
1546 | |||
1547 | int port_login_retry_count; | 1543 | int port_login_retry_count; |
1548 | int login_retry; | 1544 | int login_retry; |
1549 | atomic_t port_down_timer; | 1545 | atomic_t port_down_timer; |
@@ -1613,6 +1609,7 @@ typedef struct fc_port { | |||
1613 | #define CT_ACCEPT_RESPONSE 0x8002 | 1609 | #define CT_ACCEPT_RESPONSE 0x8002 |
1614 | #define CT_REASON_INVALID_COMMAND_CODE 0x01 | 1610 | #define CT_REASON_INVALID_COMMAND_CODE 0x01 |
1615 | #define CT_REASON_CANNOT_PERFORM 0x09 | 1611 | #define CT_REASON_CANNOT_PERFORM 0x09 |
1612 | #define CT_REASON_COMMAND_UNSUPPORTED 0x0b | ||
1616 | #define CT_EXPL_ALREADY_REGISTERED 0x10 | 1613 | #define CT_EXPL_ALREADY_REGISTERED 0x10 |
1617 | 1614 | ||
1618 | #define NS_N_PORT_TYPE 0x01 | 1615 | #define NS_N_PORT_TYPE 0x01 |
@@ -2063,7 +2060,8 @@ struct isp_operations { | |||
2063 | void (*disable_intrs) (struct scsi_qla_host *); | 2060 | void (*disable_intrs) (struct scsi_qla_host *); |
2064 | 2061 | ||
2065 | int (*abort_command) (struct scsi_qla_host *, srb_t *); | 2062 | int (*abort_command) (struct scsi_qla_host *, srb_t *); |
2066 | int (*abort_target) (struct fc_port *); | 2063 | int (*target_reset) (struct fc_port *, unsigned int); |
2064 | int (*lun_reset) (struct fc_port *, unsigned int); | ||
2067 | int (*fabric_login) (struct scsi_qla_host *, uint16_t, uint8_t, | 2065 | int (*fabric_login) (struct scsi_qla_host *, uint16_t, uint8_t, |
2068 | uint8_t, uint8_t, uint16_t *, uint8_t); | 2066 | uint8_t, uint8_t, uint16_t *, uint8_t); |
2069 | int (*fabric_logout) (struct scsi_qla_host *, uint16_t, uint8_t, | 2067 | int (*fabric_logout) (struct scsi_qla_host *, uint16_t, uint8_t, |
@@ -2117,6 +2115,46 @@ struct qla_msix_entry { | |||
2117 | 2115 | ||
2118 | #define WATCH_INTERVAL 1 /* number of seconds */ | 2116 | #define WATCH_INTERVAL 1 /* number of seconds */ |
2119 | 2117 | ||
2118 | /* Work events. */ | ||
2119 | enum qla_work_type { | ||
2120 | QLA_EVT_AEN, | ||
2121 | QLA_EVT_HWE_LOG, | ||
2122 | }; | ||
2123 | |||
2124 | |||
2125 | struct qla_work_evt { | ||
2126 | struct list_head list; | ||
2127 | enum qla_work_type type; | ||
2128 | u32 flags; | ||
2129 | #define QLA_EVT_FLAG_FREE 0x1 | ||
2130 | |||
2131 | union { | ||
2132 | struct { | ||
2133 | enum fc_host_event_code code; | ||
2134 | u32 data; | ||
2135 | } aen; | ||
2136 | struct { | ||
2137 | uint16_t code; | ||
2138 | uint16_t d1, d2, d3; | ||
2139 | } hwe; | ||
2140 | } u; | ||
2141 | }; | ||
2142 | |||
2143 | struct qla_chip_state_84xx { | ||
2144 | struct list_head list; | ||
2145 | struct kref kref; | ||
2146 | |||
2147 | void *bus; | ||
2148 | spinlock_t access_lock; | ||
2149 | struct mutex fw_update_mutex; | ||
2150 | uint32_t fw_update; | ||
2151 | uint32_t op_fw_version; | ||
2152 | uint32_t op_fw_size; | ||
2153 | uint32_t op_fw_seq_size; | ||
2154 | uint32_t diag_fw_version; | ||
2155 | uint32_t gold_fw_version; | ||
2156 | }; | ||
2157 | |||
2120 | /* | 2158 | /* |
2121 | * Linux Host Adapter structure | 2159 | * Linux Host Adapter structure |
2122 | */ | 2160 | */ |
@@ -2155,6 +2193,7 @@ typedef struct scsi_qla_host { | |||
2155 | uint32_t vsan_enabled :1; | 2193 | uint32_t vsan_enabled :1; |
2156 | uint32_t npiv_supported :1; | 2194 | uint32_t npiv_supported :1; |
2157 | uint32_t fce_enabled :1; | 2195 | uint32_t fce_enabled :1; |
2196 | uint32_t hw_event_marker_found :1; | ||
2158 | } flags; | 2197 | } flags; |
2159 | 2198 | ||
2160 | atomic_t loop_state; | 2199 | atomic_t loop_state; |
@@ -2204,6 +2243,7 @@ typedef struct scsi_qla_host { | |||
2204 | #define DFLG_NO_CABLE BIT_4 | 2243 | #define DFLG_NO_CABLE BIT_4 |
2205 | 2244 | ||
2206 | #define PCI_DEVICE_ID_QLOGIC_ISP2532 0x2532 | 2245 | #define PCI_DEVICE_ID_QLOGIC_ISP2532 0x2532 |
2246 | #define PCI_DEVICE_ID_QLOGIC_ISP8432 0x8432 | ||
2207 | uint32_t device_type; | 2247 | uint32_t device_type; |
2208 | #define DT_ISP2100 BIT_0 | 2248 | #define DT_ISP2100 BIT_0 |
2209 | #define DT_ISP2200 BIT_1 | 2249 | #define DT_ISP2200 BIT_1 |
@@ -2217,7 +2257,8 @@ typedef struct scsi_qla_host { | |||
2217 | #define DT_ISP5422 BIT_9 | 2257 | #define DT_ISP5422 BIT_9 |
2218 | #define DT_ISP5432 BIT_10 | 2258 | #define DT_ISP5432 BIT_10 |
2219 | #define DT_ISP2532 BIT_11 | 2259 | #define DT_ISP2532 BIT_11 |
2220 | #define DT_ISP_LAST (DT_ISP2532 << 1) | 2260 | #define DT_ISP8432 BIT_12 |
2261 | #define DT_ISP_LAST (DT_ISP8432 << 1) | ||
2221 | 2262 | ||
2222 | #define DT_IIDMA BIT_26 | 2263 | #define DT_IIDMA BIT_26 |
2223 | #define DT_FWI2 BIT_27 | 2264 | #define DT_FWI2 BIT_27 |
@@ -2239,12 +2280,16 @@ typedef struct scsi_qla_host { | |||
2239 | #define IS_QLA5422(ha) (DT_MASK(ha) & DT_ISP5422) | 2280 | #define IS_QLA5422(ha) (DT_MASK(ha) & DT_ISP5422) |
2240 | #define IS_QLA5432(ha) (DT_MASK(ha) & DT_ISP5432) | 2281 | #define IS_QLA5432(ha) (DT_MASK(ha) & DT_ISP5432) |
2241 | #define IS_QLA2532(ha) (DT_MASK(ha) & DT_ISP2532) | 2282 | #define IS_QLA2532(ha) (DT_MASK(ha) & DT_ISP2532) |
2283 | #define IS_QLA8432(ha) (DT_MASK(ha) & DT_ISP8432) | ||
2242 | 2284 | ||
2243 | #define IS_QLA23XX(ha) (IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA2322(ha) || \ | 2285 | #define IS_QLA23XX(ha) (IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA2322(ha) || \ |
2244 | IS_QLA6312(ha) || IS_QLA6322(ha)) | 2286 | IS_QLA6312(ha) || IS_QLA6322(ha)) |
2245 | #define IS_QLA24XX(ha) (IS_QLA2422(ha) || IS_QLA2432(ha)) | 2287 | #define IS_QLA24XX(ha) (IS_QLA2422(ha) || IS_QLA2432(ha)) |
2246 | #define IS_QLA54XX(ha) (IS_QLA5422(ha) || IS_QLA5432(ha)) | 2288 | #define IS_QLA54XX(ha) (IS_QLA5422(ha) || IS_QLA5432(ha)) |
2247 | #define IS_QLA25XX(ha) (IS_QLA2532(ha)) | 2289 | #define IS_QLA25XX(ha) (IS_QLA2532(ha)) |
2290 | #define IS_QLA84XX(ha) (IS_QLA8432(ha)) | ||
2291 | #define IS_QLA24XX_TYPE(ha) (IS_QLA24XX(ha) || IS_QLA54XX(ha) || \ | ||
2292 | IS_QLA84XX(ha)) | ||
2248 | 2293 | ||
2249 | #define IS_IIDMA_CAPABLE(ha) ((ha)->device_type & DT_IIDMA) | 2294 | #define IS_IIDMA_CAPABLE(ha) ((ha)->device_type & DT_IIDMA) |
2250 | #define IS_FWI2_CAPABLE(ha) ((ha)->device_type & DT_FWI2) | 2295 | #define IS_FWI2_CAPABLE(ha) ((ha)->device_type & DT_FWI2) |
@@ -2356,6 +2401,8 @@ typedef struct scsi_qla_host { | |||
2356 | uint32_t login_retry_count; | 2401 | uint32_t login_retry_count; |
2357 | int max_q_depth; | 2402 | int max_q_depth; |
2358 | 2403 | ||
2404 | struct list_head work_list; | ||
2405 | |||
2359 | /* Fibre Channel Device List. */ | 2406 | /* Fibre Channel Device List. */ |
2360 | struct list_head fcports; | 2407 | struct list_head fcports; |
2361 | 2408 | ||
@@ -2423,8 +2470,6 @@ typedef struct scsi_qla_host { | |||
2423 | #define MBX_TIMEDOUT BIT_5 | 2470 | #define MBX_TIMEDOUT BIT_5 |
2424 | #define MBX_ACCESS_TIMEDOUT BIT_6 | 2471 | #define MBX_ACCESS_TIMEDOUT BIT_6 |
2425 | 2472 | ||
2426 | mbx_cmd_t mc; | ||
2427 | |||
2428 | /* Basic firmware related information. */ | 2473 | /* Basic firmware related information. */ |
2429 | uint16_t fw_major_version; | 2474 | uint16_t fw_major_version; |
2430 | uint16_t fw_minor_version; | 2475 | uint16_t fw_minor_version; |
@@ -2458,6 +2503,10 @@ typedef struct scsi_qla_host { | |||
2458 | uint64_t fce_wr, fce_rd; | 2503 | uint64_t fce_wr, fce_rd; |
2459 | struct mutex fce_mutex; | 2504 | struct mutex fce_mutex; |
2460 | 2505 | ||
2506 | uint32_t hw_event_start; | ||
2507 | uint32_t hw_event_ptr; | ||
2508 | uint32_t hw_event_pause_errors; | ||
2509 | |||
2461 | uint8_t host_str[16]; | 2510 | uint8_t host_str[16]; |
2462 | uint32_t pci_attr; | 2511 | uint32_t pci_attr; |
2463 | uint16_t chip_revision; | 2512 | uint16_t chip_revision; |
@@ -2493,6 +2542,13 @@ typedef struct scsi_qla_host { | |||
2493 | uint8_t fcode_revision[16]; | 2542 | uint8_t fcode_revision[16]; |
2494 | uint32_t fw_revision[4]; | 2543 | uint32_t fw_revision[4]; |
2495 | 2544 | ||
2545 | uint16_t fdt_odd_index; | ||
2546 | uint32_t fdt_wrt_disable; | ||
2547 | uint32_t fdt_erase_cmd; | ||
2548 | uint32_t fdt_block_size; | ||
2549 | uint32_t fdt_unprotect_sec_cmd; | ||
2550 | uint32_t fdt_protect_sec_cmd; | ||
2551 | |||
2496 | /* Needed for BEACON */ | 2552 | /* Needed for BEACON */ |
2497 | uint16_t beacon_blink_led; | 2553 | uint16_t beacon_blink_led; |
2498 | uint8_t beacon_color_state; | 2554 | uint8_t beacon_color_state; |
@@ -2538,6 +2594,8 @@ typedef struct scsi_qla_host { | |||
2538 | #define VP_ERR_ADAP_NORESOURCES 5 | 2594 | #define VP_ERR_ADAP_NORESOURCES 5 |
2539 | uint16_t max_npiv_vports; /* 63 or 125 per topoloty */ | 2595 | uint16_t max_npiv_vports; /* 63 or 125 per topoloty */ |
2540 | int cur_vport_count; | 2596 | int cur_vport_count; |
2597 | |||
2598 | struct qla_chip_state_84xx *cs84xx; | ||
2541 | } scsi_qla_host_t; | 2599 | } scsi_qla_host_t; |
2542 | 2600 | ||
2543 | 2601 | ||
diff --git a/drivers/scsi/qla2xxx/qla_dfs.c b/drivers/scsi/qla2xxx/qla_dfs.c index 2cd899bfe84b..561a4411719d 100644 --- a/drivers/scsi/qla2xxx/qla_dfs.c +++ b/drivers/scsi/qla2xxx/qla_dfs.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h index 9337e138ed63..078f2a15f40b 100644 --- a/drivers/scsi/qla2xxx/qla_fw.h +++ b/drivers/scsi/qla2xxx/qla_fw.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -719,7 +719,7 @@ struct tsk_mgmt_entry { | |||
719 | 719 | ||
720 | uint16_t timeout; /* Command timeout. */ | 720 | uint16_t timeout; /* Command timeout. */ |
721 | 721 | ||
722 | uint8_t lun[8]; /* FCP LUN (BE). */ | 722 | struct scsi_lun lun; /* FCP LUN (BE). */ |
723 | 723 | ||
724 | uint32_t control_flags; /* Control Flags. */ | 724 | uint32_t control_flags; /* Control Flags. */ |
725 | #define TCF_NOTMCMD_TO_TARGET BIT_31 | 725 | #define TCF_NOTMCMD_TO_TARGET BIT_31 |
@@ -793,7 +793,19 @@ struct device_reg_24xx { | |||
793 | #define FA_VPD_NVRAM_ADDR 0x48000 | 793 | #define FA_VPD_NVRAM_ADDR 0x48000 |
794 | #define FA_FEATURE_ADDR 0x4C000 | 794 | #define FA_FEATURE_ADDR 0x4C000 |
795 | #define FA_FLASH_DESCR_ADDR 0x50000 | 795 | #define FA_FLASH_DESCR_ADDR 0x50000 |
796 | #define FA_HW_EVENT_ADDR 0x54000 | 796 | #define FA_HW_EVENT0_ADDR 0x54000 |
797 | #define FA_HW_EVENT1_ADDR 0x54200 | ||
798 | #define FA_HW_EVENT_SIZE 0x200 | ||
799 | #define FA_HW_EVENT_ENTRY_SIZE 4 | ||
800 | /* | ||
801 | * Flash Error Log Event Codes. | ||
802 | */ | ||
803 | #define HW_EVENT_RESET_ERR 0xF00B | ||
804 | #define HW_EVENT_ISP_ERR 0xF020 | ||
805 | #define HW_EVENT_PARITY_ERR 0xF022 | ||
806 | #define HW_EVENT_NVRAM_CHKSUM_ERR 0xF023 | ||
807 | #define HW_EVENT_FLASH_FW_ERR 0xF024 | ||
808 | |||
797 | #define FA_BOOT_LOG_ADDR 0x58000 | 809 | #define FA_BOOT_LOG_ADDR 0x58000 |
798 | #define FA_FW_DUMP0_ADDR 0x60000 | 810 | #define FA_FW_DUMP0_ADDR 0x60000 |
799 | #define FA_FW_DUMP1_ADDR 0x70000 | 811 | #define FA_FW_DUMP1_ADDR 0x70000 |
@@ -1174,4 +1186,159 @@ struct vf_evfp_entry_24xx { | |||
1174 | }; | 1186 | }; |
1175 | 1187 | ||
1176 | /* END MID Support ***********************************************************/ | 1188 | /* END MID Support ***********************************************************/ |
1189 | |||
1190 | /* Flash Description Table ***************************************************/ | ||
1191 | |||
1192 | struct qla_fdt_layout { | ||
1193 | uint8_t sig[4]; | ||
1194 | uint16_t version; | ||
1195 | uint16_t len; | ||
1196 | uint16_t checksum; | ||
1197 | uint8_t unused1[2]; | ||
1198 | uint8_t model[16]; | ||
1199 | uint16_t man_id; | ||
1200 | uint16_t id; | ||
1201 | uint8_t flags; | ||
1202 | uint8_t erase_cmd; | ||
1203 | uint8_t alt_erase_cmd; | ||
1204 | uint8_t wrt_enable_cmd; | ||
1205 | uint8_t wrt_enable_bits; | ||
1206 | uint8_t wrt_sts_reg_cmd; | ||
1207 | uint8_t unprotect_sec_cmd; | ||
1208 | uint8_t read_man_id_cmd; | ||
1209 | uint32_t block_size; | ||
1210 | uint32_t alt_block_size; | ||
1211 | uint32_t flash_size; | ||
1212 | uint32_t wrt_enable_data; | ||
1213 | uint8_t read_id_addr_len; | ||
1214 | uint8_t wrt_disable_bits; | ||
1215 | uint8_t read_dev_id_len; | ||
1216 | uint8_t chip_erase_cmd; | ||
1217 | uint16_t read_timeout; | ||
1218 | uint8_t protect_sec_cmd; | ||
1219 | uint8_t unused2[65]; | ||
1220 | }; | ||
1221 | |||
1222 | /* 84XX Support **************************************************************/ | ||
1223 | |||
1224 | #define MBA_ISP84XX_ALERT 0x800f /* Alert Notification. */ | ||
1225 | #define A84_PANIC_RECOVERY 0x1 | ||
1226 | #define A84_OP_LOGIN_COMPLETE 0x2 | ||
1227 | #define A84_DIAG_LOGIN_COMPLETE 0x3 | ||
1228 | #define A84_GOLD_LOGIN_COMPLETE 0x4 | ||
1229 | |||
1230 | #define MBC_ISP84XX_RESET 0x3a /* Reset. */ | ||
1231 | |||
1232 | #define FSTATE_REMOTE_FC_DOWN BIT_0 | ||
1233 | #define FSTATE_NSL_LINK_DOWN BIT_1 | ||
1234 | #define FSTATE_IS_DIAG_FW BIT_2 | ||
1235 | #define FSTATE_LOGGED_IN BIT_3 | ||
1236 | #define FSTATE_WAITING_FOR_VERIFY BIT_4 | ||
1237 | |||
1238 | #define VERIFY_CHIP_IOCB_TYPE 0x1B | ||
1239 | struct verify_chip_entry_84xx { | ||
1240 | uint8_t entry_type; | ||
1241 | uint8_t entry_count; | ||
1242 | uint8_t sys_defined; | ||
1243 | uint8_t entry_status; | ||
1244 | |||
1245 | uint32_t handle; | ||
1246 | |||
1247 | uint16_t options; | ||
1248 | #define VCO_DONT_UPDATE_FW BIT_0 | ||
1249 | #define VCO_FORCE_UPDATE BIT_1 | ||
1250 | #define VCO_DONT_RESET_UPDATE BIT_2 | ||
1251 | #define VCO_DIAG_FW BIT_3 | ||
1252 | #define VCO_END_OF_DATA BIT_14 | ||
1253 | #define VCO_ENABLE_DSD BIT_15 | ||
1254 | |||
1255 | uint16_t reserved_1; | ||
1256 | |||
1257 | uint16_t data_seg_cnt; | ||
1258 | uint16_t reserved_2[3]; | ||
1259 | |||
1260 | uint32_t fw_ver; | ||
1261 | uint32_t exchange_address; | ||
1262 | |||
1263 | uint32_t reserved_3[3]; | ||
1264 | uint32_t fw_size; | ||
1265 | uint32_t fw_seq_size; | ||
1266 | uint32_t relative_offset; | ||
1267 | |||
1268 | uint32_t dseg_address[2]; | ||
1269 | uint32_t dseg_length; | ||
1270 | }; | ||
1271 | |||
1272 | struct verify_chip_rsp_84xx { | ||
1273 | uint8_t entry_type; | ||
1274 | uint8_t entry_count; | ||
1275 | uint8_t sys_defined; | ||
1276 | uint8_t entry_status; | ||
1277 | |||
1278 | uint32_t handle; | ||
1279 | |||
1280 | uint16_t comp_status; | ||
1281 | #define CS_VCS_CHIP_FAILURE 0x3 | ||
1282 | #define CS_VCS_BAD_EXCHANGE 0x8 | ||
1283 | #define CS_VCS_SEQ_COMPLETEi 0x40 | ||
1284 | |||
1285 | uint16_t failure_code; | ||
1286 | #define VFC_CHECKSUM_ERROR 0x1 | ||
1287 | #define VFC_INVALID_LEN 0x2 | ||
1288 | #define VFC_ALREADY_IN_PROGRESS 0x8 | ||
1289 | |||
1290 | uint16_t reserved_1[4]; | ||
1291 | |||
1292 | uint32_t fw_ver; | ||
1293 | uint32_t exchange_address; | ||
1294 | |||
1295 | uint32_t reserved_2[6]; | ||
1296 | }; | ||
1297 | |||
1298 | #define ACCESS_CHIP_IOCB_TYPE 0x2B | ||
1299 | struct access_chip_84xx { | ||
1300 | uint8_t entry_type; | ||
1301 | uint8_t entry_count; | ||
1302 | uint8_t sys_defined; | ||
1303 | uint8_t entry_status; | ||
1304 | |||
1305 | uint32_t handle; | ||
1306 | |||
1307 | uint16_t options; | ||
1308 | #define ACO_DUMP_MEMORY 0x0 | ||
1309 | #define ACO_LOAD_MEMORY 0x1 | ||
1310 | #define ACO_CHANGE_CONFIG_PARAM 0x2 | ||
1311 | #define ACO_REQUEST_INFO 0x3 | ||
1312 | |||
1313 | uint16_t reserved1; | ||
1314 | |||
1315 | uint16_t dseg_count; | ||
1316 | uint16_t reserved2[3]; | ||
1317 | |||
1318 | uint32_t parameter1; | ||
1319 | uint32_t parameter2; | ||
1320 | uint32_t parameter3; | ||
1321 | |||
1322 | uint32_t reserved3[3]; | ||
1323 | uint32_t total_byte_cnt; | ||
1324 | uint32_t reserved4; | ||
1325 | |||
1326 | uint32_t dseg_address[2]; | ||
1327 | uint32_t dseg_length; | ||
1328 | }; | ||
1329 | |||
1330 | struct access_chip_rsp_84xx { | ||
1331 | uint8_t entry_type; | ||
1332 | uint8_t entry_count; | ||
1333 | uint8_t sys_defined; | ||
1334 | uint8_t entry_status; | ||
1335 | |||
1336 | uint32_t handle; | ||
1337 | |||
1338 | uint16_t comp_status; | ||
1339 | uint16_t failure_code; | ||
1340 | uint32_t residual_count; | ||
1341 | |||
1342 | uint32_t reserved[12]; | ||
1343 | }; | ||
1177 | #endif | 1344 | #endif |
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 193f688ec3d7..a9571c214a9e 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -38,9 +38,6 @@ extern int qla2x00_loop_resync(scsi_qla_host_t *); | |||
38 | extern int qla2x00_fabric_login(scsi_qla_host_t *, fc_port_t *, uint16_t *); | 38 | extern int qla2x00_fabric_login(scsi_qla_host_t *, fc_port_t *, uint16_t *); |
39 | extern int qla2x00_local_device_login(scsi_qla_host_t *, fc_port_t *); | 39 | extern int qla2x00_local_device_login(scsi_qla_host_t *, fc_port_t *); |
40 | 40 | ||
41 | extern void qla2x00_restart_queues(scsi_qla_host_t *, uint8_t); | ||
42 | |||
43 | extern void qla2x00_rescan_fcports(scsi_qla_host_t *); | ||
44 | extern void qla2x00_update_fcports(scsi_qla_host_t *); | 41 | extern void qla2x00_update_fcports(scsi_qla_host_t *); |
45 | 42 | ||
46 | extern int qla2x00_abort_isp(scsi_qla_host_t *); | 43 | extern int qla2x00_abort_isp(scsi_qla_host_t *); |
@@ -50,6 +47,8 @@ extern void qla2x00_update_fcport(scsi_qla_host_t *, fc_port_t *); | |||
50 | extern void qla2x00_alloc_fw_dump(scsi_qla_host_t *); | 47 | extern void qla2x00_alloc_fw_dump(scsi_qla_host_t *); |
51 | extern void qla2x00_try_to_stop_firmware(scsi_qla_host_t *); | 48 | extern void qla2x00_try_to_stop_firmware(scsi_qla_host_t *); |
52 | 49 | ||
50 | extern void qla84xx_put_chip(struct scsi_qla_host *); | ||
51 | |||
53 | /* | 52 | /* |
54 | * Global Data in qla_os.c source file. | 53 | * Global Data in qla_os.c source file. |
55 | */ | 54 | */ |
@@ -67,6 +66,10 @@ extern int num_hosts; | |||
67 | 66 | ||
68 | extern int qla2x00_loop_reset(scsi_qla_host_t *); | 67 | extern int qla2x00_loop_reset(scsi_qla_host_t *); |
69 | extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int); | 68 | extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int); |
69 | extern int qla2x00_post_aen_work(struct scsi_qla_host *, enum | ||
70 | fc_host_event_code, u32); | ||
71 | extern int qla2x00_post_hwe_work(struct scsi_qla_host *, uint16_t , uint16_t, | ||
72 | uint16_t, uint16_t); | ||
70 | 73 | ||
71 | /* | 74 | /* |
72 | * Global Functions in qla_mid.c source file. | 75 | * Global Functions in qla_mid.c source file. |
@@ -149,12 +152,17 @@ extern int | |||
149 | qla2x00_issue_iocb(scsi_qla_host_t *, void *, dma_addr_t, size_t); | 152 | qla2x00_issue_iocb(scsi_qla_host_t *, void *, dma_addr_t, size_t); |
150 | 153 | ||
151 | extern int | 154 | extern int |
155 | qla2x00_issue_iocb_timeout(scsi_qla_host_t *, void *, dma_addr_t, size_t, | ||
156 | uint32_t); | ||
157 | |||
158 | extern int | ||
152 | qla2x00_abort_command(scsi_qla_host_t *, srb_t *); | 159 | qla2x00_abort_command(scsi_qla_host_t *, srb_t *); |
153 | 160 | ||
154 | #if USE_ABORT_TGT | ||
155 | extern int | 161 | extern int |
156 | qla2x00_abort_target(fc_port_t *); | 162 | qla2x00_abort_target(struct fc_port *, unsigned int); |
157 | #endif | 163 | |
164 | extern int | ||
165 | qla2x00_lun_reset(struct fc_port *, unsigned int); | ||
158 | 166 | ||
159 | extern int | 167 | extern int |
160 | qla2x00_get_adapter_id(scsi_qla_host_t *, uint16_t *, uint8_t *, uint8_t *, | 168 | qla2x00_get_adapter_id(scsi_qla_host_t *, uint16_t *, uint8_t *, uint8_t *, |
@@ -220,7 +228,8 @@ qla24xx_get_isp_stats(scsi_qla_host_t *, struct link_statistics *, | |||
220 | dma_addr_t); | 228 | dma_addr_t); |
221 | 229 | ||
222 | extern int qla24xx_abort_command(scsi_qla_host_t *, srb_t *); | 230 | extern int qla24xx_abort_command(scsi_qla_host_t *, srb_t *); |
223 | extern int qla24xx_abort_target(fc_port_t *); | 231 | extern int qla24xx_abort_target(struct fc_port *, unsigned int); |
232 | extern int qla24xx_lun_reset(struct fc_port *, unsigned int); | ||
224 | 233 | ||
225 | extern int | 234 | extern int |
226 | qla2x00_set_serdes_params(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t); | 235 | qla2x00_set_serdes_params(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t); |
@@ -246,6 +255,8 @@ qla2x00_read_sfp(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t, uint16_t); | |||
246 | extern int | 255 | extern int |
247 | qla2x00_set_idma_speed(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t *); | 256 | qla2x00_set_idma_speed(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t *); |
248 | 257 | ||
258 | extern int qla84xx_verify_chip(struct scsi_qla_host *, uint16_t *); | ||
259 | |||
249 | /* | 260 | /* |
250 | * Global Function Prototypes in qla_isr.c source file. | 261 | * Global Function Prototypes in qla_isr.c source file. |
251 | */ | 262 | */ |
@@ -298,6 +309,11 @@ extern uint8_t *qla25xx_read_optrom_data(struct scsi_qla_host *, uint8_t *, | |||
298 | extern int qla2x00_get_flash_version(scsi_qla_host_t *, void *); | 309 | extern int qla2x00_get_flash_version(scsi_qla_host_t *, void *); |
299 | extern int qla24xx_get_flash_version(scsi_qla_host_t *, void *); | 310 | extern int qla24xx_get_flash_version(scsi_qla_host_t *, void *); |
300 | 311 | ||
312 | extern int qla2xxx_hw_event_log(scsi_qla_host_t *, uint16_t , uint16_t, | ||
313 | uint16_t, uint16_t); | ||
314 | |||
315 | extern void qla2xxx_get_flash_info(scsi_qla_host_t *); | ||
316 | |||
301 | /* | 317 | /* |
302 | * Global Function Prototypes in qla_dbg.c source file. | 318 | * Global Function Prototypes in qla_dbg.c source file. |
303 | */ | 319 | */ |
@@ -307,7 +323,6 @@ extern void qla24xx_fw_dump(scsi_qla_host_t *, int); | |||
307 | extern void qla25xx_fw_dump(scsi_qla_host_t *, int); | 323 | extern void qla25xx_fw_dump(scsi_qla_host_t *, int); |
308 | extern void qla2x00_dump_regs(scsi_qla_host_t *); | 324 | extern void qla2x00_dump_regs(scsi_qla_host_t *); |
309 | extern void qla2x00_dump_buffer(uint8_t *, uint32_t); | 325 | extern void qla2x00_dump_buffer(uint8_t *, uint32_t); |
310 | extern void qla2x00_print_scsi_cmd(struct scsi_cmnd *); | ||
311 | 326 | ||
312 | /* | 327 | /* |
313 | * Global Function Prototypes in qla_gs.c source file. | 328 | * Global Function Prototypes in qla_gs.c source file. |
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index c1808763d40e..750d7ef83aae 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c | |||
@@ -1,17 +1,11 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
7 | #include "qla_def.h" | 7 | #include "qla_def.h" |
8 | 8 | ||
9 | static inline struct ct_sns_req * | ||
10 | qla2x00_prep_ct_req(struct ct_sns_req *, uint16_t, uint16_t); | ||
11 | |||
12 | static inline struct sns_cmd_pkt * | ||
13 | qla2x00_prep_sns_cmd(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t); | ||
14 | |||
15 | static int qla2x00_sns_ga_nxt(scsi_qla_host_t *, fc_port_t *); | 9 | static int qla2x00_sns_ga_nxt(scsi_qla_host_t *, fc_port_t *); |
16 | static int qla2x00_sns_gid_pt(scsi_qla_host_t *, sw_info_t *); | 10 | static int qla2x00_sns_gid_pt(scsi_qla_host_t *, sw_info_t *); |
17 | static int qla2x00_sns_gpn_id(scsi_qla_host_t *, sw_info_t *); | 11 | static int qla2x00_sns_gpn_id(scsi_qla_host_t *, sw_info_t *); |
@@ -1538,7 +1532,7 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *ha) | |||
1538 | eiter->a.sup_speed = __constant_cpu_to_be32( | 1532 | eiter->a.sup_speed = __constant_cpu_to_be32( |
1539 | FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB| | 1533 | FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB| |
1540 | FDMI_PORT_SPEED_4GB|FDMI_PORT_SPEED_8GB); | 1534 | FDMI_PORT_SPEED_4GB|FDMI_PORT_SPEED_8GB); |
1541 | else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) | 1535 | else if (IS_QLA24XX_TYPE(ha)) |
1542 | eiter->a.sup_speed = __constant_cpu_to_be32( | 1536 | eiter->a.sup_speed = __constant_cpu_to_be32( |
1543 | FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB| | 1537 | FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB| |
1544 | FDMI_PORT_SPEED_4GB); | 1538 | FDMI_PORT_SPEED_4GB); |
@@ -1847,8 +1841,10 @@ qla2x00_gpsc(scsi_qla_host_t *ha, sw_info_t *list) | |||
1847 | "GPSC")) != QLA_SUCCESS) { | 1841 | "GPSC")) != QLA_SUCCESS) { |
1848 | /* FM command unsupported? */ | 1842 | /* FM command unsupported? */ |
1849 | if (rval == QLA_INVALID_COMMAND && | 1843 | if (rval == QLA_INVALID_COMMAND && |
1850 | ct_rsp->header.reason_code == | 1844 | (ct_rsp->header.reason_code == |
1851 | CT_REASON_INVALID_COMMAND_CODE) { | 1845 | CT_REASON_INVALID_COMMAND_CODE || |
1846 | ct_rsp->header.reason_code == | ||
1847 | CT_REASON_COMMAND_UNSUPPORTED)) { | ||
1852 | DEBUG2(printk("scsi(%ld): GPSC command " | 1848 | DEBUG2(printk("scsi(%ld): GPSC command " |
1853 | "unsupported, disabling query...\n", | 1849 | "unsupported, disabling query...\n", |
1854 | ha->host_no)); | 1850 | ha->host_no)); |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 364be7d06875..01e26087c1dd 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -15,14 +15,6 @@ | |||
15 | #include <asm/prom.h> | 15 | #include <asm/prom.h> |
16 | #endif | 16 | #endif |
17 | 17 | ||
18 | /* XXX(hch): this is ugly, but we don't want to pull in exioctl.h */ | ||
19 | #ifndef EXT_IS_LUN_BIT_SET | ||
20 | #define EXT_IS_LUN_BIT_SET(P,L) \ | ||
21 | (((P)->mask[L/8] & (0x80 >> (L%8)))?1:0) | ||
22 | #define EXT_SET_LUN_BIT(P,L) \ | ||
23 | ((P)->mask[L/8] |= (0x80 >> (L%8))) | ||
24 | #endif | ||
25 | |||
26 | /* | 18 | /* |
27 | * QLogic ISP2x00 Hardware Support Function Prototypes. | 19 | * QLogic ISP2x00 Hardware Support Function Prototypes. |
28 | */ | 20 | */ |
@@ -45,6 +37,9 @@ static int qla2x00_restart_isp(scsi_qla_host_t *); | |||
45 | 37 | ||
46 | static int qla2x00_find_new_loop_id(scsi_qla_host_t *ha, fc_port_t *dev); | 38 | static int qla2x00_find_new_loop_id(scsi_qla_host_t *ha, fc_port_t *dev); |
47 | 39 | ||
40 | static struct qla_chip_state_84xx *qla84xx_get_chip(struct scsi_qla_host *); | ||
41 | static int qla84xx_init_chip(scsi_qla_host_t *); | ||
42 | |||
48 | /****************************************************************************/ | 43 | /****************************************************************************/ |
49 | /* QLogic ISP2x00 Hardware Support Functions. */ | 44 | /* QLogic ISP2x00 Hardware Support Functions. */ |
50 | /****************************************************************************/ | 45 | /****************************************************************************/ |
@@ -114,6 +109,15 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha) | |||
114 | rval = qla2x00_setup_chip(ha); | 109 | rval = qla2x00_setup_chip(ha); |
115 | if (rval) | 110 | if (rval) |
116 | return (rval); | 111 | return (rval); |
112 | qla2xxx_get_flash_info(ha); | ||
113 | } | ||
114 | if (IS_QLA84XX(ha)) { | ||
115 | ha->cs84xx = qla84xx_get_chip(ha); | ||
116 | if (!ha->cs84xx) { | ||
117 | qla_printk(KERN_ERR, ha, | ||
118 | "Unable to configure ISP84XX.\n"); | ||
119 | return QLA_FUNCTION_FAILED; | ||
120 | } | ||
117 | } | 121 | } |
118 | rval = qla2x00_init_rings(ha); | 122 | rval = qla2x00_init_rings(ha); |
119 | 123 | ||
@@ -500,6 +504,7 @@ qla2x00_reset_chip(scsi_qla_host_t *ha) | |||
500 | static inline void | 504 | static inline void |
501 | qla24xx_reset_risc(scsi_qla_host_t *ha) | 505 | qla24xx_reset_risc(scsi_qla_host_t *ha) |
502 | { | 506 | { |
507 | int hw_evt = 0; | ||
503 | unsigned long flags = 0; | 508 | unsigned long flags = 0; |
504 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | 509 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; |
505 | uint32_t cnt, d2; | 510 | uint32_t cnt, d2; |
@@ -528,6 +533,8 @@ qla24xx_reset_risc(scsi_qla_host_t *ha) | |||
528 | d2 = (uint32_t) RD_REG_WORD(®->mailbox0); | 533 | d2 = (uint32_t) RD_REG_WORD(®->mailbox0); |
529 | barrier(); | 534 | barrier(); |
530 | } | 535 | } |
536 | if (cnt == 0) | ||
537 | hw_evt = 1; | ||
531 | 538 | ||
532 | /* Wait for soft-reset to complete. */ | 539 | /* Wait for soft-reset to complete. */ |
533 | d2 = RD_REG_DWORD(®->ctrl_status); | 540 | d2 = RD_REG_DWORD(®->ctrl_status); |
@@ -536,6 +543,10 @@ qla24xx_reset_risc(scsi_qla_host_t *ha) | |||
536 | d2 = RD_REG_DWORD(®->ctrl_status); | 543 | d2 = RD_REG_DWORD(®->ctrl_status); |
537 | barrier(); | 544 | barrier(); |
538 | } | 545 | } |
546 | if (cnt == 0 || hw_evt) | ||
547 | qla2xxx_hw_event_log(ha, HW_EVENT_RESET_ERR, | ||
548 | RD_REG_WORD(®->mailbox1), RD_REG_WORD(®->mailbox2), | ||
549 | RD_REG_WORD(®->mailbox3)); | ||
539 | 550 | ||
540 | WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_RESET); | 551 | WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_RESET); |
541 | RD_REG_DWORD(®->hccr); | 552 | RD_REG_DWORD(®->hccr); |
@@ -1243,10 +1254,10 @@ static int | |||
1243 | qla2x00_fw_ready(scsi_qla_host_t *ha) | 1254 | qla2x00_fw_ready(scsi_qla_host_t *ha) |
1244 | { | 1255 | { |
1245 | int rval; | 1256 | int rval; |
1246 | unsigned long wtime, mtime; | 1257 | unsigned long wtime, mtime, cs84xx_time; |
1247 | uint16_t min_wait; /* Minimum wait time if loop is down */ | 1258 | uint16_t min_wait; /* Minimum wait time if loop is down */ |
1248 | uint16_t wait_time; /* Wait time if loop is coming ready */ | 1259 | uint16_t wait_time; /* Wait time if loop is coming ready */ |
1249 | uint16_t fw_state; | 1260 | uint16_t state[3]; |
1250 | 1261 | ||
1251 | rval = QLA_SUCCESS; | 1262 | rval = QLA_SUCCESS; |
1252 | 1263 | ||
@@ -1275,12 +1286,34 @@ qla2x00_fw_ready(scsi_qla_host_t *ha) | |||
1275 | ha->host_no)); | 1286 | ha->host_no)); |
1276 | 1287 | ||
1277 | do { | 1288 | do { |
1278 | rval = qla2x00_get_firmware_state(ha, &fw_state); | 1289 | rval = qla2x00_get_firmware_state(ha, state); |
1279 | if (rval == QLA_SUCCESS) { | 1290 | if (rval == QLA_SUCCESS) { |
1280 | if (fw_state < FSTATE_LOSS_OF_SYNC) { | 1291 | if (state[0] < FSTATE_LOSS_OF_SYNC) { |
1281 | ha->device_flags &= ~DFLG_NO_CABLE; | 1292 | ha->device_flags &= ~DFLG_NO_CABLE; |
1282 | } | 1293 | } |
1283 | if (fw_state == FSTATE_READY) { | 1294 | if (IS_QLA84XX(ha) && state[0] != FSTATE_READY) { |
1295 | DEBUG16(printk("scsi(%ld): fw_state=%x " | ||
1296 | "84xx=%x.\n", ha->host_no, state[0], | ||
1297 | state[2])); | ||
1298 | if ((state[2] & FSTATE_LOGGED_IN) && | ||
1299 | (state[2] & FSTATE_WAITING_FOR_VERIFY)) { | ||
1300 | DEBUG16(printk("scsi(%ld): Sending " | ||
1301 | "verify iocb.\n", ha->host_no)); | ||
1302 | |||
1303 | cs84xx_time = jiffies; | ||
1304 | rval = qla84xx_init_chip(ha); | ||
1305 | if (rval != QLA_SUCCESS) | ||
1306 | break; | ||
1307 | |||
1308 | /* Add time taken to initialize. */ | ||
1309 | cs84xx_time = jiffies - cs84xx_time; | ||
1310 | wtime += cs84xx_time; | ||
1311 | mtime += cs84xx_time; | ||
1312 | DEBUG16(printk("scsi(%ld): Increasing " | ||
1313 | "wait time by %ld. New time %ld\n", | ||
1314 | ha->host_no, cs84xx_time, wtime)); | ||
1315 | } | ||
1316 | } else if (state[0] == FSTATE_READY) { | ||
1284 | DEBUG(printk("scsi(%ld): F/W Ready - OK \n", | 1317 | DEBUG(printk("scsi(%ld): F/W Ready - OK \n", |
1285 | ha->host_no)); | 1318 | ha->host_no)); |
1286 | 1319 | ||
@@ -1294,7 +1327,7 @@ qla2x00_fw_ready(scsi_qla_host_t *ha) | |||
1294 | rval = QLA_FUNCTION_FAILED; | 1327 | rval = QLA_FUNCTION_FAILED; |
1295 | 1328 | ||
1296 | if (atomic_read(&ha->loop_down_timer) && | 1329 | if (atomic_read(&ha->loop_down_timer) && |
1297 | fw_state != FSTATE_READY) { | 1330 | state[0] != FSTATE_READY) { |
1298 | /* Loop down. Timeout on min_wait for states | 1331 | /* Loop down. Timeout on min_wait for states |
1299 | * other than Wait for Login. | 1332 | * other than Wait for Login. |
1300 | */ | 1333 | */ |
@@ -1319,11 +1352,11 @@ qla2x00_fw_ready(scsi_qla_host_t *ha) | |||
1319 | msleep(500); | 1352 | msleep(500); |
1320 | 1353 | ||
1321 | DEBUG3(printk("scsi(%ld): fw_state=%x curr time=%lx.\n", | 1354 | DEBUG3(printk("scsi(%ld): fw_state=%x curr time=%lx.\n", |
1322 | ha->host_no, fw_state, jiffies)); | 1355 | ha->host_no, state[0], jiffies)); |
1323 | } while (1); | 1356 | } while (1); |
1324 | 1357 | ||
1325 | DEBUG(printk("scsi(%ld): fw_state=%x curr time=%lx.\n", | 1358 | DEBUG(printk("scsi(%ld): fw_state=%x curr time=%lx.\n", |
1326 | ha->host_no, fw_state, jiffies)); | 1359 | ha->host_no, state[0], jiffies)); |
1327 | 1360 | ||
1328 | if (rval) { | 1361 | if (rval) { |
1329 | DEBUG2_3(printk("scsi(%ld): Firmware ready **** FAILED ****.\n", | 1362 | DEBUG2_3(printk("scsi(%ld): Firmware ready **** FAILED ****.\n", |
@@ -1555,6 +1588,10 @@ qla2x00_nvram_config(scsi_qla_host_t *ha) | |||
1555 | qla_printk(KERN_WARNING, ha, "Falling back to functioning (yet " | 1588 | qla_printk(KERN_WARNING, ha, "Falling back to functioning (yet " |
1556 | "invalid -- WWPN) defaults.\n"); | 1589 | "invalid -- WWPN) defaults.\n"); |
1557 | 1590 | ||
1591 | if (chksum) | ||
1592 | qla2xxx_hw_event_log(ha, HW_EVENT_NVRAM_CHKSUM_ERR, 0, | ||
1593 | MSW(chksum), LSW(chksum)); | ||
1594 | |||
1558 | /* | 1595 | /* |
1559 | * Set default initialization control block. | 1596 | * Set default initialization control block. |
1560 | */ | 1597 | */ |
@@ -2165,20 +2202,6 @@ cleanup_allocation: | |||
2165 | } | 2202 | } |
2166 | 2203 | ||
2167 | static void | 2204 | static void |
2168 | qla2x00_probe_for_all_luns(scsi_qla_host_t *ha) | ||
2169 | { | ||
2170 | fc_port_t *fcport; | ||
2171 | |||
2172 | qla2x00_mark_all_devices_lost(ha, 0); | ||
2173 | list_for_each_entry(fcport, &ha->fcports, list) { | ||
2174 | if (fcport->port_type != FCT_TARGET) | ||
2175 | continue; | ||
2176 | |||
2177 | qla2x00_update_fcport(ha, fcport); | ||
2178 | } | ||
2179 | } | ||
2180 | |||
2181 | static void | ||
2182 | qla2x00_iidma_fcport(scsi_qla_host_t *ha, fc_port_t *fcport) | 2205 | qla2x00_iidma_fcport(scsi_qla_host_t *ha, fc_port_t *fcport) |
2183 | { | 2206 | { |
2184 | #define LS_UNKNOWN 2 | 2207 | #define LS_UNKNOWN 2 |
@@ -2251,10 +2274,6 @@ qla2x00_reg_remote_port(scsi_qla_host_t *ha, fc_port_t *fcport) | |||
2251 | if (fcport->port_type == FCT_TARGET) | 2274 | if (fcport->port_type == FCT_TARGET) |
2252 | rport_ids.roles |= FC_RPORT_ROLE_FCP_TARGET; | 2275 | rport_ids.roles |= FC_RPORT_ROLE_FCP_TARGET; |
2253 | fc_remote_port_rolechg(rport, rport_ids.roles); | 2276 | fc_remote_port_rolechg(rport, rport_ids.roles); |
2254 | |||
2255 | if (rport->scsi_target_id != -1 && | ||
2256 | rport->scsi_target_id < ha->host->max_id) | ||
2257 | fcport->os_target_id = rport->scsi_target_id; | ||
2258 | } | 2277 | } |
2259 | 2278 | ||
2260 | /* | 2279 | /* |
@@ -2434,7 +2453,8 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha) | |||
2434 | 2453 | ||
2435 | if (fcport->loop_id == FC_NO_LOOP_ID) { | 2454 | if (fcport->loop_id == FC_NO_LOOP_ID) { |
2436 | fcport->loop_id = next_loopid; | 2455 | fcport->loop_id = next_loopid; |
2437 | rval = qla2x00_find_new_loop_id(ha, fcport); | 2456 | rval = qla2x00_find_new_loop_id( |
2457 | to_qla_parent(ha), fcport); | ||
2438 | if (rval != QLA_SUCCESS) { | 2458 | if (rval != QLA_SUCCESS) { |
2439 | /* Ran out of IDs to use */ | 2459 | /* Ran out of IDs to use */ |
2440 | break; | 2460 | break; |
@@ -2459,7 +2479,8 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha) | |||
2459 | 2479 | ||
2460 | /* Find a new loop ID to use. */ | 2480 | /* Find a new loop ID to use. */ |
2461 | fcport->loop_id = next_loopid; | 2481 | fcport->loop_id = next_loopid; |
2462 | rval = qla2x00_find_new_loop_id(ha, fcport); | 2482 | rval = qla2x00_find_new_loop_id(to_qla_parent(ha), |
2483 | fcport); | ||
2463 | if (rval != QLA_SUCCESS) { | 2484 | if (rval != QLA_SUCCESS) { |
2464 | /* Ran out of IDs to use */ | 2485 | /* Ran out of IDs to use */ |
2465 | break; | 2486 | break; |
@@ -3193,25 +3214,6 @@ qla2x00_loop_resync(scsi_qla_host_t *ha) | |||
3193 | } | 3214 | } |
3194 | 3215 | ||
3195 | void | 3216 | void |
3196 | qla2x00_rescan_fcports(scsi_qla_host_t *ha) | ||
3197 | { | ||
3198 | int rescan_done; | ||
3199 | fc_port_t *fcport; | ||
3200 | |||
3201 | rescan_done = 0; | ||
3202 | list_for_each_entry(fcport, &ha->fcports, list) { | ||
3203 | if ((fcport->flags & FCF_RESCAN_NEEDED) == 0) | ||
3204 | continue; | ||
3205 | |||
3206 | qla2x00_update_fcport(ha, fcport); | ||
3207 | fcport->flags &= ~FCF_RESCAN_NEEDED; | ||
3208 | |||
3209 | rescan_done = 1; | ||
3210 | } | ||
3211 | qla2x00_probe_for_all_luns(ha); | ||
3212 | } | ||
3213 | |||
3214 | void | ||
3215 | qla2x00_update_fcports(scsi_qla_host_t *ha) | 3217 | qla2x00_update_fcports(scsi_qla_host_t *ha) |
3216 | { | 3218 | { |
3217 | fc_port_t *fcport; | 3219 | fc_port_t *fcport; |
@@ -4044,16 +4046,16 @@ qla24xx_configure_vhba(scsi_qla_host_t *ha) | |||
4044 | if (!ha->parent) | 4046 | if (!ha->parent) |
4045 | return -EINVAL; | 4047 | return -EINVAL; |
4046 | 4048 | ||
4047 | rval = qla2x00_fw_ready(ha); | 4049 | rval = qla2x00_fw_ready(ha->parent); |
4048 | if (rval == QLA_SUCCESS) { | 4050 | if (rval == QLA_SUCCESS) { |
4049 | clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); | 4051 | clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); |
4050 | qla2x00_marker(ha, 0, 0, MK_SYNC_ALL); | 4052 | qla2x00_marker(ha->parent, 0, 0, MK_SYNC_ALL); |
4051 | } | 4053 | } |
4052 | 4054 | ||
4053 | ha->flags.management_server_logged_in = 0; | 4055 | ha->flags.management_server_logged_in = 0; |
4054 | 4056 | ||
4055 | /* Login to SNS first */ | 4057 | /* Login to SNS first */ |
4056 | qla24xx_login_fabric(ha, NPH_SNS, 0xff, 0xff, 0xfc, | 4058 | qla24xx_login_fabric(ha->parent, NPH_SNS, 0xff, 0xff, 0xfc, |
4057 | mb, BIT_1); | 4059 | mb, BIT_1); |
4058 | if (mb[0] != MBS_COMMAND_COMPLETE) { | 4060 | if (mb[0] != MBS_COMMAND_COMPLETE) { |
4059 | DEBUG15(qla_printk(KERN_INFO, ha, | 4061 | DEBUG15(qla_printk(KERN_INFO, ha, |
@@ -4067,7 +4069,77 @@ qla24xx_configure_vhba(scsi_qla_host_t *ha) | |||
4067 | atomic_set(&ha->loop_state, LOOP_UP); | 4069 | atomic_set(&ha->loop_state, LOOP_UP); |
4068 | set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); | 4070 | set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); |
4069 | set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags); | 4071 | set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags); |
4070 | rval = qla2x00_loop_resync(ha); | 4072 | rval = qla2x00_loop_resync(ha->parent); |
4071 | 4073 | ||
4072 | return rval; | 4074 | return rval; |
4073 | } | 4075 | } |
4076 | |||
4077 | /* 84XX Support **************************************************************/ | ||
4078 | |||
4079 | static LIST_HEAD(qla_cs84xx_list); | ||
4080 | static DEFINE_MUTEX(qla_cs84xx_mutex); | ||
4081 | |||
4082 | static struct qla_chip_state_84xx * | ||
4083 | qla84xx_get_chip(struct scsi_qla_host *ha) | ||
4084 | { | ||
4085 | struct qla_chip_state_84xx *cs84xx; | ||
4086 | |||
4087 | mutex_lock(&qla_cs84xx_mutex); | ||
4088 | |||
4089 | /* Find any shared 84xx chip. */ | ||
4090 | list_for_each_entry(cs84xx, &qla_cs84xx_list, list) { | ||
4091 | if (cs84xx->bus == ha->pdev->bus) { | ||
4092 | kref_get(&cs84xx->kref); | ||
4093 | goto done; | ||
4094 | } | ||
4095 | } | ||
4096 | |||
4097 | cs84xx = kzalloc(sizeof(*cs84xx), GFP_KERNEL); | ||
4098 | if (!cs84xx) | ||
4099 | goto done; | ||
4100 | |||
4101 | kref_init(&cs84xx->kref); | ||
4102 | spin_lock_init(&cs84xx->access_lock); | ||
4103 | mutex_init(&cs84xx->fw_update_mutex); | ||
4104 | cs84xx->bus = ha->pdev->bus; | ||
4105 | |||
4106 | list_add_tail(&cs84xx->list, &qla_cs84xx_list); | ||
4107 | done: | ||
4108 | mutex_unlock(&qla_cs84xx_mutex); | ||
4109 | return cs84xx; | ||
4110 | } | ||
4111 | |||
4112 | static void | ||
4113 | __qla84xx_chip_release(struct kref *kref) | ||
4114 | { | ||
4115 | struct qla_chip_state_84xx *cs84xx = | ||
4116 | container_of(kref, struct qla_chip_state_84xx, kref); | ||
4117 | |||
4118 | mutex_lock(&qla_cs84xx_mutex); | ||
4119 | list_del(&cs84xx->list); | ||
4120 | mutex_unlock(&qla_cs84xx_mutex); | ||
4121 | kfree(cs84xx); | ||
4122 | } | ||
4123 | |||
4124 | void | ||
4125 | qla84xx_put_chip(struct scsi_qla_host *ha) | ||
4126 | { | ||
4127 | if (ha->cs84xx) | ||
4128 | kref_put(&ha->cs84xx->kref, __qla84xx_chip_release); | ||
4129 | } | ||
4130 | |||
4131 | static int | ||
4132 | qla84xx_init_chip(scsi_qla_host_t *ha) | ||
4133 | { | ||
4134 | int rval; | ||
4135 | uint16_t status[2]; | ||
4136 | |||
4137 | mutex_lock(&ha->cs84xx->fw_update_mutex); | ||
4138 | |||
4139 | rval = qla84xx_verify_chip(ha, status); | ||
4140 | |||
4141 | mutex_unlock(&ha->cs84xx->fw_update_mutex); | ||
4142 | |||
4143 | return rval != QLA_SUCCESS || status[0] ? QLA_FUNCTION_FAILED: | ||
4144 | QLA_SUCCESS; | ||
4145 | } | ||
diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h index 5d1a3f7c408f..e9bae27737d1 100644 --- a/drivers/scsi/qla2xxx/qla_inline.h +++ b/drivers/scsi/qla2xxx/qla_inline.h | |||
@@ -1,11 +1,10 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
7 | 7 | ||
8 | static __inline__ uint16_t qla2x00_debounce_register(volatile uint16_t __iomem *); | ||
9 | /* | 8 | /* |
10 | * qla2x00_debounce_register | 9 | * qla2x00_debounce_register |
11 | * Debounce register. | 10 | * Debounce register. |
@@ -32,94 +31,12 @@ qla2x00_debounce_register(volatile uint16_t __iomem *addr) | |||
32 | return (first); | 31 | return (first); |
33 | } | 32 | } |
34 | 33 | ||
35 | static __inline__ int qla2x00_normalize_dma_addr( | ||
36 | dma_addr_t *e_addr, uint32_t *e_len, | ||
37 | dma_addr_t *ne_addr, uint32_t *ne_len); | ||
38 | |||
39 | /** | ||
40 | * qla2x00_normalize_dma_addr() - Normalize an DMA address. | ||
41 | * @e_addr: Raw DMA address | ||
42 | * @e_len: Raw DMA length | ||
43 | * @ne_addr: Normalized second DMA address | ||
44 | * @ne_len: Normalized second DMA length | ||
45 | * | ||
46 | * If the address does not span a 4GB page boundary, the contents of @ne_addr | ||
47 | * and @ne_len are undefined. @e_len is updated to reflect a normalization. | ||
48 | * | ||
49 | * Example: | ||
50 | * | ||
51 | * ffffabc0ffffeeee (e_addr) start of DMA address | ||
52 | * 0000000020000000 (e_len) length of DMA transfer | ||
53 | * ffffabc11fffeeed end of DMA transfer | ||
54 | * | ||
55 | * Is the 4GB boundary crossed? | ||
56 | * | ||
57 | * ffffabc0ffffeeee (e_addr) | ||
58 | * ffffabc11fffeeed (e_addr + e_len - 1) | ||
59 | * 00000001e0000003 ((e_addr ^ (e_addr + e_len - 1)) | ||
60 | * 0000000100000000 ((e_addr ^ (e_addr + e_len - 1)) & ~(0xffffffff) | ||
61 | * | ||
62 | * Compute start of second DMA segment: | ||
63 | * | ||
64 | * ffffabc0ffffeeee (e_addr) | ||
65 | * ffffabc1ffffeeee (0x100000000 + e_addr) | ||
66 | * ffffabc100000000 (0x100000000 + e_addr) & ~(0xffffffff) | ||
67 | * ffffabc100000000 (ne_addr) | ||
68 | * | ||
69 | * Compute length of second DMA segment: | ||
70 | * | ||
71 | * 00000000ffffeeee (e_addr & 0xffffffff) | ||
72 | * 0000000000001112 (0x100000000 - (e_addr & 0xffffffff)) | ||
73 | * 000000001fffeeee (e_len - (0x100000000 - (e_addr & 0xffffffff)) | ||
74 | * 000000001fffeeee (ne_len) | ||
75 | * | ||
76 | * Adjust length of first DMA segment | ||
77 | * | ||
78 | * 0000000020000000 (e_len) | ||
79 | * 0000000000001112 (e_len - ne_len) | ||
80 | * 0000000000001112 (e_len) | ||
81 | * | ||
82 | * Returns non-zero if the specified address was normalized, else zero. | ||
83 | */ | ||
84 | static __inline__ int | ||
85 | qla2x00_normalize_dma_addr( | ||
86 | dma_addr_t *e_addr, uint32_t *e_len, | ||
87 | dma_addr_t *ne_addr, uint32_t *ne_len) | ||
88 | { | ||
89 | int normalized; | ||
90 | |||
91 | normalized = 0; | ||
92 | if ((*e_addr ^ (*e_addr + *e_len - 1)) & ~(0xFFFFFFFFULL)) { | ||
93 | /* Compute normalized crossed address and len */ | ||
94 | *ne_addr = (0x100000000ULL + *e_addr) & ~(0xFFFFFFFFULL); | ||
95 | *ne_len = *e_len - (0x100000000ULL - (*e_addr & 0xFFFFFFFFULL)); | ||
96 | *e_len -= *ne_len; | ||
97 | |||
98 | normalized++; | ||
99 | } | ||
100 | return (normalized); | ||
101 | } | ||
102 | |||
103 | static __inline__ void qla2x00_poll(scsi_qla_host_t *); | ||
104 | static inline void | 34 | static inline void |
105 | qla2x00_poll(scsi_qla_host_t *ha) | 35 | qla2x00_poll(scsi_qla_host_t *ha) |
106 | { | 36 | { |
107 | ha->isp_ops->intr_handler(0, ha); | 37 | ha->isp_ops->intr_handler(0, ha); |
108 | } | 38 | } |
109 | 39 | ||
110 | static __inline__ void qla2x00_check_fabric_devices(scsi_qla_host_t *); | ||
111 | /* | ||
112 | * This routine will wait for fabric devices for | ||
113 | * the reset delay. | ||
114 | */ | ||
115 | static __inline__ void qla2x00_check_fabric_devices(scsi_qla_host_t *ha) | ||
116 | { | ||
117 | uint16_t fw_state; | ||
118 | |||
119 | qla2x00_get_firmware_state(ha, &fw_state); | ||
120 | } | ||
121 | |||
122 | static __inline__ scsi_qla_host_t * to_qla_parent(scsi_qla_host_t *); | ||
123 | static __inline__ scsi_qla_host_t * | 40 | static __inline__ scsi_qla_host_t * |
124 | to_qla_parent(scsi_qla_host_t *ha) | 41 | to_qla_parent(scsi_qla_host_t *ha) |
125 | { | 42 | { |
@@ -152,7 +69,6 @@ qla2x00_issue_marker(scsi_qla_host_t *ha, int ha_locked) | |||
152 | return (QLA_SUCCESS); | 69 | return (QLA_SUCCESS); |
153 | } | 70 | } |
154 | 71 | ||
155 | static inline uint8_t *host_to_fcp_swap(uint8_t *, uint32_t); | ||
156 | static inline uint8_t * | 72 | static inline uint8_t * |
157 | host_to_fcp_swap(uint8_t *fcp, uint32_t bsize) | 73 | host_to_fcp_swap(uint8_t *fcp, uint32_t bsize) |
158 | { | 74 | { |
@@ -166,7 +82,6 @@ host_to_fcp_swap(uint8_t *fcp, uint32_t bsize) | |||
166 | return fcp; | 82 | return fcp; |
167 | } | 83 | } |
168 | 84 | ||
169 | static inline int qla2x00_is_reserved_id(scsi_qla_host_t *, uint16_t); | ||
170 | static inline int | 85 | static inline int |
171 | qla2x00_is_reserved_id(scsi_qla_host_t *ha, uint16_t loop_id) | 86 | qla2x00_is_reserved_id(scsi_qla_host_t *ha, uint16_t loop_id) |
172 | { | 87 | { |
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 024c662ec34d..5489d5024673 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -11,9 +11,6 @@ | |||
11 | 11 | ||
12 | #include <scsi/scsi_tcq.h> | 12 | #include <scsi/scsi_tcq.h> |
13 | 13 | ||
14 | static inline uint16_t qla2x00_get_cmd_direction(struct scsi_cmnd *cmd); | ||
15 | static inline cont_entry_t *qla2x00_prep_cont_type0_iocb(scsi_qla_host_t *); | ||
16 | static inline cont_a64_entry_t *qla2x00_prep_cont_type1_iocb(scsi_qla_host_t *); | ||
17 | static request_t *qla2x00_req_pkt(scsi_qla_host_t *ha); | 14 | static request_t *qla2x00_req_pkt(scsi_qla_host_t *ha); |
18 | static void qla2x00_isp_cmd(scsi_qla_host_t *ha); | 15 | static void qla2x00_isp_cmd(scsi_qla_host_t *ha); |
19 | 16 | ||
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index f0337036c7bb..285479b62d8f 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -14,9 +14,6 @@ static void qla2x00_process_completed_request(struct scsi_qla_host *, uint32_t); | |||
14 | static void qla2x00_status_entry(scsi_qla_host_t *, void *); | 14 | static void qla2x00_status_entry(scsi_qla_host_t *, void *); |
15 | static void qla2x00_status_cont_entry(scsi_qla_host_t *, sts_cont_entry_t *); | 15 | static void qla2x00_status_cont_entry(scsi_qla_host_t *, sts_cont_entry_t *); |
16 | static void qla2x00_error_entry(scsi_qla_host_t *, sts_entry_t *); | 16 | static void qla2x00_error_entry(scsi_qla_host_t *, sts_entry_t *); |
17 | static void qla2x00_ms_entry(scsi_qla_host_t *, ms_iocb_entry_t *); | ||
18 | |||
19 | static void qla24xx_ms_entry(scsi_qla_host_t *, struct ct_entry_24xx *); | ||
20 | 17 | ||
21 | /** | 18 | /** |
22 | * qla2100_intr_handler() - Process interrupts for the ISP2100 and ISP2200. | 19 | * qla2100_intr_handler() - Process interrupts for the ISP2100 and ISP2200. |
@@ -33,7 +30,6 @@ qla2100_intr_handler(int irq, void *dev_id) | |||
33 | scsi_qla_host_t *ha; | 30 | scsi_qla_host_t *ha; |
34 | struct device_reg_2xxx __iomem *reg; | 31 | struct device_reg_2xxx __iomem *reg; |
35 | int status; | 32 | int status; |
36 | unsigned long flags; | ||
37 | unsigned long iter; | 33 | unsigned long iter; |
38 | uint16_t hccr; | 34 | uint16_t hccr; |
39 | uint16_t mb[4]; | 35 | uint16_t mb[4]; |
@@ -48,7 +44,7 @@ qla2100_intr_handler(int irq, void *dev_id) | |||
48 | reg = &ha->iobase->isp; | 44 | reg = &ha->iobase->isp; |
49 | status = 0; | 45 | status = 0; |
50 | 46 | ||
51 | spin_lock_irqsave(&ha->hardware_lock, flags); | 47 | spin_lock(&ha->hardware_lock); |
52 | for (iter = 50; iter--; ) { | 48 | for (iter = 50; iter--; ) { |
53 | hccr = RD_REG_WORD(®->hccr); | 49 | hccr = RD_REG_WORD(®->hccr); |
54 | if (hccr & HCCR_RISC_PAUSE) { | 50 | if (hccr & HCCR_RISC_PAUSE) { |
@@ -99,7 +95,7 @@ qla2100_intr_handler(int irq, void *dev_id) | |||
99 | RD_REG_WORD(®->hccr); | 95 | RD_REG_WORD(®->hccr); |
100 | } | 96 | } |
101 | } | 97 | } |
102 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 98 | spin_unlock(&ha->hardware_lock); |
103 | 99 | ||
104 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && | 100 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && |
105 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { | 101 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { |
@@ -125,7 +121,6 @@ qla2300_intr_handler(int irq, void *dev_id) | |||
125 | scsi_qla_host_t *ha; | 121 | scsi_qla_host_t *ha; |
126 | struct device_reg_2xxx __iomem *reg; | 122 | struct device_reg_2xxx __iomem *reg; |
127 | int status; | 123 | int status; |
128 | unsigned long flags; | ||
129 | unsigned long iter; | 124 | unsigned long iter; |
130 | uint32_t stat; | 125 | uint32_t stat; |
131 | uint16_t hccr; | 126 | uint16_t hccr; |
@@ -141,7 +136,7 @@ qla2300_intr_handler(int irq, void *dev_id) | |||
141 | reg = &ha->iobase->isp; | 136 | reg = &ha->iobase->isp; |
142 | status = 0; | 137 | status = 0; |
143 | 138 | ||
144 | spin_lock_irqsave(&ha->hardware_lock, flags); | 139 | spin_lock(&ha->hardware_lock); |
145 | for (iter = 50; iter--; ) { | 140 | for (iter = 50; iter--; ) { |
146 | stat = RD_REG_DWORD(®->u.isp2300.host_status); | 141 | stat = RD_REG_DWORD(®->u.isp2300.host_status); |
147 | if (stat & HSR_RISC_PAUSED) { | 142 | if (stat & HSR_RISC_PAUSED) { |
@@ -211,7 +206,7 @@ qla2300_intr_handler(int irq, void *dev_id) | |||
211 | WRT_REG_WORD(®->hccr, HCCR_CLR_RISC_INT); | 206 | WRT_REG_WORD(®->hccr, HCCR_CLR_RISC_INT); |
212 | RD_REG_WORD_RELAXED(®->hccr); | 207 | RD_REG_WORD_RELAXED(®->hccr); |
213 | } | 208 | } |
214 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 209 | spin_unlock(&ha->hardware_lock); |
215 | 210 | ||
216 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && | 211 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && |
217 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { | 212 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { |
@@ -276,6 +271,9 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
276 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; | 271 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; |
277 | uint32_t rscn_entry, host_pid; | 272 | uint32_t rscn_entry, host_pid; |
278 | uint8_t rscn_queue_index; | 273 | uint8_t rscn_queue_index; |
274 | unsigned long flags; | ||
275 | scsi_qla_host_t *vha; | ||
276 | int i; | ||
279 | 277 | ||
280 | /* Setup to process RIO completion. */ | 278 | /* Setup to process RIO completion. */ |
281 | handle_cnt = 0; | 279 | handle_cnt = 0; |
@@ -351,6 +349,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
351 | "ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh.\n", | 349 | "ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh.\n", |
352 | mb[1], mb[2], mb[3]); | 350 | mb[1], mb[2], mb[3]); |
353 | 351 | ||
352 | qla2x00_post_hwe_work(ha, mb[0], mb[1], mb[2], mb[3]); | ||
354 | ha->isp_ops->fw_dump(ha, 1); | 353 | ha->isp_ops->fw_dump(ha, 1); |
355 | 354 | ||
356 | if (IS_FWI2_CAPABLE(ha)) { | 355 | if (IS_FWI2_CAPABLE(ha)) { |
@@ -375,6 +374,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
375 | ha->host_no)); | 374 | ha->host_no)); |
376 | qla_printk(KERN_WARNING, ha, "ISP Request Transfer Error.\n"); | 375 | qla_printk(KERN_WARNING, ha, "ISP Request Transfer Error.\n"); |
377 | 376 | ||
377 | qla2x00_post_hwe_work(ha, mb[0], mb[1], mb[2], mb[3]); | ||
378 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | 378 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); |
379 | break; | 379 | break; |
380 | 380 | ||
@@ -383,6 +383,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
383 | ha->host_no)); | 383 | ha->host_no)); |
384 | qla_printk(KERN_WARNING, ha, "ISP Response Transfer Error.\n"); | 384 | qla_printk(KERN_WARNING, ha, "ISP Response Transfer Error.\n"); |
385 | 385 | ||
386 | qla2x00_post_hwe_work(ha, mb[0], mb[1], mb[2], mb[3]); | ||
386 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | 387 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); |
387 | break; | 388 | break; |
388 | 389 | ||
@@ -410,6 +411,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
410 | set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags); | 411 | set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags); |
411 | 412 | ||
412 | ha->flags.management_server_logged_in = 0; | 413 | ha->flags.management_server_logged_in = 0; |
414 | qla2x00_post_aen_work(ha, FCH_EVT_LIP, mb[1]); | ||
413 | break; | 415 | break; |
414 | 416 | ||
415 | case MBA_LOOP_UP: /* Loop Up Event */ | 417 | case MBA_LOOP_UP: /* Loop Up Event */ |
@@ -429,12 +431,14 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
429 | link_speed); | 431 | link_speed); |
430 | 432 | ||
431 | ha->flags.management_server_logged_in = 0; | 433 | ha->flags.management_server_logged_in = 0; |
434 | qla2x00_post_aen_work(ha, FCH_EVT_LINKUP, ha->link_data_rate); | ||
432 | break; | 435 | break; |
433 | 436 | ||
434 | case MBA_LOOP_DOWN: /* Loop Down Event */ | 437 | case MBA_LOOP_DOWN: /* Loop Down Event */ |
435 | DEBUG2(printk("scsi(%ld): Asynchronous LOOP DOWN (%x).\n", | 438 | DEBUG2(printk("scsi(%ld): Asynchronous LOOP DOWN " |
436 | ha->host_no, mb[1])); | 439 | "(%x %x %x).\n", ha->host_no, mb[1], mb[2], mb[3])); |
437 | qla_printk(KERN_INFO, ha, "LOOP DOWN detected (%x).\n", mb[1]); | 440 | qla_printk(KERN_INFO, ha, "LOOP DOWN detected (%x %x %x).\n", |
441 | mb[1], mb[2], mb[3]); | ||
438 | 442 | ||
439 | if (atomic_read(&ha->loop_state) != LOOP_DOWN) { | 443 | if (atomic_read(&ha->loop_state) != LOOP_DOWN) { |
440 | atomic_set(&ha->loop_state, LOOP_DOWN); | 444 | atomic_set(&ha->loop_state, LOOP_DOWN); |
@@ -452,6 +456,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
452 | ha->link_data_rate = PORT_SPEED_UNKNOWN; | 456 | ha->link_data_rate = PORT_SPEED_UNKNOWN; |
453 | if (ql2xfdmienable) | 457 | if (ql2xfdmienable) |
454 | set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags); | 458 | set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags); |
459 | qla2x00_post_aen_work(ha, FCH_EVT_LINKDOWN, 0); | ||
455 | break; | 460 | break; |
456 | 461 | ||
457 | case MBA_LIP_RESET: /* LIP reset occurred */ | 462 | case MBA_LIP_RESET: /* LIP reset occurred */ |
@@ -475,6 +480,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
475 | 480 | ||
476 | ha->operating_mode = LOOP; | 481 | ha->operating_mode = LOOP; |
477 | ha->flags.management_server_logged_in = 0; | 482 | ha->flags.management_server_logged_in = 0; |
483 | qla2x00_post_aen_work(ha, FCH_EVT_LIPRESET, mb[1]); | ||
478 | break; | 484 | break; |
479 | 485 | ||
480 | case MBA_POINT_TO_POINT: /* Point-to-Point */ | 486 | case MBA_POINT_TO_POINT: /* Point-to-Point */ |
@@ -538,6 +544,18 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
538 | break; | 544 | break; |
539 | 545 | ||
540 | case MBA_PORT_UPDATE: /* Port database update */ | 546 | case MBA_PORT_UPDATE: /* Port database update */ |
547 | if ((ha->flags.npiv_supported) && (ha->num_vhosts)) { | ||
548 | for_each_mapped_vp_idx(ha, i) { | ||
549 | list_for_each_entry(vha, &ha->vp_list, | ||
550 | vp_list) { | ||
551 | if ((mb[3] & 0xff) | ||
552 | == vha->vp_idx) { | ||
553 | ha = vha; | ||
554 | break; | ||
555 | } | ||
556 | } | ||
557 | } | ||
558 | } | ||
541 | /* | 559 | /* |
542 | * If PORT UPDATE is global (recieved LIP_OCCURED/LIP_RESET | 560 | * If PORT UPDATE is global (recieved LIP_OCCURED/LIP_RESET |
543 | * event etc. earlier indicating loop is down) then process | 561 | * event etc. earlier indicating loop is down) then process |
@@ -572,12 +590,18 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
572 | break; | 590 | break; |
573 | 591 | ||
574 | case MBA_RSCN_UPDATE: /* State Change Registration */ | 592 | case MBA_RSCN_UPDATE: /* State Change Registration */ |
575 | /* Check if the Vport has issued a SCR */ | 593 | if ((ha->flags.npiv_supported) && (ha->num_vhosts)) { |
576 | if (ha->parent && test_bit(VP_SCR_NEEDED, &ha->vp_flags)) | 594 | for_each_mapped_vp_idx(ha, i) { |
577 | break; | 595 | list_for_each_entry(vha, &ha->vp_list, |
578 | /* Only handle SCNs for our Vport index. */ | 596 | vp_list) { |
579 | if (ha->flags.npiv_supported && ha->vp_idx != mb[3]) | 597 | if ((mb[3] & 0xff) |
580 | break; | 598 | == vha->vp_idx) { |
599 | ha = vha; | ||
600 | break; | ||
601 | } | ||
602 | } | ||
603 | } | ||
604 | } | ||
581 | 605 | ||
582 | DEBUG2(printk("scsi(%ld): Asynchronous RSCR UPDATE.\n", | 606 | DEBUG2(printk("scsi(%ld): Asynchronous RSCR UPDATE.\n", |
583 | ha->host_no)); | 607 | ha->host_no)); |
@@ -612,6 +636,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
612 | 636 | ||
613 | set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); | 637 | set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); |
614 | set_bit(RSCN_UPDATE, &ha->dpc_flags); | 638 | set_bit(RSCN_UPDATE, &ha->dpc_flags); |
639 | qla2x00_post_aen_work(ha, FCH_EVT_RSCN, rscn_entry); | ||
615 | break; | 640 | break; |
616 | 641 | ||
617 | /* case MBA_RIO_RESPONSE: */ | 642 | /* case MBA_RIO_RESPONSE: */ |
@@ -637,6 +662,42 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
637 | DEBUG2(printk("scsi(%ld): Trace Notification -- %04x %04x.\n", | 662 | DEBUG2(printk("scsi(%ld): Trace Notification -- %04x %04x.\n", |
638 | ha->host_no, mb[1], mb[2])); | 663 | ha->host_no, mb[1], mb[2])); |
639 | break; | 664 | break; |
665 | |||
666 | case MBA_ISP84XX_ALERT: | ||
667 | DEBUG2(printk("scsi(%ld): ISP84XX Alert Notification -- " | ||
668 | "%04x %04x %04x\n", ha->host_no, mb[1], mb[2], mb[3])); | ||
669 | |||
670 | spin_lock_irqsave(&ha->cs84xx->access_lock, flags); | ||
671 | switch (mb[1]) { | ||
672 | case A84_PANIC_RECOVERY: | ||
673 | qla_printk(KERN_INFO, ha, "Alert 84XX: panic recovery " | ||
674 | "%04x %04x\n", mb[2], mb[3]); | ||
675 | break; | ||
676 | case A84_OP_LOGIN_COMPLETE: | ||
677 | ha->cs84xx->op_fw_version = mb[3] << 16 | mb[2]; | ||
678 | DEBUG2(qla_printk(KERN_INFO, ha, "Alert 84XX:" | ||
679 | "firmware version %x\n", ha->cs84xx->op_fw_version)); | ||
680 | break; | ||
681 | case A84_DIAG_LOGIN_COMPLETE: | ||
682 | ha->cs84xx->diag_fw_version = mb[3] << 16 | mb[2]; | ||
683 | DEBUG2(qla_printk(KERN_INFO, ha, "Alert 84XX:" | ||
684 | "diagnostic firmware version %x\n", | ||
685 | ha->cs84xx->diag_fw_version)); | ||
686 | break; | ||
687 | case A84_GOLD_LOGIN_COMPLETE: | ||
688 | ha->cs84xx->diag_fw_version = mb[3] << 16 | mb[2]; | ||
689 | ha->cs84xx->fw_update = 1; | ||
690 | DEBUG2(qla_printk(KERN_INFO, ha, "Alert 84XX: gold " | ||
691 | "firmware version %x\n", | ||
692 | ha->cs84xx->gold_fw_version)); | ||
693 | break; | ||
694 | default: | ||
695 | qla_printk(KERN_ERR, ha, | ||
696 | "Alert 84xx: Invalid Alert %04x %04x %04x\n", | ||
697 | mb[1], mb[2], mb[3]); | ||
698 | } | ||
699 | spin_unlock_irqrestore(&ha->cs84xx->access_lock, flags); | ||
700 | break; | ||
640 | } | 701 | } |
641 | 702 | ||
642 | if (!ha->parent && ha->num_vhosts) | 703 | if (!ha->parent && ha->num_vhosts) |
@@ -803,9 +864,6 @@ qla2x00_process_response_queue(struct scsi_qla_host *ha) | |||
803 | case STATUS_CONT_TYPE: | 864 | case STATUS_CONT_TYPE: |
804 | qla2x00_status_cont_entry(ha, (sts_cont_entry_t *)pkt); | 865 | qla2x00_status_cont_entry(ha, (sts_cont_entry_t *)pkt); |
805 | break; | 866 | break; |
806 | case MS_IOCB_TYPE: | ||
807 | qla2x00_ms_entry(ha, (ms_iocb_entry_t *)pkt); | ||
808 | break; | ||
809 | default: | 867 | default: |
810 | /* Type Not Supported. */ | 868 | /* Type Not Supported. */ |
811 | DEBUG4(printk(KERN_WARNING | 869 | DEBUG4(printk(KERN_WARNING |
@@ -1340,44 +1398,6 @@ qla2x00_error_entry(scsi_qla_host_t *ha, sts_entry_t *pkt) | |||
1340 | } | 1398 | } |
1341 | 1399 | ||
1342 | /** | 1400 | /** |
1343 | * qla2x00_ms_entry() - Process a Management Server entry. | ||
1344 | * @ha: SCSI driver HA context | ||
1345 | * @index: Response queue out pointer | ||
1346 | */ | ||
1347 | static void | ||
1348 | qla2x00_ms_entry(scsi_qla_host_t *ha, ms_iocb_entry_t *pkt) | ||
1349 | { | ||
1350 | srb_t *sp; | ||
1351 | |||
1352 | DEBUG3(printk("%s(%ld): pkt=%p pkthandle=%d.\n", | ||
1353 | __func__, ha->host_no, pkt, pkt->handle1)); | ||
1354 | |||
1355 | /* Validate handle. */ | ||
1356 | if (pkt->handle1 < MAX_OUTSTANDING_COMMANDS) | ||
1357 | sp = ha->outstanding_cmds[pkt->handle1]; | ||
1358 | else | ||
1359 | sp = NULL; | ||
1360 | |||
1361 | if (sp == NULL) { | ||
1362 | DEBUG2(printk("scsi(%ld): MS entry - invalid handle\n", | ||
1363 | ha->host_no)); | ||
1364 | qla_printk(KERN_WARNING, ha, "MS entry - invalid handle\n"); | ||
1365 | |||
1366 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | ||
1367 | return; | ||
1368 | } | ||
1369 | |||
1370 | CMD_COMPL_STATUS(sp->cmd) = le16_to_cpu(pkt->status); | ||
1371 | CMD_ENTRY_STATUS(sp->cmd) = pkt->entry_status; | ||
1372 | |||
1373 | /* Free outstanding command slot. */ | ||
1374 | ha->outstanding_cmds[pkt->handle1] = NULL; | ||
1375 | |||
1376 | qla2x00_sp_compl(ha, sp); | ||
1377 | } | ||
1378 | |||
1379 | |||
1380 | /** | ||
1381 | * qla24xx_mbx_completion() - Process mailbox command completions. | 1401 | * qla24xx_mbx_completion() - Process mailbox command completions. |
1382 | * @ha: SCSI driver HA context | 1402 | * @ha: SCSI driver HA context |
1383 | * @mb0: Mailbox0 register | 1403 | * @mb0: Mailbox0 register |
@@ -1449,9 +1469,6 @@ qla24xx_process_response_queue(struct scsi_qla_host *ha) | |||
1449 | case STATUS_CONT_TYPE: | 1469 | case STATUS_CONT_TYPE: |
1450 | qla2x00_status_cont_entry(ha, (sts_cont_entry_t *)pkt); | 1470 | qla2x00_status_cont_entry(ha, (sts_cont_entry_t *)pkt); |
1451 | break; | 1471 | break; |
1452 | case MS_IOCB_TYPE: | ||
1453 | qla24xx_ms_entry(ha, (struct ct_entry_24xx *)pkt); | ||
1454 | break; | ||
1455 | case VP_RPT_ID_IOCB_TYPE: | 1472 | case VP_RPT_ID_IOCB_TYPE: |
1456 | qla24xx_report_id_acquisition(ha, | 1473 | qla24xx_report_id_acquisition(ha, |
1457 | (struct vp_rpt_id_entry_24xx *)pkt); | 1474 | (struct vp_rpt_id_entry_24xx *)pkt); |
@@ -1533,7 +1550,6 @@ qla24xx_intr_handler(int irq, void *dev_id) | |||
1533 | scsi_qla_host_t *ha; | 1550 | scsi_qla_host_t *ha; |
1534 | struct device_reg_24xx __iomem *reg; | 1551 | struct device_reg_24xx __iomem *reg; |
1535 | int status; | 1552 | int status; |
1536 | unsigned long flags; | ||
1537 | unsigned long iter; | 1553 | unsigned long iter; |
1538 | uint32_t stat; | 1554 | uint32_t stat; |
1539 | uint32_t hccr; | 1555 | uint32_t hccr; |
@@ -1549,13 +1565,19 @@ qla24xx_intr_handler(int irq, void *dev_id) | |||
1549 | reg = &ha->iobase->isp24; | 1565 | reg = &ha->iobase->isp24; |
1550 | status = 0; | 1566 | status = 0; |
1551 | 1567 | ||
1552 | spin_lock_irqsave(&ha->hardware_lock, flags); | 1568 | spin_lock(&ha->hardware_lock); |
1553 | for (iter = 50; iter--; ) { | 1569 | for (iter = 50; iter--; ) { |
1554 | stat = RD_REG_DWORD(®->host_status); | 1570 | stat = RD_REG_DWORD(®->host_status); |
1555 | if (stat & HSRX_RISC_PAUSED) { | 1571 | if (stat & HSRX_RISC_PAUSED) { |
1556 | if (pci_channel_offline(ha->pdev)) | 1572 | if (pci_channel_offline(ha->pdev)) |
1557 | break; | 1573 | break; |
1558 | 1574 | ||
1575 | if (ha->hw_event_pause_errors == 0) | ||
1576 | qla2x00_post_hwe_work(ha, HW_EVENT_PARITY_ERR, | ||
1577 | 0, MSW(stat), LSW(stat)); | ||
1578 | else if (ha->hw_event_pause_errors < 0xffffffff) | ||
1579 | ha->hw_event_pause_errors++; | ||
1580 | |||
1559 | hccr = RD_REG_DWORD(®->hccr); | 1581 | hccr = RD_REG_DWORD(®->hccr); |
1560 | 1582 | ||
1561 | qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, " | 1583 | qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, " |
@@ -1597,7 +1619,7 @@ qla24xx_intr_handler(int irq, void *dev_id) | |||
1597 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | 1619 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); |
1598 | RD_REG_DWORD_RELAXED(®->hccr); | 1620 | RD_REG_DWORD_RELAXED(®->hccr); |
1599 | } | 1621 | } |
1600 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 1622 | spin_unlock(&ha->hardware_lock); |
1601 | 1623 | ||
1602 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && | 1624 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && |
1603 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { | 1625 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { |
@@ -1608,66 +1630,21 @@ qla24xx_intr_handler(int irq, void *dev_id) | |||
1608 | return IRQ_HANDLED; | 1630 | return IRQ_HANDLED; |
1609 | } | 1631 | } |
1610 | 1632 | ||
1611 | /** | ||
1612 | * qla24xx_ms_entry() - Process a Management Server entry. | ||
1613 | * @ha: SCSI driver HA context | ||
1614 | * @index: Response queue out pointer | ||
1615 | */ | ||
1616 | static void | ||
1617 | qla24xx_ms_entry(scsi_qla_host_t *ha, struct ct_entry_24xx *pkt) | ||
1618 | { | ||
1619 | srb_t *sp; | ||
1620 | |||
1621 | DEBUG3(printk("%s(%ld): pkt=%p pkthandle=%d.\n", | ||
1622 | __func__, ha->host_no, pkt, pkt->handle)); | ||
1623 | |||
1624 | DEBUG9(printk("%s: ct pkt dump:\n", __func__)); | ||
1625 | DEBUG9(qla2x00_dump_buffer((void *)pkt, sizeof(struct ct_entry_24xx))); | ||
1626 | |||
1627 | /* Validate handle. */ | ||
1628 | if (pkt->handle < MAX_OUTSTANDING_COMMANDS) | ||
1629 | sp = ha->outstanding_cmds[pkt->handle]; | ||
1630 | else | ||
1631 | sp = NULL; | ||
1632 | |||
1633 | if (sp == NULL) { | ||
1634 | DEBUG2(printk("scsi(%ld): MS entry - invalid handle\n", | ||
1635 | ha->host_no)); | ||
1636 | DEBUG10(printk("scsi(%ld): MS entry - invalid handle\n", | ||
1637 | ha->host_no)); | ||
1638 | qla_printk(KERN_WARNING, ha, "MS entry - invalid handle %d\n", | ||
1639 | pkt->handle); | ||
1640 | |||
1641 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | ||
1642 | return; | ||
1643 | } | ||
1644 | |||
1645 | CMD_COMPL_STATUS(sp->cmd) = le16_to_cpu(pkt->comp_status); | ||
1646 | CMD_ENTRY_STATUS(sp->cmd) = pkt->entry_status; | ||
1647 | |||
1648 | /* Free outstanding command slot. */ | ||
1649 | ha->outstanding_cmds[pkt->handle] = NULL; | ||
1650 | |||
1651 | qla2x00_sp_compl(ha, sp); | ||
1652 | } | ||
1653 | |||
1654 | static irqreturn_t | 1633 | static irqreturn_t |
1655 | qla24xx_msix_rsp_q(int irq, void *dev_id) | 1634 | qla24xx_msix_rsp_q(int irq, void *dev_id) |
1656 | { | 1635 | { |
1657 | scsi_qla_host_t *ha; | 1636 | scsi_qla_host_t *ha; |
1658 | struct device_reg_24xx __iomem *reg; | 1637 | struct device_reg_24xx __iomem *reg; |
1659 | unsigned long flags; | ||
1660 | 1638 | ||
1661 | ha = dev_id; | 1639 | ha = dev_id; |
1662 | reg = &ha->iobase->isp24; | 1640 | reg = &ha->iobase->isp24; |
1663 | 1641 | ||
1664 | spin_lock_irqsave(&ha->hardware_lock, flags); | 1642 | spin_lock(&ha->hardware_lock); |
1665 | 1643 | ||
1666 | qla24xx_process_response_queue(ha); | 1644 | qla24xx_process_response_queue(ha); |
1667 | |||
1668 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | 1645 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); |
1669 | 1646 | ||
1670 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 1647 | spin_unlock(&ha->hardware_lock); |
1671 | 1648 | ||
1672 | return IRQ_HANDLED; | 1649 | return IRQ_HANDLED; |
1673 | } | 1650 | } |
@@ -1678,7 +1655,6 @@ qla24xx_msix_default(int irq, void *dev_id) | |||
1678 | scsi_qla_host_t *ha; | 1655 | scsi_qla_host_t *ha; |
1679 | struct device_reg_24xx __iomem *reg; | 1656 | struct device_reg_24xx __iomem *reg; |
1680 | int status; | 1657 | int status; |
1681 | unsigned long flags; | ||
1682 | uint32_t stat; | 1658 | uint32_t stat; |
1683 | uint32_t hccr; | 1659 | uint32_t hccr; |
1684 | uint16_t mb[4]; | 1660 | uint16_t mb[4]; |
@@ -1687,13 +1663,19 @@ qla24xx_msix_default(int irq, void *dev_id) | |||
1687 | reg = &ha->iobase->isp24; | 1663 | reg = &ha->iobase->isp24; |
1688 | status = 0; | 1664 | status = 0; |
1689 | 1665 | ||
1690 | spin_lock_irqsave(&ha->hardware_lock, flags); | 1666 | spin_lock(&ha->hardware_lock); |
1691 | do { | 1667 | do { |
1692 | stat = RD_REG_DWORD(®->host_status); | 1668 | stat = RD_REG_DWORD(®->host_status); |
1693 | if (stat & HSRX_RISC_PAUSED) { | 1669 | if (stat & HSRX_RISC_PAUSED) { |
1694 | if (pci_channel_offline(ha->pdev)) | 1670 | if (pci_channel_offline(ha->pdev)) |
1695 | break; | 1671 | break; |
1696 | 1672 | ||
1673 | if (ha->hw_event_pause_errors == 0) | ||
1674 | qla2x00_post_hwe_work(ha, HW_EVENT_PARITY_ERR, | ||
1675 | 0, MSW(stat), LSW(stat)); | ||
1676 | else if (ha->hw_event_pause_errors < 0xffffffff) | ||
1677 | ha->hw_event_pause_errors++; | ||
1678 | |||
1697 | hccr = RD_REG_DWORD(®->hccr); | 1679 | hccr = RD_REG_DWORD(®->hccr); |
1698 | 1680 | ||
1699 | qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, " | 1681 | qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, " |
@@ -1734,7 +1716,7 @@ qla24xx_msix_default(int irq, void *dev_id) | |||
1734 | } | 1716 | } |
1735 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | 1717 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); |
1736 | } while (0); | 1718 | } while (0); |
1737 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 1719 | spin_unlock(&ha->hardware_lock); |
1738 | 1720 | ||
1739 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && | 1721 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && |
1740 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { | 1722 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { |
@@ -1821,10 +1803,9 @@ qla2x00_request_irqs(scsi_qla_host_t *ha) | |||
1821 | { | 1803 | { |
1822 | int ret; | 1804 | int ret; |
1823 | device_reg_t __iomem *reg = ha->iobase; | 1805 | device_reg_t __iomem *reg = ha->iobase; |
1824 | unsigned long flags; | ||
1825 | 1806 | ||
1826 | /* If possible, enable MSI-X. */ | 1807 | /* If possible, enable MSI-X. */ |
1827 | if (!IS_QLA2432(ha) && !IS_QLA2532(ha)) | 1808 | if (!IS_QLA2432(ha) && !IS_QLA2532(ha) && !IS_QLA8432(ha)) |
1828 | goto skip_msix; | 1809 | goto skip_msix; |
1829 | 1810 | ||
1830 | if (IS_QLA2432(ha) && (ha->chip_revision < QLA_MSIX_CHIP_REV_24XX || | 1811 | if (IS_QLA2432(ha) && (ha->chip_revision < QLA_MSIX_CHIP_REV_24XX || |
@@ -1859,7 +1840,7 @@ qla2x00_request_irqs(scsi_qla_host_t *ha) | |||
1859 | "MSI-X: Falling back-to INTa mode -- %d.\n", ret); | 1840 | "MSI-X: Falling back-to INTa mode -- %d.\n", ret); |
1860 | skip_msix: | 1841 | skip_msix: |
1861 | 1842 | ||
1862 | if (!IS_QLA24XX(ha) && !IS_QLA2532(ha)) | 1843 | if (!IS_QLA24XX(ha) && !IS_QLA2532(ha) && !IS_QLA8432(ha)) |
1863 | goto skip_msi; | 1844 | goto skip_msi; |
1864 | 1845 | ||
1865 | ret = pci_enable_msi(ha->pdev); | 1846 | ret = pci_enable_msi(ha->pdev); |
@@ -1882,7 +1863,7 @@ skip_msi: | |||
1882 | clear_risc_ints: | 1863 | clear_risc_ints: |
1883 | 1864 | ||
1884 | ha->isp_ops->disable_intrs(ha); | 1865 | ha->isp_ops->disable_intrs(ha); |
1885 | spin_lock_irqsave(&ha->hardware_lock, flags); | 1866 | spin_lock_irq(&ha->hardware_lock); |
1886 | if (IS_FWI2_CAPABLE(ha)) { | 1867 | if (IS_FWI2_CAPABLE(ha)) { |
1887 | WRT_REG_DWORD(®->isp24.hccr, HCCRX_CLR_HOST_INT); | 1868 | WRT_REG_DWORD(®->isp24.hccr, HCCRX_CLR_HOST_INT); |
1888 | WRT_REG_DWORD(®->isp24.hccr, HCCRX_CLR_RISC_INT); | 1869 | WRT_REG_DWORD(®->isp24.hccr, HCCRX_CLR_RISC_INT); |
@@ -1891,7 +1872,7 @@ clear_risc_ints: | |||
1891 | WRT_REG_WORD(®->isp.hccr, HCCR_CLR_RISC_INT); | 1872 | WRT_REG_WORD(®->isp.hccr, HCCR_CLR_RISC_INT); |
1892 | WRT_REG_WORD(®->isp.hccr, HCCR_CLR_HOST_INT); | 1873 | WRT_REG_WORD(®->isp.hccr, HCCR_CLR_HOST_INT); |
1893 | } | 1874 | } |
1894 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 1875 | spin_unlock_irq(&ha->hardware_lock); |
1895 | ha->isp_ops->enable_intrs(ha); | 1876 | ha->isp_ops->enable_intrs(ha); |
1896 | 1877 | ||
1897 | fail: | 1878 | fail: |
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index bb103580e1ba..7d0a8a4c7719 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -310,7 +310,7 @@ qla2x00_load_ram(scsi_qla_host_t *ha, dma_addr_t req_dma, uint32_t risc_addr, | |||
310 | } | 310 | } |
311 | 311 | ||
312 | mcp->in_mb = MBX_0; | 312 | mcp->in_mb = MBX_0; |
313 | mcp->tov = 30; | 313 | mcp->tov = MBX_TOV_SECONDS; |
314 | mcp->flags = 0; | 314 | mcp->flags = 0; |
315 | rval = qla2x00_mailbox_command(ha, mcp); | 315 | rval = qla2x00_mailbox_command(ha, mcp); |
316 | 316 | ||
@@ -367,7 +367,7 @@ qla2x00_execute_fw(scsi_qla_host_t *ha, uint32_t risc_addr) | |||
367 | } | 367 | } |
368 | } | 368 | } |
369 | 369 | ||
370 | mcp->tov = 30; | 370 | mcp->tov = MBX_TOV_SECONDS; |
371 | mcp->flags = 0; | 371 | mcp->flags = 0; |
372 | rval = qla2x00_mailbox_command(ha, mcp); | 372 | rval = qla2x00_mailbox_command(ha, mcp); |
373 | 373 | ||
@@ -417,7 +417,7 @@ qla2x00_get_fw_version(scsi_qla_host_t *ha, uint16_t *major, uint16_t *minor, | |||
417 | mcp->out_mb = MBX_0; | 417 | mcp->out_mb = MBX_0; |
418 | mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; | 418 | mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; |
419 | mcp->flags = 0; | 419 | mcp->flags = 0; |
420 | mcp->tov = 30; | 420 | mcp->tov = MBX_TOV_SECONDS; |
421 | rval = qla2x00_mailbox_command(ha, mcp); | 421 | rval = qla2x00_mailbox_command(ha, mcp); |
422 | 422 | ||
423 | /* Return mailbox data. */ | 423 | /* Return mailbox data. */ |
@@ -466,7 +466,7 @@ qla2x00_get_fw_options(scsi_qla_host_t *ha, uint16_t *fwopts) | |||
466 | mcp->mb[0] = MBC_GET_FIRMWARE_OPTION; | 466 | mcp->mb[0] = MBC_GET_FIRMWARE_OPTION; |
467 | mcp->out_mb = MBX_0; | 467 | mcp->out_mb = MBX_0; |
468 | mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0; | 468 | mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0; |
469 | mcp->tov = 30; | 469 | mcp->tov = MBX_TOV_SECONDS; |
470 | mcp->flags = 0; | 470 | mcp->flags = 0; |
471 | rval = qla2x00_mailbox_command(ha, mcp); | 471 | rval = qla2x00_mailbox_command(ha, mcp); |
472 | 472 | ||
@@ -524,7 +524,7 @@ qla2x00_set_fw_options(scsi_qla_host_t *ha, uint16_t *fwopts) | |||
524 | mcp->mb[12] = 0; /* Undocumented, but used */ | 524 | mcp->mb[12] = 0; /* Undocumented, but used */ |
525 | mcp->out_mb |= MBX_12|MBX_11|MBX_10; | 525 | mcp->out_mb |= MBX_12|MBX_11|MBX_10; |
526 | } | 526 | } |
527 | mcp->tov = 30; | 527 | mcp->tov = MBX_TOV_SECONDS; |
528 | mcp->flags = 0; | 528 | mcp->flags = 0; |
529 | rval = qla2x00_mailbox_command(ha, mcp); | 529 | rval = qla2x00_mailbox_command(ha, mcp); |
530 | 530 | ||
@@ -576,7 +576,7 @@ qla2x00_mbx_reg_test(scsi_qla_host_t *ha) | |||
576 | mcp->mb[7] = 0x2525; | 576 | mcp->mb[7] = 0x2525; |
577 | mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; | 577 | mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; |
578 | mcp->in_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; | 578 | mcp->in_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; |
579 | mcp->tov = 30; | 579 | mcp->tov = MBX_TOV_SECONDS; |
580 | mcp->flags = 0; | 580 | mcp->flags = 0; |
581 | rval = qla2x00_mailbox_command(ha, mcp); | 581 | rval = qla2x00_mailbox_command(ha, mcp); |
582 | 582 | ||
@@ -587,6 +587,14 @@ qla2x00_mbx_reg_test(scsi_qla_host_t *ha) | |||
587 | if (mcp->mb[5] != 0xA5A5 || mcp->mb[6] != 0x5A5A || | 587 | if (mcp->mb[5] != 0xA5A5 || mcp->mb[6] != 0x5A5A || |
588 | mcp->mb[7] != 0x2525) | 588 | mcp->mb[7] != 0x2525) |
589 | rval = QLA_FUNCTION_FAILED; | 589 | rval = QLA_FUNCTION_FAILED; |
590 | if (rval == QLA_FUNCTION_FAILED) { | ||
591 | struct device_reg_24xx __iomem *reg = | ||
592 | &ha->iobase->isp24; | ||
593 | |||
594 | qla2xxx_hw_event_log(ha, HW_EVENT_ISP_ERR, 0, | ||
595 | LSW(RD_REG_DWORD(®->hccr)), | ||
596 | LSW(RD_REG_DWORD(®->istatus))); | ||
597 | } | ||
590 | } | 598 | } |
591 | 599 | ||
592 | if (rval != QLA_SUCCESS) { | 600 | if (rval != QLA_SUCCESS) { |
@@ -640,7 +648,7 @@ qla2x00_verify_checksum(scsi_qla_host_t *ha, uint32_t risc_addr) | |||
640 | mcp->in_mb |= MBX_1; | 648 | mcp->in_mb |= MBX_1; |
641 | } | 649 | } |
642 | 650 | ||
643 | mcp->tov = 30; | 651 | mcp->tov = MBX_TOV_SECONDS; |
644 | mcp->flags = 0; | 652 | mcp->flags = 0; |
645 | rval = qla2x00_mailbox_command(ha, mcp); | 653 | rval = qla2x00_mailbox_command(ha, mcp); |
646 | 654 | ||
@@ -674,8 +682,8 @@ qla2x00_verify_checksum(scsi_qla_host_t *ha, uint32_t risc_addr) | |||
674 | * Kernel context. | 682 | * Kernel context. |
675 | */ | 683 | */ |
676 | int | 684 | int |
677 | qla2x00_issue_iocb(scsi_qla_host_t *ha, void* buffer, dma_addr_t phys_addr, | 685 | qla2x00_issue_iocb_timeout(scsi_qla_host_t *ha, void *buffer, |
678 | size_t size) | 686 | dma_addr_t phys_addr, size_t size, uint32_t tov) |
679 | { | 687 | { |
680 | int rval; | 688 | int rval; |
681 | mbx_cmd_t mc; | 689 | mbx_cmd_t mc; |
@@ -689,7 +697,7 @@ qla2x00_issue_iocb(scsi_qla_host_t *ha, void* buffer, dma_addr_t phys_addr, | |||
689 | mcp->mb[7] = LSW(MSD(phys_addr)); | 697 | mcp->mb[7] = LSW(MSD(phys_addr)); |
690 | mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; | 698 | mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; |
691 | mcp->in_mb = MBX_2|MBX_0; | 699 | mcp->in_mb = MBX_2|MBX_0; |
692 | mcp->tov = 30; | 700 | mcp->tov = tov; |
693 | mcp->flags = 0; | 701 | mcp->flags = 0; |
694 | rval = qla2x00_mailbox_command(ha, mcp); | 702 | rval = qla2x00_mailbox_command(ha, mcp); |
695 | 703 | ||
@@ -710,6 +718,14 @@ qla2x00_issue_iocb(scsi_qla_host_t *ha, void* buffer, dma_addr_t phys_addr, | |||
710 | return rval; | 718 | return rval; |
711 | } | 719 | } |
712 | 720 | ||
721 | int | ||
722 | qla2x00_issue_iocb(scsi_qla_host_t *ha, void *buffer, dma_addr_t phys_addr, | ||
723 | size_t size) | ||
724 | { | ||
725 | return qla2x00_issue_iocb_timeout(ha, buffer, phys_addr, size, | ||
726 | MBX_TOV_SECONDS); | ||
727 | } | ||
728 | |||
713 | /* | 729 | /* |
714 | * qla2x00_abort_command | 730 | * qla2x00_abort_command |
715 | * Abort command aborts a specified IOCB. | 731 | * Abort command aborts a specified IOCB. |
@@ -760,7 +776,7 @@ qla2x00_abort_command(scsi_qla_host_t *ha, srb_t *sp) | |||
760 | mcp->mb[6] = (uint16_t)sp->cmd->device->lun; | 776 | mcp->mb[6] = (uint16_t)sp->cmd->device->lun; |
761 | mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; | 777 | mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; |
762 | mcp->in_mb = MBX_0; | 778 | mcp->in_mb = MBX_0; |
763 | mcp->tov = 30; | 779 | mcp->tov = MBX_TOV_SECONDS; |
764 | mcp->flags = 0; | 780 | mcp->flags = 0; |
765 | rval = qla2x00_mailbox_command(ha, mcp); | 781 | rval = qla2x00_mailbox_command(ha, mcp); |
766 | 782 | ||
@@ -776,36 +792,20 @@ qla2x00_abort_command(scsi_qla_host_t *ha, srb_t *sp) | |||
776 | return rval; | 792 | return rval; |
777 | } | 793 | } |
778 | 794 | ||
779 | #if USE_ABORT_TGT | ||
780 | /* | ||
781 | * qla2x00_abort_target | ||
782 | * Issue abort target mailbox command. | ||
783 | * | ||
784 | * Input: | ||
785 | * ha = adapter block pointer. | ||
786 | * | ||
787 | * Returns: | ||
788 | * qla2x00 local function return status code. | ||
789 | * | ||
790 | * Context: | ||
791 | * Kernel context. | ||
792 | */ | ||
793 | int | 795 | int |
794 | qla2x00_abort_target(fc_port_t *fcport) | 796 | qla2x00_abort_target(struct fc_port *fcport, unsigned int l) |
795 | { | 797 | { |
796 | int rval; | 798 | int rval, rval2; |
797 | mbx_cmd_t mc; | 799 | mbx_cmd_t mc; |
798 | mbx_cmd_t *mcp = &mc; | 800 | mbx_cmd_t *mcp = &mc; |
799 | scsi_qla_host_t *ha; | 801 | scsi_qla_host_t *ha; |
800 | 802 | ||
801 | if (fcport == NULL) | ||
802 | return 0; | ||
803 | |||
804 | DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no)); | 803 | DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no)); |
805 | 804 | ||
805 | l = l; | ||
806 | ha = fcport->ha; | 806 | ha = fcport->ha; |
807 | mcp->mb[0] = MBC_ABORT_TARGET; | 807 | mcp->mb[0] = MBC_ABORT_TARGET; |
808 | mcp->out_mb = MBX_2|MBX_1|MBX_0; | 808 | mcp->out_mb = MBX_9|MBX_2|MBX_1|MBX_0; |
809 | if (HAS_EXTENDED_IDS(ha)) { | 809 | if (HAS_EXTENDED_IDS(ha)) { |
810 | mcp->mb[1] = fcport->loop_id; | 810 | mcp->mb[1] = fcport->loop_id; |
811 | mcp->mb[10] = 0; | 811 | mcp->mb[10] = 0; |
@@ -814,27 +814,70 @@ qla2x00_abort_target(fc_port_t *fcport) | |||
814 | mcp->mb[1] = fcport->loop_id << 8; | 814 | mcp->mb[1] = fcport->loop_id << 8; |
815 | } | 815 | } |
816 | mcp->mb[2] = ha->loop_reset_delay; | 816 | mcp->mb[2] = ha->loop_reset_delay; |
817 | mcp->mb[9] = ha->vp_idx; | ||
817 | 818 | ||
818 | mcp->in_mb = MBX_0; | 819 | mcp->in_mb = MBX_0; |
819 | mcp->tov = 30; | 820 | mcp->tov = MBX_TOV_SECONDS; |
820 | mcp->flags = 0; | 821 | mcp->flags = 0; |
821 | rval = qla2x00_mailbox_command(ha, mcp); | 822 | rval = qla2x00_mailbox_command(ha, mcp); |
823 | if (rval != QLA_SUCCESS) { | ||
824 | DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__, | ||
825 | ha->host_no, rval)); | ||
826 | } | ||
822 | 827 | ||
823 | /* Issue marker command. */ | 828 | /* Issue marker IOCB. */ |
824 | ha->marker_needed = 1; | 829 | rval2 = qla2x00_marker(ha, fcport->loop_id, 0, MK_SYNC_ID); |
830 | if (rval2 != QLA_SUCCESS) { | ||
831 | DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB " | ||
832 | "(%x).\n", __func__, ha->host_no, rval2)); | ||
833 | } else { | ||
834 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); | ||
835 | } | ||
836 | |||
837 | return rval; | ||
838 | } | ||
839 | |||
840 | int | ||
841 | qla2x00_lun_reset(struct fc_port *fcport, unsigned int l) | ||
842 | { | ||
843 | int rval, rval2; | ||
844 | mbx_cmd_t mc; | ||
845 | mbx_cmd_t *mcp = &mc; | ||
846 | scsi_qla_host_t *ha; | ||
847 | |||
848 | DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no)); | ||
849 | |||
850 | ha = fcport->ha; | ||
851 | mcp->mb[0] = MBC_LUN_RESET; | ||
852 | mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0; | ||
853 | if (HAS_EXTENDED_IDS(ha)) | ||
854 | mcp->mb[1] = fcport->loop_id; | ||
855 | else | ||
856 | mcp->mb[1] = fcport->loop_id << 8; | ||
857 | mcp->mb[2] = l; | ||
858 | mcp->mb[3] = 0; | ||
859 | mcp->mb[9] = ha->vp_idx; | ||
825 | 860 | ||
861 | mcp->in_mb = MBX_0; | ||
862 | mcp->tov = MBX_TOV_SECONDS; | ||
863 | mcp->flags = 0; | ||
864 | rval = qla2x00_mailbox_command(ha, mcp); | ||
826 | if (rval != QLA_SUCCESS) { | 865 | if (rval != QLA_SUCCESS) { |
827 | DEBUG2_3_11(printk("qla2x00_abort_target(%ld): failed=%x.\n", | 866 | DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__, |
828 | ha->host_no, rval)); | 867 | ha->host_no, rval)); |
868 | } | ||
869 | |||
870 | /* Issue marker IOCB. */ | ||
871 | rval2 = qla2x00_marker(ha, fcport->loop_id, l, MK_SYNC_ID_LUN); | ||
872 | if (rval2 != QLA_SUCCESS) { | ||
873 | DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB " | ||
874 | "(%x).\n", __func__, ha->host_no, rval2)); | ||
829 | } else { | 875 | } else { |
830 | /*EMPTY*/ | 876 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); |
831 | DEBUG11(printk("qla2x00_abort_target(%ld): done.\n", | ||
832 | ha->host_no)); | ||
833 | } | 877 | } |
834 | 878 | ||
835 | return rval; | 879 | return rval; |
836 | } | 880 | } |
837 | #endif | ||
838 | 881 | ||
839 | /* | 882 | /* |
840 | * qla2x00_get_adapter_id | 883 | * qla2x00_get_adapter_id |
@@ -871,7 +914,7 @@ qla2x00_get_adapter_id(scsi_qla_host_t *ha, uint16_t *id, uint8_t *al_pa, | |||
871 | mcp->mb[9] = ha->vp_idx; | 914 | mcp->mb[9] = ha->vp_idx; |
872 | mcp->out_mb = MBX_9|MBX_0; | 915 | mcp->out_mb = MBX_9|MBX_0; |
873 | mcp->in_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; | 916 | mcp->in_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; |
874 | mcp->tov = 30; | 917 | mcp->tov = MBX_TOV_SECONDS; |
875 | mcp->flags = 0; | 918 | mcp->flags = 0; |
876 | rval = qla2x00_mailbox_command(ha, mcp); | 919 | rval = qla2x00_mailbox_command(ha, mcp); |
877 | if (mcp->mb[0] == MBS_COMMAND_ERROR) | 920 | if (mcp->mb[0] == MBS_COMMAND_ERROR) |
@@ -928,7 +971,7 @@ qla2x00_get_retry_cnt(scsi_qla_host_t *ha, uint8_t *retry_cnt, uint8_t *tov, | |||
928 | mcp->mb[0] = MBC_GET_RETRY_COUNT; | 971 | mcp->mb[0] = MBC_GET_RETRY_COUNT; |
929 | mcp->out_mb = MBX_0; | 972 | mcp->out_mb = MBX_0; |
930 | mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0; | 973 | mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0; |
931 | mcp->tov = 30; | 974 | mcp->tov = MBX_TOV_SECONDS; |
932 | mcp->flags = 0; | 975 | mcp->flags = 0; |
933 | rval = qla2x00_mailbox_command(ha, mcp); | 976 | rval = qla2x00_mailbox_command(ha, mcp); |
934 | 977 | ||
@@ -995,7 +1038,7 @@ qla2x00_init_firmware(scsi_qla_host_t *ha, uint16_t size) | |||
995 | mcp->in_mb = MBX_5|MBX_4|MBX_0; | 1038 | mcp->in_mb = MBX_5|MBX_4|MBX_0; |
996 | mcp->buf_size = size; | 1039 | mcp->buf_size = size; |
997 | mcp->flags = MBX_DMA_OUT; | 1040 | mcp->flags = MBX_DMA_OUT; |
998 | mcp->tov = 30; | 1041 | mcp->tov = MBX_TOV_SECONDS; |
999 | rval = qla2x00_mailbox_command(ha, mcp); | 1042 | rval = qla2x00_mailbox_command(ha, mcp); |
1000 | 1043 | ||
1001 | if (rval != QLA_SUCCESS) { | 1044 | if (rval != QLA_SUCCESS) { |
@@ -1173,7 +1216,7 @@ gpd_error_out: | |||
1173 | * Kernel context. | 1216 | * Kernel context. |
1174 | */ | 1217 | */ |
1175 | int | 1218 | int |
1176 | qla2x00_get_firmware_state(scsi_qla_host_t *ha, uint16_t *dptr) | 1219 | qla2x00_get_firmware_state(scsi_qla_host_t *ha, uint16_t *states) |
1177 | { | 1220 | { |
1178 | int rval; | 1221 | int rval; |
1179 | mbx_cmd_t mc; | 1222 | mbx_cmd_t mc; |
@@ -1184,13 +1227,15 @@ qla2x00_get_firmware_state(scsi_qla_host_t *ha, uint16_t *dptr) | |||
1184 | 1227 | ||
1185 | mcp->mb[0] = MBC_GET_FIRMWARE_STATE; | 1228 | mcp->mb[0] = MBC_GET_FIRMWARE_STATE; |
1186 | mcp->out_mb = MBX_0; | 1229 | mcp->out_mb = MBX_0; |
1187 | mcp->in_mb = MBX_2|MBX_1|MBX_0; | 1230 | mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0; |
1188 | mcp->tov = 30; | 1231 | mcp->tov = MBX_TOV_SECONDS; |
1189 | mcp->flags = 0; | 1232 | mcp->flags = 0; |
1190 | rval = qla2x00_mailbox_command(ha, mcp); | 1233 | rval = qla2x00_mailbox_command(ha, mcp); |
1191 | 1234 | ||
1192 | /* Return firmware state. */ | 1235 | /* Return firmware states. */ |
1193 | *dptr = mcp->mb[1]; | 1236 | states[0] = mcp->mb[1]; |
1237 | states[1] = mcp->mb[2]; | ||
1238 | states[2] = mcp->mb[3]; | ||
1194 | 1239 | ||
1195 | if (rval != QLA_SUCCESS) { | 1240 | if (rval != QLA_SUCCESS) { |
1196 | /*EMPTY*/ | 1241 | /*EMPTY*/ |
@@ -1246,7 +1291,7 @@ qla2x00_get_port_name(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t *name, | |||
1246 | } | 1291 | } |
1247 | 1292 | ||
1248 | mcp->in_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; | 1293 | mcp->in_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; |
1249 | mcp->tov = 30; | 1294 | mcp->tov = MBX_TOV_SECONDS; |
1250 | mcp->flags = 0; | 1295 | mcp->flags = 0; |
1251 | rval = qla2x00_mailbox_command(ha, mcp); | 1296 | rval = qla2x00_mailbox_command(ha, mcp); |
1252 | 1297 | ||
@@ -1318,7 +1363,7 @@ qla2x00_lip_reset(scsi_qla_host_t *ha) | |||
1318 | mcp->mb[3] = 0; | 1363 | mcp->mb[3] = 0; |
1319 | } | 1364 | } |
1320 | mcp->in_mb = MBX_0; | 1365 | mcp->in_mb = MBX_0; |
1321 | mcp->tov = 30; | 1366 | mcp->tov = MBX_TOV_SECONDS; |
1322 | mcp->flags = 0; | 1367 | mcp->flags = 0; |
1323 | rval = qla2x00_mailbox_command(ha, mcp); | 1368 | rval = qla2x00_mailbox_command(ha, mcp); |
1324 | 1369 | ||
@@ -1743,7 +1788,7 @@ qla2x00_fabric_logout(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain, | |||
1743 | } | 1788 | } |
1744 | 1789 | ||
1745 | mcp->in_mb = MBX_1|MBX_0; | 1790 | mcp->in_mb = MBX_1|MBX_0; |
1746 | mcp->tov = 30; | 1791 | mcp->tov = MBX_TOV_SECONDS; |
1747 | mcp->flags = 0; | 1792 | mcp->flags = 0; |
1748 | rval = qla2x00_mailbox_command(ha, mcp); | 1793 | rval = qla2x00_mailbox_command(ha, mcp); |
1749 | 1794 | ||
@@ -1791,7 +1836,7 @@ qla2x00_full_login_lip(scsi_qla_host_t *ha) | |||
1791 | mcp->mb[3] = 0; | 1836 | mcp->mb[3] = 0; |
1792 | mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; | 1837 | mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; |
1793 | mcp->in_mb = MBX_0; | 1838 | mcp->in_mb = MBX_0; |
1794 | mcp->tov = 30; | 1839 | mcp->tov = MBX_TOV_SECONDS; |
1795 | mcp->flags = 0; | 1840 | mcp->flags = 0; |
1796 | rval = qla2x00_mailbox_command(ha, mcp); | 1841 | rval = qla2x00_mailbox_command(ha, mcp); |
1797 | 1842 | ||
@@ -1852,7 +1897,7 @@ qla2x00_get_id_list(scsi_qla_host_t *ha, void *id_list, dma_addr_t id_list_dma, | |||
1852 | mcp->out_mb |= MBX_6|MBX_3|MBX_2|MBX_1; | 1897 | mcp->out_mb |= MBX_6|MBX_3|MBX_2|MBX_1; |
1853 | } | 1898 | } |
1854 | mcp->in_mb = MBX_1|MBX_0; | 1899 | mcp->in_mb = MBX_1|MBX_0; |
1855 | mcp->tov = 30; | 1900 | mcp->tov = MBX_TOV_SECONDS; |
1856 | mcp->flags = 0; | 1901 | mcp->flags = 0; |
1857 | rval = qla2x00_mailbox_command(ha, mcp); | 1902 | rval = qla2x00_mailbox_command(ha, mcp); |
1858 | 1903 | ||
@@ -1896,7 +1941,7 @@ qla2x00_get_resource_cnts(scsi_qla_host_t *ha, uint16_t *cur_xchg_cnt, | |||
1896 | mcp->mb[0] = MBC_GET_RESOURCE_COUNTS; | 1941 | mcp->mb[0] = MBC_GET_RESOURCE_COUNTS; |
1897 | mcp->out_mb = MBX_0; | 1942 | mcp->out_mb = MBX_0; |
1898 | mcp->in_mb = MBX_11|MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; | 1943 | mcp->in_mb = MBX_11|MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; |
1899 | mcp->tov = 30; | 1944 | mcp->tov = MBX_TOV_SECONDS; |
1900 | mcp->flags = 0; | 1945 | mcp->flags = 0; |
1901 | rval = qla2x00_mailbox_command(ha, mcp); | 1946 | rval = qla2x00_mailbox_command(ha, mcp); |
1902 | 1947 | ||
@@ -2036,7 +2081,7 @@ qla2x00_get_link_status(scsi_qla_host_t *ha, uint16_t loop_id, | |||
2036 | mcp->mb[1] = loop_id << 8; | 2081 | mcp->mb[1] = loop_id << 8; |
2037 | mcp->out_mb |= MBX_1; | 2082 | mcp->out_mb |= MBX_1; |
2038 | } | 2083 | } |
2039 | mcp->tov = 30; | 2084 | mcp->tov = MBX_TOV_SECONDS; |
2040 | mcp->flags = IOCTL_CMD; | 2085 | mcp->flags = IOCTL_CMD; |
2041 | rval = qla2x00_mailbox_command(ha, mcp); | 2086 | rval = qla2x00_mailbox_command(ha, mcp); |
2042 | 2087 | ||
@@ -2082,7 +2127,7 @@ qla24xx_get_isp_stats(scsi_qla_host_t *ha, struct link_statistics *stats, | |||
2082 | mcp->mb[10] = 0; | 2127 | mcp->mb[10] = 0; |
2083 | mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; | 2128 | mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; |
2084 | mcp->in_mb = MBX_2|MBX_1|MBX_0; | 2129 | mcp->in_mb = MBX_2|MBX_1|MBX_0; |
2085 | mcp->tov = 30; | 2130 | mcp->tov = MBX_TOV_SECONDS; |
2086 | mcp->flags = IOCTL_CMD; | 2131 | mcp->flags = IOCTL_CMD; |
2087 | rval = qla2x00_mailbox_command(ha, mcp); | 2132 | rval = qla2x00_mailbox_command(ha, mcp); |
2088 | 2133 | ||
@@ -2180,17 +2225,15 @@ struct tsk_mgmt_cmd { | |||
2180 | } p; | 2225 | } p; |
2181 | }; | 2226 | }; |
2182 | 2227 | ||
2183 | int | 2228 | static int |
2184 | qla24xx_abort_target(fc_port_t *fcport) | 2229 | __qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport, |
2230 | unsigned int l) | ||
2185 | { | 2231 | { |
2186 | int rval; | 2232 | int rval, rval2; |
2187 | struct tsk_mgmt_cmd *tsk; | 2233 | struct tsk_mgmt_cmd *tsk; |
2188 | dma_addr_t tsk_dma; | 2234 | dma_addr_t tsk_dma; |
2189 | scsi_qla_host_t *ha, *pha; | 2235 | scsi_qla_host_t *ha, *pha; |
2190 | 2236 | ||
2191 | if (fcport == NULL) | ||
2192 | return 0; | ||
2193 | |||
2194 | DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no)); | 2237 | DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no)); |
2195 | 2238 | ||
2196 | ha = fcport->ha; | 2239 | ha = fcport->ha; |
@@ -2207,47 +2250,61 @@ qla24xx_abort_target(fc_port_t *fcport) | |||
2207 | tsk->p.tsk.entry_count = 1; | 2250 | tsk->p.tsk.entry_count = 1; |
2208 | tsk->p.tsk.nport_handle = cpu_to_le16(fcport->loop_id); | 2251 | tsk->p.tsk.nport_handle = cpu_to_le16(fcport->loop_id); |
2209 | tsk->p.tsk.timeout = cpu_to_le16(ha->r_a_tov / 10 * 2); | 2252 | tsk->p.tsk.timeout = cpu_to_le16(ha->r_a_tov / 10 * 2); |
2210 | tsk->p.tsk.control_flags = __constant_cpu_to_le32(TCF_TARGET_RESET); | 2253 | tsk->p.tsk.control_flags = cpu_to_le32(type); |
2211 | tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa; | 2254 | tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa; |
2212 | tsk->p.tsk.port_id[1] = fcport->d_id.b.area; | 2255 | tsk->p.tsk.port_id[1] = fcport->d_id.b.area; |
2213 | tsk->p.tsk.port_id[2] = fcport->d_id.b.domain; | 2256 | tsk->p.tsk.port_id[2] = fcport->d_id.b.domain; |
2214 | tsk->p.tsk.vp_index = fcport->vp_idx; | 2257 | tsk->p.tsk.vp_index = fcport->vp_idx; |
2258 | if (type == TCF_LUN_RESET) { | ||
2259 | int_to_scsilun(l, &tsk->p.tsk.lun); | ||
2260 | host_to_fcp_swap((uint8_t *)&tsk->p.tsk.lun, | ||
2261 | sizeof(tsk->p.tsk.lun)); | ||
2262 | } | ||
2215 | 2263 | ||
2216 | rval = qla2x00_issue_iocb(ha, tsk, tsk_dma, 0); | 2264 | rval = qla2x00_issue_iocb(ha, tsk, tsk_dma, 0); |
2217 | if (rval != QLA_SUCCESS) { | 2265 | if (rval != QLA_SUCCESS) { |
2218 | DEBUG2_3_11(printk("%s(%ld): failed to issue Target Reset IOCB " | 2266 | DEBUG2_3_11(printk("%s(%ld): failed to issue %s Reset IOCB " |
2219 | "(%x).\n", __func__, ha->host_no, rval)); | 2267 | "(%x).\n", __func__, ha->host_no, name, rval)); |
2220 | goto atarget_done; | ||
2221 | } else if (tsk->p.sts.entry_status != 0) { | 2268 | } else if (tsk->p.sts.entry_status != 0) { |
2222 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " | 2269 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " |
2223 | "-- error status (%x).\n", __func__, ha->host_no, | 2270 | "-- error status (%x).\n", __func__, ha->host_no, |
2224 | tsk->p.sts.entry_status)); | 2271 | tsk->p.sts.entry_status)); |
2225 | rval = QLA_FUNCTION_FAILED; | 2272 | rval = QLA_FUNCTION_FAILED; |
2226 | goto atarget_done; | ||
2227 | } else if (tsk->p.sts.comp_status != | 2273 | } else if (tsk->p.sts.comp_status != |
2228 | __constant_cpu_to_le16(CS_COMPLETE)) { | 2274 | __constant_cpu_to_le16(CS_COMPLETE)) { |
2229 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " | 2275 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " |
2230 | "-- completion status (%x).\n", __func__, | 2276 | "-- completion status (%x).\n", __func__, |
2231 | ha->host_no, le16_to_cpu(tsk->p.sts.comp_status))); | 2277 | ha->host_no, le16_to_cpu(tsk->p.sts.comp_status))); |
2232 | rval = QLA_FUNCTION_FAILED; | 2278 | rval = QLA_FUNCTION_FAILED; |
2233 | goto atarget_done; | ||
2234 | } | 2279 | } |
2235 | 2280 | ||
2236 | /* Issue marker IOCB. */ | 2281 | /* Issue marker IOCB. */ |
2237 | rval = qla2x00_marker(ha, fcport->loop_id, 0, MK_SYNC_ID); | 2282 | rval2 = qla2x00_marker(ha, fcport->loop_id, l, |
2238 | if (rval != QLA_SUCCESS) { | 2283 | type == TCF_LUN_RESET ? MK_SYNC_ID_LUN: MK_SYNC_ID); |
2284 | if (rval2 != QLA_SUCCESS) { | ||
2239 | DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB " | 2285 | DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB " |
2240 | "(%x).\n", __func__, ha->host_no, rval)); | 2286 | "(%x).\n", __func__, ha->host_no, rval2)); |
2241 | } else { | 2287 | } else { |
2242 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); | 2288 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); |
2243 | } | 2289 | } |
2244 | 2290 | ||
2245 | atarget_done: | ||
2246 | dma_pool_free(pha->s_dma_pool, tsk, tsk_dma); | 2291 | dma_pool_free(pha->s_dma_pool, tsk, tsk_dma); |
2247 | 2292 | ||
2248 | return rval; | 2293 | return rval; |
2249 | } | 2294 | } |
2250 | 2295 | ||
2296 | int | ||
2297 | qla24xx_abort_target(struct fc_port *fcport, unsigned int l) | ||
2298 | { | ||
2299 | return __qla24xx_issue_tmf("Target", TCF_TARGET_RESET, fcport, l); | ||
2300 | } | ||
2301 | |||
2302 | int | ||
2303 | qla24xx_lun_reset(struct fc_port *fcport, unsigned int l) | ||
2304 | { | ||
2305 | return __qla24xx_issue_tmf("Lun", TCF_LUN_RESET, fcport, l); | ||
2306 | } | ||
2307 | |||
2251 | #if 0 | 2308 | #if 0 |
2252 | 2309 | ||
2253 | int | 2310 | int |
@@ -2304,7 +2361,7 @@ qla2x00_set_serdes_params(scsi_qla_host_t *ha, uint16_t sw_em_1g, | |||
2304 | mcp->mb[4] = sw_em_4g | BIT_15; | 2361 | mcp->mb[4] = sw_em_4g | BIT_15; |
2305 | mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; | 2362 | mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; |
2306 | mcp->in_mb = MBX_0; | 2363 | mcp->in_mb = MBX_0; |
2307 | mcp->tov = 30; | 2364 | mcp->tov = MBX_TOV_SECONDS; |
2308 | mcp->flags = 0; | 2365 | mcp->flags = 0; |
2309 | rval = qla2x00_mailbox_command(ha, mcp); | 2366 | rval = qla2x00_mailbox_command(ha, mcp); |
2310 | 2367 | ||
@@ -2372,7 +2429,7 @@ qla2x00_enable_eft_trace(scsi_qla_host_t *ha, dma_addr_t eft_dma, | |||
2372 | mcp->mb[7] = TC_AEN_DISABLE; | 2429 | mcp->mb[7] = TC_AEN_DISABLE; |
2373 | mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; | 2430 | mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; |
2374 | mcp->in_mb = MBX_1|MBX_0; | 2431 | mcp->in_mb = MBX_1|MBX_0; |
2375 | mcp->tov = 30; | 2432 | mcp->tov = MBX_TOV_SECONDS; |
2376 | mcp->flags = 0; | 2433 | mcp->flags = 0; |
2377 | rval = qla2x00_mailbox_command(ha, mcp); | 2434 | rval = qla2x00_mailbox_command(ha, mcp); |
2378 | if (rval != QLA_SUCCESS) { | 2435 | if (rval != QLA_SUCCESS) { |
@@ -2401,7 +2458,7 @@ qla2x00_disable_eft_trace(scsi_qla_host_t *ha) | |||
2401 | mcp->mb[1] = TC_EFT_DISABLE; | 2458 | mcp->mb[1] = TC_EFT_DISABLE; |
2402 | mcp->out_mb = MBX_1|MBX_0; | 2459 | mcp->out_mb = MBX_1|MBX_0; |
2403 | mcp->in_mb = MBX_1|MBX_0; | 2460 | mcp->in_mb = MBX_1|MBX_0; |
2404 | mcp->tov = 30; | 2461 | mcp->tov = MBX_TOV_SECONDS; |
2405 | mcp->flags = 0; | 2462 | mcp->flags = 0; |
2406 | rval = qla2x00_mailbox_command(ha, mcp); | 2463 | rval = qla2x00_mailbox_command(ha, mcp); |
2407 | if (rval != QLA_SUCCESS) { | 2464 | if (rval != QLA_SUCCESS) { |
@@ -2441,7 +2498,7 @@ qla2x00_enable_fce_trace(scsi_qla_host_t *ha, dma_addr_t fce_dma, | |||
2441 | mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2| | 2498 | mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2| |
2442 | MBX_1|MBX_0; | 2499 | MBX_1|MBX_0; |
2443 | mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; | 2500 | mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; |
2444 | mcp->tov = 30; | 2501 | mcp->tov = MBX_TOV_SECONDS; |
2445 | mcp->flags = 0; | 2502 | mcp->flags = 0; |
2446 | rval = qla2x00_mailbox_command(ha, mcp); | 2503 | rval = qla2x00_mailbox_command(ha, mcp); |
2447 | if (rval != QLA_SUCCESS) { | 2504 | if (rval != QLA_SUCCESS) { |
@@ -2477,7 +2534,7 @@ qla2x00_disable_fce_trace(scsi_qla_host_t *ha, uint64_t *wr, uint64_t *rd) | |||
2477 | mcp->out_mb = MBX_2|MBX_1|MBX_0; | 2534 | mcp->out_mb = MBX_2|MBX_1|MBX_0; |
2478 | mcp->in_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2| | 2535 | mcp->in_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2| |
2479 | MBX_1|MBX_0; | 2536 | MBX_1|MBX_0; |
2480 | mcp->tov = 30; | 2537 | mcp->tov = MBX_TOV_SECONDS; |
2481 | mcp->flags = 0; | 2538 | mcp->flags = 0; |
2482 | rval = qla2x00_mailbox_command(ha, mcp); | 2539 | rval = qla2x00_mailbox_command(ha, mcp); |
2483 | if (rval != QLA_SUCCESS) { | 2540 | if (rval != QLA_SUCCESS) { |
@@ -2525,7 +2582,7 @@ qla2x00_read_sfp(scsi_qla_host_t *ha, dma_addr_t sfp_dma, uint16_t addr, | |||
2525 | mcp->mb[10] = 0; | 2582 | mcp->mb[10] = 0; |
2526 | mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; | 2583 | mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; |
2527 | mcp->in_mb = MBX_0; | 2584 | mcp->in_mb = MBX_0; |
2528 | mcp->tov = 30; | 2585 | mcp->tov = MBX_TOV_SECONDS; |
2529 | mcp->flags = 0; | 2586 | mcp->flags = 0; |
2530 | rval = qla2x00_mailbox_command(ha, mcp); | 2587 | rval = qla2x00_mailbox_command(ha, mcp); |
2531 | 2588 | ||
@@ -2559,7 +2616,7 @@ qla2x00_set_idma_speed(scsi_qla_host_t *ha, uint16_t loop_id, | |||
2559 | mcp->mb[4] = mcp->mb[5] = 0; | 2616 | mcp->mb[4] = mcp->mb[5] = 0; |
2560 | mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; | 2617 | mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; |
2561 | mcp->in_mb = MBX_5|MBX_4|MBX_3|MBX_1|MBX_0; | 2618 | mcp->in_mb = MBX_5|MBX_4|MBX_3|MBX_1|MBX_0; |
2562 | mcp->tov = 30; | 2619 | mcp->tov = MBX_TOV_SECONDS; |
2563 | mcp->flags = 0; | 2620 | mcp->flags = 0; |
2564 | rval = qla2x00_mailbox_command(ha, mcp); | 2621 | rval = qla2x00_mailbox_command(ha, mcp); |
2565 | 2622 | ||
@@ -2877,7 +2934,7 @@ qla2x00_dump_ram(scsi_qla_host_t *ha, dma_addr_t req_dma, uint32_t addr, | |||
2877 | } | 2934 | } |
2878 | 2935 | ||
2879 | mcp->in_mb = MBX_0; | 2936 | mcp->in_mb = MBX_0; |
2880 | mcp->tov = 30; | 2937 | mcp->tov = MBX_TOV_SECONDS; |
2881 | mcp->flags = 0; | 2938 | mcp->flags = 0; |
2882 | rval = qla2x00_mailbox_command(ha, mcp); | 2939 | rval = qla2x00_mailbox_command(ha, mcp); |
2883 | 2940 | ||
@@ -2890,3 +2947,104 @@ qla2x00_dump_ram(scsi_qla_host_t *ha, dma_addr_t req_dma, uint32_t addr, | |||
2890 | 2947 | ||
2891 | return rval; | 2948 | return rval; |
2892 | } | 2949 | } |
2950 | |||
2951 | /* 84XX Support **************************************************************/ | ||
2952 | |||
2953 | struct cs84xx_mgmt_cmd { | ||
2954 | union { | ||
2955 | struct verify_chip_entry_84xx req; | ||
2956 | struct verify_chip_rsp_84xx rsp; | ||
2957 | } p; | ||
2958 | }; | ||
2959 | |||
2960 | int | ||
2961 | qla84xx_verify_chip(struct scsi_qla_host *ha, uint16_t *status) | ||
2962 | { | ||
2963 | int rval, retry; | ||
2964 | struct cs84xx_mgmt_cmd *mn; | ||
2965 | dma_addr_t mn_dma; | ||
2966 | uint16_t options; | ||
2967 | unsigned long flags; | ||
2968 | |||
2969 | DEBUG16(printk("%s(%ld): entered.\n", __func__, ha->host_no)); | ||
2970 | |||
2971 | mn = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma); | ||
2972 | if (mn == NULL) { | ||
2973 | DEBUG2_3(printk("%s(%ld): failed to allocate Verify ISP84XX " | ||
2974 | "IOCB.\n", __func__, ha->host_no)); | ||
2975 | return QLA_MEMORY_ALLOC_FAILED; | ||
2976 | } | ||
2977 | |||
2978 | /* Force Update? */ | ||
2979 | options = ha->cs84xx->fw_update ? VCO_FORCE_UPDATE : 0; | ||
2980 | /* Diagnostic firmware? */ | ||
2981 | /* options |= MENLO_DIAG_FW; */ | ||
2982 | /* We update the firmware with only one data sequence. */ | ||
2983 | options |= VCO_END_OF_DATA; | ||
2984 | |||
2985 | retry = 0; | ||
2986 | do { | ||
2987 | memset(mn, 0, sizeof(*mn)); | ||
2988 | mn->p.req.entry_type = VERIFY_CHIP_IOCB_TYPE; | ||
2989 | mn->p.req.entry_count = 1; | ||
2990 | mn->p.req.options = cpu_to_le16(options); | ||
2991 | |||
2992 | DEBUG16(printk("%s(%ld): Dump of Verify Request.\n", __func__, | ||
2993 | ha->host_no)); | ||
2994 | DEBUG16(qla2x00_dump_buffer((uint8_t *)mn, | ||
2995 | sizeof(*mn))); | ||
2996 | |||
2997 | rval = qla2x00_issue_iocb_timeout(ha, mn, mn_dma, 0, 120); | ||
2998 | if (rval != QLA_SUCCESS) { | ||
2999 | DEBUG2_16(printk("%s(%ld): failed to issue Verify " | ||
3000 | "IOCB (%x).\n", __func__, ha->host_no, rval)); | ||
3001 | goto verify_done; | ||
3002 | } | ||
3003 | |||
3004 | DEBUG16(printk("%s(%ld): Dump of Verify Response.\n", __func__, | ||
3005 | ha->host_no)); | ||
3006 | DEBUG16(qla2x00_dump_buffer((uint8_t *)mn, | ||
3007 | sizeof(*mn))); | ||
3008 | |||
3009 | status[0] = le16_to_cpu(mn->p.rsp.comp_status); | ||
3010 | status[1] = status[0] == CS_VCS_CHIP_FAILURE ? | ||
3011 | le16_to_cpu(mn->p.rsp.failure_code) : 0; | ||
3012 | DEBUG2_16(printk("%s(%ld): cs=%x fc=%x\n", __func__, | ||
3013 | ha->host_no, status[0], status[1])); | ||
3014 | |||
3015 | if (status[0] != CS_COMPLETE) { | ||
3016 | rval = QLA_FUNCTION_FAILED; | ||
3017 | if (!(options & VCO_DONT_UPDATE_FW)) { | ||
3018 | DEBUG2_16(printk("%s(%ld): Firmware update " | ||
3019 | "failed. Retrying without update " | ||
3020 | "firmware.\n", __func__, ha->host_no)); | ||
3021 | options |= VCO_DONT_UPDATE_FW; | ||
3022 | options &= ~VCO_FORCE_UPDATE; | ||
3023 | retry = 1; | ||
3024 | } | ||
3025 | } else { | ||
3026 | DEBUG2_16(printk("%s(%ld): firmware updated to %x.\n", | ||
3027 | __func__, ha->host_no, | ||
3028 | le32_to_cpu(mn->p.rsp.fw_ver))); | ||
3029 | |||
3030 | /* NOTE: we only update OP firmware. */ | ||
3031 | spin_lock_irqsave(&ha->cs84xx->access_lock, flags); | ||
3032 | ha->cs84xx->op_fw_version = | ||
3033 | le32_to_cpu(mn->p.rsp.fw_ver); | ||
3034 | spin_unlock_irqrestore(&ha->cs84xx->access_lock, | ||
3035 | flags); | ||
3036 | } | ||
3037 | } while (retry); | ||
3038 | |||
3039 | verify_done: | ||
3040 | dma_pool_free(ha->s_dma_pool, mn, mn_dma); | ||
3041 | |||
3042 | if (rval != QLA_SUCCESS) { | ||
3043 | DEBUG2_16(printk("%s(%ld): failed=%x.\n", __func__, | ||
3044 | ha->host_no, rval)); | ||
3045 | } else { | ||
3046 | DEBUG16(printk("%s(%ld): done.\n", __func__, ha->host_no)); | ||
3047 | } | ||
3048 | |||
3049 | return rval; | ||
3050 | } | ||
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index cf784cdafb01..f2b04979e5f0 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c | |||
@@ -1,20 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * QLOGIC LINUX SOFTWARE | 2 | * QLogic Fibre Channel HBA Driver |
3 | * | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * QLogic ISP2x00 device driver for Linux 2.6.x | ||
5 | * Copyright (C) 2003-2005 QLogic Corporation | ||
6 | * (www.qlogic.com) | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2, or (at your option) any | ||
11 | * later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but | ||
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16 | * General Public License for more details. | ||
17 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | ||
18 | */ | 6 | */ |
19 | #include "qla_def.h" | 7 | #include "qla_def.h" |
20 | 8 | ||
@@ -28,8 +16,6 @@ | |||
28 | #include <scsi/scsicam.h> | 16 | #include <scsi/scsicam.h> |
29 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
30 | 18 | ||
31 | void qla2x00_vp_stop_timer(scsi_qla_host_t *); | ||
32 | |||
33 | void | 19 | void |
34 | qla2x00_vp_stop_timer(scsi_qla_host_t *vha) | 20 | qla2x00_vp_stop_timer(scsi_qla_host_t *vha) |
35 | { | 21 | { |
@@ -268,9 +254,17 @@ qla2x00_vp_abort_isp(scsi_qla_host_t *vha) | |||
268 | static int | 254 | static int |
269 | qla2x00_do_dpc_vp(scsi_qla_host_t *vha) | 255 | qla2x00_do_dpc_vp(scsi_qla_host_t *vha) |
270 | { | 256 | { |
257 | scsi_qla_host_t *ha = vha->parent; | ||
258 | |||
271 | if (test_and_clear_bit(VP_IDX_ACQUIRED, &vha->vp_flags)) { | 259 | if (test_and_clear_bit(VP_IDX_ACQUIRED, &vha->vp_flags)) { |
272 | /* VP acquired. complete port configuration */ | 260 | /* VP acquired. complete port configuration */ |
273 | qla24xx_configure_vp(vha); | 261 | if (atomic_read(&ha->loop_state) == LOOP_READY) { |
262 | qla24xx_configure_vp(vha); | ||
263 | } else { | ||
264 | set_bit(VP_IDX_ACQUIRED, &vha->vp_flags); | ||
265 | set_bit(VP_DPC_NEEDED, &ha->dpc_flags); | ||
266 | } | ||
267 | |||
274 | return 0; | 268 | return 0; |
275 | } | 269 | } |
276 | 270 | ||
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 3c1b43356adb..8b33b163b1d4 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -26,9 +26,6 @@ char qla2x00_version_str[40]; | |||
26 | */ | 26 | */ |
27 | static struct kmem_cache *srb_cachep; | 27 | static struct kmem_cache *srb_cachep; |
28 | 28 | ||
29 | /* | ||
30 | * Ioctl related information. | ||
31 | */ | ||
32 | int num_hosts; | 29 | int num_hosts; |
33 | int ql2xlogintimeout = 20; | 30 | int ql2xlogintimeout = 20; |
34 | module_param(ql2xlogintimeout, int, S_IRUGO|S_IRUSR); | 31 | module_param(ql2xlogintimeout, int, S_IRUGO|S_IRUSR); |
@@ -103,9 +100,9 @@ static int qla24xx_queuecommand(struct scsi_cmnd *cmd, | |||
103 | void (*fn)(struct scsi_cmnd *)); | 100 | void (*fn)(struct scsi_cmnd *)); |
104 | static int qla2xxx_eh_abort(struct scsi_cmnd *); | 101 | static int qla2xxx_eh_abort(struct scsi_cmnd *); |
105 | static int qla2xxx_eh_device_reset(struct scsi_cmnd *); | 102 | static int qla2xxx_eh_device_reset(struct scsi_cmnd *); |
103 | static int qla2xxx_eh_target_reset(struct scsi_cmnd *); | ||
106 | static int qla2xxx_eh_bus_reset(struct scsi_cmnd *); | 104 | static int qla2xxx_eh_bus_reset(struct scsi_cmnd *); |
107 | static int qla2xxx_eh_host_reset(struct scsi_cmnd *); | 105 | static int qla2xxx_eh_host_reset(struct scsi_cmnd *); |
108 | static int qla2x00_device_reset(scsi_qla_host_t *, fc_port_t *); | ||
109 | 106 | ||
110 | static int qla2x00_change_queue_depth(struct scsi_device *, int); | 107 | static int qla2x00_change_queue_depth(struct scsi_device *, int); |
111 | static int qla2x00_change_queue_type(struct scsi_device *, int); | 108 | static int qla2x00_change_queue_type(struct scsi_device *, int); |
@@ -117,6 +114,7 @@ static struct scsi_host_template qla2x00_driver_template = { | |||
117 | 114 | ||
118 | .eh_abort_handler = qla2xxx_eh_abort, | 115 | .eh_abort_handler = qla2xxx_eh_abort, |
119 | .eh_device_reset_handler = qla2xxx_eh_device_reset, | 116 | .eh_device_reset_handler = qla2xxx_eh_device_reset, |
117 | .eh_target_reset_handler = qla2xxx_eh_target_reset, | ||
120 | .eh_bus_reset_handler = qla2xxx_eh_bus_reset, | 118 | .eh_bus_reset_handler = qla2xxx_eh_bus_reset, |
121 | .eh_host_reset_handler = qla2xxx_eh_host_reset, | 119 | .eh_host_reset_handler = qla2xxx_eh_host_reset, |
122 | 120 | ||
@@ -148,6 +146,7 @@ struct scsi_host_template qla24xx_driver_template = { | |||
148 | 146 | ||
149 | .eh_abort_handler = qla2xxx_eh_abort, | 147 | .eh_abort_handler = qla2xxx_eh_abort, |
150 | .eh_device_reset_handler = qla2xxx_eh_device_reset, | 148 | .eh_device_reset_handler = qla2xxx_eh_device_reset, |
149 | .eh_target_reset_handler = qla2xxx_eh_target_reset, | ||
151 | .eh_bus_reset_handler = qla2xxx_eh_bus_reset, | 150 | .eh_bus_reset_handler = qla2xxx_eh_bus_reset, |
152 | .eh_host_reset_handler = qla2xxx_eh_host_reset, | 151 | .eh_host_reset_handler = qla2xxx_eh_host_reset, |
153 | 152 | ||
@@ -253,9 +252,9 @@ qla24xx_pci_info_str(struct scsi_qla_host *ha, char *str) | |||
253 | 252 | ||
254 | strcpy(str, "PCIe ("); | 253 | strcpy(str, "PCIe ("); |
255 | if (lspeed == 1) | 254 | if (lspeed == 1) |
256 | strcat(str, "2.5Gb/s "); | 255 | strcat(str, "2.5GT/s "); |
257 | else if (lspeed == 2) | 256 | else if (lspeed == 2) |
258 | strcat(str, "5.0Gb/s "); | 257 | strcat(str, "5.0GT/s "); |
259 | else | 258 | else |
260 | strcat(str, "<unknown> "); | 259 | strcat(str, "<unknown> "); |
261 | snprintf(lwstr, sizeof(lwstr), "x%d)", lwidth); | 260 | snprintf(lwstr, sizeof(lwstr), "x%d)", lwidth); |
@@ -340,6 +339,8 @@ qla24xx_fw_version_str(struct scsi_qla_host *ha, char *str) | |||
340 | strcat(str, "[T10 CRC] "); | 339 | strcat(str, "[T10 CRC] "); |
341 | if (ha->fw_attributes & BIT_5) | 340 | if (ha->fw_attributes & BIT_5) |
342 | strcat(str, "[VI] "); | 341 | strcat(str, "[VI] "); |
342 | if (ha->fw_attributes & BIT_10) | ||
343 | strcat(str, "[84XX] "); | ||
343 | if (ha->fw_attributes & BIT_13) | 344 | if (ha->fw_attributes & BIT_13) |
344 | strcat(str, "[Experimental]"); | 345 | strcat(str, "[Experimental]"); |
345 | return str; | 346 | return str; |
@@ -570,8 +571,6 @@ qla2x00_wait_for_hba_online(scsi_qla_host_t *ha) | |||
570 | else | 571 | else |
571 | return_status = QLA_FUNCTION_FAILED; | 572 | return_status = QLA_FUNCTION_FAILED; |
572 | 573 | ||
573 | DEBUG2(printk("%s return_status=%d\n",__func__,return_status)); | ||
574 | |||
575 | return (return_status); | 574 | return (return_status); |
576 | } | 575 | } |
577 | 576 | ||
@@ -685,7 +684,6 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) | |||
685 | 684 | ||
686 | DEBUG2(printk("%s(%ld): aborting sp %p from RISC. pid=%ld.\n", | 685 | DEBUG2(printk("%s(%ld): aborting sp %p from RISC. pid=%ld.\n", |
687 | __func__, ha->host_no, sp, serial)); | 686 | __func__, ha->host_no, sp, serial)); |
688 | DEBUG3(qla2x00_print_scsi_cmd(cmd)); | ||
689 | 687 | ||
690 | spin_unlock_irqrestore(&pha->hardware_lock, flags); | 688 | spin_unlock_irqrestore(&pha->hardware_lock, flags); |
691 | if (ha->isp_ops->abort_command(ha, sp)) { | 689 | if (ha->isp_ops->abort_command(ha, sp)) { |
@@ -719,190 +717,122 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) | |||
719 | return ret; | 717 | return ret; |
720 | } | 718 | } |
721 | 719 | ||
722 | /************************************************************************** | 720 | enum nexus_wait_type { |
723 | * qla2x00_eh_wait_for_pending_target_commands | 721 | WAIT_HOST = 0, |
724 | * | 722 | WAIT_TARGET, |
725 | * Description: | 723 | WAIT_LUN, |
726 | * Waits for all the commands to come back from the specified target. | 724 | }; |
727 | * | 725 | |
728 | * Input: | ||
729 | * ha - pointer to scsi_qla_host structure. | ||
730 | * t - target | ||
731 | * Returns: | ||
732 | * Either SUCCESS or FAILED. | ||
733 | * | ||
734 | * Note: | ||
735 | **************************************************************************/ | ||
736 | static int | 726 | static int |
737 | qla2x00_eh_wait_for_pending_target_commands(scsi_qla_host_t *ha, unsigned int t) | 727 | qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha, unsigned int t, |
728 | unsigned int l, enum nexus_wait_type type) | ||
738 | { | 729 | { |
739 | int cnt; | 730 | int cnt, match, status; |
740 | int status; | 731 | srb_t *sp; |
741 | srb_t *sp; | ||
742 | struct scsi_cmnd *cmd; | ||
743 | unsigned long flags; | 732 | unsigned long flags; |
744 | scsi_qla_host_t *pha = to_qla_parent(ha); | 733 | scsi_qla_host_t *pha = to_qla_parent(ha); |
745 | 734 | ||
746 | status = 0; | 735 | status = QLA_SUCCESS; |
747 | 736 | spin_lock_irqsave(&pha->hardware_lock, flags); | |
748 | /* | 737 | for (cnt = 1; status == QLA_SUCCESS && cnt < MAX_OUTSTANDING_COMMANDS; |
749 | * Waiting for all commands for the designated target in the active | 738 | cnt++) { |
750 | * array | ||
751 | */ | ||
752 | for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) { | ||
753 | spin_lock_irqsave(&pha->hardware_lock, flags); | ||
754 | sp = pha->outstanding_cmds[cnt]; | 739 | sp = pha->outstanding_cmds[cnt]; |
755 | if (sp) { | 740 | if (!sp) |
756 | cmd = sp->cmd; | 741 | continue; |
757 | spin_unlock_irqrestore(&pha->hardware_lock, flags); | 742 | if (ha->vp_idx != sp->ha->vp_idx) |
758 | if (cmd->device->id == t && | 743 | continue; |
759 | ha->vp_idx == sp->ha->vp_idx) { | 744 | match = 0; |
760 | if (!qla2x00_eh_wait_on_command(ha, cmd)) { | 745 | switch (type) { |
761 | status = 1; | 746 | case WAIT_HOST: |
762 | break; | 747 | match = 1; |
763 | } | 748 | break; |
764 | } | 749 | case WAIT_TARGET: |
765 | } else { | 750 | match = sp->cmd->device->id == t; |
766 | spin_unlock_irqrestore(&pha->hardware_lock, flags); | 751 | break; |
752 | case WAIT_LUN: | ||
753 | match = (sp->cmd->device->id == t && | ||
754 | sp->cmd->device->lun == l); | ||
755 | break; | ||
767 | } | 756 | } |
757 | if (!match) | ||
758 | continue; | ||
759 | |||
760 | spin_unlock_irqrestore(&pha->hardware_lock, flags); | ||
761 | status = qla2x00_eh_wait_on_command(ha, sp->cmd); | ||
762 | spin_lock_irqsave(&pha->hardware_lock, flags); | ||
768 | } | 763 | } |
769 | return (status); | 764 | spin_unlock_irqrestore(&pha->hardware_lock, flags); |
765 | |||
766 | return status; | ||
770 | } | 767 | } |
771 | 768 | ||
769 | static char *reset_errors[] = { | ||
770 | "HBA not online", | ||
771 | "HBA not ready", | ||
772 | "Task management failed", | ||
773 | "Waiting for command completions", | ||
774 | }; | ||
772 | 775 | ||
773 | /************************************************************************** | ||
774 | * qla2xxx_eh_device_reset | ||
775 | * | ||
776 | * Description: | ||
777 | * The device reset function will reset the target and abort any | ||
778 | * executing commands. | ||
779 | * | ||
780 | * NOTE: The use of SP is undefined within this context. Do *NOT* | ||
781 | * attempt to use this value, even if you determine it is | ||
782 | * non-null. | ||
783 | * | ||
784 | * Input: | ||
785 | * cmd = Linux SCSI command packet of the command that cause the | ||
786 | * bus device reset. | ||
787 | * | ||
788 | * Returns: | ||
789 | * SUCCESS/FAILURE (defined as macro in scsi.h). | ||
790 | * | ||
791 | **************************************************************************/ | ||
792 | static int | 776 | static int |
793 | qla2xxx_eh_device_reset(struct scsi_cmnd *cmd) | 777 | __qla2xxx_eh_generic_reset(char *name, enum nexus_wait_type type, |
778 | struct scsi_cmnd *cmd, int (*do_reset)(struct fc_port *, unsigned int)) | ||
794 | { | 779 | { |
795 | scsi_qla_host_t *ha = shost_priv(cmd->device->host); | 780 | scsi_qla_host_t *ha = shost_priv(cmd->device->host); |
796 | fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; | 781 | fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; |
797 | int ret = FAILED; | 782 | int err; |
798 | unsigned int id, lun; | ||
799 | unsigned long serial; | ||
800 | 783 | ||
801 | qla2x00_block_error_handler(cmd); | 784 | qla2x00_block_error_handler(cmd); |
802 | 785 | ||
803 | id = cmd->device->id; | ||
804 | lun = cmd->device->lun; | ||
805 | serial = cmd->serial_number; | ||
806 | |||
807 | if (!fcport) | 786 | if (!fcport) |
808 | return ret; | 787 | return FAILED; |
809 | 788 | ||
810 | qla_printk(KERN_INFO, ha, | 789 | qla_printk(KERN_INFO, ha, "scsi(%ld:%d:%d): %s RESET ISSUED.\n", |
811 | "scsi(%ld:%d:%d): DEVICE RESET ISSUED.\n", ha->host_no, id, lun); | 790 | ha->host_no, cmd->device->id, cmd->device->lun, name); |
812 | 791 | ||
792 | err = 0; | ||
813 | if (qla2x00_wait_for_hba_online(ha) != QLA_SUCCESS) | 793 | if (qla2x00_wait_for_hba_online(ha) != QLA_SUCCESS) |
814 | goto eh_dev_reset_done; | 794 | goto eh_reset_failed; |
815 | 795 | err = 1; | |
816 | if (qla2x00_wait_for_loop_ready(ha) == QLA_SUCCESS) { | 796 | if (qla2x00_wait_for_loop_ready(ha) != QLA_SUCCESS) |
817 | if (qla2x00_device_reset(ha, fcport) == 0) | 797 | goto eh_reset_failed; |
818 | ret = SUCCESS; | 798 | err = 2; |
819 | 799 | if (do_reset(fcport, cmd->device->lun) != QLA_SUCCESS) | |
820 | #if defined(LOGOUT_AFTER_DEVICE_RESET) | 800 | goto eh_reset_failed; |
821 | if (ret == SUCCESS) { | 801 | err = 3; |
822 | if (fcport->flags & FC_FABRIC_DEVICE) { | 802 | if (qla2x00_eh_wait_for_pending_commands(ha, cmd->device->id, |
823 | ha->isp_ops->fabric_logout(ha, fcport->loop_id); | 803 | cmd->device->lun, type) != QLA_SUCCESS) |
824 | qla2x00_mark_device_lost(ha, fcport, 0, 0); | 804 | goto eh_reset_failed; |
825 | } | 805 | |
826 | } | 806 | qla_printk(KERN_INFO, ha, "scsi(%ld:%d:%d): %s RESET SUCCEEDED.\n", |
827 | #endif | 807 | ha->host_no, cmd->device->id, cmd->device->lun, name); |
828 | } else { | 808 | |
829 | DEBUG2(printk(KERN_INFO | 809 | return SUCCESS; |
830 | "%s failed: loop not ready\n",__func__)); | 810 | |
831 | } | 811 | eh_reset_failed: |
832 | 812 | qla_printk(KERN_INFO, ha, "scsi(%ld:%d:%d): %s RESET FAILED: %s.\n", | |
833 | if (ret == FAILED) { | 813 | ha->host_no, cmd->device->id, cmd->device->lun, name, |
834 | DEBUG3(printk("%s(%ld): device reset failed\n", | 814 | reset_errors[err]); |
835 | __func__, ha->host_no)); | 815 | return FAILED; |
836 | qla_printk(KERN_INFO, ha, "%s: device reset failed\n", | 816 | } |
837 | __func__); | ||
838 | 817 | ||
839 | goto eh_dev_reset_done; | 818 | static int |
840 | } | 819 | qla2xxx_eh_device_reset(struct scsi_cmnd *cmd) |
820 | { | ||
821 | scsi_qla_host_t *ha = shost_priv(cmd->device->host); | ||
841 | 822 | ||
842 | /* Flush outstanding commands. */ | 823 | return __qla2xxx_eh_generic_reset("DEVICE", WAIT_LUN, cmd, |
843 | if (qla2x00_eh_wait_for_pending_target_commands(ha, id)) | 824 | ha->isp_ops->lun_reset); |
844 | ret = FAILED; | ||
845 | if (ret == FAILED) { | ||
846 | DEBUG3(printk("%s(%ld): failed while waiting for commands\n", | ||
847 | __func__, ha->host_no)); | ||
848 | qla_printk(KERN_INFO, ha, | ||
849 | "%s: failed while waiting for commands\n", __func__); | ||
850 | } else | ||
851 | qla_printk(KERN_INFO, ha, | ||
852 | "scsi(%ld:%d:%d): DEVICE RESET SUCCEEDED.\n", ha->host_no, | ||
853 | id, lun); | ||
854 | eh_dev_reset_done: | ||
855 | return ret; | ||
856 | } | 825 | } |
857 | 826 | ||
858 | /************************************************************************** | ||
859 | * qla2x00_eh_wait_for_pending_commands | ||
860 | * | ||
861 | * Description: | ||
862 | * Waits for all the commands to come back from the specified host. | ||
863 | * | ||
864 | * Input: | ||
865 | * ha - pointer to scsi_qla_host structure. | ||
866 | * | ||
867 | * Returns: | ||
868 | * 1 : SUCCESS | ||
869 | * 0 : FAILED | ||
870 | * | ||
871 | * Note: | ||
872 | **************************************************************************/ | ||
873 | static int | 827 | static int |
874 | qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha) | 828 | qla2xxx_eh_target_reset(struct scsi_cmnd *cmd) |
875 | { | 829 | { |
876 | int cnt; | 830 | scsi_qla_host_t *ha = shost_priv(cmd->device->host); |
877 | int status; | ||
878 | srb_t *sp; | ||
879 | struct scsi_cmnd *cmd; | ||
880 | unsigned long flags; | ||
881 | |||
882 | status = 1; | ||
883 | 831 | ||
884 | /* | 832 | return __qla2xxx_eh_generic_reset("TARGET", WAIT_TARGET, cmd, |
885 | * Waiting for all commands for the designated target in the active | 833 | ha->isp_ops->target_reset); |
886 | * array | ||
887 | */ | ||
888 | for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) { | ||
889 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
890 | sp = ha->outstanding_cmds[cnt]; | ||
891 | if (sp) { | ||
892 | cmd = sp->cmd; | ||
893 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
894 | status = qla2x00_eh_wait_on_command(ha, cmd); | ||
895 | if (status == 0) | ||
896 | break; | ||
897 | } | ||
898 | else { | ||
899 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
900 | } | ||
901 | } | ||
902 | return (status); | ||
903 | } | 834 | } |
904 | 835 | ||
905 | |||
906 | /************************************************************************** | 836 | /************************************************************************** |
907 | * qla2xxx_eh_bus_reset | 837 | * qla2xxx_eh_bus_reset |
908 | * | 838 | * |
@@ -953,7 +883,8 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd) | |||
953 | goto eh_bus_reset_done; | 883 | goto eh_bus_reset_done; |
954 | 884 | ||
955 | /* Flush outstanding commands. */ | 885 | /* Flush outstanding commands. */ |
956 | if (!qla2x00_eh_wait_for_pending_commands(pha)) | 886 | if (qla2x00_eh_wait_for_pending_commands(pha, 0, 0, WAIT_HOST) != |
887 | QLA_SUCCESS) | ||
957 | ret = FAILED; | 888 | ret = FAILED; |
958 | 889 | ||
959 | eh_bus_reset_done: | 890 | eh_bus_reset_done: |
@@ -1024,7 +955,8 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd) | |||
1024 | clear_bit(ABORT_ISP_ACTIVE, &pha->dpc_flags); | 955 | clear_bit(ABORT_ISP_ACTIVE, &pha->dpc_flags); |
1025 | 956 | ||
1026 | /* Waiting for our command in done_queue to be returned to OS.*/ | 957 | /* Waiting for our command in done_queue to be returned to OS.*/ |
1027 | if (qla2x00_eh_wait_for_pending_commands(pha)) | 958 | if (qla2x00_eh_wait_for_pending_commands(pha, 0, 0, WAIT_HOST) == |
959 | QLA_SUCCESS) | ||
1028 | ret = SUCCESS; | 960 | ret = SUCCESS; |
1029 | 961 | ||
1030 | if (ha->parent) | 962 | if (ha->parent) |
@@ -1080,7 +1012,7 @@ qla2x00_loop_reset(scsi_qla_host_t *ha) | |||
1080 | if (fcport->port_type != FCT_TARGET) | 1012 | if (fcport->port_type != FCT_TARGET) |
1081 | continue; | 1013 | continue; |
1082 | 1014 | ||
1083 | ret = qla2x00_device_reset(ha, fcport); | 1015 | ret = ha->isp_ops->target_reset(fcport, 0); |
1084 | if (ret != QLA_SUCCESS) { | 1016 | if (ret != QLA_SUCCESS) { |
1085 | DEBUG2_3(printk("%s(%ld): bus_reset failed: " | 1017 | DEBUG2_3(printk("%s(%ld): bus_reset failed: " |
1086 | "target_reset=%d d_id=%x.\n", __func__, | 1018 | "target_reset=%d d_id=%x.\n", __func__, |
@@ -1095,26 +1027,6 @@ qla2x00_loop_reset(scsi_qla_host_t *ha) | |||
1095 | return QLA_SUCCESS; | 1027 | return QLA_SUCCESS; |
1096 | } | 1028 | } |
1097 | 1029 | ||
1098 | /* | ||
1099 | * qla2x00_device_reset | ||
1100 | * Issue bus device reset message to the target. | ||
1101 | * | ||
1102 | * Input: | ||
1103 | * ha = adapter block pointer. | ||
1104 | * t = SCSI ID. | ||
1105 | * TARGET_QUEUE_LOCK must be released. | ||
1106 | * ADAPTER_STATE_LOCK must be released. | ||
1107 | * | ||
1108 | * Context: | ||
1109 | * Kernel context. | ||
1110 | */ | ||
1111 | static int | ||
1112 | qla2x00_device_reset(scsi_qla_host_t *ha, fc_port_t *reset_fcport) | ||
1113 | { | ||
1114 | /* Abort Target command will clear Reservation */ | ||
1115 | return ha->isp_ops->abort_target(reset_fcport); | ||
1116 | } | ||
1117 | |||
1118 | void | 1030 | void |
1119 | qla2x00_abort_all_cmds(scsi_qla_host_t *ha, int res) | 1031 | qla2x00_abort_all_cmds(scsi_qla_host_t *ha, int res) |
1120 | { | 1032 | { |
@@ -1292,7 +1204,8 @@ static struct isp_operations qla2100_isp_ops = { | |||
1292 | .enable_intrs = qla2x00_enable_intrs, | 1204 | .enable_intrs = qla2x00_enable_intrs, |
1293 | .disable_intrs = qla2x00_disable_intrs, | 1205 | .disable_intrs = qla2x00_disable_intrs, |
1294 | .abort_command = qla2x00_abort_command, | 1206 | .abort_command = qla2x00_abort_command, |
1295 | .abort_target = qla2x00_abort_target, | 1207 | .target_reset = qla2x00_abort_target, |
1208 | .lun_reset = qla2x00_lun_reset, | ||
1296 | .fabric_login = qla2x00_login_fabric, | 1209 | .fabric_login = qla2x00_login_fabric, |
1297 | .fabric_logout = qla2x00_fabric_logout, | 1210 | .fabric_logout = qla2x00_fabric_logout, |
1298 | .calc_req_entries = qla2x00_calc_iocbs_32, | 1211 | .calc_req_entries = qla2x00_calc_iocbs_32, |
@@ -1325,7 +1238,8 @@ static struct isp_operations qla2300_isp_ops = { | |||
1325 | .enable_intrs = qla2x00_enable_intrs, | 1238 | .enable_intrs = qla2x00_enable_intrs, |
1326 | .disable_intrs = qla2x00_disable_intrs, | 1239 | .disable_intrs = qla2x00_disable_intrs, |
1327 | .abort_command = qla2x00_abort_command, | 1240 | .abort_command = qla2x00_abort_command, |
1328 | .abort_target = qla2x00_abort_target, | 1241 | .target_reset = qla2x00_abort_target, |
1242 | .lun_reset = qla2x00_lun_reset, | ||
1329 | .fabric_login = qla2x00_login_fabric, | 1243 | .fabric_login = qla2x00_login_fabric, |
1330 | .fabric_logout = qla2x00_fabric_logout, | 1244 | .fabric_logout = qla2x00_fabric_logout, |
1331 | .calc_req_entries = qla2x00_calc_iocbs_32, | 1245 | .calc_req_entries = qla2x00_calc_iocbs_32, |
@@ -1358,7 +1272,8 @@ static struct isp_operations qla24xx_isp_ops = { | |||
1358 | .enable_intrs = qla24xx_enable_intrs, | 1272 | .enable_intrs = qla24xx_enable_intrs, |
1359 | .disable_intrs = qla24xx_disable_intrs, | 1273 | .disable_intrs = qla24xx_disable_intrs, |
1360 | .abort_command = qla24xx_abort_command, | 1274 | .abort_command = qla24xx_abort_command, |
1361 | .abort_target = qla24xx_abort_target, | 1275 | .target_reset = qla24xx_abort_target, |
1276 | .lun_reset = qla24xx_lun_reset, | ||
1362 | .fabric_login = qla24xx_login_fabric, | 1277 | .fabric_login = qla24xx_login_fabric, |
1363 | .fabric_logout = qla24xx_fabric_logout, | 1278 | .fabric_logout = qla24xx_fabric_logout, |
1364 | .calc_req_entries = NULL, | 1279 | .calc_req_entries = NULL, |
@@ -1391,7 +1306,8 @@ static struct isp_operations qla25xx_isp_ops = { | |||
1391 | .enable_intrs = qla24xx_enable_intrs, | 1306 | .enable_intrs = qla24xx_enable_intrs, |
1392 | .disable_intrs = qla24xx_disable_intrs, | 1307 | .disable_intrs = qla24xx_disable_intrs, |
1393 | .abort_command = qla24xx_abort_command, | 1308 | .abort_command = qla24xx_abort_command, |
1394 | .abort_target = qla24xx_abort_target, | 1309 | .target_reset = qla24xx_abort_target, |
1310 | .lun_reset = qla24xx_lun_reset, | ||
1395 | .fabric_login = qla24xx_login_fabric, | 1311 | .fabric_login = qla24xx_login_fabric, |
1396 | .fabric_logout = qla24xx_fabric_logout, | 1312 | .fabric_logout = qla24xx_fabric_logout, |
1397 | .calc_req_entries = NULL, | 1313 | .calc_req_entries = NULL, |
@@ -1464,6 +1380,13 @@ qla2x00_set_isp_flags(scsi_qla_host_t *ha) | |||
1464 | ha->device_type |= DT_IIDMA; | 1380 | ha->device_type |= DT_IIDMA; |
1465 | ha->fw_srisc_address = RISC_START_ADDRESS_2400; | 1381 | ha->fw_srisc_address = RISC_START_ADDRESS_2400; |
1466 | break; | 1382 | break; |
1383 | case PCI_DEVICE_ID_QLOGIC_ISP8432: | ||
1384 | ha->device_type |= DT_ISP8432; | ||
1385 | ha->device_type |= DT_ZIO_SUPPORTED; | ||
1386 | ha->device_type |= DT_FWI2; | ||
1387 | ha->device_type |= DT_IIDMA; | ||
1388 | ha->fw_srisc_address = RISC_START_ADDRESS_2400; | ||
1389 | break; | ||
1467 | case PCI_DEVICE_ID_QLOGIC_ISP5422: | 1390 | case PCI_DEVICE_ID_QLOGIC_ISP5422: |
1468 | ha->device_type |= DT_ISP5422; | 1391 | ha->device_type |= DT_ISP5422; |
1469 | ha->device_type |= DT_FWI2; | 1392 | ha->device_type |= DT_FWI2; |
@@ -1587,6 +1510,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1587 | sht = &qla2x00_driver_template; | 1510 | sht = &qla2x00_driver_template; |
1588 | if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 || | 1511 | if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 || |
1589 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432 || | 1512 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432 || |
1513 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8432 || | ||
1590 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5422 || | 1514 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5422 || |
1591 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5432 || | 1515 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5432 || |
1592 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2532) { | 1516 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2532) { |
@@ -1677,7 +1601,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1677 | if (IS_QLA2322(ha) || IS_QLA6322(ha)) | 1601 | if (IS_QLA2322(ha) || IS_QLA6322(ha)) |
1678 | ha->optrom_size = OPTROM_SIZE_2322; | 1602 | ha->optrom_size = OPTROM_SIZE_2322; |
1679 | ha->isp_ops = &qla2300_isp_ops; | 1603 | ha->isp_ops = &qla2300_isp_ops; |
1680 | } else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | 1604 | } else if (IS_QLA24XX_TYPE(ha)) { |
1681 | host->max_id = MAX_TARGETS_2200; | 1605 | host->max_id = MAX_TARGETS_2200; |
1682 | ha->mbx_count = MAILBOX_REGISTER_COUNT; | 1606 | ha->mbx_count = MAILBOX_REGISTER_COUNT; |
1683 | ha->request_q_length = REQUEST_ENTRY_CNT_24XX; | 1607 | ha->request_q_length = REQUEST_ENTRY_CNT_24XX; |
@@ -1699,6 +1623,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1699 | ha->gid_list_info_size = 8; | 1623 | ha->gid_list_info_size = 8; |
1700 | ha->optrom_size = OPTROM_SIZE_25XX; | 1624 | ha->optrom_size = OPTROM_SIZE_25XX; |
1701 | ha->isp_ops = &qla25xx_isp_ops; | 1625 | ha->isp_ops = &qla25xx_isp_ops; |
1626 | ha->hw_event_start = PCI_FUNC(pdev->devfn) ? | ||
1627 | FA_HW_EVENT1_ADDR: FA_HW_EVENT0_ADDR; | ||
1702 | } | 1628 | } |
1703 | host->can_queue = ha->request_q_length + 128; | 1629 | host->can_queue = ha->request_q_length + 128; |
1704 | 1630 | ||
@@ -1713,6 +1639,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1713 | INIT_LIST_HEAD(&ha->list); | 1639 | INIT_LIST_HEAD(&ha->list); |
1714 | INIT_LIST_HEAD(&ha->fcports); | 1640 | INIT_LIST_HEAD(&ha->fcports); |
1715 | INIT_LIST_HEAD(&ha->vp_list); | 1641 | INIT_LIST_HEAD(&ha->vp_list); |
1642 | INIT_LIST_HEAD(&ha->work_list); | ||
1716 | 1643 | ||
1717 | set_bit(0, (unsigned long *) ha->vp_idx_map); | 1644 | set_bit(0, (unsigned long *) ha->vp_idx_map); |
1718 | 1645 | ||
@@ -1819,6 +1746,8 @@ qla2x00_remove_one(struct pci_dev *pdev) | |||
1819 | 1746 | ||
1820 | qla2x00_dfs_remove(ha); | 1747 | qla2x00_dfs_remove(ha); |
1821 | 1748 | ||
1749 | qla84xx_put_chip(ha); | ||
1750 | |||
1822 | qla2x00_free_sysfs_attr(ha); | 1751 | qla2x00_free_sysfs_attr(ha); |
1823 | 1752 | ||
1824 | fc_remove_host(ha->host); | 1753 | fc_remove_host(ha->host); |
@@ -2206,6 +2135,97 @@ qla2x00_mem_free(scsi_qla_host_t *ha) | |||
2206 | kfree(ha->nvram); | 2135 | kfree(ha->nvram); |
2207 | } | 2136 | } |
2208 | 2137 | ||
2138 | struct qla_work_evt * | ||
2139 | qla2x00_alloc_work(struct scsi_qla_host *ha, enum qla_work_type type, | ||
2140 | int locked) | ||
2141 | { | ||
2142 | struct qla_work_evt *e; | ||
2143 | |||
2144 | e = kzalloc(sizeof(struct qla_work_evt), locked ? GFP_ATOMIC: | ||
2145 | GFP_KERNEL); | ||
2146 | if (!e) | ||
2147 | return NULL; | ||
2148 | |||
2149 | INIT_LIST_HEAD(&e->list); | ||
2150 | e->type = type; | ||
2151 | e->flags = QLA_EVT_FLAG_FREE; | ||
2152 | return e; | ||
2153 | } | ||
2154 | |||
2155 | int | ||
2156 | qla2x00_post_work(struct scsi_qla_host *ha, struct qla_work_evt *e, int locked) | ||
2157 | { | ||
2158 | unsigned long flags; | ||
2159 | |||
2160 | if (!locked) | ||
2161 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
2162 | list_add_tail(&e->list, &ha->work_list); | ||
2163 | qla2xxx_wake_dpc(ha); | ||
2164 | if (!locked) | ||
2165 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
2166 | return QLA_SUCCESS; | ||
2167 | } | ||
2168 | |||
2169 | int | ||
2170 | qla2x00_post_aen_work(struct scsi_qla_host *ha, enum fc_host_event_code code, | ||
2171 | u32 data) | ||
2172 | { | ||
2173 | struct qla_work_evt *e; | ||
2174 | |||
2175 | e = qla2x00_alloc_work(ha, QLA_EVT_AEN, 1); | ||
2176 | if (!e) | ||
2177 | return QLA_FUNCTION_FAILED; | ||
2178 | |||
2179 | e->u.aen.code = code; | ||
2180 | e->u.aen.data = data; | ||
2181 | return qla2x00_post_work(ha, e, 1); | ||
2182 | } | ||
2183 | |||
2184 | int | ||
2185 | qla2x00_post_hwe_work(struct scsi_qla_host *ha, uint16_t code, uint16_t d1, | ||
2186 | uint16_t d2, uint16_t d3) | ||
2187 | { | ||
2188 | struct qla_work_evt *e; | ||
2189 | |||
2190 | e = qla2x00_alloc_work(ha, QLA_EVT_HWE_LOG, 1); | ||
2191 | if (!e) | ||
2192 | return QLA_FUNCTION_FAILED; | ||
2193 | |||
2194 | e->u.hwe.code = code; | ||
2195 | e->u.hwe.d1 = d1; | ||
2196 | e->u.hwe.d2 = d2; | ||
2197 | e->u.hwe.d3 = d3; | ||
2198 | return qla2x00_post_work(ha, e, 1); | ||
2199 | } | ||
2200 | |||
2201 | static void | ||
2202 | qla2x00_do_work(struct scsi_qla_host *ha) | ||
2203 | { | ||
2204 | struct qla_work_evt *e; | ||
2205 | |||
2206 | spin_lock_irq(&ha->hardware_lock); | ||
2207 | while (!list_empty(&ha->work_list)) { | ||
2208 | e = list_entry(ha->work_list.next, struct qla_work_evt, list); | ||
2209 | list_del_init(&e->list); | ||
2210 | spin_unlock_irq(&ha->hardware_lock); | ||
2211 | |||
2212 | switch (e->type) { | ||
2213 | case QLA_EVT_AEN: | ||
2214 | fc_host_post_event(ha->host, fc_get_event_number(), | ||
2215 | e->u.aen.code, e->u.aen.data); | ||
2216 | break; | ||
2217 | case QLA_EVT_HWE_LOG: | ||
2218 | qla2xxx_hw_event_log(ha, e->u.hwe.code, e->u.hwe.d1, | ||
2219 | e->u.hwe.d2, e->u.hwe.d3); | ||
2220 | break; | ||
2221 | } | ||
2222 | if (e->flags & QLA_EVT_FLAG_FREE) | ||
2223 | kfree(e); | ||
2224 | spin_lock_irq(&ha->hardware_lock); | ||
2225 | } | ||
2226 | spin_unlock_irq(&ha->hardware_lock); | ||
2227 | } | ||
2228 | |||
2209 | /************************************************************************** | 2229 | /************************************************************************** |
2210 | * qla2x00_do_dpc | 2230 | * qla2x00_do_dpc |
2211 | * This kernel thread is a task that is schedule by the interrupt handler | 2231 | * This kernel thread is a task that is schedule by the interrupt handler |
@@ -2257,6 +2277,8 @@ qla2x00_do_dpc(void *data) | |||
2257 | continue; | 2277 | continue; |
2258 | } | 2278 | } |
2259 | 2279 | ||
2280 | qla2x00_do_work(ha); | ||
2281 | |||
2260 | if (test_and_clear_bit(ISP_ABORT_NEEDED, &ha->dpc_flags)) { | 2282 | if (test_and_clear_bit(ISP_ABORT_NEEDED, &ha->dpc_flags)) { |
2261 | 2283 | ||
2262 | DEBUG(printk("scsi(%ld): dpc: sched " | 2284 | DEBUG(printk("scsi(%ld): dpc: sched " |
@@ -2291,12 +2313,6 @@ qla2x00_do_dpc(void *data) | |||
2291 | if (test_and_clear_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags)) | 2313 | if (test_and_clear_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags)) |
2292 | qla2x00_update_fcports(ha); | 2314 | qla2x00_update_fcports(ha); |
2293 | 2315 | ||
2294 | if (test_and_clear_bit(LOOP_RESET_NEEDED, &ha->dpc_flags)) { | ||
2295 | DEBUG(printk("scsi(%ld): dpc: sched loop_reset()\n", | ||
2296 | ha->host_no)); | ||
2297 | qla2x00_loop_reset(ha); | ||
2298 | } | ||
2299 | |||
2300 | if (test_and_clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) && | 2316 | if (test_and_clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) && |
2301 | (!(test_and_set_bit(RESET_ACTIVE, &ha->dpc_flags)))) { | 2317 | (!(test_and_set_bit(RESET_ACTIVE, &ha->dpc_flags)))) { |
2302 | 2318 | ||
@@ -2367,19 +2383,6 @@ qla2x00_do_dpc(void *data) | |||
2367 | ha->host_no)); | 2383 | ha->host_no)); |
2368 | } | 2384 | } |
2369 | 2385 | ||
2370 | if ((test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags)) && | ||
2371 | atomic_read(&ha->loop_state) != LOOP_DOWN) { | ||
2372 | |||
2373 | clear_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags); | ||
2374 | DEBUG(printk("scsi(%ld): qla2x00_login_retry()\n", | ||
2375 | ha->host_no)); | ||
2376 | |||
2377 | set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); | ||
2378 | |||
2379 | DEBUG(printk("scsi(%ld): qla2x00_login_retry - end\n", | ||
2380 | ha->host_no)); | ||
2381 | } | ||
2382 | |||
2383 | if (test_and_clear_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)) { | 2386 | if (test_and_clear_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)) { |
2384 | 2387 | ||
2385 | DEBUG(printk("scsi(%ld): qla2x00_loop_resync()\n", | 2388 | DEBUG(printk("scsi(%ld): qla2x00_loop_resync()\n", |
@@ -2397,18 +2400,6 @@ qla2x00_do_dpc(void *data) | |||
2397 | ha->host_no)); | 2400 | ha->host_no)); |
2398 | } | 2401 | } |
2399 | 2402 | ||
2400 | if (test_and_clear_bit(FCPORT_RESCAN_NEEDED, &ha->dpc_flags)) { | ||
2401 | |||
2402 | DEBUG(printk("scsi(%ld): Rescan flagged fcports...\n", | ||
2403 | ha->host_no)); | ||
2404 | |||
2405 | qla2x00_rescan_fcports(ha); | ||
2406 | |||
2407 | DEBUG(printk("scsi(%ld): Rescan flagged fcports..." | ||
2408 | "end.\n", | ||
2409 | ha->host_no)); | ||
2410 | } | ||
2411 | |||
2412 | if (!ha->interrupts_on) | 2403 | if (!ha->interrupts_on) |
2413 | ha->isp_ops->enable_intrs(ha); | 2404 | ha->isp_ops->enable_intrs(ha); |
2414 | 2405 | ||
@@ -2586,7 +2577,8 @@ qla2x00_timer(scsi_qla_host_t *ha) | |||
2586 | set_bit(RESTART_QUEUES_NEEDED, &ha->dpc_flags); | 2577 | set_bit(RESTART_QUEUES_NEEDED, &ha->dpc_flags); |
2587 | start_dpc++; | 2578 | start_dpc++; |
2588 | 2579 | ||
2589 | if (!(ha->device_flags & DFLG_NO_CABLE)) { | 2580 | if (!(ha->device_flags & DFLG_NO_CABLE) && |
2581 | !ha->parent) { | ||
2590 | DEBUG(printk("scsi(%ld): Loop down - " | 2582 | DEBUG(printk("scsi(%ld): Loop down - " |
2591 | "aborting ISP.\n", | 2583 | "aborting ISP.\n", |
2592 | ha->host_no)); | 2584 | ha->host_no)); |
@@ -2610,10 +2602,8 @@ qla2x00_timer(scsi_qla_host_t *ha) | |||
2610 | /* Schedule the DPC routine if needed */ | 2602 | /* Schedule the DPC routine if needed */ |
2611 | if ((test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) || | 2603 | if ((test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) || |
2612 | test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) || | 2604 | test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) || |
2613 | test_bit(LOOP_RESET_NEEDED, &ha->dpc_flags) || | ||
2614 | test_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags) || | 2605 | test_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags) || |
2615 | start_dpc || | 2606 | start_dpc || |
2616 | test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags) || | ||
2617 | test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) || | 2607 | test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) || |
2618 | test_bit(BEACON_BLINK_NEEDED, &ha->dpc_flags) || | 2608 | test_bit(BEACON_BLINK_NEEDED, &ha->dpc_flags) || |
2619 | test_bit(VP_DPC_NEEDED, &ha->dpc_flags) || | 2609 | test_bit(VP_DPC_NEEDED, &ha->dpc_flags) || |
@@ -2665,7 +2655,7 @@ qla2x00_request_firmware(scsi_qla_host_t *ha) | |||
2665 | blob = &qla_fw_blobs[FW_ISP2300]; | 2655 | blob = &qla_fw_blobs[FW_ISP2300]; |
2666 | } else if (IS_QLA2322(ha) || IS_QLA6322(ha)) { | 2656 | } else if (IS_QLA2322(ha) || IS_QLA6322(ha)) { |
2667 | blob = &qla_fw_blobs[FW_ISP2322]; | 2657 | blob = &qla_fw_blobs[FW_ISP2322]; |
2668 | } else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | 2658 | } else if (IS_QLA24XX_TYPE(ha)) { |
2669 | blob = &qla_fw_blobs[FW_ISP24XX]; | 2659 | blob = &qla_fw_blobs[FW_ISP24XX]; |
2670 | } else if (IS_QLA25XX(ha)) { | 2660 | } else if (IS_QLA25XX(ha)) { |
2671 | blob = &qla_fw_blobs[FW_ISP25XX]; | 2661 | blob = &qla_fw_blobs[FW_ISP25XX]; |
@@ -2815,6 +2805,7 @@ static struct pci_device_id qla2xxx_pci_tbl[] = { | |||
2815 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP6322) }, | 2805 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP6322) }, |
2816 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2422) }, | 2806 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2422) }, |
2817 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2432) }, | 2807 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2432) }, |
2808 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP8432) }, | ||
2818 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5422) }, | 2809 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5422) }, |
2819 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5432) }, | 2810 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5432) }, |
2820 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2532) }, | 2811 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2532) }, |
diff --git a/drivers/scsi/qla2xxx/qla_settings.h b/drivers/scsi/qla2xxx/qla_settings.h index 249e4d90fdc5..2801c2664b40 100644 --- a/drivers/scsi/qla2xxx/qla_settings.h +++ b/drivers/scsi/qla2xxx/qla_settings.h | |||
@@ -1,26 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
7 | /* | ||
8 | * Compile time Options: | ||
9 | * 0 - Disable and 1 - Enable | ||
10 | */ | ||
11 | #define DEBUG_QLA2100 0 /* For Debug of qla2x00 */ | ||
12 | |||
13 | #define USE_ABORT_TGT 1 /* Use Abort Target mbx cmd */ | ||
14 | |||
15 | #define MAX_RETRIES_OF_ISP_ABORT 5 | 7 | #define MAX_RETRIES_OF_ISP_ABORT 5 |
16 | 8 | ||
17 | /* Max time to wait for the loop to be in LOOP_READY state */ | 9 | /* Max time to wait for the loop to be in LOOP_READY state */ |
18 | #define MAX_LOOP_TIMEOUT (60 * 5) | 10 | #define MAX_LOOP_TIMEOUT (60 * 5) |
19 | 11 | ||
20 | /* | ||
21 | * Some vendor subsystems do not recover properly after a device reset. Define | ||
22 | * the following to force a logout after a successful device reset. | ||
23 | */ | ||
24 | #undef LOGOUT_AFTER_DEVICE_RESET | ||
25 | |||
26 | #include "qla_version.h" | 12 | #include "qla_version.h" |
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index 26822c8807ee..1728ab3ccb20 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -543,79 +543,174 @@ qla24xx_get_flash_manufacturer(scsi_qla_host_t *ha, uint8_t *man_id, | |||
543 | } | 543 | } |
544 | } | 544 | } |
545 | 545 | ||
546 | static int | 546 | void |
547 | qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, | 547 | qla2xxx_get_flash_info(scsi_qla_host_t *ha) |
548 | uint32_t dwords) | ||
549 | { | 548 | { |
550 | int ret; | 549 | #define FLASH_BLK_SIZE_32K 0x8000 |
551 | uint32_t liter, miter; | 550 | #define FLASH_BLK_SIZE_64K 0x10000 |
552 | uint32_t sec_mask, rest_addr, conf_addr; | 551 | uint16_t cnt, chksum; |
553 | uint32_t fdata, findex, cnt; | 552 | uint16_t *wptr; |
553 | struct qla_fdt_layout *fdt; | ||
554 | uint8_t man_id, flash_id; | 554 | uint8_t man_id, flash_id; |
555 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | ||
556 | dma_addr_t optrom_dma; | ||
557 | void *optrom = NULL; | ||
558 | uint32_t *s, *d; | ||
559 | 555 | ||
560 | ret = QLA_SUCCESS; | 556 | if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha)) |
557 | return; | ||
561 | 558 | ||
562 | /* Prepare burst-capable write on supported ISPs. */ | 559 | wptr = (uint16_t *)ha->request_ring; |
563 | if (IS_QLA25XX(ha) && !(faddr & 0xfff) && | 560 | fdt = (struct qla_fdt_layout *)ha->request_ring; |
564 | dwords > OPTROM_BURST_DWORDS) { | 561 | ha->isp_ops->read_optrom(ha, (uint8_t *)ha->request_ring, |
565 | optrom = dma_alloc_coherent(&ha->pdev->dev, OPTROM_BURST_SIZE, | 562 | FA_FLASH_DESCR_ADDR << 2, OPTROM_BURST_SIZE); |
566 | &optrom_dma, GFP_KERNEL); | 563 | if (*wptr == __constant_cpu_to_le16(0xffff)) |
567 | if (!optrom) { | 564 | goto no_flash_data; |
568 | qla_printk(KERN_DEBUG, ha, | 565 | if (fdt->sig[0] != 'Q' || fdt->sig[1] != 'L' || fdt->sig[2] != 'I' || |
569 | "Unable to allocate memory for optrom burst write " | 566 | fdt->sig[3] != 'D') |
570 | "(%x KB).\n", OPTROM_BURST_SIZE / 1024); | 567 | goto no_flash_data; |
571 | } | 568 | |
569 | for (cnt = 0, chksum = 0; cnt < sizeof(struct qla_fdt_layout) >> 1; | ||
570 | cnt++) | ||
571 | chksum += le16_to_cpu(*wptr++); | ||
572 | if (chksum) { | ||
573 | DEBUG2(qla_printk(KERN_INFO, ha, "Inconsistent FDT detected: " | ||
574 | "checksum=0x%x id=%c version=0x%x.\n", chksum, fdt->sig[0], | ||
575 | le16_to_cpu(fdt->version))); | ||
576 | DEBUG9(qla2x00_dump_buffer((uint8_t *)fdt, sizeof(*fdt))); | ||
577 | goto no_flash_data; | ||
572 | } | 578 | } |
573 | 579 | ||
574 | qla24xx_get_flash_manufacturer(ha, &man_id, &flash_id); | 580 | ha->fdt_odd_index = le16_to_cpu(fdt->man_id) == 0x1f; |
575 | DEBUG9(printk("%s(%ld): Flash man_id=%d flash_id=%d\n", __func__, | 581 | ha->fdt_wrt_disable = fdt->wrt_disable_bits; |
576 | ha->host_no, man_id, flash_id)); | 582 | ha->fdt_erase_cmd = flash_conf_to_access_addr(0x0300 | fdt->erase_cmd); |
583 | ha->fdt_block_size = le32_to_cpu(fdt->block_size); | ||
584 | if (fdt->unprotect_sec_cmd) { | ||
585 | ha->fdt_unprotect_sec_cmd = flash_conf_to_access_addr(0x0300 | | ||
586 | fdt->unprotect_sec_cmd); | ||
587 | ha->fdt_protect_sec_cmd = fdt->protect_sec_cmd ? | ||
588 | flash_conf_to_access_addr(0x0300 | fdt->protect_sec_cmd): | ||
589 | flash_conf_to_access_addr(0x0336); | ||
590 | } | ||
577 | 591 | ||
578 | conf_addr = flash_conf_to_access_addr(0x03d8); | 592 | DEBUG2(qla_printk(KERN_DEBUG, ha, "Flash[FDT]: (0x%x/0x%x) erase=0x%x " |
593 | "pro=%x upro=%x idx=%d wrtd=0x%x blk=0x%x.\n", | ||
594 | le16_to_cpu(fdt->man_id), le16_to_cpu(fdt->id), ha->fdt_erase_cmd, | ||
595 | ha->fdt_protect_sec_cmd, ha->fdt_unprotect_sec_cmd, | ||
596 | ha->fdt_odd_index, ha->fdt_wrt_disable, ha->fdt_block_size)); | ||
597 | return; | ||
598 | |||
599 | no_flash_data: | ||
600 | qla24xx_get_flash_manufacturer(ha, &man_id, &flash_id); | ||
601 | ha->fdt_wrt_disable = 0x9c; | ||
602 | ha->fdt_erase_cmd = flash_conf_to_access_addr(0x03d8); | ||
579 | switch (man_id) { | 603 | switch (man_id) { |
580 | case 0xbf: /* STT flash. */ | 604 | case 0xbf: /* STT flash. */ |
581 | if (flash_id == 0x8e) { | 605 | if (flash_id == 0x8e) |
582 | rest_addr = 0x3fff; | 606 | ha->fdt_block_size = FLASH_BLK_SIZE_64K; |
583 | sec_mask = 0x7c000; | 607 | else |
584 | } else { | 608 | ha->fdt_block_size = FLASH_BLK_SIZE_32K; |
585 | rest_addr = 0x1fff; | 609 | |
586 | sec_mask = 0x7e000; | ||
587 | } | ||
588 | if (flash_id == 0x80) | 610 | if (flash_id == 0x80) |
589 | conf_addr = flash_conf_to_access_addr(0x0352); | 611 | ha->fdt_erase_cmd = flash_conf_to_access_addr(0x0352); |
590 | break; | 612 | break; |
591 | case 0x13: /* ST M25P80. */ | 613 | case 0x13: /* ST M25P80. */ |
592 | rest_addr = 0x3fff; | 614 | ha->fdt_block_size = FLASH_BLK_SIZE_64K; |
593 | sec_mask = 0x7c000; | ||
594 | break; | 615 | break; |
595 | case 0x1f: // Atmel 26DF081A | 616 | case 0x1f: /* Atmel 26DF081A. */ |
596 | rest_addr = 0x3fff; | 617 | ha->fdt_odd_index = 1; |
597 | sec_mask = 0x7c000; | 618 | ha->fdt_block_size = FLASH_BLK_SIZE_64K; |
598 | conf_addr = flash_conf_to_access_addr(0x0320); | 619 | ha->fdt_erase_cmd = flash_conf_to_access_addr(0x0320); |
620 | ha->fdt_unprotect_sec_cmd = flash_conf_to_access_addr(0x0339); | ||
621 | ha->fdt_protect_sec_cmd = flash_conf_to_access_addr(0x0336); | ||
599 | break; | 622 | break; |
600 | default: | 623 | default: |
601 | /* Default to 64 kb sector size. */ | 624 | /* Default to 64 kb sector size. */ |
602 | rest_addr = 0x3fff; | 625 | ha->fdt_block_size = FLASH_BLK_SIZE_64K; |
603 | sec_mask = 0x7c000; | ||
604 | break; | 626 | break; |
605 | } | 627 | } |
606 | 628 | ||
629 | DEBUG2(qla_printk(KERN_DEBUG, ha, "Flash[MID]: (0x%x/0x%x) erase=0x%x " | ||
630 | "pro=%x upro=%x idx=%d wrtd=0x%x blk=0x%x.\n", man_id, flash_id, | ||
631 | ha->fdt_erase_cmd, ha->fdt_protect_sec_cmd, | ||
632 | ha->fdt_unprotect_sec_cmd, ha->fdt_odd_index, ha->fdt_wrt_disable, | ||
633 | ha->fdt_block_size)); | ||
634 | } | ||
635 | |||
636 | static void | ||
637 | qla24xx_unprotect_flash(scsi_qla_host_t *ha) | ||
638 | { | ||
639 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | ||
640 | |||
607 | /* Enable flash write. */ | 641 | /* Enable flash write. */ |
608 | WRT_REG_DWORD(®->ctrl_status, | 642 | WRT_REG_DWORD(®->ctrl_status, |
609 | RD_REG_DWORD(®->ctrl_status) | CSRX_FLASH_ENABLE); | 643 | RD_REG_DWORD(®->ctrl_status) | CSRX_FLASH_ENABLE); |
610 | RD_REG_DWORD(®->ctrl_status); /* PCI Posting. */ | 644 | RD_REG_DWORD(®->ctrl_status); /* PCI Posting. */ |
611 | 645 | ||
646 | if (!ha->fdt_wrt_disable) | ||
647 | return; | ||
648 | |||
612 | /* Disable flash write-protection. */ | 649 | /* Disable flash write-protection. */ |
613 | qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), 0); | 650 | qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), 0); |
614 | /* Some flash parts need an additional zero-write to clear bits.*/ | 651 | /* Some flash parts need an additional zero-write to clear bits.*/ |
615 | qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), 0); | 652 | qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), 0); |
653 | } | ||
654 | |||
655 | static void | ||
656 | qla24xx_protect_flash(scsi_qla_host_t *ha) | ||
657 | { | ||
658 | uint32_t cnt; | ||
659 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | ||
660 | |||
661 | if (!ha->fdt_wrt_disable) | ||
662 | goto skip_wrt_protect; | ||
663 | |||
664 | /* Enable flash write-protection and wait for completion. */ | ||
665 | qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), | ||
666 | ha->fdt_wrt_disable); | ||
667 | for (cnt = 300; cnt && | ||
668 | qla24xx_read_flash_dword(ha, | ||
669 | flash_conf_to_access_addr(0x005)) & BIT_0; | ||
670 | cnt--) { | ||
671 | udelay(10); | ||
672 | } | ||
673 | |||
674 | skip_wrt_protect: | ||
675 | /* Disable flash write. */ | ||
676 | WRT_REG_DWORD(®->ctrl_status, | ||
677 | RD_REG_DWORD(®->ctrl_status) & ~CSRX_FLASH_ENABLE); | ||
678 | RD_REG_DWORD(®->ctrl_status); /* PCI Posting. */ | ||
679 | } | ||
680 | |||
681 | static int | ||
682 | qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, | ||
683 | uint32_t dwords) | ||
684 | { | ||
685 | int ret; | ||
686 | uint32_t liter, miter; | ||
687 | uint32_t sec_mask, rest_addr; | ||
688 | uint32_t fdata, findex; | ||
689 | dma_addr_t optrom_dma; | ||
690 | void *optrom = NULL; | ||
691 | uint32_t *s, *d; | ||
692 | |||
693 | ret = QLA_SUCCESS; | ||
694 | |||
695 | /* Prepare burst-capable write on supported ISPs. */ | ||
696 | if (IS_QLA25XX(ha) && !(faddr & 0xfff) && | ||
697 | dwords > OPTROM_BURST_DWORDS) { | ||
698 | optrom = dma_alloc_coherent(&ha->pdev->dev, OPTROM_BURST_SIZE, | ||
699 | &optrom_dma, GFP_KERNEL); | ||
700 | if (!optrom) { | ||
701 | qla_printk(KERN_DEBUG, ha, | ||
702 | "Unable to allocate memory for optrom burst write " | ||
703 | "(%x KB).\n", OPTROM_BURST_SIZE / 1024); | ||
704 | } | ||
705 | } | ||
706 | |||
707 | rest_addr = (ha->fdt_block_size >> 2) - 1; | ||
708 | sec_mask = 0x80000 - (ha->fdt_block_size >> 2); | ||
709 | |||
710 | qla24xx_unprotect_flash(ha); | ||
616 | 711 | ||
617 | for (liter = 0; liter < dwords; liter++, faddr++, dwptr++) { | 712 | for (liter = 0; liter < dwords; liter++, faddr++, dwptr++) { |
618 | if (man_id == 0x1f) { | 713 | if (ha->fdt_odd_index) { |
619 | findex = faddr << 2; | 714 | findex = faddr << 2; |
620 | fdata = findex & sec_mask; | 715 | fdata = findex & sec_mask; |
621 | } else { | 716 | } else { |
@@ -625,13 +720,13 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, | |||
625 | 720 | ||
626 | /* Are we at the beginning of a sector? */ | 721 | /* Are we at the beginning of a sector? */ |
627 | if ((findex & rest_addr) == 0) { | 722 | if ((findex & rest_addr) == 0) { |
628 | /* Do sector unprotect at 4K boundry for Atmel part. */ | 723 | /* Do sector unprotect. */ |
629 | if (man_id == 0x1f) | 724 | if (ha->fdt_unprotect_sec_cmd) |
630 | qla24xx_write_flash_dword(ha, | 725 | qla24xx_write_flash_dword(ha, |
631 | flash_conf_to_access_addr(0x0339), | 726 | ha->fdt_unprotect_sec_cmd, |
632 | (fdata & 0xff00) | ((fdata << 16) & | 727 | (fdata & 0xff00) | ((fdata << 16) & |
633 | 0xff0000) | ((fdata >> 16) & 0xff)); | 728 | 0xff0000) | ((fdata >> 16) & 0xff)); |
634 | ret = qla24xx_write_flash_dword(ha, conf_addr, | 729 | ret = qla24xx_write_flash_dword(ha, ha->fdt_erase_cmd, |
635 | (fdata & 0xff00) |((fdata << 16) & | 730 | (fdata & 0xff00) |((fdata << 16) & |
636 | 0xff0000) | ((fdata >> 16) & 0xff)); | 731 | 0xff0000) | ((fdata >> 16) & 0xff)); |
637 | if (ret != QLA_SUCCESS) { | 732 | if (ret != QLA_SUCCESS) { |
@@ -681,28 +776,16 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, | |||
681 | break; | 776 | break; |
682 | } | 777 | } |
683 | 778 | ||
684 | /* Do sector protect at 4K boundry for Atmel part. */ | 779 | /* Do sector protect. */ |
685 | if (man_id == 0x1f && | 780 | if (ha->fdt_unprotect_sec_cmd && |
686 | ((faddr & rest_addr) == rest_addr)) | 781 | ((faddr & rest_addr) == rest_addr)) |
687 | qla24xx_write_flash_dword(ha, | 782 | qla24xx_write_flash_dword(ha, |
688 | flash_conf_to_access_addr(0x0336), | 783 | ha->fdt_protect_sec_cmd, |
689 | (fdata & 0xff00) | ((fdata << 16) & | 784 | (fdata & 0xff00) | ((fdata << 16) & |
690 | 0xff0000) | ((fdata >> 16) & 0xff)); | 785 | 0xff0000) | ((fdata >> 16) & 0xff)); |
691 | } | 786 | } |
692 | 787 | ||
693 | /* Enable flash write-protection and wait for completion. */ | 788 | qla24xx_protect_flash(ha); |
694 | qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), 0x9c); | ||
695 | for (cnt = 300; cnt && | ||
696 | qla24xx_read_flash_dword(ha, | ||
697 | flash_conf_to_access_addr(0x005)) & BIT_0; | ||
698 | cnt--) { | ||
699 | udelay(10); | ||
700 | } | ||
701 | |||
702 | /* Disable flash write. */ | ||
703 | WRT_REG_DWORD(®->ctrl_status, | ||
704 | RD_REG_DWORD(®->ctrl_status) & ~CSRX_FLASH_ENABLE); | ||
705 | RD_REG_DWORD(®->ctrl_status); /* PCI Posting. */ | ||
706 | 789 | ||
707 | if (optrom) | 790 | if (optrom) |
708 | dma_free_coherent(&ha->pdev->dev, | 791 | dma_free_coherent(&ha->pdev->dev, |
@@ -2221,3 +2304,107 @@ qla24xx_get_flash_version(scsi_qla_host_t *ha, void *mbuf) | |||
2221 | 2304 | ||
2222 | return ret; | 2305 | return ret; |
2223 | } | 2306 | } |
2307 | |||
2308 | static int | ||
2309 | qla2xxx_hw_event_store(scsi_qla_host_t *ha, uint32_t *fdata) | ||
2310 | { | ||
2311 | uint32_t d[2], faddr; | ||
2312 | |||
2313 | /* Locate first empty entry. */ | ||
2314 | for (;;) { | ||
2315 | if (ha->hw_event_ptr >= | ||
2316 | ha->hw_event_start + FA_HW_EVENT_SIZE) { | ||
2317 | DEBUG2(qla_printk(KERN_WARNING, ha, | ||
2318 | "HW event -- Log Full!\n")); | ||
2319 | return QLA_MEMORY_ALLOC_FAILED; | ||
2320 | } | ||
2321 | |||
2322 | qla24xx_read_flash_data(ha, d, ha->hw_event_ptr, 2); | ||
2323 | faddr = flash_data_to_access_addr(ha->hw_event_ptr); | ||
2324 | ha->hw_event_ptr += FA_HW_EVENT_ENTRY_SIZE; | ||
2325 | if (d[0] == __constant_cpu_to_le32(0xffffffff) && | ||
2326 | d[1] == __constant_cpu_to_le32(0xffffffff)) { | ||
2327 | qla24xx_unprotect_flash(ha); | ||
2328 | |||
2329 | qla24xx_write_flash_dword(ha, faddr++, | ||
2330 | cpu_to_le32(jiffies)); | ||
2331 | qla24xx_write_flash_dword(ha, faddr++, 0); | ||
2332 | qla24xx_write_flash_dword(ha, faddr++, *fdata++); | ||
2333 | qla24xx_write_flash_dword(ha, faddr++, *fdata); | ||
2334 | |||
2335 | qla24xx_protect_flash(ha); | ||
2336 | break; | ||
2337 | } | ||
2338 | } | ||
2339 | return QLA_SUCCESS; | ||
2340 | } | ||
2341 | |||
2342 | int | ||
2343 | qla2xxx_hw_event_log(scsi_qla_host_t *ha, uint16_t code, uint16_t d1, | ||
2344 | uint16_t d2, uint16_t d3) | ||
2345 | { | ||
2346 | #define QMARK(a, b, c, d) \ | ||
2347 | cpu_to_le32(LSB(a) << 24 | LSB(b) << 16 | LSB(c) << 8 | LSB(d)) | ||
2348 | |||
2349 | int rval; | ||
2350 | uint32_t marker[2], fdata[4]; | ||
2351 | |||
2352 | if (ha->hw_event_start == 0) | ||
2353 | return QLA_FUNCTION_FAILED; | ||
2354 | |||
2355 | DEBUG2(qla_printk(KERN_WARNING, ha, | ||
2356 | "HW event -- code=%x, d1=%x, d2=%x, d3=%x.\n", code, d1, d2, d3)); | ||
2357 | |||
2358 | /* If marker not already found, locate or write. */ | ||
2359 | if (!ha->flags.hw_event_marker_found) { | ||
2360 | /* Create marker. */ | ||
2361 | marker[0] = QMARK('L', ha->fw_major_version, | ||
2362 | ha->fw_minor_version, ha->fw_subminor_version); | ||
2363 | marker[1] = QMARK(QLA_DRIVER_MAJOR_VER, QLA_DRIVER_MINOR_VER, | ||
2364 | QLA_DRIVER_PATCH_VER, QLA_DRIVER_BETA_VER); | ||
2365 | |||
2366 | /* Locate marker. */ | ||
2367 | ha->hw_event_ptr = ha->hw_event_start; | ||
2368 | for (;;) { | ||
2369 | qla24xx_read_flash_data(ha, fdata, ha->hw_event_ptr, | ||
2370 | 4); | ||
2371 | if (fdata[0] == __constant_cpu_to_le32(0xffffffff) && | ||
2372 | fdata[1] == __constant_cpu_to_le32(0xffffffff)) | ||
2373 | break; | ||
2374 | ha->hw_event_ptr += FA_HW_EVENT_ENTRY_SIZE; | ||
2375 | if (ha->hw_event_ptr >= | ||
2376 | ha->hw_event_start + FA_HW_EVENT_SIZE) { | ||
2377 | DEBUG2(qla_printk(KERN_WARNING, ha, | ||
2378 | "HW event -- Log Full!\n")); | ||
2379 | return QLA_MEMORY_ALLOC_FAILED; | ||
2380 | } | ||
2381 | if (fdata[2] == marker[0] && fdata[3] == marker[1]) { | ||
2382 | ha->flags.hw_event_marker_found = 1; | ||
2383 | break; | ||
2384 | } | ||
2385 | } | ||
2386 | /* No marker, write it. */ | ||
2387 | if (!ha->flags.hw_event_marker_found) { | ||
2388 | rval = qla2xxx_hw_event_store(ha, marker); | ||
2389 | if (rval != QLA_SUCCESS) { | ||
2390 | DEBUG2(qla_printk(KERN_WARNING, ha, | ||
2391 | "HW event -- Failed marker write=%x.!\n", | ||
2392 | rval)); | ||
2393 | return rval; | ||
2394 | } | ||
2395 | ha->flags.hw_event_marker_found = 1; | ||
2396 | } | ||
2397 | } | ||
2398 | |||
2399 | /* Store error. */ | ||
2400 | fdata[0] = cpu_to_le32(code << 16 | d1); | ||
2401 | fdata[1] = cpu_to_le32(d2 << 16 | d3); | ||
2402 | rval = qla2xxx_hw_event_store(ha, fdata); | ||
2403 | if (rval != QLA_SUCCESS) { | ||
2404 | DEBUG2(qla_printk(KERN_WARNING, ha, | ||
2405 | "HW event -- Failed error write=%x.!\n", | ||
2406 | rval)); | ||
2407 | } | ||
2408 | |||
2409 | return rval; | ||
2410 | } | ||
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index ea08a129fee9..f42f17acf2cf 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h | |||
@@ -1,15 +1,15 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
7 | /* | 7 | /* |
8 | * Driver version | 8 | * Driver version |
9 | */ | 9 | */ |
10 | #define QLA2XXX_VERSION "8.02.00-k9" | 10 | #define QLA2XXX_VERSION "8.02.01-k1" |
11 | 11 | ||
12 | #define QLA_DRIVER_MAJOR_VER 8 | 12 | #define QLA_DRIVER_MAJOR_VER 8 |
13 | #define QLA_DRIVER_MINOR_VER 2 | 13 | #define QLA_DRIVER_MINOR_VER 2 |
14 | #define QLA_DRIVER_PATCH_VER 0 | 14 | #define QLA_DRIVER_PATCH_VER 1 |
15 | #define QLA_DRIVER_BETA_VER 0 | 15 | #define QLA_DRIVER_BETA_VER 0 |
diff --git a/drivers/scsi/qla4xxx/ql4_fw.h b/drivers/scsi/qla4xxx/ql4_fw.h index fe415ec85655..1b667a70cffa 100644 --- a/drivers/scsi/qla4xxx/ql4_fw.h +++ b/drivers/scsi/qla4xxx/ql4_fw.h | |||
@@ -216,6 +216,7 @@ union external_hw_config_reg { | |||
216 | #define MBOX_CMD_ABOUT_FW 0x0009 | 216 | #define MBOX_CMD_ABOUT_FW 0x0009 |
217 | #define MBOX_CMD_PING 0x000B | 217 | #define MBOX_CMD_PING 0x000B |
218 | #define MBOX_CMD_LUN_RESET 0x0016 | 218 | #define MBOX_CMD_LUN_RESET 0x0016 |
219 | #define MBOX_CMD_TARGET_WARM_RESET 0x0017 | ||
219 | #define MBOX_CMD_GET_MANAGEMENT_DATA 0x001E | 220 | #define MBOX_CMD_GET_MANAGEMENT_DATA 0x001E |
220 | #define MBOX_CMD_GET_FW_STATUS 0x001F | 221 | #define MBOX_CMD_GET_FW_STATUS 0x001F |
221 | #define MBOX_CMD_SET_ISNS_SERVICE 0x0021 | 222 | #define MBOX_CMD_SET_ISNS_SERVICE 0x0021 |
@@ -677,7 +678,8 @@ struct qla4_marker_entry { | |||
677 | uint32_t system_defined; /* 04-07 */ | 678 | uint32_t system_defined; /* 04-07 */ |
678 | uint16_t target; /* 08-09 */ | 679 | uint16_t target; /* 08-09 */ |
679 | uint16_t modifier; /* 0A-0B */ | 680 | uint16_t modifier; /* 0A-0B */ |
680 | #define MM_LUN_RESET 0 | 681 | #define MM_LUN_RESET 0 |
682 | #define MM_TGT_WARM_RESET 1 | ||
681 | 683 | ||
682 | uint16_t flags; /* 0C-0D */ | 684 | uint16_t flags; /* 0C-0D */ |
683 | uint16_t reserved1; /* 0E-0F */ | 685 | uint16_t reserved1; /* 0E-0F */ |
diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h index a3608e028bf6..96ebfb021f6c 100644 --- a/drivers/scsi/qla4xxx/ql4_glbl.h +++ b/drivers/scsi/qla4xxx/ql4_glbl.h | |||
@@ -27,6 +27,8 @@ int qla4xxx_relogin_device(struct scsi_qla_host * ha, | |||
27 | struct ddb_entry * ddb_entry); | 27 | struct ddb_entry * ddb_entry); |
28 | int qla4xxx_reset_lun(struct scsi_qla_host * ha, struct ddb_entry * ddb_entry, | 28 | int qla4xxx_reset_lun(struct scsi_qla_host * ha, struct ddb_entry * ddb_entry, |
29 | int lun); | 29 | int lun); |
30 | int qla4xxx_reset_target(struct scsi_qla_host * ha, | ||
31 | struct ddb_entry * ddb_entry); | ||
30 | int qla4xxx_get_flash(struct scsi_qla_host * ha, dma_addr_t dma_addr, | 32 | int qla4xxx_get_flash(struct scsi_qla_host * ha, dma_addr_t dma_addr, |
31 | uint32_t offset, uint32_t len); | 33 | uint32_t offset, uint32_t len); |
32 | int qla4xxx_get_firmware_status(struct scsi_qla_host * ha); | 34 | int qla4xxx_get_firmware_status(struct scsi_qla_host * ha); |
@@ -68,6 +70,8 @@ int qla4xxx_reinitialize_ddb_list(struct scsi_qla_host * ha); | |||
68 | int qla4xxx_process_ddb_changed(struct scsi_qla_host * ha, | 70 | int qla4xxx_process_ddb_changed(struct scsi_qla_host * ha, |
69 | uint32_t fw_ddb_index, uint32_t state); | 71 | uint32_t fw_ddb_index, uint32_t state); |
70 | void qla4xxx_dump_buffer(void *b, uint32_t size); | 72 | void qla4xxx_dump_buffer(void *b, uint32_t size); |
73 | int qla4xxx_send_marker_iocb(struct scsi_qla_host *ha, | ||
74 | struct ddb_entry *ddb_entry, int lun, uint16_t mrkr_mod); | ||
71 | 75 | ||
72 | extern int ql4xextended_error_logging; | 76 | extern int ql4xextended_error_logging; |
73 | extern int ql4xdiscoverywait; | 77 | extern int ql4xdiscoverywait; |
diff --git a/drivers/scsi/qla4xxx/ql4_iocb.c b/drivers/scsi/qla4xxx/ql4_iocb.c index e4461b5d767a..912a67494adf 100644 --- a/drivers/scsi/qla4xxx/ql4_iocb.c +++ b/drivers/scsi/qla4xxx/ql4_iocb.c | |||
@@ -66,8 +66,8 @@ static int qla4xxx_get_req_pkt(struct scsi_qla_host *ha, | |||
66 | * | 66 | * |
67 | * This routine issues a marker IOCB. | 67 | * This routine issues a marker IOCB. |
68 | **/ | 68 | **/ |
69 | static int qla4xxx_send_marker_iocb(struct scsi_qla_host *ha, | 69 | int qla4xxx_send_marker_iocb(struct scsi_qla_host *ha, |
70 | struct ddb_entry *ddb_entry, int lun) | 70 | struct ddb_entry *ddb_entry, int lun, uint16_t mrkr_mod) |
71 | { | 71 | { |
72 | struct qla4_marker_entry *marker_entry; | 72 | struct qla4_marker_entry *marker_entry; |
73 | unsigned long flags = 0; | 73 | unsigned long flags = 0; |
@@ -87,7 +87,7 @@ static int qla4xxx_send_marker_iocb(struct scsi_qla_host *ha, | |||
87 | marker_entry->hdr.entryType = ET_MARKER; | 87 | marker_entry->hdr.entryType = ET_MARKER; |
88 | marker_entry->hdr.entryCount = 1; | 88 | marker_entry->hdr.entryCount = 1; |
89 | marker_entry->target = cpu_to_le16(ddb_entry->fw_ddb_index); | 89 | marker_entry->target = cpu_to_le16(ddb_entry->fw_ddb_index); |
90 | marker_entry->modifier = cpu_to_le16(MM_LUN_RESET); | 90 | marker_entry->modifier = cpu_to_le16(mrkr_mod); |
91 | int_to_scsilun(lun, &marker_entry->lun); | 91 | int_to_scsilun(lun, &marker_entry->lun); |
92 | wmb(); | 92 | wmb(); |
93 | 93 | ||
@@ -210,14 +210,6 @@ int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb) | |||
210 | /* Get real lun and adapter */ | 210 | /* Get real lun and adapter */ |
211 | ddb_entry = srb->ddb; | 211 | ddb_entry = srb->ddb; |
212 | 212 | ||
213 | /* Send marker(s) if needed. */ | ||
214 | if (ha->marker_needed == 1) { | ||
215 | if (qla4xxx_send_marker_iocb(ha, ddb_entry, | ||
216 | cmd->device->lun) != QLA_SUCCESS) | ||
217 | return QLA_ERROR; | ||
218 | |||
219 | ha->marker_needed = 0; | ||
220 | } | ||
221 | tot_dsds = 0; | 213 | tot_dsds = 0; |
222 | 214 | ||
223 | /* Acquire hardware specific lock */ | 215 | /* Acquire hardware specific lock */ |
diff --git a/drivers/scsi/qla4xxx/ql4_isr.c b/drivers/scsi/qla4xxx/ql4_isr.c index fc84db4069f4..a91a57c57bff 100644 --- a/drivers/scsi/qla4xxx/ql4_isr.c +++ b/drivers/scsi/qla4xxx/ql4_isr.c | |||
@@ -11,28 +11,6 @@ | |||
11 | #include "ql4_inline.h" | 11 | #include "ql4_inline.h" |
12 | 12 | ||
13 | /** | 13 | /** |
14 | * qla2x00_process_completed_request() - Process a Fast Post response. | ||
15 | * @ha: SCSI driver HA context | ||
16 | * @index: SRB index | ||
17 | **/ | ||
18 | static void qla4xxx_process_completed_request(struct scsi_qla_host *ha, | ||
19 | uint32_t index) | ||
20 | { | ||
21 | struct srb *srb; | ||
22 | |||
23 | srb = qla4xxx_del_from_active_array(ha, index); | ||
24 | if (srb) { | ||
25 | /* Save ISP completion status */ | ||
26 | srb->cmd->result = DID_OK << 16; | ||
27 | qla4xxx_srb_compl(ha, srb); | ||
28 | } else { | ||
29 | DEBUG2(printk("scsi%ld: Invalid ISP SCSI completion handle = " | ||
30 | "%d\n", ha->host_no, index)); | ||
31 | set_bit(DPC_RESET_HA, &ha->dpc_flags); | ||
32 | } | ||
33 | } | ||
34 | |||
35 | /** | ||
36 | * qla4xxx_status_entry - processes status IOCBs | 14 | * qla4xxx_status_entry - processes status IOCBs |
37 | * @ha: Pointer to host adapter structure. | 15 | * @ha: Pointer to host adapter structure. |
38 | * @sts_entry: Pointer to status entry structure. | 16 | * @sts_entry: Pointer to status entry structure. |
@@ -47,14 +25,6 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha, | |||
47 | uint32_t residual; | 25 | uint32_t residual; |
48 | uint16_t sensebytecnt; | 26 | uint16_t sensebytecnt; |
49 | 27 | ||
50 | if (sts_entry->completionStatus == SCS_COMPLETE && | ||
51 | sts_entry->scsiStatus == 0) { | ||
52 | qla4xxx_process_completed_request(ha, | ||
53 | le32_to_cpu(sts_entry-> | ||
54 | handle)); | ||
55 | return; | ||
56 | } | ||
57 | |||
58 | srb = qla4xxx_del_from_active_array(ha, le32_to_cpu(sts_entry->handle)); | 28 | srb = qla4xxx_del_from_active_array(ha, le32_to_cpu(sts_entry->handle)); |
59 | if (!srb) { | 29 | if (!srb) { |
60 | /* FIXMEdg: Don't we need to reset ISP in this case??? */ | 30 | /* FIXMEdg: Don't we need to reset ISP in this case??? */ |
@@ -62,6 +32,9 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha, | |||
62 | "handle 0x%x, sp=%p. This cmd may have already " | 32 | "handle 0x%x, sp=%p. This cmd may have already " |
63 | "been completed.\n", ha->host_no, __func__, | 33 | "been completed.\n", ha->host_no, __func__, |
64 | le32_to_cpu(sts_entry->handle), srb)); | 34 | le32_to_cpu(sts_entry->handle), srb)); |
35 | dev_warn(&ha->pdev->dev, "%s invalid status entry:" | ||
36 | " handle=0x%0x\n", __func__, sts_entry->handle); | ||
37 | set_bit(DPC_RESET_HA, &ha->dpc_flags); | ||
65 | return; | 38 | return; |
66 | } | 39 | } |
67 | 40 | ||
@@ -88,10 +61,6 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha, | |||
88 | scsi_status = sts_entry->scsiStatus; | 61 | scsi_status = sts_entry->scsiStatus; |
89 | switch (sts_entry->completionStatus) { | 62 | switch (sts_entry->completionStatus) { |
90 | case SCS_COMPLETE: | 63 | case SCS_COMPLETE: |
91 | if (scsi_status == 0) { | ||
92 | cmd->result = DID_OK << 16; | ||
93 | break; | ||
94 | } | ||
95 | 64 | ||
96 | if (sts_entry->iscsiFlags & ISCSI_FLAG_RESIDUAL_OVER) { | 65 | if (sts_entry->iscsiFlags & ISCSI_FLAG_RESIDUAL_OVER) { |
97 | cmd->result = DID_ERROR << 16; | 66 | cmd->result = DID_ERROR << 16; |
@@ -100,7 +69,8 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha, | |||
100 | 69 | ||
101 | if (sts_entry->iscsiFlags &ISCSI_FLAG_RESIDUAL_UNDER) { | 70 | if (sts_entry->iscsiFlags &ISCSI_FLAG_RESIDUAL_UNDER) { |
102 | scsi_set_resid(cmd, residual); | 71 | scsi_set_resid(cmd, residual); |
103 | if ((scsi_bufflen(cmd) - residual) < cmd->underflow) { | 72 | if (!scsi_status && ((scsi_bufflen(cmd) - residual) < |
73 | cmd->underflow)) { | ||
104 | 74 | ||
105 | cmd->result = DID_ERROR << 16; | 75 | cmd->result = DID_ERROR << 16; |
106 | 76 | ||
diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c index 35cd73c72a68..c577d79bd7e8 100644 --- a/drivers/scsi/qla4xxx/ql4_mbx.c +++ b/drivers/scsi/qla4xxx/ql4_mbx.c | |||
@@ -713,6 +713,45 @@ int qla4xxx_reset_lun(struct scsi_qla_host * ha, struct ddb_entry * ddb_entry, | |||
713 | return status; | 713 | return status; |
714 | } | 714 | } |
715 | 715 | ||
716 | /** | ||
717 | * qla4xxx_reset_target - issues target Reset | ||
718 | * @ha: Pointer to host adapter structure. | ||
719 | * @db_entry: Pointer to device database entry | ||
720 | * @un_entry: Pointer to lun entry structure | ||
721 | * | ||
722 | * This routine performs a TARGET RESET on the specified target. | ||
723 | * The caller must ensure that the ddb_entry pointers | ||
724 | * are valid before calling this routine. | ||
725 | **/ | ||
726 | int qla4xxx_reset_target(struct scsi_qla_host *ha, | ||
727 | struct ddb_entry *ddb_entry) | ||
728 | { | ||
729 | uint32_t mbox_cmd[MBOX_REG_COUNT]; | ||
730 | uint32_t mbox_sts[MBOX_REG_COUNT]; | ||
731 | int status = QLA_SUCCESS; | ||
732 | |||
733 | DEBUG2(printk("scsi%ld:%d: target reset issued\n", ha->host_no, | ||
734 | ddb_entry->os_target_id)); | ||
735 | |||
736 | /* | ||
737 | * Send target reset command to ISP, so that the ISP will return all | ||
738 | * outstanding requests with RESET status | ||
739 | */ | ||
740 | memset(&mbox_cmd, 0, sizeof(mbox_cmd)); | ||
741 | memset(&mbox_sts, 0, sizeof(mbox_sts)); | ||
742 | |||
743 | mbox_cmd[0] = MBOX_CMD_TARGET_WARM_RESET; | ||
744 | mbox_cmd[1] = ddb_entry->fw_ddb_index; | ||
745 | mbox_cmd[5] = 0x01; /* Immediate Command Enable */ | ||
746 | |||
747 | qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], | ||
748 | &mbox_sts[0]); | ||
749 | if (mbox_sts[0] != MBOX_STS_COMMAND_COMPLETE && | ||
750 | mbox_sts[0] != MBOX_STS_COMMAND_ERROR) | ||
751 | status = QLA_ERROR; | ||
752 | |||
753 | return status; | ||
754 | } | ||
716 | 755 | ||
717 | int qla4xxx_get_flash(struct scsi_qla_host * ha, dma_addr_t dma_addr, | 756 | int qla4xxx_get_flash(struct scsi_qla_host * ha, dma_addr_t dma_addr, |
718 | uint32_t offset, uint32_t len) | 757 | uint32_t offset, uint32_t len) |
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index 8b92f348f02c..0c786944d2c2 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c | |||
@@ -71,6 +71,7 @@ static void qla4xxx_recovery_timedout(struct iscsi_cls_session *session); | |||
71 | static int qla4xxx_queuecommand(struct scsi_cmnd *cmd, | 71 | static int qla4xxx_queuecommand(struct scsi_cmnd *cmd, |
72 | void (*done) (struct scsi_cmnd *)); | 72 | void (*done) (struct scsi_cmnd *)); |
73 | static int qla4xxx_eh_device_reset(struct scsi_cmnd *cmd); | 73 | static int qla4xxx_eh_device_reset(struct scsi_cmnd *cmd); |
74 | static int qla4xxx_eh_target_reset(struct scsi_cmnd *cmd); | ||
74 | static int qla4xxx_eh_host_reset(struct scsi_cmnd *cmd); | 75 | static int qla4xxx_eh_host_reset(struct scsi_cmnd *cmd); |
75 | static int qla4xxx_slave_alloc(struct scsi_device *device); | 76 | static int qla4xxx_slave_alloc(struct scsi_device *device); |
76 | static int qla4xxx_slave_configure(struct scsi_device *device); | 77 | static int qla4xxx_slave_configure(struct scsi_device *device); |
@@ -84,6 +85,7 @@ static struct scsi_host_template qla4xxx_driver_template = { | |||
84 | .queuecommand = qla4xxx_queuecommand, | 85 | .queuecommand = qla4xxx_queuecommand, |
85 | 86 | ||
86 | .eh_device_reset_handler = qla4xxx_eh_device_reset, | 87 | .eh_device_reset_handler = qla4xxx_eh_device_reset, |
88 | .eh_target_reset_handler = qla4xxx_eh_target_reset, | ||
87 | .eh_host_reset_handler = qla4xxx_eh_host_reset, | 89 | .eh_host_reset_handler = qla4xxx_eh_host_reset, |
88 | 90 | ||
89 | .slave_configure = qla4xxx_slave_configure, | 91 | .slave_configure = qla4xxx_slave_configure, |
@@ -1482,7 +1484,7 @@ static int qla4xxx_wait_for_hba_online(struct scsi_qla_host *ha) | |||
1482 | } | 1484 | } |
1483 | 1485 | ||
1484 | /** | 1486 | /** |
1485 | * qla4xxx_eh_wait_for_active_target_commands - wait for active cmds to finish. | 1487 | * qla4xxx_eh_wait_for_commands - wait for active cmds to finish. |
1486 | * @ha: pointer to to HBA | 1488 | * @ha: pointer to to HBA |
1487 | * @t: target id | 1489 | * @t: target id |
1488 | * @l: lun id | 1490 | * @l: lun id |
@@ -1490,20 +1492,22 @@ static int qla4xxx_wait_for_hba_online(struct scsi_qla_host *ha) | |||
1490 | * This function waits for all outstanding commands to a lun to complete. It | 1492 | * This function waits for all outstanding commands to a lun to complete. It |
1491 | * returns 0 if all pending commands are returned and 1 otherwise. | 1493 | * returns 0 if all pending commands are returned and 1 otherwise. |
1492 | **/ | 1494 | **/ |
1493 | static int qla4xxx_eh_wait_for_active_target_commands(struct scsi_qla_host *ha, | 1495 | static int qla4xxx_eh_wait_for_commands(struct scsi_qla_host *ha, |
1494 | int t, int l) | 1496 | struct scsi_target *stgt, |
1497 | struct scsi_device *sdev) | ||
1495 | { | 1498 | { |
1496 | int cnt; | 1499 | int cnt; |
1497 | int status = 0; | 1500 | int status = 0; |
1498 | struct scsi_cmnd *cmd; | 1501 | struct scsi_cmnd *cmd; |
1499 | 1502 | ||
1500 | /* | 1503 | /* |
1501 | * Waiting for all commands for the designated target in the active | 1504 | * Waiting for all commands for the designated target or dev |
1502 | * array | 1505 | * in the active array |
1503 | */ | 1506 | */ |
1504 | for (cnt = 0; cnt < ha->host->can_queue; cnt++) { | 1507 | for (cnt = 0; cnt < ha->host->can_queue; cnt++) { |
1505 | cmd = scsi_host_find_tag(ha->host, cnt); | 1508 | cmd = scsi_host_find_tag(ha->host, cnt); |
1506 | if (cmd && cmd->device->id == t && cmd->device->lun == l) { | 1509 | if (cmd && stgt == scsi_target(cmd->device) && |
1510 | (!sdev || sdev == cmd->device)) { | ||
1507 | if (!qla4xxx_eh_wait_on_command(ha, cmd)) { | 1511 | if (!qla4xxx_eh_wait_on_command(ha, cmd)) { |
1508 | status++; | 1512 | status++; |
1509 | break; | 1513 | break; |
@@ -1548,24 +1552,19 @@ static int qla4xxx_eh_device_reset(struct scsi_cmnd *cmd) | |||
1548 | goto eh_dev_reset_done; | 1552 | goto eh_dev_reset_done; |
1549 | } | 1553 | } |
1550 | 1554 | ||
1551 | /* Send marker. */ | 1555 | if (qla4xxx_eh_wait_for_commands(ha, scsi_target(cmd->device), |
1552 | ha->marker_needed = 1; | 1556 | cmd->device)) { |
1553 | 1557 | dev_info(&ha->pdev->dev, | |
1554 | /* | 1558 | "DEVICE RESET FAILED - waiting for " |
1555 | * If we are coming down the EH path, wait for all commands to complete | 1559 | "commands.\n"); |
1556 | * for the device. | 1560 | goto eh_dev_reset_done; |
1557 | */ | ||
1558 | if (cmd->device->host->shost_state == SHOST_RECOVERY) { | ||
1559 | if (qla4xxx_eh_wait_for_active_target_commands(ha, | ||
1560 | cmd->device->id, | ||
1561 | cmd->device->lun)){ | ||
1562 | dev_info(&ha->pdev->dev, | ||
1563 | "DEVICE RESET FAILED - waiting for " | ||
1564 | "commands.\n"); | ||
1565 | goto eh_dev_reset_done; | ||
1566 | } | ||
1567 | } | 1561 | } |
1568 | 1562 | ||
1563 | /* Send marker. */ | ||
1564 | if (qla4xxx_send_marker_iocb(ha, ddb_entry, cmd->device->lun, | ||
1565 | MM_LUN_RESET) != QLA_SUCCESS) | ||
1566 | goto eh_dev_reset_done; | ||
1567 | |||
1569 | dev_info(&ha->pdev->dev, | 1568 | dev_info(&ha->pdev->dev, |
1570 | "scsi(%ld:%d:%d:%d): DEVICE RESET SUCCEEDED.\n", | 1569 | "scsi(%ld:%d:%d:%d): DEVICE RESET SUCCEEDED.\n", |
1571 | ha->host_no, cmd->device->channel, cmd->device->id, | 1570 | ha->host_no, cmd->device->channel, cmd->device->id, |
@@ -1579,6 +1578,59 @@ eh_dev_reset_done: | |||
1579 | } | 1578 | } |
1580 | 1579 | ||
1581 | /** | 1580 | /** |
1581 | * qla4xxx_eh_target_reset - callback for target reset. | ||
1582 | * @cmd: Pointer to Linux's SCSI command structure | ||
1583 | * | ||
1584 | * This routine is called by the Linux OS to reset the target. | ||
1585 | **/ | ||
1586 | static int qla4xxx_eh_target_reset(struct scsi_cmnd *cmd) | ||
1587 | { | ||
1588 | struct scsi_qla_host *ha = to_qla_host(cmd->device->host); | ||
1589 | struct ddb_entry *ddb_entry = cmd->device->hostdata; | ||
1590 | int stat; | ||
1591 | |||
1592 | if (!ddb_entry) | ||
1593 | return FAILED; | ||
1594 | |||
1595 | starget_printk(KERN_INFO, scsi_target(cmd->device), | ||
1596 | "WARM TARGET RESET ISSUED.\n"); | ||
1597 | |||
1598 | DEBUG2(printk(KERN_INFO | ||
1599 | "scsi%ld: TARGET_DEVICE_RESET cmd=%p jiffies = 0x%lx, " | ||
1600 | "to=%x,dpc_flags=%lx, status=%x allowed=%d\n", | ||
1601 | ha->host_no, cmd, jiffies, cmd->timeout_per_command / HZ, | ||
1602 | ha->dpc_flags, cmd->result, cmd->allowed)); | ||
1603 | |||
1604 | stat = qla4xxx_reset_target(ha, ddb_entry); | ||
1605 | if (stat != QLA_SUCCESS) { | ||
1606 | starget_printk(KERN_INFO, scsi_target(cmd->device), | ||
1607 | "WARM TARGET RESET FAILED.\n"); | ||
1608 | return FAILED; | ||
1609 | } | ||
1610 | |||
1611 | if (qla4xxx_eh_wait_for_commands(ha, scsi_target(cmd->device), | ||
1612 | NULL)) { | ||
1613 | starget_printk(KERN_INFO, scsi_target(cmd->device), | ||
1614 | "WARM TARGET DEVICE RESET FAILED - " | ||
1615 | "waiting for commands.\n"); | ||
1616 | return FAILED; | ||
1617 | } | ||
1618 | |||
1619 | /* Send marker. */ | ||
1620 | if (qla4xxx_send_marker_iocb(ha, ddb_entry, cmd->device->lun, | ||
1621 | MM_TGT_WARM_RESET) != QLA_SUCCESS) { | ||
1622 | starget_printk(KERN_INFO, scsi_target(cmd->device), | ||
1623 | "WARM TARGET DEVICE RESET FAILED - " | ||
1624 | "marker iocb failed.\n"); | ||
1625 | return FAILED; | ||
1626 | } | ||
1627 | |||
1628 | starget_printk(KERN_INFO, scsi_target(cmd->device), | ||
1629 | "WARM TARGET RESET SUCCEEDED.\n"); | ||
1630 | return SUCCESS; | ||
1631 | } | ||
1632 | |||
1633 | /** | ||
1582 | * qla4xxx_eh_host_reset - kernel callback | 1634 | * qla4xxx_eh_host_reset - kernel callback |
1583 | * @cmd: Pointer to Linux's SCSI command structure | 1635 | * @cmd: Pointer to Linux's SCSI command structure |
1584 | * | 1636 | * |
diff --git a/drivers/scsi/raid_class.c b/drivers/scsi/raid_class.c index 86e13183c9ba..52182a744ba6 100644 --- a/drivers/scsi/raid_class.c +++ b/drivers/scsi/raid_class.c | |||
@@ -289,7 +289,7 @@ raid_class_release(struct raid_template *r) | |||
289 | { | 289 | { |
290 | struct raid_internal *i = to_raid_internal(r); | 290 | struct raid_internal *i = to_raid_internal(r); |
291 | 291 | ||
292 | attribute_container_unregister(&i->r.raid_attrs.ac); | 292 | BUG_ON(attribute_container_unregister(&i->r.raid_attrs.ac)); |
293 | 293 | ||
294 | kfree(i); | 294 | kfree(i); |
295 | } | 295 | } |
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index c78b836f59dd..f6980bd9d8f9 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c | |||
@@ -166,6 +166,51 @@ static struct scsi_host_cmd_pool scsi_cmd_dma_pool = { | |||
166 | static DEFINE_MUTEX(host_cmd_pool_mutex); | 166 | static DEFINE_MUTEX(host_cmd_pool_mutex); |
167 | 167 | ||
168 | /** | 168 | /** |
169 | * scsi_pool_alloc_command - internal function to get a fully allocated command | ||
170 | * @pool: slab pool to allocate the command from | ||
171 | * @gfp_mask: mask for the allocation | ||
172 | * | ||
173 | * Returns a fully allocated command (with the allied sense buffer) or | ||
174 | * NULL on failure | ||
175 | */ | ||
176 | static struct scsi_cmnd * | ||
177 | scsi_pool_alloc_command(struct scsi_host_cmd_pool *pool, gfp_t gfp_mask) | ||
178 | { | ||
179 | struct scsi_cmnd *cmd; | ||
180 | |||
181 | cmd = kmem_cache_alloc(pool->cmd_slab, gfp_mask | pool->gfp_mask); | ||
182 | if (!cmd) | ||
183 | return NULL; | ||
184 | |||
185 | memset(cmd, 0, sizeof(*cmd)); | ||
186 | |||
187 | cmd->sense_buffer = kmem_cache_alloc(pool->sense_slab, | ||
188 | gfp_mask | pool->gfp_mask); | ||
189 | if (!cmd->sense_buffer) { | ||
190 | kmem_cache_free(pool->cmd_slab, cmd); | ||
191 | return NULL; | ||
192 | } | ||
193 | |||
194 | return cmd; | ||
195 | } | ||
196 | |||
197 | /** | ||
198 | * scsi_pool_free_command - internal function to release a command | ||
199 | * @pool: slab pool to allocate the command from | ||
200 | * @cmd: command to release | ||
201 | * | ||
202 | * the command must previously have been allocated by | ||
203 | * scsi_pool_alloc_command. | ||
204 | */ | ||
205 | static void | ||
206 | scsi_pool_free_command(struct scsi_host_cmd_pool *pool, | ||
207 | struct scsi_cmnd *cmd) | ||
208 | { | ||
209 | kmem_cache_free(pool->sense_slab, cmd->sense_buffer); | ||
210 | kmem_cache_free(pool->cmd_slab, cmd); | ||
211 | } | ||
212 | |||
213 | /** | ||
169 | * __scsi_get_command - Allocate a struct scsi_cmnd | 214 | * __scsi_get_command - Allocate a struct scsi_cmnd |
170 | * @shost: host to transmit command | 215 | * @shost: host to transmit command |
171 | * @gfp_mask: allocation mask | 216 | * @gfp_mask: allocation mask |
@@ -178,20 +223,7 @@ struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *shost, gfp_t gfp_mask) | |||
178 | struct scsi_cmnd *cmd; | 223 | struct scsi_cmnd *cmd; |
179 | unsigned char *buf; | 224 | unsigned char *buf; |
180 | 225 | ||
181 | cmd = kmem_cache_alloc(shost->cmd_pool->cmd_slab, | 226 | cmd = scsi_pool_alloc_command(shost->cmd_pool, gfp_mask); |
182 | gfp_mask | shost->cmd_pool->gfp_mask); | ||
183 | |||
184 | if (likely(cmd)) { | ||
185 | buf = kmem_cache_alloc(shost->cmd_pool->sense_slab, | ||
186 | gfp_mask | shost->cmd_pool->gfp_mask); | ||
187 | if (likely(buf)) { | ||
188 | memset(cmd, 0, sizeof(*cmd)); | ||
189 | cmd->sense_buffer = buf; | ||
190 | } else { | ||
191 | kmem_cache_free(shost->cmd_pool->cmd_slab, cmd); | ||
192 | cmd = NULL; | ||
193 | } | ||
194 | } | ||
195 | 227 | ||
196 | if (unlikely(!cmd)) { | 228 | if (unlikely(!cmd)) { |
197 | unsigned long flags; | 229 | unsigned long flags; |
@@ -268,11 +300,8 @@ void __scsi_put_command(struct Scsi_Host *shost, struct scsi_cmnd *cmd, | |||
268 | } | 300 | } |
269 | spin_unlock_irqrestore(&shost->free_list_lock, flags); | 301 | spin_unlock_irqrestore(&shost->free_list_lock, flags); |
270 | 302 | ||
271 | if (likely(cmd != NULL)) { | 303 | if (likely(cmd != NULL)) |
272 | kmem_cache_free(shost->cmd_pool->sense_slab, | 304 | scsi_pool_free_command(shost->cmd_pool, cmd); |
273 | cmd->sense_buffer); | ||
274 | kmem_cache_free(shost->cmd_pool->cmd_slab, cmd); | ||
275 | } | ||
276 | 305 | ||
277 | put_device(dev); | 306 | put_device(dev); |
278 | } | 307 | } |
@@ -301,30 +330,16 @@ void scsi_put_command(struct scsi_cmnd *cmd) | |||
301 | } | 330 | } |
302 | EXPORT_SYMBOL(scsi_put_command); | 331 | EXPORT_SYMBOL(scsi_put_command); |
303 | 332 | ||
304 | /** | 333 | static struct scsi_host_cmd_pool *scsi_get_host_cmd_pool(gfp_t gfp_mask) |
305 | * scsi_setup_command_freelist - Setup the command freelist for a scsi host. | ||
306 | * @shost: host to allocate the freelist for. | ||
307 | * | ||
308 | * Description: The command freelist protects against system-wide out of memory | ||
309 | * deadlock by preallocating one SCSI command structure for each host, so the | ||
310 | * system can always write to a swap file on a device associated with that host. | ||
311 | * | ||
312 | * Returns: Nothing. | ||
313 | */ | ||
314 | int scsi_setup_command_freelist(struct Scsi_Host *shost) | ||
315 | { | 334 | { |
316 | struct scsi_host_cmd_pool *pool; | 335 | struct scsi_host_cmd_pool *retval = NULL, *pool; |
317 | struct scsi_cmnd *cmd; | ||
318 | |||
319 | spin_lock_init(&shost->free_list_lock); | ||
320 | INIT_LIST_HEAD(&shost->free_list); | ||
321 | |||
322 | /* | 336 | /* |
323 | * Select a command slab for this host and create it if not | 337 | * Select a command slab for this host and create it if not |
324 | * yet existent. | 338 | * yet existent. |
325 | */ | 339 | */ |
326 | mutex_lock(&host_cmd_pool_mutex); | 340 | mutex_lock(&host_cmd_pool_mutex); |
327 | pool = (shost->unchecked_isa_dma ? &scsi_cmd_dma_pool : &scsi_cmd_pool); | 341 | pool = (gfp_mask & __GFP_DMA) ? &scsi_cmd_dma_pool : |
342 | &scsi_cmd_pool; | ||
328 | if (!pool->users) { | 343 | if (!pool->users) { |
329 | pool->cmd_slab = kmem_cache_create(pool->cmd_name, | 344 | pool->cmd_slab = kmem_cache_create(pool->cmd_name, |
330 | sizeof(struct scsi_cmnd), 0, | 345 | sizeof(struct scsi_cmnd), 0, |
@@ -342,37 +357,122 @@ int scsi_setup_command_freelist(struct Scsi_Host *shost) | |||
342 | } | 357 | } |
343 | 358 | ||
344 | pool->users++; | 359 | pool->users++; |
345 | shost->cmd_pool = pool; | 360 | retval = pool; |
361 | fail: | ||
346 | mutex_unlock(&host_cmd_pool_mutex); | 362 | mutex_unlock(&host_cmd_pool_mutex); |
363 | return retval; | ||
364 | } | ||
365 | |||
366 | static void scsi_put_host_cmd_pool(gfp_t gfp_mask) | ||
367 | { | ||
368 | struct scsi_host_cmd_pool *pool; | ||
347 | 369 | ||
370 | mutex_lock(&host_cmd_pool_mutex); | ||
371 | pool = (gfp_mask & __GFP_DMA) ? &scsi_cmd_dma_pool : | ||
372 | &scsi_cmd_pool; | ||
348 | /* | 373 | /* |
349 | * Get one backup command for this host. | 374 | * This may happen if a driver has a mismatched get and put |
375 | * of the command pool; the driver should be implicated in | ||
376 | * the stack trace | ||
350 | */ | 377 | */ |
351 | cmd = kmem_cache_alloc(shost->cmd_pool->cmd_slab, | 378 | BUG_ON(pool->users == 0); |
352 | GFP_KERNEL | shost->cmd_pool->gfp_mask); | ||
353 | if (!cmd) | ||
354 | goto fail2; | ||
355 | 379 | ||
356 | cmd->sense_buffer = kmem_cache_alloc(shost->cmd_pool->sense_slab, | ||
357 | GFP_KERNEL | | ||
358 | shost->cmd_pool->gfp_mask); | ||
359 | if (!cmd->sense_buffer) | ||
360 | goto fail2; | ||
361 | |||
362 | list_add(&cmd->list, &shost->free_list); | ||
363 | return 0; | ||
364 | |||
365 | fail2: | ||
366 | if (cmd) | ||
367 | kmem_cache_free(shost->cmd_pool->cmd_slab, cmd); | ||
368 | mutex_lock(&host_cmd_pool_mutex); | ||
369 | if (!--pool->users) { | 380 | if (!--pool->users) { |
370 | kmem_cache_destroy(pool->cmd_slab); | 381 | kmem_cache_destroy(pool->cmd_slab); |
371 | kmem_cache_destroy(pool->sense_slab); | 382 | kmem_cache_destroy(pool->sense_slab); |
372 | } | 383 | } |
373 | fail: | ||
374 | mutex_unlock(&host_cmd_pool_mutex); | 384 | mutex_unlock(&host_cmd_pool_mutex); |
375 | return -ENOMEM; | 385 | } |
386 | |||
387 | /** | ||
388 | * scsi_allocate_command - get a fully allocated SCSI command | ||
389 | * @gfp_mask: allocation mask | ||
390 | * | ||
391 | * This function is for use outside of the normal host based pools. | ||
392 | * It allocates the relevant command and takes an additional reference | ||
393 | * on the pool it used. This function *must* be paired with | ||
394 | * scsi_free_command which also has the identical mask, otherwise the | ||
395 | * free pool counts will eventually go wrong and you'll trigger a bug. | ||
396 | * | ||
397 | * This function should *only* be used by drivers that need a static | ||
398 | * command allocation at start of day for internal functions. | ||
399 | */ | ||
400 | struct scsi_cmnd *scsi_allocate_command(gfp_t gfp_mask) | ||
401 | { | ||
402 | struct scsi_host_cmd_pool *pool = scsi_get_host_cmd_pool(gfp_mask); | ||
403 | |||
404 | if (!pool) | ||
405 | return NULL; | ||
406 | |||
407 | return scsi_pool_alloc_command(pool, gfp_mask); | ||
408 | } | ||
409 | EXPORT_SYMBOL(scsi_allocate_command); | ||
410 | |||
411 | /** | ||
412 | * scsi_free_command - free a command allocated by scsi_allocate_command | ||
413 | * @gfp_mask: mask used in the original allocation | ||
414 | * @cmd: command to free | ||
415 | * | ||
416 | * Note: using the original allocation mask is vital because that's | ||
417 | * what determines which command pool we use to free the command. Any | ||
418 | * mismatch will cause the system to BUG eventually. | ||
419 | */ | ||
420 | void scsi_free_command(gfp_t gfp_mask, struct scsi_cmnd *cmd) | ||
421 | { | ||
422 | struct scsi_host_cmd_pool *pool = scsi_get_host_cmd_pool(gfp_mask); | ||
423 | |||
424 | /* | ||
425 | * this could trigger if the mask to scsi_allocate_command | ||
426 | * doesn't match this mask. Otherwise we're guaranteed that this | ||
427 | * succeeds because scsi_allocate_command must have taken a reference | ||
428 | * on the pool | ||
429 | */ | ||
430 | BUG_ON(!pool); | ||
431 | |||
432 | scsi_pool_free_command(pool, cmd); | ||
433 | /* | ||
434 | * scsi_put_host_cmd_pool is called twice; once to release the | ||
435 | * reference we took above, and once to release the reference | ||
436 | * originally taken by scsi_allocate_command | ||
437 | */ | ||
438 | scsi_put_host_cmd_pool(gfp_mask); | ||
439 | scsi_put_host_cmd_pool(gfp_mask); | ||
440 | } | ||
441 | EXPORT_SYMBOL(scsi_free_command); | ||
442 | |||
443 | /** | ||
444 | * scsi_setup_command_freelist - Setup the command freelist for a scsi host. | ||
445 | * @shost: host to allocate the freelist for. | ||
446 | * | ||
447 | * Description: The command freelist protects against system-wide out of memory | ||
448 | * deadlock by preallocating one SCSI command structure for each host, so the | ||
449 | * system can always write to a swap file on a device associated with that host. | ||
450 | * | ||
451 | * Returns: Nothing. | ||
452 | */ | ||
453 | int scsi_setup_command_freelist(struct Scsi_Host *shost) | ||
454 | { | ||
455 | struct scsi_cmnd *cmd; | ||
456 | const gfp_t gfp_mask = shost->unchecked_isa_dma ? GFP_DMA : GFP_KERNEL; | ||
457 | |||
458 | spin_lock_init(&shost->free_list_lock); | ||
459 | INIT_LIST_HEAD(&shost->free_list); | ||
460 | |||
461 | shost->cmd_pool = scsi_get_host_cmd_pool(gfp_mask); | ||
462 | |||
463 | if (!shost->cmd_pool) | ||
464 | return -ENOMEM; | ||
465 | |||
466 | /* | ||
467 | * Get one backup command for this host. | ||
468 | */ | ||
469 | cmd = scsi_pool_alloc_command(shost->cmd_pool, gfp_mask); | ||
470 | if (!cmd) { | ||
471 | scsi_put_host_cmd_pool(gfp_mask); | ||
472 | return -ENOMEM; | ||
473 | } | ||
474 | list_add(&cmd->list, &shost->free_list); | ||
475 | return 0; | ||
376 | } | 476 | } |
377 | 477 | ||
378 | /** | 478 | /** |
@@ -386,17 +486,10 @@ void scsi_destroy_command_freelist(struct Scsi_Host *shost) | |||
386 | 486 | ||
387 | cmd = list_entry(shost->free_list.next, struct scsi_cmnd, list); | 487 | cmd = list_entry(shost->free_list.next, struct scsi_cmnd, list); |
388 | list_del_init(&cmd->list); | 488 | list_del_init(&cmd->list); |
389 | kmem_cache_free(shost->cmd_pool->sense_slab, | 489 | scsi_pool_free_command(shost->cmd_pool, cmd); |
390 | cmd->sense_buffer); | ||
391 | kmem_cache_free(shost->cmd_pool->cmd_slab, cmd); | ||
392 | } | 490 | } |
393 | 491 | shost->cmd_pool = NULL; | |
394 | mutex_lock(&host_cmd_pool_mutex); | 492 | scsi_put_host_cmd_pool(shost->unchecked_isa_dma ? GFP_DMA : GFP_KERNEL); |
395 | if (!--shost->cmd_pool->users) { | ||
396 | kmem_cache_destroy(shost->cmd_pool->cmd_slab); | ||
397 | kmem_cache_destroy(shost->cmd_pool->sense_slab); | ||
398 | } | ||
399 | mutex_unlock(&host_cmd_pool_mutex); | ||
400 | } | 493 | } |
401 | 494 | ||
402 | #ifdef CONFIG_SCSI_LOGGING | 495 | #ifdef CONFIG_SCSI_LOGGING |
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index d1777a9a9625..07103c399fe0 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c | |||
@@ -39,16 +39,18 @@ | |||
39 | #include <linux/vmalloc.h> | 39 | #include <linux/vmalloc.h> |
40 | #include <linux/moduleparam.h> | 40 | #include <linux/moduleparam.h> |
41 | #include <linux/scatterlist.h> | 41 | #include <linux/scatterlist.h> |
42 | |||
43 | #include <linux/blkdev.h> | 42 | #include <linux/blkdev.h> |
44 | #include "scsi.h" | 43 | |
44 | #include <scsi/scsi.h> | ||
45 | #include <scsi/scsi_cmnd.h> | ||
46 | #include <scsi/scsi_device.h> | ||
45 | #include <scsi/scsi_host.h> | 47 | #include <scsi/scsi_host.h> |
46 | #include <scsi/scsicam.h> | 48 | #include <scsi/scsicam.h> |
49 | #include <scsi/scsi_eh.h> | ||
47 | 50 | ||
48 | #include <linux/stat.h> | 51 | #include <linux/stat.h> |
49 | 52 | ||
50 | #include "scsi_logging.h" | 53 | #include "scsi_logging.h" |
51 | #include "scsi_debug.h" | ||
52 | 54 | ||
53 | #define SCSI_DEBUG_VERSION "1.81" | 55 | #define SCSI_DEBUG_VERSION "1.81" |
54 | static const char * scsi_debug_version_date = "20070104"; | 56 | static const char * scsi_debug_version_date = "20070104"; |
@@ -146,7 +148,6 @@ static int scsi_debug_cmnd_count = 0; | |||
146 | #define DEV_READONLY(TGT) (0) | 148 | #define DEV_READONLY(TGT) (0) |
147 | #define DEV_REMOVEABLE(TGT) (0) | 149 | #define DEV_REMOVEABLE(TGT) (0) |
148 | 150 | ||
149 | static unsigned int sdebug_store_size; /* in bytes */ | ||
150 | static unsigned int sdebug_store_sectors; | 151 | static unsigned int sdebug_store_sectors; |
151 | static sector_t sdebug_capacity; /* in sectors */ | 152 | static sector_t sdebug_capacity; /* in sectors */ |
152 | 153 | ||
@@ -165,6 +166,9 @@ static int sdebug_sectors_per; /* sectors per cylinder */ | |||
165 | 166 | ||
166 | #define SDEBUG_SENSE_LEN 32 | 167 | #define SDEBUG_SENSE_LEN 32 |
167 | 168 | ||
169 | #define SCSI_DEBUG_CANQUEUE 255 | ||
170 | #define SCSI_DEBUG_MAX_CMD_LEN 16 | ||
171 | |||
168 | struct sdebug_dev_info { | 172 | struct sdebug_dev_info { |
169 | struct list_head dev_list; | 173 | struct list_head dev_list; |
170 | unsigned char sense_buff[SDEBUG_SENSE_LEN]; /* weak nexus */ | 174 | unsigned char sense_buff[SDEBUG_SENSE_LEN]; /* weak nexus */ |
@@ -202,30 +206,6 @@ struct sdebug_queued_cmd { | |||
202 | }; | 206 | }; |
203 | static struct sdebug_queued_cmd queued_arr[SCSI_DEBUG_CANQUEUE]; | 207 | static struct sdebug_queued_cmd queued_arr[SCSI_DEBUG_CANQUEUE]; |
204 | 208 | ||
205 | static struct scsi_host_template sdebug_driver_template = { | ||
206 | .proc_info = scsi_debug_proc_info, | ||
207 | .name = "SCSI DEBUG", | ||
208 | .info = scsi_debug_info, | ||
209 | .slave_alloc = scsi_debug_slave_alloc, | ||
210 | .slave_configure = scsi_debug_slave_configure, | ||
211 | .slave_destroy = scsi_debug_slave_destroy, | ||
212 | .ioctl = scsi_debug_ioctl, | ||
213 | .queuecommand = scsi_debug_queuecommand, | ||
214 | .eh_abort_handler = scsi_debug_abort, | ||
215 | .eh_bus_reset_handler = scsi_debug_bus_reset, | ||
216 | .eh_device_reset_handler = scsi_debug_device_reset, | ||
217 | .eh_host_reset_handler = scsi_debug_host_reset, | ||
218 | .bios_param = scsi_debug_biosparam, | ||
219 | .can_queue = SCSI_DEBUG_CANQUEUE, | ||
220 | .this_id = 7, | ||
221 | .sg_tablesize = 256, | ||
222 | .cmd_per_lun = 16, | ||
223 | .max_sectors = 0xffff, | ||
224 | .unchecked_isa_dma = 0, | ||
225 | .use_clustering = DISABLE_CLUSTERING, | ||
226 | .module = THIS_MODULE, | ||
227 | }; | ||
228 | |||
229 | static unsigned char * fake_storep; /* ramdisk storage */ | 209 | static unsigned char * fake_storep; /* ramdisk storage */ |
230 | 210 | ||
231 | static int num_aborts = 0; | 211 | static int num_aborts = 0; |
@@ -238,8 +218,6 @@ static DEFINE_RWLOCK(atomic_rw); | |||
238 | 218 | ||
239 | static char sdebug_proc_name[] = "scsi_debug"; | 219 | static char sdebug_proc_name[] = "scsi_debug"; |
240 | 220 | ||
241 | static int sdebug_driver_probe(struct device *); | ||
242 | static int sdebug_driver_remove(struct device *); | ||
243 | static struct bus_type pseudo_lld_bus; | 221 | static struct bus_type pseudo_lld_bus; |
244 | 222 | ||
245 | static struct device_driver sdebug_driverfs_driver = { | 223 | static struct device_driver sdebug_driverfs_driver = { |
@@ -255,94 +233,77 @@ static unsigned char ctrl_m_pg[] = {0xa, 10, 2, 0, 0, 0, 0, 0, | |||
255 | static unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0, | 233 | static unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0, |
256 | 0, 0, 0x0, 0x0}; | 234 | 0, 0, 0x0, 0x0}; |
257 | 235 | ||
258 | /* function declarations */ | ||
259 | static int resp_inquiry(struct scsi_cmnd * SCpnt, int target, | ||
260 | struct sdebug_dev_info * devip); | ||
261 | static int resp_requests(struct scsi_cmnd * SCpnt, | ||
262 | struct sdebug_dev_info * devip); | ||
263 | static int resp_start_stop(struct scsi_cmnd * scp, | ||
264 | struct sdebug_dev_info * devip); | ||
265 | static int resp_report_tgtpgs(struct scsi_cmnd * scp, | ||
266 | struct sdebug_dev_info * devip); | ||
267 | static int resp_readcap(struct scsi_cmnd * SCpnt, | ||
268 | struct sdebug_dev_info * devip); | ||
269 | static int resp_readcap16(struct scsi_cmnd * SCpnt, | ||
270 | struct sdebug_dev_info * devip); | ||
271 | static int resp_mode_sense(struct scsi_cmnd * scp, int target, | ||
272 | struct sdebug_dev_info * devip); | ||
273 | static int resp_mode_select(struct scsi_cmnd * scp, int mselect6, | ||
274 | struct sdebug_dev_info * devip); | ||
275 | static int resp_log_sense(struct scsi_cmnd * scp, | ||
276 | struct sdebug_dev_info * devip); | ||
277 | static int resp_read(struct scsi_cmnd * SCpnt, unsigned long long lba, | ||
278 | unsigned int num, struct sdebug_dev_info * devip); | ||
279 | static int resp_write(struct scsi_cmnd * SCpnt, unsigned long long lba, | ||
280 | unsigned int num, struct sdebug_dev_info * devip); | ||
281 | static int resp_report_luns(struct scsi_cmnd * SCpnt, | ||
282 | struct sdebug_dev_info * devip); | ||
283 | static int resp_xdwriteread(struct scsi_cmnd *scp, unsigned long long lba, | ||
284 | unsigned int num, struct sdebug_dev_info *devip); | ||
285 | static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr, | ||
286 | int arr_len); | ||
287 | static int fetch_to_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr, | ||
288 | int max_arr_len); | ||
289 | static void timer_intr_handler(unsigned long); | ||
290 | static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev); | ||
291 | static void mk_sense_buffer(struct sdebug_dev_info * devip, int key, | ||
292 | int asc, int asq); | ||
293 | static int check_readiness(struct scsi_cmnd * SCpnt, int reset_only, | ||
294 | struct sdebug_dev_info * devip); | ||
295 | static int schedule_resp(struct scsi_cmnd * cmnd, | ||
296 | struct sdebug_dev_info * devip, | ||
297 | done_funct_t done, int scsi_result, int delta_jiff); | ||
298 | static void __init sdebug_build_parts(unsigned char * ramp); | ||
299 | static void __init init_all_queued(void); | ||
300 | static void stop_all_queued(void); | ||
301 | static int stop_queued_cmnd(struct scsi_cmnd * cmnd); | ||
302 | static int inquiry_evpd_83(unsigned char * arr, int port_group_id, | ||
303 | int target_dev_id, int dev_id_num, | ||
304 | const char * dev_id_str, int dev_id_str_len); | ||
305 | static int inquiry_evpd_88(unsigned char * arr, int target_dev_id); | ||
306 | static int do_create_driverfs_files(void); | ||
307 | static void do_remove_driverfs_files(void); | ||
308 | |||
309 | static int sdebug_add_adapter(void); | 236 | static int sdebug_add_adapter(void); |
310 | static void sdebug_remove_adapter(void); | 237 | static void sdebug_remove_adapter(void); |
311 | static void sdebug_max_tgts_luns(void); | ||
312 | 238 | ||
313 | static struct device pseudo_primary; | 239 | static void sdebug_max_tgts_luns(void) |
314 | static struct bus_type pseudo_lld_bus; | 240 | { |
241 | struct sdebug_host_info *sdbg_host; | ||
242 | struct Scsi_Host *hpnt; | ||
243 | |||
244 | spin_lock(&sdebug_host_list_lock); | ||
245 | list_for_each_entry(sdbg_host, &sdebug_host_list, host_list) { | ||
246 | hpnt = sdbg_host->shost; | ||
247 | if ((hpnt->this_id >= 0) && | ||
248 | (scsi_debug_num_tgts > hpnt->this_id)) | ||
249 | hpnt->max_id = scsi_debug_num_tgts + 1; | ||
250 | else | ||
251 | hpnt->max_id = scsi_debug_num_tgts; | ||
252 | /* scsi_debug_max_luns; */ | ||
253 | hpnt->max_lun = SAM2_WLUN_REPORT_LUNS; | ||
254 | } | ||
255 | spin_unlock(&sdebug_host_list_lock); | ||
256 | } | ||
257 | |||
258 | static void mk_sense_buffer(struct sdebug_dev_info *devip, int key, | ||
259 | int asc, int asq) | ||
260 | { | ||
261 | unsigned char *sbuff; | ||
262 | |||
263 | sbuff = devip->sense_buff; | ||
264 | memset(sbuff, 0, SDEBUG_SENSE_LEN); | ||
265 | |||
266 | scsi_build_sense_buffer(scsi_debug_dsense, sbuff, key, asc, asq); | ||
267 | |||
268 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | ||
269 | printk(KERN_INFO "scsi_debug: [sense_key,asc,ascq]: " | ||
270 | "[0x%x,0x%x,0x%x]\n", key, asc, asq); | ||
271 | } | ||
315 | 272 | ||
316 | static void get_data_transfer_info(unsigned char *cmd, | 273 | static void get_data_transfer_info(unsigned char *cmd, |
317 | unsigned long long *lba, unsigned int *num) | 274 | unsigned long long *lba, unsigned int *num) |
318 | { | 275 | { |
319 | int i; | ||
320 | |||
321 | switch (*cmd) { | 276 | switch (*cmd) { |
322 | case WRITE_16: | 277 | case WRITE_16: |
323 | case READ_16: | 278 | case READ_16: |
324 | for (*lba = 0, i = 0; i < 8; ++i) { | 279 | *lba = (u64)cmd[9] | (u64)cmd[8] << 8 | |
325 | if (i > 0) | 280 | (u64)cmd[7] << 16 | (u64)cmd[6] << 24 | |
326 | *lba <<= 8; | 281 | (u64)cmd[5] << 32 | (u64)cmd[4] << 40 | |
327 | *lba += cmd[2 + i]; | 282 | (u64)cmd[3] << 48 | (u64)cmd[2] << 56; |
328 | } | 283 | |
329 | *num = cmd[13] + (cmd[12] << 8) + | 284 | *num = (u32)cmd[13] | (u32)cmd[12] << 8 | (u32)cmd[11] << 16 | |
330 | (cmd[11] << 16) + (cmd[10] << 24); | 285 | (u32)cmd[10] << 24; |
331 | break; | 286 | break; |
332 | case WRITE_12: | 287 | case WRITE_12: |
333 | case READ_12: | 288 | case READ_12: |
334 | *lba = cmd[5] + (cmd[4] << 8) + (cmd[3] << 16) + (cmd[2] << 24); | 289 | *lba = (u32)cmd[5] | (u32)cmd[4] << 8 | (u32)cmd[3] << 16 | |
335 | *num = cmd[9] + (cmd[8] << 8) + (cmd[7] << 16) + (cmd[6] << 24); | 290 | (u32)cmd[2] << 24; |
291 | |||
292 | *num = (u32)cmd[9] | (u32)cmd[8] << 8 | (u32)cmd[7] << 16 | | ||
293 | (u32)cmd[6] << 24; | ||
336 | break; | 294 | break; |
337 | case WRITE_10: | 295 | case WRITE_10: |
338 | case READ_10: | 296 | case READ_10: |
339 | case XDWRITEREAD_10: | 297 | case XDWRITEREAD_10: |
340 | *lba = cmd[5] + (cmd[4] << 8) + (cmd[3] << 16) + (cmd[2] << 24); | 298 | *lba = (u32)cmd[5] | (u32)cmd[4] << 8 | (u32)cmd[3] << 16 | |
341 | *num = cmd[8] + (cmd[7] << 8); | 299 | (u32)cmd[2] << 24; |
300 | |||
301 | *num = (u32)cmd[8] | (u32)cmd[7] << 8; | ||
342 | break; | 302 | break; |
343 | case WRITE_6: | 303 | case WRITE_6: |
344 | case READ_6: | 304 | case READ_6: |
345 | *lba = cmd[3] + (cmd[2] << 8) + ((cmd[1] & 0x1f) << 16); | 305 | *lba = (u32)cmd[3] | (u32)cmd[2] << 8 | |
306 | (u32)(cmd[1] & 0x1f) << 16; | ||
346 | *num = (0 == cmd[4]) ? 256 : cmd[4]; | 307 | *num = (0 == cmd[4]) ? 256 : cmd[4]; |
347 | break; | 308 | break; |
348 | default: | 309 | default: |
@@ -350,237 +311,6 @@ static void get_data_transfer_info(unsigned char *cmd, | |||
350 | } | 311 | } |
351 | } | 312 | } |
352 | 313 | ||
353 | static | ||
354 | int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) | ||
355 | { | ||
356 | unsigned char *cmd = (unsigned char *) SCpnt->cmnd; | ||
357 | int len, k; | ||
358 | unsigned int num; | ||
359 | unsigned long long lba; | ||
360 | int errsts = 0; | ||
361 | int target = SCpnt->device->id; | ||
362 | struct sdebug_dev_info * devip = NULL; | ||
363 | int inj_recovered = 0; | ||
364 | int inj_transport = 0; | ||
365 | int delay_override = 0; | ||
366 | |||
367 | if (done == NULL) | ||
368 | return 0; /* assume mid level reprocessing command */ | ||
369 | |||
370 | scsi_set_resid(SCpnt, 0); | ||
371 | if ((SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) && cmd) { | ||
372 | printk(KERN_INFO "scsi_debug: cmd "); | ||
373 | for (k = 0, len = SCpnt->cmd_len; k < len; ++k) | ||
374 | printk("%02x ", (int)cmd[k]); | ||
375 | printk("\n"); | ||
376 | } | ||
377 | if(target == sdebug_driver_template.this_id) { | ||
378 | printk(KERN_INFO "scsi_debug: initiator's id used as " | ||
379 | "target!\n"); | ||
380 | return schedule_resp(SCpnt, NULL, done, | ||
381 | DID_NO_CONNECT << 16, 0); | ||
382 | } | ||
383 | |||
384 | if ((SCpnt->device->lun >= scsi_debug_max_luns) && | ||
385 | (SCpnt->device->lun != SAM2_WLUN_REPORT_LUNS)) | ||
386 | return schedule_resp(SCpnt, NULL, done, | ||
387 | DID_NO_CONNECT << 16, 0); | ||
388 | devip = devInfoReg(SCpnt->device); | ||
389 | if (NULL == devip) | ||
390 | return schedule_resp(SCpnt, NULL, done, | ||
391 | DID_NO_CONNECT << 16, 0); | ||
392 | |||
393 | if ((scsi_debug_every_nth != 0) && | ||
394 | (++scsi_debug_cmnd_count >= abs(scsi_debug_every_nth))) { | ||
395 | scsi_debug_cmnd_count = 0; | ||
396 | if (scsi_debug_every_nth < -1) | ||
397 | scsi_debug_every_nth = -1; | ||
398 | if (SCSI_DEBUG_OPT_TIMEOUT & scsi_debug_opts) | ||
399 | return 0; /* ignore command causing timeout */ | ||
400 | else if (SCSI_DEBUG_OPT_RECOVERED_ERR & scsi_debug_opts) | ||
401 | inj_recovered = 1; /* to reads and writes below */ | ||
402 | else if (SCSI_DEBUG_OPT_TRANSPORT_ERR & scsi_debug_opts) | ||
403 | inj_transport = 1; /* to reads and writes below */ | ||
404 | } | ||
405 | |||
406 | if (devip->wlun) { | ||
407 | switch (*cmd) { | ||
408 | case INQUIRY: | ||
409 | case REQUEST_SENSE: | ||
410 | case TEST_UNIT_READY: | ||
411 | case REPORT_LUNS: | ||
412 | break; /* only allowable wlun commands */ | ||
413 | default: | ||
414 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | ||
415 | printk(KERN_INFO "scsi_debug: Opcode: 0x%x " | ||
416 | "not supported for wlun\n", *cmd); | ||
417 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
418 | INVALID_OPCODE, 0); | ||
419 | errsts = check_condition_result; | ||
420 | return schedule_resp(SCpnt, devip, done, errsts, | ||
421 | 0); | ||
422 | } | ||
423 | } | ||
424 | |||
425 | switch (*cmd) { | ||
426 | case INQUIRY: /* mandatory, ignore unit attention */ | ||
427 | delay_override = 1; | ||
428 | errsts = resp_inquiry(SCpnt, target, devip); | ||
429 | break; | ||
430 | case REQUEST_SENSE: /* mandatory, ignore unit attention */ | ||
431 | delay_override = 1; | ||
432 | errsts = resp_requests(SCpnt, devip); | ||
433 | break; | ||
434 | case REZERO_UNIT: /* actually this is REWIND for SSC */ | ||
435 | case START_STOP: | ||
436 | errsts = resp_start_stop(SCpnt, devip); | ||
437 | break; | ||
438 | case ALLOW_MEDIUM_REMOVAL: | ||
439 | if ((errsts = check_readiness(SCpnt, 1, devip))) | ||
440 | break; | ||
441 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | ||
442 | printk(KERN_INFO "scsi_debug: Medium removal %s\n", | ||
443 | cmd[4] ? "inhibited" : "enabled"); | ||
444 | break; | ||
445 | case SEND_DIAGNOSTIC: /* mandatory */ | ||
446 | errsts = check_readiness(SCpnt, 1, devip); | ||
447 | break; | ||
448 | case TEST_UNIT_READY: /* mandatory */ | ||
449 | delay_override = 1; | ||
450 | errsts = check_readiness(SCpnt, 0, devip); | ||
451 | break; | ||
452 | case RESERVE: | ||
453 | errsts = check_readiness(SCpnt, 1, devip); | ||
454 | break; | ||
455 | case RESERVE_10: | ||
456 | errsts = check_readiness(SCpnt, 1, devip); | ||
457 | break; | ||
458 | case RELEASE: | ||
459 | errsts = check_readiness(SCpnt, 1, devip); | ||
460 | break; | ||
461 | case RELEASE_10: | ||
462 | errsts = check_readiness(SCpnt, 1, devip); | ||
463 | break; | ||
464 | case READ_CAPACITY: | ||
465 | errsts = resp_readcap(SCpnt, devip); | ||
466 | break; | ||
467 | case SERVICE_ACTION_IN: | ||
468 | if (SAI_READ_CAPACITY_16 != cmd[1]) { | ||
469 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
470 | INVALID_OPCODE, 0); | ||
471 | errsts = check_condition_result; | ||
472 | break; | ||
473 | } | ||
474 | errsts = resp_readcap16(SCpnt, devip); | ||
475 | break; | ||
476 | case MAINTENANCE_IN: | ||
477 | if (MI_REPORT_TARGET_PGS != cmd[1]) { | ||
478 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
479 | INVALID_OPCODE, 0); | ||
480 | errsts = check_condition_result; | ||
481 | break; | ||
482 | } | ||
483 | errsts = resp_report_tgtpgs(SCpnt, devip); | ||
484 | break; | ||
485 | case READ_16: | ||
486 | case READ_12: | ||
487 | case READ_10: | ||
488 | case READ_6: | ||
489 | if ((errsts = check_readiness(SCpnt, 0, devip))) | ||
490 | break; | ||
491 | if (scsi_debug_fake_rw) | ||
492 | break; | ||
493 | get_data_transfer_info(cmd, &lba, &num); | ||
494 | errsts = resp_read(SCpnt, lba, num, devip); | ||
495 | if (inj_recovered && (0 == errsts)) { | ||
496 | mk_sense_buffer(devip, RECOVERED_ERROR, | ||
497 | THRESHOLD_EXCEEDED, 0); | ||
498 | errsts = check_condition_result; | ||
499 | } else if (inj_transport && (0 == errsts)) { | ||
500 | mk_sense_buffer(devip, ABORTED_COMMAND, | ||
501 | TRANSPORT_PROBLEM, ACK_NAK_TO); | ||
502 | errsts = check_condition_result; | ||
503 | } | ||
504 | break; | ||
505 | case REPORT_LUNS: /* mandatory, ignore unit attention */ | ||
506 | delay_override = 1; | ||
507 | errsts = resp_report_luns(SCpnt, devip); | ||
508 | break; | ||
509 | case VERIFY: /* 10 byte SBC-2 command */ | ||
510 | errsts = check_readiness(SCpnt, 0, devip); | ||
511 | break; | ||
512 | case WRITE_16: | ||
513 | case WRITE_12: | ||
514 | case WRITE_10: | ||
515 | case WRITE_6: | ||
516 | if ((errsts = check_readiness(SCpnt, 0, devip))) | ||
517 | break; | ||
518 | if (scsi_debug_fake_rw) | ||
519 | break; | ||
520 | get_data_transfer_info(cmd, &lba, &num); | ||
521 | errsts = resp_write(SCpnt, lba, num, devip); | ||
522 | if (inj_recovered && (0 == errsts)) { | ||
523 | mk_sense_buffer(devip, RECOVERED_ERROR, | ||
524 | THRESHOLD_EXCEEDED, 0); | ||
525 | errsts = check_condition_result; | ||
526 | } | ||
527 | break; | ||
528 | case MODE_SENSE: | ||
529 | case MODE_SENSE_10: | ||
530 | errsts = resp_mode_sense(SCpnt, target, devip); | ||
531 | break; | ||
532 | case MODE_SELECT: | ||
533 | errsts = resp_mode_select(SCpnt, 1, devip); | ||
534 | break; | ||
535 | case MODE_SELECT_10: | ||
536 | errsts = resp_mode_select(SCpnt, 0, devip); | ||
537 | break; | ||
538 | case LOG_SENSE: | ||
539 | errsts = resp_log_sense(SCpnt, devip); | ||
540 | break; | ||
541 | case SYNCHRONIZE_CACHE: | ||
542 | delay_override = 1; | ||
543 | errsts = check_readiness(SCpnt, 0, devip); | ||
544 | break; | ||
545 | case WRITE_BUFFER: | ||
546 | errsts = check_readiness(SCpnt, 1, devip); | ||
547 | break; | ||
548 | case XDWRITEREAD_10: | ||
549 | if (!scsi_bidi_cmnd(SCpnt)) { | ||
550 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
551 | INVALID_FIELD_IN_CDB, 0); | ||
552 | errsts = check_condition_result; | ||
553 | break; | ||
554 | } | ||
555 | |||
556 | errsts = check_readiness(SCpnt, 0, devip); | ||
557 | if (errsts) | ||
558 | break; | ||
559 | if (scsi_debug_fake_rw) | ||
560 | break; | ||
561 | get_data_transfer_info(cmd, &lba, &num); | ||
562 | errsts = resp_read(SCpnt, lba, num, devip); | ||
563 | if (errsts) | ||
564 | break; | ||
565 | errsts = resp_write(SCpnt, lba, num, devip); | ||
566 | if (errsts) | ||
567 | break; | ||
568 | errsts = resp_xdwriteread(SCpnt, lba, num, devip); | ||
569 | break; | ||
570 | default: | ||
571 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | ||
572 | printk(KERN_INFO "scsi_debug: Opcode: 0x%x not " | ||
573 | "supported\n", *cmd); | ||
574 | if ((errsts = check_readiness(SCpnt, 1, devip))) | ||
575 | break; /* Unit attention takes precedence */ | ||
576 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_OPCODE, 0); | ||
577 | errsts = check_condition_result; | ||
578 | break; | ||
579 | } | ||
580 | return schedule_resp(SCpnt, devip, done, errsts, | ||
581 | (delay_override ? 0 : scsi_debug_delay)); | ||
582 | } | ||
583 | |||
584 | static int scsi_debug_ioctl(struct scsi_device *dev, int cmd, void __user *arg) | 314 | static int scsi_debug_ioctl(struct scsi_device *dev, int cmd, void __user *arg) |
585 | { | 315 | { |
586 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) { | 316 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) { |
@@ -613,81 +343,37 @@ static int check_readiness(struct scsi_cmnd * SCpnt, int reset_only, | |||
613 | } | 343 | } |
614 | 344 | ||
615 | /* Returns 0 if ok else (DID_ERROR << 16). Sets scp->resid . */ | 345 | /* Returns 0 if ok else (DID_ERROR << 16). Sets scp->resid . */ |
616 | static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr, | 346 | static int fill_from_dev_buffer(struct scsi_cmnd *scp, unsigned char *arr, |
617 | int arr_len) | 347 | int arr_len) |
618 | { | 348 | { |
619 | int k, req_len, act_len, len, active; | 349 | int act_len; |
620 | void * kaddr; | ||
621 | void * kaddr_off; | ||
622 | struct scatterlist *sg; | ||
623 | struct scsi_data_buffer *sdb = scsi_in(scp); | 350 | struct scsi_data_buffer *sdb = scsi_in(scp); |
624 | 351 | ||
625 | if (!sdb->length) | 352 | if (!sdb->length) |
626 | return 0; | 353 | return 0; |
627 | if (!sdb->table.sgl) | ||
628 | return (DID_ERROR << 16); | ||
629 | if (!(scsi_bidi_cmnd(scp) || scp->sc_data_direction == DMA_FROM_DEVICE)) | 354 | if (!(scsi_bidi_cmnd(scp) || scp->sc_data_direction == DMA_FROM_DEVICE)) |
630 | return (DID_ERROR << 16); | 355 | return (DID_ERROR << 16); |
631 | active = 1; | 356 | |
632 | req_len = act_len = 0; | 357 | act_len = sg_copy_from_buffer(sdb->table.sgl, sdb->table.nents, |
633 | for_each_sg(sdb->table.sgl, sg, sdb->table.nents, k) { | 358 | arr, arr_len); |
634 | if (active) { | ||
635 | kaddr = (unsigned char *) | ||
636 | kmap_atomic(sg_page(sg), KM_USER0); | ||
637 | if (NULL == kaddr) | ||
638 | return (DID_ERROR << 16); | ||
639 | kaddr_off = (unsigned char *)kaddr + sg->offset; | ||
640 | len = sg->length; | ||
641 | if ((req_len + len) > arr_len) { | ||
642 | active = 0; | ||
643 | len = arr_len - req_len; | ||
644 | } | ||
645 | memcpy(kaddr_off, arr + req_len, len); | ||
646 | kunmap_atomic(kaddr, KM_USER0); | ||
647 | act_len += len; | ||
648 | } | ||
649 | req_len += sg->length; | ||
650 | } | ||
651 | if (sdb->resid) | 359 | if (sdb->resid) |
652 | sdb->resid -= act_len; | 360 | sdb->resid -= act_len; |
653 | else | 361 | else |
654 | sdb->resid = req_len - act_len; | 362 | sdb->resid = scsi_bufflen(scp) - act_len; |
363 | |||
655 | return 0; | 364 | return 0; |
656 | } | 365 | } |
657 | 366 | ||
658 | /* Returns number of bytes fetched into 'arr' or -1 if error. */ | 367 | /* Returns number of bytes fetched into 'arr' or -1 if error. */ |
659 | static int fetch_to_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr, | 368 | static int fetch_to_dev_buffer(struct scsi_cmnd *scp, unsigned char *arr, |
660 | int max_arr_len) | 369 | int arr_len) |
661 | { | 370 | { |
662 | int k, req_len, len, fin; | 371 | if (!scsi_bufflen(scp)) |
663 | void * kaddr; | ||
664 | void * kaddr_off; | ||
665 | struct scatterlist * sg; | ||
666 | |||
667 | if (0 == scsi_bufflen(scp)) | ||
668 | return 0; | 372 | return 0; |
669 | if (NULL == scsi_sglist(scp)) | ||
670 | return -1; | ||
671 | if (!(scsi_bidi_cmnd(scp) || scp->sc_data_direction == DMA_TO_DEVICE)) | 373 | if (!(scsi_bidi_cmnd(scp) || scp->sc_data_direction == DMA_TO_DEVICE)) |
672 | return -1; | 374 | return -1; |
673 | req_len = fin = 0; | 375 | |
674 | scsi_for_each_sg(scp, sg, scsi_sg_count(scp), k) { | 376 | return scsi_sg_copy_to_buffer(scp, arr, arr_len); |
675 | kaddr = (unsigned char *)kmap_atomic(sg_page(sg), KM_USER0); | ||
676 | if (NULL == kaddr) | ||
677 | return -1; | ||
678 | kaddr_off = (unsigned char *)kaddr + sg->offset; | ||
679 | len = sg->length; | ||
680 | if ((req_len + len) > max_arr_len) { | ||
681 | len = max_arr_len - req_len; | ||
682 | fin = 1; | ||
683 | } | ||
684 | memcpy(arr + req_len, kaddr_off, len); | ||
685 | kunmap_atomic(kaddr, KM_USER0); | ||
686 | if (fin) | ||
687 | return req_len + len; | ||
688 | req_len += sg->length; | ||
689 | } | ||
690 | return req_len; | ||
691 | } | 377 | } |
692 | 378 | ||
693 | 379 | ||
@@ -1159,6 +845,14 @@ static int resp_start_stop(struct scsi_cmnd * scp, | |||
1159 | return 0; | 845 | return 0; |
1160 | } | 846 | } |
1161 | 847 | ||
848 | static sector_t get_sdebug_capacity(void) | ||
849 | { | ||
850 | if (scsi_debug_virtual_gb > 0) | ||
851 | return 2048 * 1024 * scsi_debug_virtual_gb; | ||
852 | else | ||
853 | return sdebug_store_sectors; | ||
854 | } | ||
855 | |||
1162 | #define SDEBUG_READCAP_ARR_SZ 8 | 856 | #define SDEBUG_READCAP_ARR_SZ 8 |
1163 | static int resp_readcap(struct scsi_cmnd * scp, | 857 | static int resp_readcap(struct scsi_cmnd * scp, |
1164 | struct sdebug_dev_info * devip) | 858 | struct sdebug_dev_info * devip) |
@@ -1170,11 +864,7 @@ static int resp_readcap(struct scsi_cmnd * scp, | |||
1170 | if ((errsts = check_readiness(scp, 1, devip))) | 864 | if ((errsts = check_readiness(scp, 1, devip))) |
1171 | return errsts; | 865 | return errsts; |
1172 | /* following just in case virtual_gb changed */ | 866 | /* following just in case virtual_gb changed */ |
1173 | if (scsi_debug_virtual_gb > 0) { | 867 | sdebug_capacity = get_sdebug_capacity(); |
1174 | sdebug_capacity = 2048 * 1024; | ||
1175 | sdebug_capacity *= scsi_debug_virtual_gb; | ||
1176 | } else | ||
1177 | sdebug_capacity = sdebug_store_sectors; | ||
1178 | memset(arr, 0, SDEBUG_READCAP_ARR_SZ); | 868 | memset(arr, 0, SDEBUG_READCAP_ARR_SZ); |
1179 | if (sdebug_capacity < 0xffffffff) { | 869 | if (sdebug_capacity < 0xffffffff) { |
1180 | capac = (unsigned int)sdebug_capacity - 1; | 870 | capac = (unsigned int)sdebug_capacity - 1; |
@@ -1207,11 +897,7 @@ static int resp_readcap16(struct scsi_cmnd * scp, | |||
1207 | alloc_len = ((cmd[10] << 24) + (cmd[11] << 16) + (cmd[12] << 8) | 897 | alloc_len = ((cmd[10] << 24) + (cmd[11] << 16) + (cmd[12] << 8) |
1208 | + cmd[13]); | 898 | + cmd[13]); |
1209 | /* following just in case virtual_gb changed */ | 899 | /* following just in case virtual_gb changed */ |
1210 | if (scsi_debug_virtual_gb > 0) { | 900 | sdebug_capacity = get_sdebug_capacity(); |
1211 | sdebug_capacity = 2048 * 1024; | ||
1212 | sdebug_capacity *= scsi_debug_virtual_gb; | ||
1213 | } else | ||
1214 | sdebug_capacity = sdebug_store_sectors; | ||
1215 | memset(arr, 0, SDEBUG_READCAP16_ARR_SZ); | 901 | memset(arr, 0, SDEBUG_READCAP16_ARR_SZ); |
1216 | capac = sdebug_capacity - 1; | 902 | capac = sdebug_capacity - 1; |
1217 | for (k = 0; k < 8; ++k, capac >>= 8) | 903 | for (k = 0; k < 8; ++k, capac >>= 8) |
@@ -1505,13 +1191,9 @@ static int resp_mode_sense(struct scsi_cmnd * scp, int target, | |||
1505 | offset = 8; | 1191 | offset = 8; |
1506 | } | 1192 | } |
1507 | ap = arr + offset; | 1193 | ap = arr + offset; |
1508 | if ((bd_len > 0) && (0 == sdebug_capacity)) { | 1194 | if ((bd_len > 0) && (!sdebug_capacity)) |
1509 | if (scsi_debug_virtual_gb > 0) { | 1195 | sdebug_capacity = get_sdebug_capacity(); |
1510 | sdebug_capacity = 2048 * 1024; | 1196 | |
1511 | sdebug_capacity *= scsi_debug_virtual_gb; | ||
1512 | } else | ||
1513 | sdebug_capacity = sdebug_store_sectors; | ||
1514 | } | ||
1515 | if (8 == bd_len) { | 1197 | if (8 == bd_len) { |
1516 | if (sdebug_capacity > 0xfffffffe) { | 1198 | if (sdebug_capacity > 0xfffffffe) { |
1517 | ap[0] = 0xff; | 1199 | ap[0] = 0xff; |
@@ -1808,25 +1490,53 @@ static int resp_log_sense(struct scsi_cmnd * scp, | |||
1808 | min(len, SDEBUG_MAX_INQ_ARR_SZ)); | 1490 | min(len, SDEBUG_MAX_INQ_ARR_SZ)); |
1809 | } | 1491 | } |
1810 | 1492 | ||
1811 | static int resp_read(struct scsi_cmnd * SCpnt, unsigned long long lba, | 1493 | static int check_device_access_params(struct sdebug_dev_info *devi, |
1812 | unsigned int num, struct sdebug_dev_info * devip) | 1494 | unsigned long long lba, unsigned int num) |
1813 | { | 1495 | { |
1814 | unsigned long iflags; | ||
1815 | unsigned int block, from_bottom; | ||
1816 | unsigned long long u; | ||
1817 | int ret; | ||
1818 | |||
1819 | if (lba + num > sdebug_capacity) { | 1496 | if (lba + num > sdebug_capacity) { |
1820 | mk_sense_buffer(devip, ILLEGAL_REQUEST, ADDR_OUT_OF_RANGE, | 1497 | mk_sense_buffer(devi, ILLEGAL_REQUEST, ADDR_OUT_OF_RANGE, 0); |
1821 | 0); | ||
1822 | return check_condition_result; | 1498 | return check_condition_result; |
1823 | } | 1499 | } |
1824 | /* transfer length excessive (tie in to block limits VPD page) */ | 1500 | /* transfer length excessive (tie in to block limits VPD page) */ |
1825 | if (num > sdebug_store_sectors) { | 1501 | if (num > sdebug_store_sectors) { |
1826 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, | 1502 | mk_sense_buffer(devi, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, 0); |
1827 | 0); | ||
1828 | return check_condition_result; | 1503 | return check_condition_result; |
1829 | } | 1504 | } |
1505 | return 0; | ||
1506 | } | ||
1507 | |||
1508 | static int do_device_access(struct scsi_cmnd *scmd, | ||
1509 | struct sdebug_dev_info *devi, | ||
1510 | unsigned long long lba, unsigned int num, int write) | ||
1511 | { | ||
1512 | int ret; | ||
1513 | unsigned int block, rest = 0; | ||
1514 | int (*func)(struct scsi_cmnd *, unsigned char *, int); | ||
1515 | |||
1516 | func = write ? fetch_to_dev_buffer : fill_from_dev_buffer; | ||
1517 | |||
1518 | block = do_div(lba, sdebug_store_sectors); | ||
1519 | if (block + num > sdebug_store_sectors) | ||
1520 | rest = block + num - sdebug_store_sectors; | ||
1521 | |||
1522 | ret = func(scmd, fake_storep + (block * SECT_SIZE), | ||
1523 | (num - rest) * SECT_SIZE); | ||
1524 | if (!ret && rest) | ||
1525 | ret = func(scmd, fake_storep, rest * SECT_SIZE); | ||
1526 | |||
1527 | return ret; | ||
1528 | } | ||
1529 | |||
1530 | static int resp_read(struct scsi_cmnd *SCpnt, unsigned long long lba, | ||
1531 | unsigned int num, struct sdebug_dev_info *devip) | ||
1532 | { | ||
1533 | unsigned long iflags; | ||
1534 | int ret; | ||
1535 | |||
1536 | ret = check_device_access_params(devip, lba, num); | ||
1537 | if (ret) | ||
1538 | return ret; | ||
1539 | |||
1830 | if ((SCSI_DEBUG_OPT_MEDIUM_ERR & scsi_debug_opts) && | 1540 | if ((SCSI_DEBUG_OPT_MEDIUM_ERR & scsi_debug_opts) && |
1831 | (lba <= OPT_MEDIUM_ERR_ADDR) && | 1541 | (lba <= OPT_MEDIUM_ERR_ADDR) && |
1832 | ((lba + num) > OPT_MEDIUM_ERR_ADDR)) { | 1542 | ((lba + num) > OPT_MEDIUM_ERR_ADDR)) { |
@@ -1845,74 +1555,30 @@ static int resp_read(struct scsi_cmnd * SCpnt, unsigned long long lba, | |||
1845 | return check_condition_result; | 1555 | return check_condition_result; |
1846 | } | 1556 | } |
1847 | read_lock_irqsave(&atomic_rw, iflags); | 1557 | read_lock_irqsave(&atomic_rw, iflags); |
1848 | if ((lba + num) <= sdebug_store_sectors) | 1558 | ret = do_device_access(SCpnt, devip, lba, num, 0); |
1849 | ret = fill_from_dev_buffer(SCpnt, | ||
1850 | fake_storep + (lba * SECT_SIZE), | ||
1851 | num * SECT_SIZE); | ||
1852 | else { | ||
1853 | /* modulo when one arg is 64 bits needs do_div() */ | ||
1854 | u = lba; | ||
1855 | block = do_div(u, sdebug_store_sectors); | ||
1856 | from_bottom = 0; | ||
1857 | if ((block + num) > sdebug_store_sectors) | ||
1858 | from_bottom = (block + num) - sdebug_store_sectors; | ||
1859 | ret = fill_from_dev_buffer(SCpnt, | ||
1860 | fake_storep + (block * SECT_SIZE), | ||
1861 | (num - from_bottom) * SECT_SIZE); | ||
1862 | if ((0 == ret) && (from_bottom > 0)) | ||
1863 | ret = fill_from_dev_buffer(SCpnt, fake_storep, | ||
1864 | from_bottom * SECT_SIZE); | ||
1865 | } | ||
1866 | read_unlock_irqrestore(&atomic_rw, iflags); | 1559 | read_unlock_irqrestore(&atomic_rw, iflags); |
1867 | return ret; | 1560 | return ret; |
1868 | } | 1561 | } |
1869 | 1562 | ||
1870 | static int resp_write(struct scsi_cmnd * SCpnt, unsigned long long lba, | 1563 | static int resp_write(struct scsi_cmnd *SCpnt, unsigned long long lba, |
1871 | unsigned int num, struct sdebug_dev_info * devip) | 1564 | unsigned int num, struct sdebug_dev_info *devip) |
1872 | { | 1565 | { |
1873 | unsigned long iflags; | 1566 | unsigned long iflags; |
1874 | unsigned int block, to_bottom; | 1567 | int ret; |
1875 | unsigned long long u; | ||
1876 | int res; | ||
1877 | 1568 | ||
1878 | if (lba + num > sdebug_capacity) { | 1569 | ret = check_device_access_params(devip, lba, num); |
1879 | mk_sense_buffer(devip, ILLEGAL_REQUEST, ADDR_OUT_OF_RANGE, | 1570 | if (ret) |
1880 | 0); | 1571 | return ret; |
1881 | return check_condition_result; | ||
1882 | } | ||
1883 | /* transfer length excessive (tie in to block limits VPD page) */ | ||
1884 | if (num > sdebug_store_sectors) { | ||
1885 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, | ||
1886 | 0); | ||
1887 | return check_condition_result; | ||
1888 | } | ||
1889 | 1572 | ||
1890 | write_lock_irqsave(&atomic_rw, iflags); | 1573 | write_lock_irqsave(&atomic_rw, iflags); |
1891 | if ((lba + num) <= sdebug_store_sectors) | 1574 | ret = do_device_access(SCpnt, devip, lba, num, 1); |
1892 | res = fetch_to_dev_buffer(SCpnt, | ||
1893 | fake_storep + (lba * SECT_SIZE), | ||
1894 | num * SECT_SIZE); | ||
1895 | else { | ||
1896 | /* modulo when one arg is 64 bits needs do_div() */ | ||
1897 | u = lba; | ||
1898 | block = do_div(u, sdebug_store_sectors); | ||
1899 | to_bottom = 0; | ||
1900 | if ((block + num) > sdebug_store_sectors) | ||
1901 | to_bottom = (block + num) - sdebug_store_sectors; | ||
1902 | res = fetch_to_dev_buffer(SCpnt, | ||
1903 | fake_storep + (block * SECT_SIZE), | ||
1904 | (num - to_bottom) * SECT_SIZE); | ||
1905 | if ((0 == res) && (to_bottom > 0)) | ||
1906 | res = fetch_to_dev_buffer(SCpnt, fake_storep, | ||
1907 | to_bottom * SECT_SIZE); | ||
1908 | } | ||
1909 | write_unlock_irqrestore(&atomic_rw, iflags); | 1575 | write_unlock_irqrestore(&atomic_rw, iflags); |
1910 | if (-1 == res) | 1576 | if (-1 == ret) |
1911 | return (DID_ERROR << 16); | 1577 | return (DID_ERROR << 16); |
1912 | else if ((res < (num * SECT_SIZE)) && | 1578 | else if ((ret < (num * SECT_SIZE)) && |
1913 | (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)) | 1579 | (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)) |
1914 | printk(KERN_INFO "scsi_debug: write: cdb indicated=%u, " | 1580 | printk(KERN_INFO "scsi_debug: write: cdb indicated=%u, " |
1915 | " IO sent=%d bytes\n", num * SECT_SIZE, res); | 1581 | " IO sent=%d bytes\n", num * SECT_SIZE, ret); |
1916 | return 0; | 1582 | return 0; |
1917 | } | 1583 | } |
1918 | 1584 | ||
@@ -1987,16 +1653,7 @@ static int resp_xdwriteread(struct scsi_cmnd *scp, unsigned long long lba, | |||
1987 | if (!buf) | 1653 | if (!buf) |
1988 | return ret; | 1654 | return ret; |
1989 | 1655 | ||
1990 | offset = 0; | 1656 | scsi_sg_copy_to_buffer(scp, buf, scsi_bufflen(scp)); |
1991 | scsi_for_each_sg(scp, sg, scsi_sg_count(scp), i) { | ||
1992 | kaddr = (unsigned char *)kmap_atomic(sg_page(sg), KM_USER0); | ||
1993 | if (!kaddr) | ||
1994 | goto out; | ||
1995 | |||
1996 | memcpy(buf + offset, kaddr + sg->offset, sg->length); | ||
1997 | offset += sg->length; | ||
1998 | kunmap_atomic(kaddr, KM_USER0); | ||
1999 | } | ||
2000 | 1657 | ||
2001 | offset = 0; | 1658 | offset = 0; |
2002 | for_each_sg(sdb->table.sgl, sg, sdb->table.nents, i) { | 1659 | for_each_sg(sdb->table.sgl, sg, sdb->table.nents, i) { |
@@ -2045,7 +1702,73 @@ static void timer_intr_handler(unsigned long indx) | |||
2045 | spin_unlock_irqrestore(&queued_arr_lock, iflags); | 1702 | spin_unlock_irqrestore(&queued_arr_lock, iflags); |
2046 | } | 1703 | } |
2047 | 1704 | ||
2048 | static int scsi_debug_slave_alloc(struct scsi_device * sdp) | 1705 | |
1706 | static struct sdebug_dev_info * | ||
1707 | sdebug_device_create(struct sdebug_host_info *sdbg_host, gfp_t flags) | ||
1708 | { | ||
1709 | struct sdebug_dev_info *devip; | ||
1710 | |||
1711 | devip = kzalloc(sizeof(*devip), flags); | ||
1712 | if (devip) { | ||
1713 | devip->sdbg_host = sdbg_host; | ||
1714 | list_add_tail(&devip->dev_list, &sdbg_host->dev_info_list); | ||
1715 | } | ||
1716 | return devip; | ||
1717 | } | ||
1718 | |||
1719 | static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev) | ||
1720 | { | ||
1721 | struct sdebug_host_info * sdbg_host; | ||
1722 | struct sdebug_dev_info * open_devip = NULL; | ||
1723 | struct sdebug_dev_info * devip = | ||
1724 | (struct sdebug_dev_info *)sdev->hostdata; | ||
1725 | |||
1726 | if (devip) | ||
1727 | return devip; | ||
1728 | sdbg_host = *(struct sdebug_host_info **)shost_priv(sdev->host); | ||
1729 | if (!sdbg_host) { | ||
1730 | printk(KERN_ERR "Host info NULL\n"); | ||
1731 | return NULL; | ||
1732 | } | ||
1733 | list_for_each_entry(devip, &sdbg_host->dev_info_list, dev_list) { | ||
1734 | if ((devip->used) && (devip->channel == sdev->channel) && | ||
1735 | (devip->target == sdev->id) && | ||
1736 | (devip->lun == sdev->lun)) | ||
1737 | return devip; | ||
1738 | else { | ||
1739 | if ((!devip->used) && (!open_devip)) | ||
1740 | open_devip = devip; | ||
1741 | } | ||
1742 | } | ||
1743 | if (!open_devip) { /* try and make a new one */ | ||
1744 | open_devip = sdebug_device_create(sdbg_host, GFP_ATOMIC); | ||
1745 | if (!open_devip) { | ||
1746 | printk(KERN_ERR "%s: out of memory at line %d\n", | ||
1747 | __FUNCTION__, __LINE__); | ||
1748 | return NULL; | ||
1749 | } | ||
1750 | } | ||
1751 | |||
1752 | open_devip->channel = sdev->channel; | ||
1753 | open_devip->target = sdev->id; | ||
1754 | open_devip->lun = sdev->lun; | ||
1755 | open_devip->sdbg_host = sdbg_host; | ||
1756 | open_devip->reset = 1; | ||
1757 | open_devip->used = 1; | ||
1758 | memset(open_devip->sense_buff, 0, SDEBUG_SENSE_LEN); | ||
1759 | if (scsi_debug_dsense) | ||
1760 | open_devip->sense_buff[0] = 0x72; | ||
1761 | else { | ||
1762 | open_devip->sense_buff[0] = 0x70; | ||
1763 | open_devip->sense_buff[7] = 0xa; | ||
1764 | } | ||
1765 | if (sdev->lun == SAM2_WLUN_REPORT_LUNS) | ||
1766 | open_devip->wlun = SAM2_WLUN_REPORT_LUNS & 0xff; | ||
1767 | |||
1768 | return open_devip; | ||
1769 | } | ||
1770 | |||
1771 | static int scsi_debug_slave_alloc(struct scsi_device *sdp) | ||
2049 | { | 1772 | { |
2050 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 1773 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) |
2051 | printk(KERN_INFO "scsi_debug: slave_alloc <%u %u %u %u>\n", | 1774 | printk(KERN_INFO "scsi_debug: slave_alloc <%u %u %u %u>\n", |
@@ -2054,9 +1777,9 @@ static int scsi_debug_slave_alloc(struct scsi_device * sdp) | |||
2054 | return 0; | 1777 | return 0; |
2055 | } | 1778 | } |
2056 | 1779 | ||
2057 | static int scsi_debug_slave_configure(struct scsi_device * sdp) | 1780 | static int scsi_debug_slave_configure(struct scsi_device *sdp) |
2058 | { | 1781 | { |
2059 | struct sdebug_dev_info * devip; | 1782 | struct sdebug_dev_info *devip; |
2060 | 1783 | ||
2061 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 1784 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) |
2062 | printk(KERN_INFO "scsi_debug: slave_configure <%u %u %u %u>\n", | 1785 | printk(KERN_INFO "scsi_debug: slave_configure <%u %u %u %u>\n", |
@@ -2074,10 +1797,10 @@ static int scsi_debug_slave_configure(struct scsi_device * sdp) | |||
2074 | return 0; | 1797 | return 0; |
2075 | } | 1798 | } |
2076 | 1799 | ||
2077 | static void scsi_debug_slave_destroy(struct scsi_device * sdp) | 1800 | static void scsi_debug_slave_destroy(struct scsi_device *sdp) |
2078 | { | 1801 | { |
2079 | struct sdebug_dev_info * devip = | 1802 | struct sdebug_dev_info *devip = |
2080 | (struct sdebug_dev_info *)sdp->hostdata; | 1803 | (struct sdebug_dev_info *)sdp->hostdata; |
2081 | 1804 | ||
2082 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 1805 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) |
2083 | printk(KERN_INFO "scsi_debug: slave_destroy <%u %u %u %u>\n", | 1806 | printk(KERN_INFO "scsi_debug: slave_destroy <%u %u %u %u>\n", |
@@ -2089,84 +1812,44 @@ static void scsi_debug_slave_destroy(struct scsi_device * sdp) | |||
2089 | } | 1812 | } |
2090 | } | 1813 | } |
2091 | 1814 | ||
2092 | static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev) | 1815 | /* Returns 1 if found 'cmnd' and deleted its timer. else returns 0 */ |
1816 | static int stop_queued_cmnd(struct scsi_cmnd *cmnd) | ||
2093 | { | 1817 | { |
2094 | struct sdebug_host_info * sdbg_host; | 1818 | unsigned long iflags; |
2095 | struct sdebug_dev_info * open_devip = NULL; | 1819 | int k; |
2096 | struct sdebug_dev_info * devip = | 1820 | struct sdebug_queued_cmd *sqcp; |
2097 | (struct sdebug_dev_info *)sdev->hostdata; | ||
2098 | 1821 | ||
2099 | if (devip) | 1822 | spin_lock_irqsave(&queued_arr_lock, iflags); |
2100 | return devip; | 1823 | for (k = 0; k < SCSI_DEBUG_CANQUEUE; ++k) { |
2101 | sdbg_host = *(struct sdebug_host_info **) sdev->host->hostdata; | 1824 | sqcp = &queued_arr[k]; |
2102 | if(! sdbg_host) { | 1825 | if (sqcp->in_use && (cmnd == sqcp->a_cmnd)) { |
2103 | printk(KERN_ERR "Host info NULL\n"); | 1826 | del_timer_sync(&sqcp->cmnd_timer); |
2104 | return NULL; | 1827 | sqcp->in_use = 0; |
2105 | } | 1828 | sqcp->a_cmnd = NULL; |
2106 | list_for_each_entry(devip, &sdbg_host->dev_info_list, dev_list) { | 1829 | break; |
2107 | if ((devip->used) && (devip->channel == sdev->channel) && | ||
2108 | (devip->target == sdev->id) && | ||
2109 | (devip->lun == sdev->lun)) | ||
2110 | return devip; | ||
2111 | else { | ||
2112 | if ((!devip->used) && (!open_devip)) | ||
2113 | open_devip = devip; | ||
2114 | } | 1830 | } |
2115 | } | 1831 | } |
2116 | if (NULL == open_devip) { /* try and make a new one */ | 1832 | spin_unlock_irqrestore(&queued_arr_lock, iflags); |
2117 | open_devip = kzalloc(sizeof(*open_devip),GFP_ATOMIC); | 1833 | return (k < SCSI_DEBUG_CANQUEUE) ? 1 : 0; |
2118 | if (NULL == open_devip) { | ||
2119 | printk(KERN_ERR "%s: out of memory at line %d\n", | ||
2120 | __FUNCTION__, __LINE__); | ||
2121 | return NULL; | ||
2122 | } | ||
2123 | open_devip->sdbg_host = sdbg_host; | ||
2124 | list_add_tail(&open_devip->dev_list, | ||
2125 | &sdbg_host->dev_info_list); | ||
2126 | } | ||
2127 | if (open_devip) { | ||
2128 | open_devip->channel = sdev->channel; | ||
2129 | open_devip->target = sdev->id; | ||
2130 | open_devip->lun = sdev->lun; | ||
2131 | open_devip->sdbg_host = sdbg_host; | ||
2132 | open_devip->reset = 1; | ||
2133 | open_devip->used = 1; | ||
2134 | memset(open_devip->sense_buff, 0, SDEBUG_SENSE_LEN); | ||
2135 | if (scsi_debug_dsense) | ||
2136 | open_devip->sense_buff[0] = 0x72; | ||
2137 | else { | ||
2138 | open_devip->sense_buff[0] = 0x70; | ||
2139 | open_devip->sense_buff[7] = 0xa; | ||
2140 | } | ||
2141 | if (sdev->lun == SAM2_WLUN_REPORT_LUNS) | ||
2142 | open_devip->wlun = SAM2_WLUN_REPORT_LUNS & 0xff; | ||
2143 | return open_devip; | ||
2144 | } | ||
2145 | return NULL; | ||
2146 | } | 1834 | } |
2147 | 1835 | ||
2148 | static void mk_sense_buffer(struct sdebug_dev_info * devip, int key, | 1836 | /* Deletes (stops) timers of all queued commands */ |
2149 | int asc, int asq) | 1837 | static void stop_all_queued(void) |
2150 | { | 1838 | { |
2151 | unsigned char * sbuff; | 1839 | unsigned long iflags; |
1840 | int k; | ||
1841 | struct sdebug_queued_cmd *sqcp; | ||
2152 | 1842 | ||
2153 | sbuff = devip->sense_buff; | 1843 | spin_lock_irqsave(&queued_arr_lock, iflags); |
2154 | memset(sbuff, 0, SDEBUG_SENSE_LEN); | 1844 | for (k = 0; k < SCSI_DEBUG_CANQUEUE; ++k) { |
2155 | if (scsi_debug_dsense) { | 1845 | sqcp = &queued_arr[k]; |
2156 | sbuff[0] = 0x72; /* descriptor, current */ | 1846 | if (sqcp->in_use && sqcp->a_cmnd) { |
2157 | sbuff[1] = key; | 1847 | del_timer_sync(&sqcp->cmnd_timer); |
2158 | sbuff[2] = asc; | 1848 | sqcp->in_use = 0; |
2159 | sbuff[3] = asq; | 1849 | sqcp->a_cmnd = NULL; |
2160 | } else { | 1850 | } |
2161 | sbuff[0] = 0x70; /* fixed, current */ | ||
2162 | sbuff[2] = key; | ||
2163 | sbuff[7] = 0xa; /* implies 18 byte sense buffer */ | ||
2164 | sbuff[12] = asc; | ||
2165 | sbuff[13] = asq; | ||
2166 | } | 1851 | } |
2167 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 1852 | spin_unlock_irqrestore(&queued_arr_lock, iflags); |
2168 | printk(KERN_INFO "scsi_debug: [sense_key,asc,ascq]: " | ||
2169 | "[0x%x,0x%x,0x%x]\n", key, asc, asq); | ||
2170 | } | 1853 | } |
2171 | 1854 | ||
2172 | static int scsi_debug_abort(struct scsi_cmnd * SCpnt) | 1855 | static int scsi_debug_abort(struct scsi_cmnd * SCpnt) |
@@ -2226,7 +1909,7 @@ static int scsi_debug_bus_reset(struct scsi_cmnd * SCpnt) | |||
2226 | printk(KERN_INFO "scsi_debug: bus_reset\n"); | 1909 | printk(KERN_INFO "scsi_debug: bus_reset\n"); |
2227 | ++num_bus_resets; | 1910 | ++num_bus_resets; |
2228 | if (SCpnt && ((sdp = SCpnt->device)) && ((hp = sdp->host))) { | 1911 | if (SCpnt && ((sdp = SCpnt->device)) && ((hp = sdp->host))) { |
2229 | sdbg_host = *(struct sdebug_host_info **) hp->hostdata; | 1912 | sdbg_host = *(struct sdebug_host_info **)shost_priv(hp); |
2230 | if (sdbg_host) { | 1913 | if (sdbg_host) { |
2231 | list_for_each_entry(dev_info, | 1914 | list_for_each_entry(dev_info, |
2232 | &sdbg_host->dev_info_list, | 1915 | &sdbg_host->dev_info_list, |
@@ -2256,46 +1939,6 @@ static int scsi_debug_host_reset(struct scsi_cmnd * SCpnt) | |||
2256 | return SUCCESS; | 1939 | return SUCCESS; |
2257 | } | 1940 | } |
2258 | 1941 | ||
2259 | /* Returns 1 if found 'cmnd' and deleted its timer. else returns 0 */ | ||
2260 | static int stop_queued_cmnd(struct scsi_cmnd * cmnd) | ||
2261 | { | ||
2262 | unsigned long iflags; | ||
2263 | int k; | ||
2264 | struct sdebug_queued_cmd * sqcp; | ||
2265 | |||
2266 | spin_lock_irqsave(&queued_arr_lock, iflags); | ||
2267 | for (k = 0; k < SCSI_DEBUG_CANQUEUE; ++k) { | ||
2268 | sqcp = &queued_arr[k]; | ||
2269 | if (sqcp->in_use && (cmnd == sqcp->a_cmnd)) { | ||
2270 | del_timer_sync(&sqcp->cmnd_timer); | ||
2271 | sqcp->in_use = 0; | ||
2272 | sqcp->a_cmnd = NULL; | ||
2273 | break; | ||
2274 | } | ||
2275 | } | ||
2276 | spin_unlock_irqrestore(&queued_arr_lock, iflags); | ||
2277 | return (k < SCSI_DEBUG_CANQUEUE) ? 1 : 0; | ||
2278 | } | ||
2279 | |||
2280 | /* Deletes (stops) timers of all queued commands */ | ||
2281 | static void stop_all_queued(void) | ||
2282 | { | ||
2283 | unsigned long iflags; | ||
2284 | int k; | ||
2285 | struct sdebug_queued_cmd * sqcp; | ||
2286 | |||
2287 | spin_lock_irqsave(&queued_arr_lock, iflags); | ||
2288 | for (k = 0; k < SCSI_DEBUG_CANQUEUE; ++k) { | ||
2289 | sqcp = &queued_arr[k]; | ||
2290 | if (sqcp->in_use && sqcp->a_cmnd) { | ||
2291 | del_timer_sync(&sqcp->cmnd_timer); | ||
2292 | sqcp->in_use = 0; | ||
2293 | sqcp->a_cmnd = NULL; | ||
2294 | } | ||
2295 | } | ||
2296 | spin_unlock_irqrestore(&queued_arr_lock, iflags); | ||
2297 | } | ||
2298 | |||
2299 | /* Initializes timers in queued array */ | 1942 | /* Initializes timers in queued array */ |
2300 | static void __init init_all_queued(void) | 1943 | static void __init init_all_queued(void) |
2301 | { | 1944 | { |
@@ -2313,7 +1956,8 @@ static void __init init_all_queued(void) | |||
2313 | spin_unlock_irqrestore(&queued_arr_lock, iflags); | 1956 | spin_unlock_irqrestore(&queued_arr_lock, iflags); |
2314 | } | 1957 | } |
2315 | 1958 | ||
2316 | static void __init sdebug_build_parts(unsigned char * ramp) | 1959 | static void __init sdebug_build_parts(unsigned char *ramp, |
1960 | unsigned long store_size) | ||
2317 | { | 1961 | { |
2318 | struct partition * pp; | 1962 | struct partition * pp; |
2319 | int starts[SDEBUG_MAX_PARTS + 2]; | 1963 | int starts[SDEBUG_MAX_PARTS + 2]; |
@@ -2321,7 +1965,7 @@ static void __init sdebug_build_parts(unsigned char * ramp) | |||
2321 | int heads_by_sects, start_sec, end_sec; | 1965 | int heads_by_sects, start_sec, end_sec; |
2322 | 1966 | ||
2323 | /* assume partition table already zeroed */ | 1967 | /* assume partition table already zeroed */ |
2324 | if ((scsi_debug_num_parts < 1) || (sdebug_store_size < 1048576)) | 1968 | if ((scsi_debug_num_parts < 1) || (store_size < 1048576)) |
2325 | return; | 1969 | return; |
2326 | if (scsi_debug_num_parts > SDEBUG_MAX_PARTS) { | 1970 | if (scsi_debug_num_parts > SDEBUG_MAX_PARTS) { |
2327 | scsi_debug_num_parts = SDEBUG_MAX_PARTS; | 1971 | scsi_debug_num_parts = SDEBUG_MAX_PARTS; |
@@ -2419,7 +2063,6 @@ static int schedule_resp(struct scsi_cmnd * cmnd, | |||
2419 | return 0; | 2063 | return 0; |
2420 | } | 2064 | } |
2421 | } | 2065 | } |
2422 | |||
2423 | /* Note: The following macros create attribute files in the | 2066 | /* Note: The following macros create attribute files in the |
2424 | /sys/module/scsi_debug/parameters directory. Unfortunately this | 2067 | /sys/module/scsi_debug/parameters directory. Unfortunately this |
2425 | driver is unaware of a change and cannot trigger auxiliary actions | 2068 | driver is unaware of a change and cannot trigger auxiliary actions |
@@ -2736,11 +2379,9 @@ static ssize_t sdebug_virtual_gb_store(struct device_driver * ddp, | |||
2736 | 2379 | ||
2737 | if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0)) { | 2380 | if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0)) { |
2738 | scsi_debug_virtual_gb = n; | 2381 | scsi_debug_virtual_gb = n; |
2739 | if (scsi_debug_virtual_gb > 0) { | 2382 | |
2740 | sdebug_capacity = 2048 * 1024; | 2383 | sdebug_capacity = get_sdebug_capacity(); |
2741 | sdebug_capacity *= scsi_debug_virtual_gb; | 2384 | |
2742 | } else | ||
2743 | sdebug_capacity = sdebug_store_sectors; | ||
2744 | return count; | 2385 | return count; |
2745 | } | 2386 | } |
2746 | return -EINVAL; | 2387 | return -EINVAL; |
@@ -2756,21 +2397,10 @@ static ssize_t sdebug_add_host_show(struct device_driver * ddp, char * buf) | |||
2756 | static ssize_t sdebug_add_host_store(struct device_driver * ddp, | 2397 | static ssize_t sdebug_add_host_store(struct device_driver * ddp, |
2757 | const char * buf, size_t count) | 2398 | const char * buf, size_t count) |
2758 | { | 2399 | { |
2759 | int delta_hosts; | 2400 | int delta_hosts; |
2760 | char work[20]; | ||
2761 | 2401 | ||
2762 | if (1 != sscanf(buf, "%10s", work)) | 2402 | if (sscanf(buf, "%d", &delta_hosts) != 1) |
2763 | return -EINVAL; | 2403 | return -EINVAL; |
2764 | { /* temporary hack around sscanf() problem with -ve nums */ | ||
2765 | int neg = 0; | ||
2766 | |||
2767 | if ('-' == *work) | ||
2768 | neg = 1; | ||
2769 | if (1 != sscanf(work + neg, "%d", &delta_hosts)) | ||
2770 | return -EINVAL; | ||
2771 | if (neg) | ||
2772 | delta_hosts = -delta_hosts; | ||
2773 | } | ||
2774 | if (delta_hosts > 0) { | 2404 | if (delta_hosts > 0) { |
2775 | do { | 2405 | do { |
2776 | sdebug_add_adapter(); | 2406 | sdebug_add_adapter(); |
@@ -2782,7 +2412,7 @@ static ssize_t sdebug_add_host_store(struct device_driver * ddp, | |||
2782 | } | 2412 | } |
2783 | return count; | 2413 | return count; |
2784 | } | 2414 | } |
2785 | DRIVER_ATTR(add_host, S_IRUGO | S_IWUSR, sdebug_add_host_show, | 2415 | DRIVER_ATTR(add_host, S_IRUGO | S_IWUSR, sdebug_add_host_show, |
2786 | sdebug_add_host_store); | 2416 | sdebug_add_host_store); |
2787 | 2417 | ||
2788 | static ssize_t sdebug_vpd_use_hostno_show(struct device_driver * ddp, | 2418 | static ssize_t sdebug_vpd_use_hostno_show(struct device_driver * ddp, |
@@ -2851,22 +2481,29 @@ static void do_remove_driverfs_files(void) | |||
2851 | driver_remove_file(&sdebug_driverfs_driver, &driver_attr_add_host); | 2481 | driver_remove_file(&sdebug_driverfs_driver, &driver_attr_add_host); |
2852 | } | 2482 | } |
2853 | 2483 | ||
2484 | static void pseudo_0_release(struct device *dev) | ||
2485 | { | ||
2486 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | ||
2487 | printk(KERN_INFO "scsi_debug: pseudo_0_release() called\n"); | ||
2488 | } | ||
2489 | |||
2490 | static struct device pseudo_primary = { | ||
2491 | .bus_id = "pseudo_0", | ||
2492 | .release = pseudo_0_release, | ||
2493 | }; | ||
2494 | |||
2854 | static int __init scsi_debug_init(void) | 2495 | static int __init scsi_debug_init(void) |
2855 | { | 2496 | { |
2856 | unsigned int sz; | 2497 | unsigned long sz; |
2857 | int host_to_add; | 2498 | int host_to_add; |
2858 | int k; | 2499 | int k; |
2859 | int ret; | 2500 | int ret; |
2860 | 2501 | ||
2861 | if (scsi_debug_dev_size_mb < 1) | 2502 | if (scsi_debug_dev_size_mb < 1) |
2862 | scsi_debug_dev_size_mb = 1; /* force minimum 1 MB ramdisk */ | 2503 | scsi_debug_dev_size_mb = 1; /* force minimum 1 MB ramdisk */ |
2863 | sdebug_store_size = (unsigned int)scsi_debug_dev_size_mb * 1048576; | 2504 | sz = (unsigned long)scsi_debug_dev_size_mb * 1048576; |
2864 | sdebug_store_sectors = sdebug_store_size / SECT_SIZE; | 2505 | sdebug_store_sectors = sz / SECT_SIZE; |
2865 | if (scsi_debug_virtual_gb > 0) { | 2506 | sdebug_capacity = get_sdebug_capacity(); |
2866 | sdebug_capacity = 2048 * 1024; | ||
2867 | sdebug_capacity *= scsi_debug_virtual_gb; | ||
2868 | } else | ||
2869 | sdebug_capacity = sdebug_store_sectors; | ||
2870 | 2507 | ||
2871 | /* play around with geometry, don't waste too much on track 0 */ | 2508 | /* play around with geometry, don't waste too much on track 0 */ |
2872 | sdebug_heads = 8; | 2509 | sdebug_heads = 8; |
@@ -2885,7 +2522,6 @@ static int __init scsi_debug_init(void) | |||
2885 | (sdebug_sectors_per * sdebug_heads); | 2522 | (sdebug_sectors_per * sdebug_heads); |
2886 | } | 2523 | } |
2887 | 2524 | ||
2888 | sz = sdebug_store_size; | ||
2889 | fake_storep = vmalloc(sz); | 2525 | fake_storep = vmalloc(sz); |
2890 | if (NULL == fake_storep) { | 2526 | if (NULL == fake_storep) { |
2891 | printk(KERN_ERR "scsi_debug_init: out of memory, 1\n"); | 2527 | printk(KERN_ERR "scsi_debug_init: out of memory, 1\n"); |
@@ -2893,7 +2529,7 @@ static int __init scsi_debug_init(void) | |||
2893 | } | 2529 | } |
2894 | memset(fake_storep, 0, sz); | 2530 | memset(fake_storep, 0, sz); |
2895 | if (scsi_debug_num_parts > 0) | 2531 | if (scsi_debug_num_parts > 0) |
2896 | sdebug_build_parts(fake_storep); | 2532 | sdebug_build_parts(fake_storep, sz); |
2897 | 2533 | ||
2898 | ret = device_register(&pseudo_primary); | 2534 | ret = device_register(&pseudo_primary); |
2899 | if (ret < 0) { | 2535 | if (ret < 0) { |
@@ -2922,8 +2558,6 @@ static int __init scsi_debug_init(void) | |||
2922 | 2558 | ||
2923 | init_all_queued(); | 2559 | init_all_queued(); |
2924 | 2560 | ||
2925 | sdebug_driver_template.proc_name = sdebug_proc_name; | ||
2926 | |||
2927 | host_to_add = scsi_debug_add_host; | 2561 | host_to_add = scsi_debug_add_host; |
2928 | scsi_debug_add_host = 0; | 2562 | scsi_debug_add_host = 0; |
2929 | 2563 | ||
@@ -2972,30 +2606,6 @@ static void __exit scsi_debug_exit(void) | |||
2972 | device_initcall(scsi_debug_init); | 2606 | device_initcall(scsi_debug_init); |
2973 | module_exit(scsi_debug_exit); | 2607 | module_exit(scsi_debug_exit); |
2974 | 2608 | ||
2975 | static void pseudo_0_release(struct device * dev) | ||
2976 | { | ||
2977 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | ||
2978 | printk(KERN_INFO "scsi_debug: pseudo_0_release() called\n"); | ||
2979 | } | ||
2980 | |||
2981 | static struct device pseudo_primary = { | ||
2982 | .bus_id = "pseudo_0", | ||
2983 | .release = pseudo_0_release, | ||
2984 | }; | ||
2985 | |||
2986 | static int pseudo_lld_bus_match(struct device *dev, | ||
2987 | struct device_driver *dev_driver) | ||
2988 | { | ||
2989 | return 1; | ||
2990 | } | ||
2991 | |||
2992 | static struct bus_type pseudo_lld_bus = { | ||
2993 | .name = "pseudo", | ||
2994 | .match = pseudo_lld_bus_match, | ||
2995 | .probe = sdebug_driver_probe, | ||
2996 | .remove = sdebug_driver_remove, | ||
2997 | }; | ||
2998 | |||
2999 | static void sdebug_release_adapter(struct device * dev) | 2609 | static void sdebug_release_adapter(struct device * dev) |
3000 | { | 2610 | { |
3001 | struct sdebug_host_info *sdbg_host; | 2611 | struct sdebug_host_info *sdbg_host; |
@@ -3009,8 +2619,7 @@ static int sdebug_add_adapter(void) | |||
3009 | int k, devs_per_host; | 2619 | int k, devs_per_host; |
3010 | int error = 0; | 2620 | int error = 0; |
3011 | struct sdebug_host_info *sdbg_host; | 2621 | struct sdebug_host_info *sdbg_host; |
3012 | struct sdebug_dev_info *sdbg_devinfo; | 2622 | struct sdebug_dev_info *sdbg_devinfo, *tmp; |
3013 | struct list_head *lh, *lh_sf; | ||
3014 | 2623 | ||
3015 | sdbg_host = kzalloc(sizeof(*sdbg_host),GFP_KERNEL); | 2624 | sdbg_host = kzalloc(sizeof(*sdbg_host),GFP_KERNEL); |
3016 | if (NULL == sdbg_host) { | 2625 | if (NULL == sdbg_host) { |
@@ -3023,16 +2632,13 @@ static int sdebug_add_adapter(void) | |||
3023 | 2632 | ||
3024 | devs_per_host = scsi_debug_num_tgts * scsi_debug_max_luns; | 2633 | devs_per_host = scsi_debug_num_tgts * scsi_debug_max_luns; |
3025 | for (k = 0; k < devs_per_host; k++) { | 2634 | for (k = 0; k < devs_per_host; k++) { |
3026 | sdbg_devinfo = kzalloc(sizeof(*sdbg_devinfo),GFP_KERNEL); | 2635 | sdbg_devinfo = sdebug_device_create(sdbg_host, GFP_KERNEL); |
3027 | if (NULL == sdbg_devinfo) { | 2636 | if (!sdbg_devinfo) { |
3028 | printk(KERN_ERR "%s: out of memory at line %d\n", | 2637 | printk(KERN_ERR "%s: out of memory at line %d\n", |
3029 | __FUNCTION__, __LINE__); | 2638 | __FUNCTION__, __LINE__); |
3030 | error = -ENOMEM; | 2639 | error = -ENOMEM; |
3031 | goto clean; | 2640 | goto clean; |
3032 | } | 2641 | } |
3033 | sdbg_devinfo->sdbg_host = sdbg_host; | ||
3034 | list_add_tail(&sdbg_devinfo->dev_list, | ||
3035 | &sdbg_host->dev_info_list); | ||
3036 | } | 2642 | } |
3037 | 2643 | ||
3038 | spin_lock(&sdebug_host_list_lock); | 2644 | spin_lock(&sdebug_host_list_lock); |
@@ -3053,9 +2659,8 @@ static int sdebug_add_adapter(void) | |||
3053 | return error; | 2659 | return error; |
3054 | 2660 | ||
3055 | clean: | 2661 | clean: |
3056 | list_for_each_safe(lh, lh_sf, &sdbg_host->dev_info_list) { | 2662 | list_for_each_entry_safe(sdbg_devinfo, tmp, &sdbg_host->dev_info_list, |
3057 | sdbg_devinfo = list_entry(lh, struct sdebug_dev_info, | 2663 | dev_list) { |
3058 | dev_list); | ||
3059 | list_del(&sdbg_devinfo->dev_list); | 2664 | list_del(&sdbg_devinfo->dev_list); |
3060 | kfree(sdbg_devinfo); | 2665 | kfree(sdbg_devinfo); |
3061 | } | 2666 | } |
@@ -3083,6 +2688,263 @@ static void sdebug_remove_adapter(void) | |||
3083 | --scsi_debug_add_host; | 2688 | --scsi_debug_add_host; |
3084 | } | 2689 | } |
3085 | 2690 | ||
2691 | static | ||
2692 | int scsi_debug_queuecommand(struct scsi_cmnd *SCpnt, done_funct_t done) | ||
2693 | { | ||
2694 | unsigned char *cmd = (unsigned char *) SCpnt->cmnd; | ||
2695 | int len, k; | ||
2696 | unsigned int num; | ||
2697 | unsigned long long lba; | ||
2698 | int errsts = 0; | ||
2699 | int target = SCpnt->device->id; | ||
2700 | struct sdebug_dev_info *devip = NULL; | ||
2701 | int inj_recovered = 0; | ||
2702 | int inj_transport = 0; | ||
2703 | int delay_override = 0; | ||
2704 | |||
2705 | scsi_set_resid(SCpnt, 0); | ||
2706 | if ((SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) && cmd) { | ||
2707 | printk(KERN_INFO "scsi_debug: cmd "); | ||
2708 | for (k = 0, len = SCpnt->cmd_len; k < len; ++k) | ||
2709 | printk("%02x ", (int)cmd[k]); | ||
2710 | printk("\n"); | ||
2711 | } | ||
2712 | |||
2713 | if (target == SCpnt->device->host->hostt->this_id) { | ||
2714 | printk(KERN_INFO "scsi_debug: initiator's id used as " | ||
2715 | "target!\n"); | ||
2716 | return schedule_resp(SCpnt, NULL, done, | ||
2717 | DID_NO_CONNECT << 16, 0); | ||
2718 | } | ||
2719 | |||
2720 | if ((SCpnt->device->lun >= scsi_debug_max_luns) && | ||
2721 | (SCpnt->device->lun != SAM2_WLUN_REPORT_LUNS)) | ||
2722 | return schedule_resp(SCpnt, NULL, done, | ||
2723 | DID_NO_CONNECT << 16, 0); | ||
2724 | devip = devInfoReg(SCpnt->device); | ||
2725 | if (NULL == devip) | ||
2726 | return schedule_resp(SCpnt, NULL, done, | ||
2727 | DID_NO_CONNECT << 16, 0); | ||
2728 | |||
2729 | if ((scsi_debug_every_nth != 0) && | ||
2730 | (++scsi_debug_cmnd_count >= abs(scsi_debug_every_nth))) { | ||
2731 | scsi_debug_cmnd_count = 0; | ||
2732 | if (scsi_debug_every_nth < -1) | ||
2733 | scsi_debug_every_nth = -1; | ||
2734 | if (SCSI_DEBUG_OPT_TIMEOUT & scsi_debug_opts) | ||
2735 | return 0; /* ignore command causing timeout */ | ||
2736 | else if (SCSI_DEBUG_OPT_RECOVERED_ERR & scsi_debug_opts) | ||
2737 | inj_recovered = 1; /* to reads and writes below */ | ||
2738 | else if (SCSI_DEBUG_OPT_TRANSPORT_ERR & scsi_debug_opts) | ||
2739 | inj_transport = 1; /* to reads and writes below */ | ||
2740 | } | ||
2741 | |||
2742 | if (devip->wlun) { | ||
2743 | switch (*cmd) { | ||
2744 | case INQUIRY: | ||
2745 | case REQUEST_SENSE: | ||
2746 | case TEST_UNIT_READY: | ||
2747 | case REPORT_LUNS: | ||
2748 | break; /* only allowable wlun commands */ | ||
2749 | default: | ||
2750 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | ||
2751 | printk(KERN_INFO "scsi_debug: Opcode: 0x%x " | ||
2752 | "not supported for wlun\n", *cmd); | ||
2753 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
2754 | INVALID_OPCODE, 0); | ||
2755 | errsts = check_condition_result; | ||
2756 | return schedule_resp(SCpnt, devip, done, errsts, | ||
2757 | 0); | ||
2758 | } | ||
2759 | } | ||
2760 | |||
2761 | switch (*cmd) { | ||
2762 | case INQUIRY: /* mandatory, ignore unit attention */ | ||
2763 | delay_override = 1; | ||
2764 | errsts = resp_inquiry(SCpnt, target, devip); | ||
2765 | break; | ||
2766 | case REQUEST_SENSE: /* mandatory, ignore unit attention */ | ||
2767 | delay_override = 1; | ||
2768 | errsts = resp_requests(SCpnt, devip); | ||
2769 | break; | ||
2770 | case REZERO_UNIT: /* actually this is REWIND for SSC */ | ||
2771 | case START_STOP: | ||
2772 | errsts = resp_start_stop(SCpnt, devip); | ||
2773 | break; | ||
2774 | case ALLOW_MEDIUM_REMOVAL: | ||
2775 | errsts = check_readiness(SCpnt, 1, devip); | ||
2776 | if (errsts) | ||
2777 | break; | ||
2778 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | ||
2779 | printk(KERN_INFO "scsi_debug: Medium removal %s\n", | ||
2780 | cmd[4] ? "inhibited" : "enabled"); | ||
2781 | break; | ||
2782 | case SEND_DIAGNOSTIC: /* mandatory */ | ||
2783 | errsts = check_readiness(SCpnt, 1, devip); | ||
2784 | break; | ||
2785 | case TEST_UNIT_READY: /* mandatory */ | ||
2786 | delay_override = 1; | ||
2787 | errsts = check_readiness(SCpnt, 0, devip); | ||
2788 | break; | ||
2789 | case RESERVE: | ||
2790 | errsts = check_readiness(SCpnt, 1, devip); | ||
2791 | break; | ||
2792 | case RESERVE_10: | ||
2793 | errsts = check_readiness(SCpnt, 1, devip); | ||
2794 | break; | ||
2795 | case RELEASE: | ||
2796 | errsts = check_readiness(SCpnt, 1, devip); | ||
2797 | break; | ||
2798 | case RELEASE_10: | ||
2799 | errsts = check_readiness(SCpnt, 1, devip); | ||
2800 | break; | ||
2801 | case READ_CAPACITY: | ||
2802 | errsts = resp_readcap(SCpnt, devip); | ||
2803 | break; | ||
2804 | case SERVICE_ACTION_IN: | ||
2805 | if (SAI_READ_CAPACITY_16 != cmd[1]) { | ||
2806 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
2807 | INVALID_OPCODE, 0); | ||
2808 | errsts = check_condition_result; | ||
2809 | break; | ||
2810 | } | ||
2811 | errsts = resp_readcap16(SCpnt, devip); | ||
2812 | break; | ||
2813 | case MAINTENANCE_IN: | ||
2814 | if (MI_REPORT_TARGET_PGS != cmd[1]) { | ||
2815 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
2816 | INVALID_OPCODE, 0); | ||
2817 | errsts = check_condition_result; | ||
2818 | break; | ||
2819 | } | ||
2820 | errsts = resp_report_tgtpgs(SCpnt, devip); | ||
2821 | break; | ||
2822 | case READ_16: | ||
2823 | case READ_12: | ||
2824 | case READ_10: | ||
2825 | case READ_6: | ||
2826 | errsts = check_readiness(SCpnt, 0, devip); | ||
2827 | if (errsts) | ||
2828 | break; | ||
2829 | if (scsi_debug_fake_rw) | ||
2830 | break; | ||
2831 | get_data_transfer_info(cmd, &lba, &num); | ||
2832 | errsts = resp_read(SCpnt, lba, num, devip); | ||
2833 | if (inj_recovered && (0 == errsts)) { | ||
2834 | mk_sense_buffer(devip, RECOVERED_ERROR, | ||
2835 | THRESHOLD_EXCEEDED, 0); | ||
2836 | errsts = check_condition_result; | ||
2837 | } else if (inj_transport && (0 == errsts)) { | ||
2838 | mk_sense_buffer(devip, ABORTED_COMMAND, | ||
2839 | TRANSPORT_PROBLEM, ACK_NAK_TO); | ||
2840 | errsts = check_condition_result; | ||
2841 | } | ||
2842 | break; | ||
2843 | case REPORT_LUNS: /* mandatory, ignore unit attention */ | ||
2844 | delay_override = 1; | ||
2845 | errsts = resp_report_luns(SCpnt, devip); | ||
2846 | break; | ||
2847 | case VERIFY: /* 10 byte SBC-2 command */ | ||
2848 | errsts = check_readiness(SCpnt, 0, devip); | ||
2849 | break; | ||
2850 | case WRITE_16: | ||
2851 | case WRITE_12: | ||
2852 | case WRITE_10: | ||
2853 | case WRITE_6: | ||
2854 | errsts = check_readiness(SCpnt, 0, devip); | ||
2855 | if (errsts) | ||
2856 | break; | ||
2857 | if (scsi_debug_fake_rw) | ||
2858 | break; | ||
2859 | get_data_transfer_info(cmd, &lba, &num); | ||
2860 | errsts = resp_write(SCpnt, lba, num, devip); | ||
2861 | if (inj_recovered && (0 == errsts)) { | ||
2862 | mk_sense_buffer(devip, RECOVERED_ERROR, | ||
2863 | THRESHOLD_EXCEEDED, 0); | ||
2864 | errsts = check_condition_result; | ||
2865 | } | ||
2866 | break; | ||
2867 | case MODE_SENSE: | ||
2868 | case MODE_SENSE_10: | ||
2869 | errsts = resp_mode_sense(SCpnt, target, devip); | ||
2870 | break; | ||
2871 | case MODE_SELECT: | ||
2872 | errsts = resp_mode_select(SCpnt, 1, devip); | ||
2873 | break; | ||
2874 | case MODE_SELECT_10: | ||
2875 | errsts = resp_mode_select(SCpnt, 0, devip); | ||
2876 | break; | ||
2877 | case LOG_SENSE: | ||
2878 | errsts = resp_log_sense(SCpnt, devip); | ||
2879 | break; | ||
2880 | case SYNCHRONIZE_CACHE: | ||
2881 | delay_override = 1; | ||
2882 | errsts = check_readiness(SCpnt, 0, devip); | ||
2883 | break; | ||
2884 | case WRITE_BUFFER: | ||
2885 | errsts = check_readiness(SCpnt, 1, devip); | ||
2886 | break; | ||
2887 | case XDWRITEREAD_10: | ||
2888 | if (!scsi_bidi_cmnd(SCpnt)) { | ||
2889 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
2890 | INVALID_FIELD_IN_CDB, 0); | ||
2891 | errsts = check_condition_result; | ||
2892 | break; | ||
2893 | } | ||
2894 | |||
2895 | errsts = check_readiness(SCpnt, 0, devip); | ||
2896 | if (errsts) | ||
2897 | break; | ||
2898 | if (scsi_debug_fake_rw) | ||
2899 | break; | ||
2900 | get_data_transfer_info(cmd, &lba, &num); | ||
2901 | errsts = resp_read(SCpnt, lba, num, devip); | ||
2902 | if (errsts) | ||
2903 | break; | ||
2904 | errsts = resp_write(SCpnt, lba, num, devip); | ||
2905 | if (errsts) | ||
2906 | break; | ||
2907 | errsts = resp_xdwriteread(SCpnt, lba, num, devip); | ||
2908 | break; | ||
2909 | default: | ||
2910 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | ||
2911 | printk(KERN_INFO "scsi_debug: Opcode: 0x%x not " | ||
2912 | "supported\n", *cmd); | ||
2913 | errsts = check_readiness(SCpnt, 1, devip); | ||
2914 | if (errsts) | ||
2915 | break; /* Unit attention takes precedence */ | ||
2916 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_OPCODE, 0); | ||
2917 | errsts = check_condition_result; | ||
2918 | break; | ||
2919 | } | ||
2920 | return schedule_resp(SCpnt, devip, done, errsts, | ||
2921 | (delay_override ? 0 : scsi_debug_delay)); | ||
2922 | } | ||
2923 | |||
2924 | static struct scsi_host_template sdebug_driver_template = { | ||
2925 | .proc_info = scsi_debug_proc_info, | ||
2926 | .proc_name = sdebug_proc_name, | ||
2927 | .name = "SCSI DEBUG", | ||
2928 | .info = scsi_debug_info, | ||
2929 | .slave_alloc = scsi_debug_slave_alloc, | ||
2930 | .slave_configure = scsi_debug_slave_configure, | ||
2931 | .slave_destroy = scsi_debug_slave_destroy, | ||
2932 | .ioctl = scsi_debug_ioctl, | ||
2933 | .queuecommand = scsi_debug_queuecommand, | ||
2934 | .eh_abort_handler = scsi_debug_abort, | ||
2935 | .eh_bus_reset_handler = scsi_debug_bus_reset, | ||
2936 | .eh_device_reset_handler = scsi_debug_device_reset, | ||
2937 | .eh_host_reset_handler = scsi_debug_host_reset, | ||
2938 | .bios_param = scsi_debug_biosparam, | ||
2939 | .can_queue = SCSI_DEBUG_CANQUEUE, | ||
2940 | .this_id = 7, | ||
2941 | .sg_tablesize = 256, | ||
2942 | .cmd_per_lun = 16, | ||
2943 | .max_sectors = 0xffff, | ||
2944 | .use_clustering = DISABLE_CLUSTERING, | ||
2945 | .module = THIS_MODULE, | ||
2946 | }; | ||
2947 | |||
3086 | static int sdebug_driver_probe(struct device * dev) | 2948 | static int sdebug_driver_probe(struct device * dev) |
3087 | { | 2949 | { |
3088 | int error = 0; | 2950 | int error = 0; |
@@ -3120,9 +2982,8 @@ static int sdebug_driver_probe(struct device * dev) | |||
3120 | 2982 | ||
3121 | static int sdebug_driver_remove(struct device * dev) | 2983 | static int sdebug_driver_remove(struct device * dev) |
3122 | { | 2984 | { |
3123 | struct list_head *lh, *lh_sf; | ||
3124 | struct sdebug_host_info *sdbg_host; | 2985 | struct sdebug_host_info *sdbg_host; |
3125 | struct sdebug_dev_info *sdbg_devinfo; | 2986 | struct sdebug_dev_info *sdbg_devinfo, *tmp; |
3126 | 2987 | ||
3127 | sdbg_host = to_sdebug_host(dev); | 2988 | sdbg_host = to_sdebug_host(dev); |
3128 | 2989 | ||
@@ -3134,9 +2995,8 @@ static int sdebug_driver_remove(struct device * dev) | |||
3134 | 2995 | ||
3135 | scsi_remove_host(sdbg_host->shost); | 2996 | scsi_remove_host(sdbg_host->shost); |
3136 | 2997 | ||
3137 | list_for_each_safe(lh, lh_sf, &sdbg_host->dev_info_list) { | 2998 | list_for_each_entry_safe(sdbg_devinfo, tmp, &sdbg_host->dev_info_list, |
3138 | sdbg_devinfo = list_entry(lh, struct sdebug_dev_info, | 2999 | dev_list) { |
3139 | dev_list); | ||
3140 | list_del(&sdbg_devinfo->dev_list); | 3000 | list_del(&sdbg_devinfo->dev_list); |
3141 | kfree(sdbg_devinfo); | 3001 | kfree(sdbg_devinfo); |
3142 | } | 3002 | } |
@@ -3145,20 +3005,15 @@ static int sdebug_driver_remove(struct device * dev) | |||
3145 | return 0; | 3005 | return 0; |
3146 | } | 3006 | } |
3147 | 3007 | ||
3148 | static void sdebug_max_tgts_luns(void) | 3008 | static int pseudo_lld_bus_match(struct device *dev, |
3009 | struct device_driver *dev_driver) | ||
3149 | { | 3010 | { |
3150 | struct sdebug_host_info * sdbg_host; | 3011 | return 1; |
3151 | struct Scsi_Host *hpnt; | ||
3152 | |||
3153 | spin_lock(&sdebug_host_list_lock); | ||
3154 | list_for_each_entry(sdbg_host, &sdebug_host_list, host_list) { | ||
3155 | hpnt = sdbg_host->shost; | ||
3156 | if ((hpnt->this_id >= 0) && | ||
3157 | (scsi_debug_num_tgts > hpnt->this_id)) | ||
3158 | hpnt->max_id = scsi_debug_num_tgts + 1; | ||
3159 | else | ||
3160 | hpnt->max_id = scsi_debug_num_tgts; | ||
3161 | hpnt->max_lun = SAM2_WLUN_REPORT_LUNS; /* scsi_debug_max_luns; */ | ||
3162 | } | ||
3163 | spin_unlock(&sdebug_host_list_lock); | ||
3164 | } | 3012 | } |
3013 | |||
3014 | static struct bus_type pseudo_lld_bus = { | ||
3015 | .name = "pseudo", | ||
3016 | .match = pseudo_lld_bus_match, | ||
3017 | .probe = sdebug_driver_probe, | ||
3018 | .remove = sdebug_driver_remove, | ||
3019 | }; | ||
diff --git a/drivers/scsi/scsi_debug.h b/drivers/scsi/scsi_debug.h deleted file mode 100644 index 965dd5e760c1..000000000000 --- a/drivers/scsi/scsi_debug.h +++ /dev/null | |||
@@ -1,24 +0,0 @@ | |||
1 | #ifndef _SCSI_DEBUG_H | ||
2 | |||
3 | #include <linux/types.h> | ||
4 | |||
5 | static int scsi_debug_slave_alloc(struct scsi_device *); | ||
6 | static int scsi_debug_slave_configure(struct scsi_device *); | ||
7 | static void scsi_debug_slave_destroy(struct scsi_device *); | ||
8 | static int scsi_debug_queuecommand(struct scsi_cmnd *, | ||
9 | void (*done) (struct scsi_cmnd *)); | ||
10 | static int scsi_debug_ioctl(struct scsi_device *, int, void __user *); | ||
11 | static int scsi_debug_biosparam(struct scsi_device *, struct block_device *, | ||
12 | sector_t, int[]); | ||
13 | static int scsi_debug_abort(struct scsi_cmnd *); | ||
14 | static int scsi_debug_bus_reset(struct scsi_cmnd *); | ||
15 | static int scsi_debug_device_reset(struct scsi_cmnd *); | ||
16 | static int scsi_debug_host_reset(struct scsi_cmnd *); | ||
17 | static int scsi_debug_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int); | ||
18 | static const char * scsi_debug_info(struct Scsi_Host *); | ||
19 | |||
20 | #define SCSI_DEBUG_CANQUEUE 255 /* needs to be >= 1 */ | ||
21 | |||
22 | #define SCSI_DEBUG_MAX_CMD_LEN 16 | ||
23 | |||
24 | #endif | ||
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 045a0868fc7b..221f31e36d26 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -524,6 +524,41 @@ static int scsi_try_bus_reset(struct scsi_cmnd *scmd) | |||
524 | return rtn; | 524 | return rtn; |
525 | } | 525 | } |
526 | 526 | ||
527 | static void __scsi_report_device_reset(struct scsi_device *sdev, void *data) | ||
528 | { | ||
529 | sdev->was_reset = 1; | ||
530 | sdev->expecting_cc_ua = 1; | ||
531 | } | ||
532 | |||
533 | /** | ||
534 | * scsi_try_target_reset - Ask host to perform a target reset | ||
535 | * @scmd: SCSI cmd used to send a target reset | ||
536 | * | ||
537 | * Notes: | ||
538 | * There is no timeout for this operation. if this operation is | ||
539 | * unreliable for a given host, then the host itself needs to put a | ||
540 | * timer on it, and set the host back to a consistent state prior to | ||
541 | * returning. | ||
542 | */ | ||
543 | static int scsi_try_target_reset(struct scsi_cmnd *scmd) | ||
544 | { | ||
545 | unsigned long flags; | ||
546 | int rtn; | ||
547 | |||
548 | if (!scmd->device->host->hostt->eh_target_reset_handler) | ||
549 | return FAILED; | ||
550 | |||
551 | rtn = scmd->device->host->hostt->eh_target_reset_handler(scmd); | ||
552 | if (rtn == SUCCESS) { | ||
553 | spin_lock_irqsave(scmd->device->host->host_lock, flags); | ||
554 | __starget_for_each_device(scsi_target(scmd->device), NULL, | ||
555 | __scsi_report_device_reset); | ||
556 | spin_unlock_irqrestore(scmd->device->host->host_lock, flags); | ||
557 | } | ||
558 | |||
559 | return rtn; | ||
560 | } | ||
561 | |||
527 | /** | 562 | /** |
528 | * scsi_try_bus_device_reset - Ask host to perform a BDR on a dev | 563 | * scsi_try_bus_device_reset - Ask host to perform a BDR on a dev |
529 | * @scmd: SCSI cmd used to send BDR | 564 | * @scmd: SCSI cmd used to send BDR |
@@ -542,11 +577,8 @@ static int scsi_try_bus_device_reset(struct scsi_cmnd *scmd) | |||
542 | return FAILED; | 577 | return FAILED; |
543 | 578 | ||
544 | rtn = scmd->device->host->hostt->eh_device_reset_handler(scmd); | 579 | rtn = scmd->device->host->hostt->eh_device_reset_handler(scmd); |
545 | if (rtn == SUCCESS) { | 580 | if (rtn == SUCCESS) |
546 | scmd->device->was_reset = 1; | 581 | __scsi_report_device_reset(scmd->device, NULL); |
547 | scmd->device->expecting_cc_ua = 1; | ||
548 | } | ||
549 | |||
550 | return rtn; | 582 | return rtn; |
551 | } | 583 | } |
552 | 584 | ||
@@ -584,8 +616,9 @@ static void scsi_abort_eh_cmnd(struct scsi_cmnd *scmd) | |||
584 | { | 616 | { |
585 | if (__scsi_try_to_abort_cmd(scmd) != SUCCESS) | 617 | if (__scsi_try_to_abort_cmd(scmd) != SUCCESS) |
586 | if (scsi_try_bus_device_reset(scmd) != SUCCESS) | 618 | if (scsi_try_bus_device_reset(scmd) != SUCCESS) |
587 | if (scsi_try_bus_reset(scmd) != SUCCESS) | 619 | if (scsi_try_target_reset(scmd) != SUCCESS) |
588 | scsi_try_host_reset(scmd); | 620 | if (scsi_try_bus_reset(scmd) != SUCCESS) |
621 | scsi_try_host_reset(scmd); | ||
589 | } | 622 | } |
590 | 623 | ||
591 | /** | 624 | /** |
@@ -1060,6 +1093,56 @@ static int scsi_eh_bus_device_reset(struct Scsi_Host *shost, | |||
1060 | } | 1093 | } |
1061 | 1094 | ||
1062 | /** | 1095 | /** |
1096 | * scsi_eh_target_reset - send target reset if needed | ||
1097 | * @shost: scsi host being recovered. | ||
1098 | * @work_q: &list_head for pending commands. | ||
1099 | * @done_q: &list_head for processed commands. | ||
1100 | * | ||
1101 | * Notes: | ||
1102 | * Try a target reset. | ||
1103 | */ | ||
1104 | static int scsi_eh_target_reset(struct Scsi_Host *shost, | ||
1105 | struct list_head *work_q, | ||
1106 | struct list_head *done_q) | ||
1107 | { | ||
1108 | struct scsi_cmnd *scmd, *tgtr_scmd, *next; | ||
1109 | unsigned int id; | ||
1110 | int rtn; | ||
1111 | |||
1112 | for (id = 0; id <= shost->max_id; id++) { | ||
1113 | tgtr_scmd = NULL; | ||
1114 | list_for_each_entry(scmd, work_q, eh_entry) { | ||
1115 | if (id == scmd_id(scmd)) { | ||
1116 | tgtr_scmd = scmd; | ||
1117 | break; | ||
1118 | } | ||
1119 | } | ||
1120 | if (!tgtr_scmd) | ||
1121 | continue; | ||
1122 | |||
1123 | SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Sending target reset " | ||
1124 | "to target %d\n", | ||
1125 | current->comm, id)); | ||
1126 | rtn = scsi_try_target_reset(tgtr_scmd); | ||
1127 | if (rtn == SUCCESS) { | ||
1128 | list_for_each_entry_safe(scmd, next, work_q, eh_entry) { | ||
1129 | if (id == scmd_id(scmd)) | ||
1130 | if (!scsi_device_online(scmd->device) || | ||
1131 | !scsi_eh_tur(tgtr_scmd)) | ||
1132 | scsi_eh_finish_cmd(scmd, | ||
1133 | done_q); | ||
1134 | } | ||
1135 | } else | ||
1136 | SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Target reset" | ||
1137 | " failed target: " | ||
1138 | "%d\n", | ||
1139 | current->comm, id)); | ||
1140 | } | ||
1141 | |||
1142 | return list_empty(work_q); | ||
1143 | } | ||
1144 | |||
1145 | /** | ||
1063 | * scsi_eh_bus_reset - send a bus reset | 1146 | * scsi_eh_bus_reset - send a bus reset |
1064 | * @shost: &scsi host being recovered. | 1147 | * @shost: &scsi host being recovered. |
1065 | * @work_q: &list_head for pending commands. | 1148 | * @work_q: &list_head for pending commands. |
@@ -1447,9 +1530,11 @@ void scsi_eh_ready_devs(struct Scsi_Host *shost, | |||
1447 | { | 1530 | { |
1448 | if (!scsi_eh_stu(shost, work_q, done_q)) | 1531 | if (!scsi_eh_stu(shost, work_q, done_q)) |
1449 | if (!scsi_eh_bus_device_reset(shost, work_q, done_q)) | 1532 | if (!scsi_eh_bus_device_reset(shost, work_q, done_q)) |
1450 | if (!scsi_eh_bus_reset(shost, work_q, done_q)) | 1533 | if (!scsi_eh_target_reset(shost, work_q, done_q)) |
1451 | if (!scsi_eh_host_reset(work_q, done_q)) | 1534 | if (!scsi_eh_bus_reset(shost, work_q, done_q)) |
1452 | scsi_eh_offline_sdevs(work_q, done_q); | 1535 | if (!scsi_eh_host_reset(work_q, done_q)) |
1536 | scsi_eh_offline_sdevs(work_q, | ||
1537 | done_q); | ||
1453 | } | 1538 | } |
1454 | EXPORT_SYMBOL_GPL(scsi_eh_ready_devs); | 1539 | EXPORT_SYMBOL_GPL(scsi_eh_ready_devs); |
1455 | 1540 | ||
@@ -1619,10 +1704,8 @@ void scsi_report_bus_reset(struct Scsi_Host *shost, int channel) | |||
1619 | struct scsi_device *sdev; | 1704 | struct scsi_device *sdev; |
1620 | 1705 | ||
1621 | __shost_for_each_device(sdev, shost) { | 1706 | __shost_for_each_device(sdev, shost) { |
1622 | if (channel == sdev_channel(sdev)) { | 1707 | if (channel == sdev_channel(sdev)) |
1623 | sdev->was_reset = 1; | 1708 | __scsi_report_device_reset(sdev, NULL); |
1624 | sdev->expecting_cc_ua = 1; | ||
1625 | } | ||
1626 | } | 1709 | } |
1627 | } | 1710 | } |
1628 | EXPORT_SYMBOL(scsi_report_bus_reset); | 1711 | EXPORT_SYMBOL(scsi_report_bus_reset); |
@@ -1655,10 +1738,8 @@ void scsi_report_device_reset(struct Scsi_Host *shost, int channel, int target) | |||
1655 | 1738 | ||
1656 | __shost_for_each_device(sdev, shost) { | 1739 | __shost_for_each_device(sdev, shost) { |
1657 | if (channel == sdev_channel(sdev) && | 1740 | if (channel == sdev_channel(sdev) && |
1658 | target == sdev_id(sdev)) { | 1741 | target == sdev_id(sdev)) |
1659 | sdev->was_reset = 1; | 1742 | __scsi_report_device_reset(sdev, NULL); |
1660 | sdev->expecting_cc_ua = 1; | ||
1661 | } | ||
1662 | } | 1743 | } |
1663 | } | 1744 | } |
1664 | EXPORT_SYMBOL(scsi_report_device_reset); | 1745 | EXPORT_SYMBOL(scsi_report_device_reset); |
@@ -1714,6 +1795,11 @@ scsi_reset_provider(struct scsi_device *dev, int flag) | |||
1714 | if (rtn == SUCCESS) | 1795 | if (rtn == SUCCESS) |
1715 | break; | 1796 | break; |
1716 | /* FALLTHROUGH */ | 1797 | /* FALLTHROUGH */ |
1798 | case SCSI_TRY_RESET_TARGET: | ||
1799 | rtn = scsi_try_target_reset(scmd); | ||
1800 | if (rtn == SUCCESS) | ||
1801 | break; | ||
1802 | /* FALLTHROUGH */ | ||
1717 | case SCSI_TRY_RESET_BUS: | 1803 | case SCSI_TRY_RESET_BUS: |
1718 | rtn = scsi_try_bus_reset(scmd); | 1804 | rtn = scsi_try_bus_reset(scmd); |
1719 | if (rtn == SUCCESS) | 1805 | if (rtn == SUCCESS) |
@@ -1907,3 +1993,31 @@ int scsi_get_sense_info_fld(const u8 * sense_buffer, int sb_len, | |||
1907 | } | 1993 | } |
1908 | } | 1994 | } |
1909 | EXPORT_SYMBOL(scsi_get_sense_info_fld); | 1995 | EXPORT_SYMBOL(scsi_get_sense_info_fld); |
1996 | |||
1997 | /** | ||
1998 | * scsi_build_sense_buffer - build sense data in a buffer | ||
1999 | * @desc: Sense format (non zero == descriptor format, | ||
2000 | * 0 == fixed format) | ||
2001 | * @buf: Where to build sense data | ||
2002 | * @key: Sense key | ||
2003 | * @asc: Additional sense code | ||
2004 | * @ascq: Additional sense code qualifier | ||
2005 | * | ||
2006 | **/ | ||
2007 | void scsi_build_sense_buffer(int desc, u8 *buf, u8 key, u8 asc, u8 ascq) | ||
2008 | { | ||
2009 | if (desc) { | ||
2010 | buf[0] = 0x72; /* descriptor, current */ | ||
2011 | buf[1] = key; | ||
2012 | buf[2] = asc; | ||
2013 | buf[3] = ascq; | ||
2014 | buf[7] = 0; | ||
2015 | } else { | ||
2016 | buf[0] = 0x70; /* fixed, current */ | ||
2017 | buf[2] = key; | ||
2018 | buf[7] = 0xa; | ||
2019 | buf[12] = asc; | ||
2020 | buf[13] = ascq; | ||
2021 | } | ||
2022 | } | ||
2023 | EXPORT_SYMBOL(scsi_build_sense_buffer); | ||
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index f40898dc2d14..67f412bb4974 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -784,7 +784,7 @@ EXPORT_SYMBOL(scsi_release_buffers); | |||
784 | * in req->data_len and req->next_rq->data_len. The upper-layer driver can | 784 | * in req->data_len and req->next_rq->data_len. The upper-layer driver can |
785 | * decide what to do with this information. | 785 | * decide what to do with this information. |
786 | */ | 786 | */ |
787 | void scsi_end_bidi_request(struct scsi_cmnd *cmd) | 787 | static void scsi_end_bidi_request(struct scsi_cmnd *cmd) |
788 | { | 788 | { |
789 | struct request *req = cmd->request; | 789 | struct request *req = cmd->request; |
790 | unsigned int dlen = req->data_len; | 790 | unsigned int dlen = req->data_len; |
@@ -839,7 +839,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | |||
839 | int this_count = scsi_bufflen(cmd); | 839 | int this_count = scsi_bufflen(cmd); |
840 | struct request_queue *q = cmd->device->request_queue; | 840 | struct request_queue *q = cmd->device->request_queue; |
841 | struct request *req = cmd->request; | 841 | struct request *req = cmd->request; |
842 | int clear_errors = 1; | 842 | int error = 0; |
843 | struct scsi_sense_hdr sshdr; | 843 | struct scsi_sense_hdr sshdr; |
844 | int sense_valid = 0; | 844 | int sense_valid = 0; |
845 | int sense_deferred = 0; | 845 | int sense_deferred = 0; |
@@ -853,7 +853,6 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | |||
853 | if (blk_pc_request(req)) { /* SG_IO ioctl from block level */ | 853 | if (blk_pc_request(req)) { /* SG_IO ioctl from block level */ |
854 | req->errors = result; | 854 | req->errors = result; |
855 | if (result) { | 855 | if (result) { |
856 | clear_errors = 0; | ||
857 | if (sense_valid && req->sense) { | 856 | if (sense_valid && req->sense) { |
858 | /* | 857 | /* |
859 | * SG_IO wants current and deferred errors | 858 | * SG_IO wants current and deferred errors |
@@ -865,6 +864,8 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | |||
865 | memcpy(req->sense, cmd->sense_buffer, len); | 864 | memcpy(req->sense, cmd->sense_buffer, len); |
866 | req->sense_len = len; | 865 | req->sense_len = len; |
867 | } | 866 | } |
867 | if (!sense_deferred) | ||
868 | error = -EIO; | ||
868 | } | 869 | } |
869 | if (scsi_bidi_cmnd(cmd)) { | 870 | if (scsi_bidi_cmnd(cmd)) { |
870 | /* will also release_buffers */ | 871 | /* will also release_buffers */ |
@@ -885,14 +886,11 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | |||
885 | "%d bytes done.\n", | 886 | "%d bytes done.\n", |
886 | req->nr_sectors, good_bytes)); | 887 | req->nr_sectors, good_bytes)); |
887 | 888 | ||
888 | if (clear_errors) | ||
889 | req->errors = 0; | ||
890 | |||
891 | /* A number of bytes were successfully read. If there | 889 | /* A number of bytes were successfully read. If there |
892 | * are leftovers and there is some kind of error | 890 | * are leftovers and there is some kind of error |
893 | * (result != 0), retry the rest. | 891 | * (result != 0), retry the rest. |
894 | */ | 892 | */ |
895 | if (scsi_end_request(cmd, 0, good_bytes, result == 0) == NULL) | 893 | if (scsi_end_request(cmd, error, good_bytes, result == 0) == NULL) |
896 | return; | 894 | return; |
897 | 895 | ||
898 | /* good_bytes = 0, or (inclusive) there were leftovers and | 896 | /* good_bytes = 0, or (inclusive) there were leftovers and |
diff --git a/drivers/scsi/scsi_tgt_lib.c b/drivers/scsi/scsi_tgt_lib.c index a0f308bd145b..ee8496aa0336 100644 --- a/drivers/scsi/scsi_tgt_lib.c +++ b/drivers/scsi/scsi_tgt_lib.c | |||
@@ -621,9 +621,7 @@ static int __init scsi_tgt_init(void) | |||
621 | { | 621 | { |
622 | int err; | 622 | int err; |
623 | 623 | ||
624 | scsi_tgt_cmd_cache = kmem_cache_create("scsi_tgt_cmd", | 624 | scsi_tgt_cmd_cache = KMEM_CACHE(scsi_tgt_cmd, 0); |
625 | sizeof(struct scsi_tgt_cmd), | ||
626 | 0, 0, NULL); | ||
627 | if (!scsi_tgt_cmd_cache) | 625 | if (!scsi_tgt_cmd_cache) |
628 | return -ENOMEM; | 626 | return -ENOMEM; |
629 | 627 | ||
diff --git a/drivers/scsi/sgiwd93.c b/drivers/scsi/sgiwd93.c index 26cfc56c7091..03e359670506 100644 --- a/drivers/scsi/sgiwd93.c +++ b/drivers/scsi/sgiwd93.c | |||
@@ -263,10 +263,11 @@ static int __init sgiwd93_probe(struct platform_device *pdev) | |||
263 | regs.SASR = wdregs + 3; | 263 | regs.SASR = wdregs + 3; |
264 | regs.SCMD = wdregs + 7; | 264 | regs.SCMD = wdregs + 7; |
265 | 265 | ||
266 | wd33c93_init(host, regs, dma_setup, dma_stop, WD33C93_FS_MHZ(20)); | 266 | hdata->wh.no_sync = 0; |
267 | hdata->wh.fast = 1; | ||
268 | hdata->wh.dma_mode = CTRL_BURST; | ||
267 | 269 | ||
268 | if (hdata->wh.no_sync == 0xff) | 270 | wd33c93_init(host, regs, dma_setup, dma_stop, WD33C93_FS_MHZ(20)); |
269 | hdata->wh.no_sync = 0; | ||
270 | 271 | ||
271 | err = request_irq(irq, sgiwd93_intr, 0, "SGI WD93", host); | 272 | err = request_irq(irq, sgiwd93_intr, 0, "SGI WD93", host); |
272 | if (err) { | 273 | if (err) { |
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 0a52d9d2da2c..df83bea2c620 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c | |||
@@ -17,7 +17,7 @@ | |||
17 | Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support | 17 | Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support |
18 | */ | 18 | */ |
19 | 19 | ||
20 | static const char *verstr = "20080221"; | 20 | static const char *verstr = "20080224"; |
21 | 21 | ||
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | 23 | ||
@@ -183,6 +183,7 @@ static int modes_defined; | |||
183 | 183 | ||
184 | static struct st_buffer *new_tape_buffer(int, int, int); | 184 | static struct st_buffer *new_tape_buffer(int, int, int); |
185 | static int enlarge_buffer(struct st_buffer *, int, int); | 185 | static int enlarge_buffer(struct st_buffer *, int, int); |
186 | static void clear_buffer(struct st_buffer *); | ||
186 | static void normalize_buffer(struct st_buffer *); | 187 | static void normalize_buffer(struct st_buffer *); |
187 | static int append_to_buffer(const char __user *, struct st_buffer *, int); | 188 | static int append_to_buffer(const char __user *, struct st_buffer *, int); |
188 | static int from_buffer(struct st_buffer *, char __user *, int); | 189 | static int from_buffer(struct st_buffer *, char __user *, int); |
@@ -442,6 +443,7 @@ static void st_sleep_done(void *data, char *sense, int result, int resid) | |||
442 | 443 | ||
443 | memcpy(SRpnt->sense, sense, SCSI_SENSE_BUFFERSIZE); | 444 | memcpy(SRpnt->sense, sense, SCSI_SENSE_BUFFERSIZE); |
444 | (STp->buffer)->cmdstat.midlevel_result = SRpnt->result = result; | 445 | (STp->buffer)->cmdstat.midlevel_result = SRpnt->result = result; |
446 | (STp->buffer)->cmdstat.residual = resid; | ||
445 | DEB( STp->write_pending = 0; ) | 447 | DEB( STp->write_pending = 0; ) |
446 | 448 | ||
447 | if (SRpnt->waiting) | 449 | if (SRpnt->waiting) |
@@ -626,7 +628,7 @@ static int cross_eof(struct scsi_tape * STp, int forward) | |||
626 | 628 | ||
627 | 629 | ||
628 | /* Flush the write buffer (never need to write if variable blocksize). */ | 630 | /* Flush the write buffer (never need to write if variable blocksize). */ |
629 | static int flush_write_buffer(struct scsi_tape * STp) | 631 | static int st_flush_write_buffer(struct scsi_tape * STp) |
630 | { | 632 | { |
631 | int offset, transfer, blks; | 633 | int offset, transfer, blks; |
632 | int result; | 634 | int result; |
@@ -717,7 +719,7 @@ static int flush_buffer(struct scsi_tape *STp, int seek_next) | |||
717 | return 0; | 719 | return 0; |
718 | STps = &(STp->ps[STp->partition]); | 720 | STps = &(STp->ps[STp->partition]); |
719 | if (STps->rw == ST_WRITING) /* Writing */ | 721 | if (STps->rw == ST_WRITING) /* Writing */ |
720 | return flush_write_buffer(STp); | 722 | return st_flush_write_buffer(STp); |
721 | 723 | ||
722 | if (STp->block_size == 0) | 724 | if (STp->block_size == 0) |
723 | return 0; | 725 | return 0; |
@@ -1159,6 +1161,7 @@ static int st_open(struct inode *inode, struct file *filp) | |||
1159 | goto err_out; | 1161 | goto err_out; |
1160 | } | 1162 | } |
1161 | 1163 | ||
1164 | (STp->buffer)->cleared = 0; | ||
1162 | (STp->buffer)->writing = 0; | 1165 | (STp->buffer)->writing = 0; |
1163 | (STp->buffer)->syscall_result = 0; | 1166 | (STp->buffer)->syscall_result = 0; |
1164 | 1167 | ||
@@ -1211,7 +1214,7 @@ static int st_flush(struct file *filp, fl_owner_t id) | |||
1211 | return 0; | 1214 | return 0; |
1212 | 1215 | ||
1213 | if (STps->rw == ST_WRITING && !STp->pos_unknown) { | 1216 | if (STps->rw == ST_WRITING && !STp->pos_unknown) { |
1214 | result = flush_write_buffer(STp); | 1217 | result = st_flush_write_buffer(STp); |
1215 | if (result != 0 && result != (-ENOSPC)) | 1218 | if (result != 0 && result != (-ENOSPC)) |
1216 | goto out; | 1219 | goto out; |
1217 | } | 1220 | } |
@@ -1432,8 +1435,14 @@ static int setup_buffering(struct scsi_tape *STp, const char __user *buf, | |||
1432 | if (STp->block_size) | 1435 | if (STp->block_size) |
1433 | bufsize = STp->block_size > st_fixed_buffer_size ? | 1436 | bufsize = STp->block_size > st_fixed_buffer_size ? |
1434 | STp->block_size : st_fixed_buffer_size; | 1437 | STp->block_size : st_fixed_buffer_size; |
1435 | else | 1438 | else { |
1436 | bufsize = count; | 1439 | bufsize = count; |
1440 | /* Make sure that data from previous user is not leaked even if | ||
1441 | HBA does not return correct residual */ | ||
1442 | if (is_read && STp->sili && !STbp->cleared) | ||
1443 | clear_buffer(STbp); | ||
1444 | } | ||
1445 | |||
1437 | if (bufsize > STbp->buffer_size && | 1446 | if (bufsize > STbp->buffer_size && |
1438 | !enlarge_buffer(STbp, bufsize, STp->restr_dma)) { | 1447 | !enlarge_buffer(STbp, bufsize, STp->restr_dma)) { |
1439 | printk(KERN_WARNING "%s: Can't allocate %d byte tape buffer.\n", | 1448 | printk(KERN_WARNING "%s: Can't allocate %d byte tape buffer.\n", |
@@ -1783,6 +1792,8 @@ static long read_tape(struct scsi_tape *STp, long count, | |||
1783 | memset(cmd, 0, MAX_COMMAND_SIZE); | 1792 | memset(cmd, 0, MAX_COMMAND_SIZE); |
1784 | cmd[0] = READ_6; | 1793 | cmd[0] = READ_6; |
1785 | cmd[1] = (STp->block_size != 0); | 1794 | cmd[1] = (STp->block_size != 0); |
1795 | if (!cmd[1] && STp->sili) | ||
1796 | cmd[1] |= 2; | ||
1786 | cmd[2] = blks >> 16; | 1797 | cmd[2] = blks >> 16; |
1787 | cmd[3] = blks >> 8; | 1798 | cmd[3] = blks >> 8; |
1788 | cmd[4] = blks; | 1799 | cmd[4] = blks; |
@@ -1911,8 +1922,11 @@ static long read_tape(struct scsi_tape *STp, long count, | |||
1911 | 1922 | ||
1912 | } | 1923 | } |
1913 | /* End of error handling */ | 1924 | /* End of error handling */ |
1914 | else /* Read successful */ | 1925 | else { /* Read successful */ |
1915 | STbp->buffer_bytes = bytes; | 1926 | STbp->buffer_bytes = bytes; |
1927 | if (STp->sili) /* In fixed block mode residual is always zero here */ | ||
1928 | STbp->buffer_bytes -= STp->buffer->cmdstat.residual; | ||
1929 | } | ||
1916 | 1930 | ||
1917 | if (STps->drv_block >= 0) { | 1931 | if (STps->drv_block >= 0) { |
1918 | if (STp->block_size == 0) | 1932 | if (STp->block_size == 0) |
@@ -2090,7 +2104,8 @@ static void st_log_options(struct scsi_tape * STp, struct st_modedef * STm, char | |||
2090 | name, STm->defaults_for_writes, STp->omit_blklims, STp->can_partitions, | 2104 | name, STm->defaults_for_writes, STp->omit_blklims, STp->can_partitions, |
2091 | STp->scsi2_logical); | 2105 | STp->scsi2_logical); |
2092 | printk(KERN_INFO | 2106 | printk(KERN_INFO |
2093 | "%s: sysv: %d nowait: %d\n", name, STm->sysv, STp->immediate); | 2107 | "%s: sysv: %d nowait: %d sili: %d\n", name, STm->sysv, STp->immediate, |
2108 | STp->sili); | ||
2094 | printk(KERN_INFO "%s: debugging: %d\n", | 2109 | printk(KERN_INFO "%s: debugging: %d\n", |
2095 | name, debugging); | 2110 | name, debugging); |
2096 | } | 2111 | } |
@@ -2133,6 +2148,7 @@ static int st_set_options(struct scsi_tape *STp, long options) | |||
2133 | STp->scsi2_logical = (options & MT_ST_SCSI2LOGICAL) != 0; | 2148 | STp->scsi2_logical = (options & MT_ST_SCSI2LOGICAL) != 0; |
2134 | STp->immediate = (options & MT_ST_NOWAIT) != 0; | 2149 | STp->immediate = (options & MT_ST_NOWAIT) != 0; |
2135 | STm->sysv = (options & MT_ST_SYSV) != 0; | 2150 | STm->sysv = (options & MT_ST_SYSV) != 0; |
2151 | STp->sili = (options & MT_ST_SILI) != 0; | ||
2136 | DEB( debugging = (options & MT_ST_DEBUGGING) != 0; | 2152 | DEB( debugging = (options & MT_ST_DEBUGGING) != 0; |
2137 | st_log_options(STp, STm, name); ) | 2153 | st_log_options(STp, STm, name); ) |
2138 | } else if (code == MT_ST_SETBOOLEANS || code == MT_ST_CLEARBOOLEANS) { | 2154 | } else if (code == MT_ST_SETBOOLEANS || code == MT_ST_CLEARBOOLEANS) { |
@@ -2164,6 +2180,8 @@ static int st_set_options(struct scsi_tape *STp, long options) | |||
2164 | STp->immediate = value; | 2180 | STp->immediate = value; |
2165 | if ((options & MT_ST_SYSV) != 0) | 2181 | if ((options & MT_ST_SYSV) != 0) |
2166 | STm->sysv = value; | 2182 | STm->sysv = value; |
2183 | if ((options & MT_ST_SILI) != 0) | ||
2184 | STp->sili = value; | ||
2167 | DEB( | 2185 | DEB( |
2168 | if ((options & MT_ST_DEBUGGING) != 0) | 2186 | if ((options & MT_ST_DEBUGGING) != 0) |
2169 | debugging = value; | 2187 | debugging = value; |
@@ -3655,6 +3673,8 @@ static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dm | |||
3655 | STbuffer->frp_segs += 1; | 3673 | STbuffer->frp_segs += 1; |
3656 | got += b_size; | 3674 | got += b_size; |
3657 | STbuffer->buffer_size = got; | 3675 | STbuffer->buffer_size = got; |
3676 | if (STbuffer->cleared) | ||
3677 | memset(page_address(STbuffer->frp[segs].page), 0, b_size); | ||
3658 | segs++; | 3678 | segs++; |
3659 | } | 3679 | } |
3660 | STbuffer->b_data = page_address(STbuffer->frp[0].page); | 3680 | STbuffer->b_data = page_address(STbuffer->frp[0].page); |
@@ -3663,6 +3683,17 @@ static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dm | |||
3663 | } | 3683 | } |
3664 | 3684 | ||
3665 | 3685 | ||
3686 | /* Make sure that no data from previous user is in the internal buffer */ | ||
3687 | static void clear_buffer(struct st_buffer * st_bp) | ||
3688 | { | ||
3689 | int i; | ||
3690 | |||
3691 | for (i=0; i < st_bp->frp_segs; i++) | ||
3692 | memset(page_address(st_bp->frp[i].page), 0, st_bp->frp[i].length); | ||
3693 | st_bp->cleared = 1; | ||
3694 | } | ||
3695 | |||
3696 | |||
3666 | /* Release the extra buffer */ | 3697 | /* Release the extra buffer */ |
3667 | static void normalize_buffer(struct st_buffer * STbuffer) | 3698 | static void normalize_buffer(struct st_buffer * STbuffer) |
3668 | { | 3699 | { |
@@ -3987,6 +4018,7 @@ static int st_probe(struct device *dev) | |||
3987 | tpnt->two_fm = ST_TWO_FM; | 4018 | tpnt->two_fm = ST_TWO_FM; |
3988 | tpnt->fast_mteom = ST_FAST_MTEOM; | 4019 | tpnt->fast_mteom = ST_FAST_MTEOM; |
3989 | tpnt->scsi2_logical = ST_SCSI2LOGICAL; | 4020 | tpnt->scsi2_logical = ST_SCSI2LOGICAL; |
4021 | tpnt->sili = ST_SILI; | ||
3990 | tpnt->immediate = ST_NOWAIT; | 4022 | tpnt->immediate = ST_NOWAIT; |
3991 | tpnt->default_drvbuffer = 0xff; /* No forced buffering */ | 4023 | tpnt->default_drvbuffer = 0xff; /* No forced buffering */ |
3992 | tpnt->partition = 0; | 4024 | tpnt->partition = 0; |
@@ -4333,6 +4365,46 @@ static ssize_t st_defcompression_show(struct class_device *class_dev, char *buf) | |||
4333 | 4365 | ||
4334 | CLASS_DEVICE_ATTR(default_compression, S_IRUGO, st_defcompression_show, NULL); | 4366 | CLASS_DEVICE_ATTR(default_compression, S_IRUGO, st_defcompression_show, NULL); |
4335 | 4367 | ||
4368 | static ssize_t st_options_show(struct class_device *class_dev, char *buf) | ||
4369 | { | ||
4370 | struct st_modedef *STm = (struct st_modedef *)class_get_devdata(class_dev); | ||
4371 | struct scsi_tape *STp; | ||
4372 | int i, j, options; | ||
4373 | ssize_t l = 0; | ||
4374 | |||
4375 | for (i=0; i < st_dev_max; i++) { | ||
4376 | for (j=0; j < ST_NBR_MODES; j++) | ||
4377 | if (&scsi_tapes[i]->modes[j] == STm) | ||
4378 | break; | ||
4379 | if (j < ST_NBR_MODES) | ||
4380 | break; | ||
4381 | } | ||
4382 | if (i == st_dev_max) | ||
4383 | return 0; /* should never happen */ | ||
4384 | |||
4385 | STp = scsi_tapes[i]; | ||
4386 | |||
4387 | options = STm->do_buffer_writes ? MT_ST_BUFFER_WRITES : 0; | ||
4388 | options |= STm->do_async_writes ? MT_ST_ASYNC_WRITES : 0; | ||
4389 | options |= STm->do_read_ahead ? MT_ST_READ_AHEAD : 0; | ||
4390 | DEB( options |= debugging ? MT_ST_DEBUGGING : 0 ); | ||
4391 | options |= STp->two_fm ? MT_ST_TWO_FM : 0; | ||
4392 | options |= STp->fast_mteom ? MT_ST_FAST_MTEOM : 0; | ||
4393 | options |= STm->defaults_for_writes ? MT_ST_DEF_WRITES : 0; | ||
4394 | options |= STp->can_bsr ? MT_ST_CAN_BSR : 0; | ||
4395 | options |= STp->omit_blklims ? MT_ST_NO_BLKLIMS : 0; | ||
4396 | options |= STp->can_partitions ? MT_ST_CAN_PARTITIONS : 0; | ||
4397 | options |= STp->scsi2_logical ? MT_ST_SCSI2LOGICAL : 0; | ||
4398 | options |= STm->sysv ? MT_ST_SYSV : 0; | ||
4399 | options |= STp->immediate ? MT_ST_NOWAIT : 0; | ||
4400 | options |= STp->sili ? MT_ST_SILI : 0; | ||
4401 | |||
4402 | l = snprintf(buf, PAGE_SIZE, "0x%08x\n", options); | ||
4403 | return l; | ||
4404 | } | ||
4405 | |||
4406 | CLASS_DEVICE_ATTR(options, S_IRUGO, st_options_show, NULL); | ||
4407 | |||
4336 | static int do_create_class_files(struct scsi_tape *STp, int dev_num, int mode) | 4408 | static int do_create_class_files(struct scsi_tape *STp, int dev_num, int mode) |
4337 | { | 4409 | { |
4338 | int i, rew, error; | 4410 | int i, rew, error; |
@@ -4370,6 +4442,9 @@ static int do_create_class_files(struct scsi_tape *STp, int dev_num, int mode) | |||
4370 | error = class_device_create_file(st_class_member, | 4442 | error = class_device_create_file(st_class_member, |
4371 | &class_device_attr_default_compression); | 4443 | &class_device_attr_default_compression); |
4372 | if (error) goto out; | 4444 | if (error) goto out; |
4445 | error = class_device_create_file(st_class_member, | ||
4446 | &class_device_attr_options); | ||
4447 | if (error) goto out; | ||
4373 | 4448 | ||
4374 | if (mode == 0 && rew == 0) { | 4449 | if (mode == 0 && rew == 0) { |
4375 | error = sysfs_create_link(&STp->device->sdev_gendev.kobj, | 4450 | error = sysfs_create_link(&STp->device->sdev_gendev.kobj, |
diff --git a/drivers/scsi/st.h b/drivers/scsi/st.h index 5931726fcf93..b92712f95931 100644 --- a/drivers/scsi/st.h +++ b/drivers/scsi/st.h | |||
@@ -12,6 +12,7 @@ struct st_cmdstatus { | |||
12 | int midlevel_result; | 12 | int midlevel_result; |
13 | struct scsi_sense_hdr sense_hdr; | 13 | struct scsi_sense_hdr sense_hdr; |
14 | int have_sense; | 14 | int have_sense; |
15 | int residual; | ||
15 | u64 uremainder64; | 16 | u64 uremainder64; |
16 | u8 flags; | 17 | u8 flags; |
17 | u8 remainder_valid; | 18 | u8 remainder_valid; |
@@ -34,6 +35,7 @@ struct st_request { | |||
34 | struct st_buffer { | 35 | struct st_buffer { |
35 | unsigned char dma; /* DMA-able buffer */ | 36 | unsigned char dma; /* DMA-able buffer */ |
36 | unsigned char do_dio; /* direct i/o set up? */ | 37 | unsigned char do_dio; /* direct i/o set up? */ |
38 | unsigned char cleared; /* internal buffer cleared after open? */ | ||
37 | int buffer_size; | 39 | int buffer_size; |
38 | int buffer_blocks; | 40 | int buffer_blocks; |
39 | int buffer_bytes; | 41 | int buffer_bytes; |
@@ -122,6 +124,7 @@ struct scsi_tape { | |||
122 | unsigned char try_dio_now; /* try direct i/o before next close? */ | 124 | unsigned char try_dio_now; /* try direct i/o before next close? */ |
123 | unsigned char c_algo; /* compression algorithm */ | 125 | unsigned char c_algo; /* compression algorithm */ |
124 | unsigned char pos_unknown; /* after reset position unknown */ | 126 | unsigned char pos_unknown; /* after reset position unknown */ |
127 | unsigned char sili; /* use SILI when reading in variable b mode */ | ||
125 | int tape_type; | 128 | int tape_type; |
126 | int long_timeout; /* timeout for commands known to take long time */ | 129 | int long_timeout; /* timeout for commands known to take long time */ |
127 | 130 | ||
diff --git a/drivers/scsi/st_options.h b/drivers/scsi/st_options.h index b6b5c9c37677..d2f947935554 100644 --- a/drivers/scsi/st_options.h +++ b/drivers/scsi/st_options.h | |||
@@ -3,7 +3,7 @@ | |||
3 | 3 | ||
4 | Copyright 1995-2003 Kai Makisara. | 4 | Copyright 1995-2003 Kai Makisara. |
5 | 5 | ||
6 | Last modified: Mon Apr 7 22:49:18 2003 by makisara | 6 | Last modified: Thu Feb 21 21:47:07 2008 by kai.makisara |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #ifndef _ST_OPTIONS_H | 9 | #ifndef _ST_OPTIONS_H |
@@ -94,6 +94,10 @@ | |||
94 | The default is BSD semantics. */ | 94 | The default is BSD semantics. */ |
95 | #define ST_SYSV 0 | 95 | #define ST_SYSV 0 |
96 | 96 | ||
97 | /* If ST_SILI is non-zero, the SILI bit is set when reading in variable block | ||
98 | mode and the block size is determined using the residual returned by the HBA. */ | ||
99 | #define ST_SILI 0 | ||
100 | |||
97 | /* Time to wait for the drive to become ready if blocking open */ | 101 | /* Time to wait for the drive to become ready if blocking open */ |
98 | #define ST_BLOCK_SECONDS 120 | 102 | #define ST_BLOCK_SECONDS 120 |
99 | 103 | ||
diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c index 654430edf74d..f308a0308829 100644 --- a/drivers/scsi/stex.c +++ b/drivers/scsi/stex.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <scsi/scsi_host.h> | 33 | #include <scsi/scsi_host.h> |
34 | #include <scsi/scsi_tcq.h> | 34 | #include <scsi/scsi_tcq.h> |
35 | #include <scsi/scsi_dbg.h> | 35 | #include <scsi/scsi_dbg.h> |
36 | #include <scsi/scsi_eh.h> | ||
36 | 37 | ||
37 | #define DRV_NAME "stex" | 38 | #define DRV_NAME "stex" |
38 | #define ST_DRIVER_VERSION "3.6.0000.1" | 39 | #define ST_DRIVER_VERSION "3.6.0000.1" |
@@ -362,22 +363,14 @@ static struct status_msg *stex_get_status(struct st_hba *hba) | |||
362 | return status; | 363 | return status; |
363 | } | 364 | } |
364 | 365 | ||
365 | static void stex_set_sense(struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq) | ||
366 | { | ||
367 | cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; | ||
368 | |||
369 | cmd->sense_buffer[0] = 0x70; /* fixed format, current */ | ||
370 | cmd->sense_buffer[2] = sk; | ||
371 | cmd->sense_buffer[7] = 18 - 8; /* additional sense length */ | ||
372 | cmd->sense_buffer[12] = asc; | ||
373 | cmd->sense_buffer[13] = ascq; | ||
374 | } | ||
375 | |||
376 | static void stex_invalid_field(struct scsi_cmnd *cmd, | 366 | static void stex_invalid_field(struct scsi_cmnd *cmd, |
377 | void (*done)(struct scsi_cmnd *)) | 367 | void (*done)(struct scsi_cmnd *)) |
378 | { | 368 | { |
369 | cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; | ||
370 | |||
379 | /* "Invalid field in cbd" */ | 371 | /* "Invalid field in cbd" */ |
380 | stex_set_sense(cmd, ILLEGAL_REQUEST, 0x24, 0x0); | 372 | scsi_build_sense_buffer(0, cmd->sense_buffer, ILLEGAL_REQUEST, 0x24, |
373 | 0x0); | ||
381 | done(cmd); | 374 | done(cmd); |
382 | } | 375 | } |
383 | 376 | ||
@@ -426,49 +419,13 @@ static int stex_map_sg(struct st_hba *hba, | |||
426 | return 0; | 419 | return 0; |
427 | } | 420 | } |
428 | 421 | ||
429 | static void stex_internal_copy(struct scsi_cmnd *cmd, | ||
430 | const void *src, size_t *count, int sg_count, int direction) | ||
431 | { | ||
432 | size_t lcount; | ||
433 | size_t len; | ||
434 | void *s, *d, *base = NULL; | ||
435 | size_t offset; | ||
436 | |||
437 | if (*count > scsi_bufflen(cmd)) | ||
438 | *count = scsi_bufflen(cmd); | ||
439 | lcount = *count; | ||
440 | while (lcount) { | ||
441 | len = lcount; | ||
442 | s = (void *)src; | ||
443 | |||
444 | offset = *count - lcount; | ||
445 | s += offset; | ||
446 | base = scsi_kmap_atomic_sg(scsi_sglist(cmd), | ||
447 | sg_count, &offset, &len); | ||
448 | if (!base) { | ||
449 | *count -= lcount; | ||
450 | return; | ||
451 | } | ||
452 | d = base + offset; | ||
453 | |||
454 | if (direction == ST_TO_CMD) | ||
455 | memcpy(d, s, len); | ||
456 | else | ||
457 | memcpy(s, d, len); | ||
458 | |||
459 | lcount -= len; | ||
460 | scsi_kunmap_atomic_sg(base); | ||
461 | } | ||
462 | } | ||
463 | |||
464 | static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb) | 422 | static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb) |
465 | { | 423 | { |
466 | struct st_frame *p; | 424 | struct st_frame *p; |
467 | size_t count = sizeof(struct st_frame); | 425 | size_t count = sizeof(struct st_frame); |
468 | 426 | ||
469 | p = hba->copy_buffer; | 427 | p = hba->copy_buffer; |
470 | stex_internal_copy(ccb->cmd, p, &count, scsi_sg_count(ccb->cmd), | 428 | count = scsi_sg_copy_to_buffer(ccb->cmd, p, count); |
471 | ST_FROM_CMD); | ||
472 | memset(p->base, 0, sizeof(u32)*6); | 429 | memset(p->base, 0, sizeof(u32)*6); |
473 | *(unsigned long *)(p->base) = pci_resource_start(hba->pdev, 0); | 430 | *(unsigned long *)(p->base) = pci_resource_start(hba->pdev, 0); |
474 | p->rom_addr = 0; | 431 | p->rom_addr = 0; |
@@ -486,8 +443,7 @@ static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb) | |||
486 | p->subid = | 443 | p->subid = |
487 | hba->pdev->subsystem_vendor << 16 | hba->pdev->subsystem_device; | 444 | hba->pdev->subsystem_vendor << 16 | hba->pdev->subsystem_device; |
488 | 445 | ||
489 | stex_internal_copy(ccb->cmd, p, &count, scsi_sg_count(ccb->cmd), | 446 | count = scsi_sg_copy_from_buffer(ccb->cmd, p, count); |
490 | ST_TO_CMD); | ||
491 | } | 447 | } |
492 | 448 | ||
493 | static void | 449 | static void |
@@ -554,10 +510,8 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) | |||
554 | unsigned char page; | 510 | unsigned char page; |
555 | page = cmd->cmnd[2] & 0x3f; | 511 | page = cmd->cmnd[2] & 0x3f; |
556 | if (page == 0x8 || page == 0x3f) { | 512 | if (page == 0x8 || page == 0x3f) { |
557 | size_t cp_len = sizeof(ms10_caching_page); | 513 | scsi_sg_copy_from_buffer(cmd, ms10_caching_page, |
558 | stex_internal_copy(cmd, ms10_caching_page, | 514 | sizeof(ms10_caching_page)); |
559 | &cp_len, scsi_sg_count(cmd), | ||
560 | ST_TO_CMD); | ||
561 | cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8; | 515 | cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8; |
562 | done(cmd); | 516 | done(cmd); |
563 | } else | 517 | } else |
@@ -586,10 +540,8 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) | |||
586 | if (id != host->max_id - 1) | 540 | if (id != host->max_id - 1) |
587 | break; | 541 | break; |
588 | if (lun == 0 && (cmd->cmnd[1] & INQUIRY_EVPD) == 0) { | 542 | if (lun == 0 && (cmd->cmnd[1] & INQUIRY_EVPD) == 0) { |
589 | size_t cp_len = sizeof(console_inq_page); | 543 | scsi_sg_copy_from_buffer(cmd, (void *)console_inq_page, |
590 | stex_internal_copy(cmd, console_inq_page, | 544 | sizeof(console_inq_page)); |
591 | &cp_len, scsi_sg_count(cmd), | ||
592 | ST_TO_CMD); | ||
593 | cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8; | 545 | cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8; |
594 | done(cmd); | 546 | done(cmd); |
595 | } else | 547 | } else |
@@ -606,8 +558,7 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) | |||
606 | ver.signature[0] = PASSTHRU_SIGNATURE; | 558 | ver.signature[0] = PASSTHRU_SIGNATURE; |
607 | ver.console_id = host->max_id - 1; | 559 | ver.console_id = host->max_id - 1; |
608 | ver.host_no = hba->host->host_no; | 560 | ver.host_no = hba->host->host_no; |
609 | stex_internal_copy(cmd, &ver, &cp_len, | 561 | cp_len = scsi_sg_copy_from_buffer(cmd, &ver, cp_len); |
610 | scsi_sg_count(cmd), ST_TO_CMD); | ||
611 | cmd->result = sizeof(ver) == cp_len ? | 562 | cmd->result = sizeof(ver) == cp_len ? |
612 | DID_OK << 16 | COMMAND_COMPLETE << 8 : | 563 | DID_OK << 16 | COMMAND_COMPLETE << 8 : |
613 | DID_ERROR << 16 | COMMAND_COMPLETE << 8; | 564 | DID_ERROR << 16 | COMMAND_COMPLETE << 8; |
@@ -700,15 +651,12 @@ static void stex_copy_data(struct st_ccb *ccb, | |||
700 | 651 | ||
701 | if (ccb->cmd == NULL) | 652 | if (ccb->cmd == NULL) |
702 | return; | 653 | return; |
703 | stex_internal_copy(ccb->cmd, | 654 | count = scsi_sg_copy_from_buffer(ccb->cmd, resp->variable, count); |
704 | resp->variable, &count, scsi_sg_count(ccb->cmd), ST_TO_CMD); | ||
705 | } | 655 | } |
706 | 656 | ||
707 | static void stex_ys_commands(struct st_hba *hba, | 657 | static void stex_ys_commands(struct st_hba *hba, |
708 | struct st_ccb *ccb, struct status_msg *resp) | 658 | struct st_ccb *ccb, struct status_msg *resp) |
709 | { | 659 | { |
710 | size_t count; | ||
711 | |||
712 | if (ccb->cmd->cmnd[0] == MGT_CMD && | 660 | if (ccb->cmd->cmnd[0] == MGT_CMD && |
713 | resp->scsi_status != SAM_STAT_CHECK_CONDITION) { | 661 | resp->scsi_status != SAM_STAT_CHECK_CONDITION) { |
714 | scsi_set_resid(ccb->cmd, scsi_bufflen(ccb->cmd) - | 662 | scsi_set_resid(ccb->cmd, scsi_bufflen(ccb->cmd) - |
@@ -724,9 +672,8 @@ static void stex_ys_commands(struct st_hba *hba, | |||
724 | resp->scsi_status == SAM_STAT_GOOD) { | 672 | resp->scsi_status == SAM_STAT_GOOD) { |
725 | ST_INQ *inq_data; | 673 | ST_INQ *inq_data; |
726 | 674 | ||
727 | count = STEX_EXTRA_SIZE; | 675 | scsi_sg_copy_to_buffer(ccb->cmd, hba->copy_buffer, |
728 | stex_internal_copy(ccb->cmd, hba->copy_buffer, | 676 | STEX_EXTRA_SIZE); |
729 | &count, scsi_sg_count(ccb->cmd), ST_FROM_CMD); | ||
730 | inq_data = (ST_INQ *)hba->copy_buffer; | 677 | inq_data = (ST_INQ *)hba->copy_buffer; |
731 | if (inq_data->DeviceTypeQualifier != 0) | 678 | if (inq_data->DeviceTypeQualifier != 0) |
732 | ccb->srb_status = SRB_STATUS_SELECTION_TIMEOUT; | 679 | ccb->srb_status = SRB_STATUS_SELECTION_TIMEOUT; |
diff --git a/drivers/scsi/sun3_scsi_vme.c b/drivers/scsi/sun3_scsi_vme.c index 02d9727f017a..aaa4fd0dd1b9 100644 --- a/drivers/scsi/sun3_scsi_vme.c +++ b/drivers/scsi/sun3_scsi_vme.c | |||
@@ -582,3 +582,4 @@ static struct scsi_host_template driver_template = { | |||
582 | 582 | ||
583 | #include "scsi_module.c" | 583 | #include "scsi_module.c" |
584 | 584 | ||
585 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/scsi/wd33c93.c b/drivers/scsi/wd33c93.c index f286c37da7e0..5fda881c2470 100644 --- a/drivers/scsi/wd33c93.c +++ b/drivers/scsi/wd33c93.c | |||
@@ -1973,10 +1973,7 @@ wd33c93_init(struct Scsi_Host *instance, const wd33c93_regs regs, | |||
1973 | hostdata->incoming_ptr = 0; | 1973 | hostdata->incoming_ptr = 0; |
1974 | hostdata->outgoing_len = 0; | 1974 | hostdata->outgoing_len = 0; |
1975 | hostdata->default_sx_per = DEFAULT_SX_PER; | 1975 | hostdata->default_sx_per = DEFAULT_SX_PER; |
1976 | hostdata->no_sync = 0xff; /* sync defaults to off */ | ||
1977 | hostdata->no_dma = 0; /* default is DMA enabled */ | 1976 | hostdata->no_dma = 0; /* default is DMA enabled */ |
1978 | hostdata->fast = 0; /* default is Fast SCSI transfers disabled */ | ||
1979 | hostdata->dma_mode = CTRL_DMA; /* default is Single Byte DMA */ | ||
1980 | 1977 | ||
1981 | #ifdef PROC_INTERFACE | 1978 | #ifdef PROC_INTERFACE |
1982 | hostdata->proc = PR_VERSION | PR_INFO | PR_STATISTICS | | 1979 | hostdata->proc = PR_VERSION | PR_INFO | PR_STATISTICS | |