diff options
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/aic7xxx/aic7xxx_osm.c | 9 | ||||
-rw-r--r-- | drivers/scsi/aic7xxx/aic7xxx_osm.h | 2 | ||||
-rw-r--r-- | drivers/scsi/aic7xxx/aic7xxx_osm_pci.c | 8 | ||||
-rw-r--r-- | drivers/scsi/atp870u.c | 6 | ||||
-rw-r--r-- | drivers/scsi/atp870u.h | 5 | ||||
-rw-r--r-- | drivers/scsi/fd_mcs.c | 2 | ||||
-rw-r--r-- | drivers/scsi/hosts.c | 35 | ||||
-rw-r--r-- | drivers/scsi/ibmmca.c | 2 | ||||
-rw-r--r-- | drivers/scsi/ibmvscsi/ibmvscsi.c | 10 | ||||
-rw-r--r-- | drivers/scsi/libata-core.c | 37 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 21 | ||||
-rw-r--r-- | drivers/scsi/sata_sis.c | 4 | ||||
-rw-r--r-- | drivers/scsi/scsi.c | 5 | ||||
-rw-r--r-- | drivers/scsi/scsi_devinfo.c | 1 | ||||
-rw-r--r-- | drivers/scsi/scsi_error.c | 78 | ||||
-rw-r--r-- | drivers/scsi/scsi_ioctl.c | 2 | ||||
-rw-r--r-- | drivers/scsi/scsi_lib.c | 12 | ||||
-rw-r--r-- | drivers/scsi/scsi_scan.c | 20 | ||||
-rw-r--r-- | drivers/scsi/scsi_sysfs.c | 17 | ||||
-rw-r--r-- | drivers/scsi/sd.c | 1 | ||||
-rw-r--r-- | drivers/scsi/sg.c | 2 | ||||
-rw-r--r-- | drivers/scsi/sr.c | 1 | ||||
-rw-r--r-- | drivers/scsi/st.c | 1 |
23 files changed, 166 insertions, 115 deletions
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index c932b3b94490..876d1de8480d 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c | |||
@@ -1109,15 +1109,6 @@ ahc_linux_register_host(struct ahc_softc *ahc, struct scsi_host_template *templa | |||
1109 | return (0); | 1109 | return (0); |
1110 | } | 1110 | } |
1111 | 1111 | ||
1112 | uint64_t | ||
1113 | ahc_linux_get_memsize(void) | ||
1114 | { | ||
1115 | struct sysinfo si; | ||
1116 | |||
1117 | si_meminfo(&si); | ||
1118 | return ((uint64_t)si.totalram << PAGE_SHIFT); | ||
1119 | } | ||
1120 | |||
1121 | /* | 1112 | /* |
1122 | * Place the SCSI bus into a known state by either resetting it, | 1113 | * Place the SCSI bus into a known state by either resetting it, |
1123 | * or forcing transfer negotiations on the next command to any | 1114 | * or forcing transfer negotiations on the next command to any |
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h index c52996269240..be9edbe26dbe 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.h +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h | |||
@@ -494,8 +494,6 @@ ahc_insb(struct ahc_softc * ahc, long port, uint8_t *array, int count) | |||
494 | int ahc_linux_register_host(struct ahc_softc *, | 494 | int ahc_linux_register_host(struct ahc_softc *, |
495 | struct scsi_host_template *); | 495 | struct scsi_host_template *); |
496 | 496 | ||
497 | uint64_t ahc_linux_get_memsize(void); | ||
498 | |||
499 | /*************************** Pretty Printing **********************************/ | 497 | /*************************** Pretty Printing **********************************/ |
500 | struct info_str { | 498 | struct info_str { |
501 | char *buffer; | 499 | char *buffer; |
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c index 0d44a6907dd2..3ce77ddc889e 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c | |||
@@ -180,6 +180,7 @@ ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
180 | struct ahc_pci_identity *entry; | 180 | struct ahc_pci_identity *entry; |
181 | char *name; | 181 | char *name; |
182 | int error; | 182 | int error; |
183 | struct device *dev = &pdev->dev; | ||
183 | 184 | ||
184 | pci = pdev; | 185 | pci = pdev; |
185 | entry = ahc_find_pci_device(pci); | 186 | entry = ahc_find_pci_device(pci); |
@@ -209,11 +210,12 @@ ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
209 | pci_set_master(pdev); | 210 | pci_set_master(pdev); |
210 | 211 | ||
211 | if (sizeof(dma_addr_t) > 4 | 212 | if (sizeof(dma_addr_t) > 4 |
212 | && ahc_linux_get_memsize() > 0x80000000 | 213 | && ahc->features & AHC_LARGE_SCBS |
213 | && pci_set_dma_mask(pdev, mask_39bit) == 0) { | 214 | && dma_set_mask(dev, mask_39bit) == 0 |
215 | && dma_get_required_mask(dev) > DMA_32BIT_MASK) { | ||
214 | ahc->flags |= AHC_39BIT_ADDRESSING; | 216 | ahc->flags |= AHC_39BIT_ADDRESSING; |
215 | } else { | 217 | } else { |
216 | if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { | 218 | if (dma_set_mask(dev, DMA_32BIT_MASK)) { |
217 | printk(KERN_WARNING "aic7xxx: No suitable DMA available.\n"); | 219 | printk(KERN_WARNING "aic7xxx: No suitable DMA available.\n"); |
218 | return (-ENODEV); | 220 | return (-ENODEV); |
219 | } | 221 | } |
diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index e6153fe5842a..a8cfbef304b5 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c | |||
@@ -996,6 +996,7 @@ oktosend: | |||
996 | #ifdef ED_DBGP | 996 | #ifdef ED_DBGP |
997 | printk("send_s870: prdaddr_2 0x%8x tmpcip %x target_id %d\n", dev->id[c][target_id].prdaddr,tmpcip,target_id); | 997 | printk("send_s870: prdaddr_2 0x%8x tmpcip %x target_id %d\n", dev->id[c][target_id].prdaddr,tmpcip,target_id); |
998 | #endif | 998 | #endif |
999 | dev->id[c][target_id].prdaddr = dev->id[c][target_id].prd_bus; | ||
999 | outl(dev->id[c][target_id].prdaddr, tmpcip); | 1000 | outl(dev->id[c][target_id].prdaddr, tmpcip); |
1000 | tmpcip = tmpcip - 2; | 1001 | tmpcip = tmpcip - 2; |
1001 | outb(0x06, tmpcip); | 1002 | outb(0x06, tmpcip); |
@@ -2572,7 +2573,7 @@ static void atp870u_free_tables(struct Scsi_Host *host) | |||
2572 | for (k = 0; k < 16; k++) { | 2573 | for (k = 0; k < 16; k++) { |
2573 | if (!atp_dev->id[j][k].prd_table) | 2574 | if (!atp_dev->id[j][k].prd_table) |
2574 | continue; | 2575 | continue; |
2575 | pci_free_consistent(atp_dev->pdev, 1024, atp_dev->id[j][k].prd_table, atp_dev->id[j][k].prdaddr); | 2576 | pci_free_consistent(atp_dev->pdev, 1024, atp_dev->id[j][k].prd_table, atp_dev->id[j][k].prd_bus); |
2576 | atp_dev->id[j][k].prd_table = NULL; | 2577 | atp_dev->id[j][k].prd_table = NULL; |
2577 | } | 2578 | } |
2578 | } | 2579 | } |
@@ -2584,12 +2585,13 @@ static int atp870u_init_tables(struct Scsi_Host *host) | |||
2584 | int c,k; | 2585 | int c,k; |
2585 | for(c=0;c < 2;c++) { | 2586 | for(c=0;c < 2;c++) { |
2586 | for(k=0;k<16;k++) { | 2587 | for(k=0;k<16;k++) { |
2587 | atp_dev->id[c][k].prd_table = pci_alloc_consistent(atp_dev->pdev, 1024, &(atp_dev->id[c][k].prdaddr)); | 2588 | atp_dev->id[c][k].prd_table = pci_alloc_consistent(atp_dev->pdev, 1024, &(atp_dev->id[c][k].prd_bus)); |
2588 | if (!atp_dev->id[c][k].prd_table) { | 2589 | if (!atp_dev->id[c][k].prd_table) { |
2589 | printk("atp870u_init_tables fail\n"); | 2590 | printk("atp870u_init_tables fail\n"); |
2590 | atp870u_free_tables(host); | 2591 | atp870u_free_tables(host); |
2591 | return -ENOMEM; | 2592 | return -ENOMEM; |
2592 | } | 2593 | } |
2594 | atp_dev->id[c][k].prdaddr = atp_dev->id[c][k].prd_bus; | ||
2593 | atp_dev->id[c][k].devsp=0x20; | 2595 | atp_dev->id[c][k].devsp=0x20; |
2594 | atp_dev->id[c][k].devtype = 0x7f; | 2596 | atp_dev->id[c][k].devtype = 0x7f; |
2595 | atp_dev->id[c][k].curr_req = NULL; | 2597 | atp_dev->id[c][k].curr_req = NULL; |
diff --git a/drivers/scsi/atp870u.h b/drivers/scsi/atp870u.h index 89f43af39cf2..62bae64a01c1 100644 --- a/drivers/scsi/atp870u.h +++ b/drivers/scsi/atp870u.h | |||
@@ -54,8 +54,9 @@ struct atp_unit | |||
54 | unsigned long tran_len; | 54 | unsigned long tran_len; |
55 | unsigned long last_len; | 55 | unsigned long last_len; |
56 | unsigned char *prd_pos; | 56 | unsigned char *prd_pos; |
57 | unsigned char *prd_table; | 57 | unsigned char *prd_table; /* Kernel address of PRD table */ |
58 | dma_addr_t prdaddr; | 58 | dma_addr_t prd_bus; /* Bus address of PRD */ |
59 | dma_addr_t prdaddr; /* Dynamically updated in driver */ | ||
59 | struct scsi_cmnd *curr_req; | 60 | struct scsi_cmnd *curr_req; |
60 | } id[2][16]; | 61 | } id[2][16]; |
61 | struct Scsi_Host *host; | 62 | struct Scsi_Host *host; |
diff --git a/drivers/scsi/fd_mcs.c b/drivers/scsi/fd_mcs.c index fa652f8aa643..d59d449a9e4d 100644 --- a/drivers/scsi/fd_mcs.c +++ b/drivers/scsi/fd_mcs.c | |||
@@ -1360,3 +1360,5 @@ static Scsi_Host_Template driver_template = { | |||
1360 | .use_clustering = DISABLE_CLUSTERING, | 1360 | .use_clustering = DISABLE_CLUSTERING, |
1361 | }; | 1361 | }; |
1362 | #include "scsi_module.c" | 1362 | #include "scsi_module.c" |
1363 | |||
1364 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 85503fad789a..f2a72d33132c 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c | |||
@@ -98,6 +98,7 @@ int scsi_host_set_state(struct Scsi_Host *shost, enum scsi_host_state state) | |||
98 | switch (oldstate) { | 98 | switch (oldstate) { |
99 | case SHOST_CREATED: | 99 | case SHOST_CREATED: |
100 | case SHOST_RUNNING: | 100 | case SHOST_RUNNING: |
101 | case SHOST_CANCEL_RECOVERY: | ||
101 | break; | 102 | break; |
102 | default: | 103 | default: |
103 | goto illegal; | 104 | goto illegal; |
@@ -107,12 +108,31 @@ int scsi_host_set_state(struct Scsi_Host *shost, enum scsi_host_state state) | |||
107 | case SHOST_DEL: | 108 | case SHOST_DEL: |
108 | switch (oldstate) { | 109 | switch (oldstate) { |
109 | case SHOST_CANCEL: | 110 | case SHOST_CANCEL: |
111 | case SHOST_DEL_RECOVERY: | ||
110 | break; | 112 | break; |
111 | default: | 113 | default: |
112 | goto illegal; | 114 | goto illegal; |
113 | } | 115 | } |
114 | break; | 116 | break; |
115 | 117 | ||
118 | case SHOST_CANCEL_RECOVERY: | ||
119 | switch (oldstate) { | ||
120 | case SHOST_CANCEL: | ||
121 | case SHOST_RECOVERY: | ||
122 | break; | ||
123 | default: | ||
124 | goto illegal; | ||
125 | } | ||
126 | break; | ||
127 | |||
128 | case SHOST_DEL_RECOVERY: | ||
129 | switch (oldstate) { | ||
130 | case SHOST_CANCEL_RECOVERY: | ||
131 | break; | ||
132 | default: | ||
133 | goto illegal; | ||
134 | } | ||
135 | break; | ||
116 | } | 136 | } |
117 | shost->shost_state = state; | 137 | shost->shost_state = state; |
118 | return 0; | 138 | return 0; |
@@ -134,13 +154,24 @@ EXPORT_SYMBOL(scsi_host_set_state); | |||
134 | **/ | 154 | **/ |
135 | void scsi_remove_host(struct Scsi_Host *shost) | 155 | void scsi_remove_host(struct Scsi_Host *shost) |
136 | { | 156 | { |
157 | unsigned long flags; | ||
137 | down(&shost->scan_mutex); | 158 | down(&shost->scan_mutex); |
138 | scsi_host_set_state(shost, SHOST_CANCEL); | 159 | spin_lock_irqsave(shost->host_lock, flags); |
160 | if (scsi_host_set_state(shost, SHOST_CANCEL)) | ||
161 | if (scsi_host_set_state(shost, SHOST_CANCEL_RECOVERY)) { | ||
162 | spin_unlock_irqrestore(shost->host_lock, flags); | ||
163 | up(&shost->scan_mutex); | ||
164 | return; | ||
165 | } | ||
166 | spin_unlock_irqrestore(shost->host_lock, flags); | ||
139 | up(&shost->scan_mutex); | 167 | up(&shost->scan_mutex); |
140 | scsi_forget_host(shost); | 168 | scsi_forget_host(shost); |
141 | scsi_proc_host_rm(shost); | 169 | scsi_proc_host_rm(shost); |
142 | 170 | ||
143 | scsi_host_set_state(shost, SHOST_DEL); | 171 | spin_lock_irqsave(shost->host_lock, flags); |
172 | if (scsi_host_set_state(shost, SHOST_DEL)) | ||
173 | BUG_ON(scsi_host_set_state(shost, SHOST_DEL_RECOVERY)); | ||
174 | spin_unlock_irqrestore(shost->host_lock, flags); | ||
144 | 175 | ||
145 | transport_unregister_device(&shost->shost_gendev); | 176 | transport_unregister_device(&shost->shost_gendev); |
146 | class_device_unregister(&shost->shost_classdev); | 177 | class_device_unregister(&shost->shost_classdev); |
diff --git a/drivers/scsi/ibmmca.c b/drivers/scsi/ibmmca.c index 6e54c7d9b33c..19392f651272 100644 --- a/drivers/scsi/ibmmca.c +++ b/drivers/scsi/ibmmca.c | |||
@@ -460,6 +460,8 @@ MODULE_PARM(adisplay, "1i"); | |||
460 | MODULE_PARM(normal, "1i"); | 460 | MODULE_PARM(normal, "1i"); |
461 | MODULE_PARM(ansi, "1i"); | 461 | MODULE_PARM(ansi, "1i"); |
462 | #endif | 462 | #endif |
463 | |||
464 | MODULE_LICENSE("GPL"); | ||
463 | #endif | 465 | #endif |
464 | /*counter of concurrent disk read/writes, to turn on/off disk led */ | 466 | /*counter of concurrent disk read/writes, to turn on/off disk led */ |
465 | static int disk_rw_in_progress = 0; | 467 | static int disk_rw_in_progress = 0; |
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index 5b14934ba861..ff25210b00ba 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c | |||
@@ -727,6 +727,16 @@ static void adapter_info_rsp(struct srp_event_struct *evt_struct) | |||
727 | if (hostdata->madapter_info.port_max_txu[0]) | 727 | if (hostdata->madapter_info.port_max_txu[0]) |
728 | hostdata->host->max_sectors = | 728 | hostdata->host->max_sectors = |
729 | hostdata->madapter_info.port_max_txu[0] >> 9; | 729 | hostdata->madapter_info.port_max_txu[0] >> 9; |
730 | |||
731 | if (hostdata->madapter_info.os_type == 3 && | ||
732 | strcmp(hostdata->madapter_info.srp_version, "1.6a") <= 0) { | ||
733 | printk("ibmvscsi: host (Ver. %s) doesn't support large" | ||
734 | "transfers\n", | ||
735 | hostdata->madapter_info.srp_version); | ||
736 | printk("ibmvscsi: limiting scatterlists to %d\n", | ||
737 | MAX_INDIRECT_BUFS); | ||
738 | hostdata->host->sg_tablesize = MAX_INDIRECT_BUFS; | ||
739 | } | ||
730 | } | 740 | } |
731 | } | 741 | } |
732 | 742 | ||
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 72bdc91e148c..e5b01997117a 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
@@ -2465,9 +2465,12 @@ static unsigned long ata_pio_poll(struct ata_port *ap) | |||
2465 | * | 2465 | * |
2466 | * LOCKING: | 2466 | * LOCKING: |
2467 | * None. (executing in kernel thread context) | 2467 | * None. (executing in kernel thread context) |
2468 | * | ||
2469 | * RETURNS: | ||
2470 | * Non-zero if qc completed, zero otherwise. | ||
2468 | */ | 2471 | */ |
2469 | 2472 | ||
2470 | static void ata_pio_complete (struct ata_port *ap) | 2473 | static int ata_pio_complete (struct ata_port *ap) |
2471 | { | 2474 | { |
2472 | struct ata_queued_cmd *qc; | 2475 | struct ata_queued_cmd *qc; |
2473 | u8 drv_stat; | 2476 | u8 drv_stat; |
@@ -2486,14 +2489,14 @@ static void ata_pio_complete (struct ata_port *ap) | |||
2486 | if (drv_stat & (ATA_BUSY | ATA_DRQ)) { | 2489 | if (drv_stat & (ATA_BUSY | ATA_DRQ)) { |
2487 | ap->pio_task_state = PIO_ST_LAST_POLL; | 2490 | ap->pio_task_state = PIO_ST_LAST_POLL; |
2488 | ap->pio_task_timeout = jiffies + ATA_TMOUT_PIO; | 2491 | ap->pio_task_timeout = jiffies + ATA_TMOUT_PIO; |
2489 | return; | 2492 | return 0; |
2490 | } | 2493 | } |
2491 | } | 2494 | } |
2492 | 2495 | ||
2493 | drv_stat = ata_wait_idle(ap); | 2496 | drv_stat = ata_wait_idle(ap); |
2494 | if (!ata_ok(drv_stat)) { | 2497 | if (!ata_ok(drv_stat)) { |
2495 | ap->pio_task_state = PIO_ST_ERR; | 2498 | ap->pio_task_state = PIO_ST_ERR; |
2496 | return; | 2499 | return 0; |
2497 | } | 2500 | } |
2498 | 2501 | ||
2499 | qc = ata_qc_from_tag(ap, ap->active_tag); | 2502 | qc = ata_qc_from_tag(ap, ap->active_tag); |
@@ -2502,6 +2505,10 @@ static void ata_pio_complete (struct ata_port *ap) | |||
2502 | ap->pio_task_state = PIO_ST_IDLE; | 2505 | ap->pio_task_state = PIO_ST_IDLE; |
2503 | 2506 | ||
2504 | ata_poll_qc_complete(qc, drv_stat); | 2507 | ata_poll_qc_complete(qc, drv_stat); |
2508 | |||
2509 | /* another command may start at this point */ | ||
2510 | |||
2511 | return 1; | ||
2505 | } | 2512 | } |
2506 | 2513 | ||
2507 | 2514 | ||
@@ -2709,7 +2716,7 @@ static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes) | |||
2709 | 2716 | ||
2710 | next_sg: | 2717 | next_sg: |
2711 | if (unlikely(qc->cursg >= qc->n_elem)) { | 2718 | if (unlikely(qc->cursg >= qc->n_elem)) { |
2712 | /* | 2719 | /* |
2713 | * The end of qc->sg is reached and the device expects | 2720 | * The end of qc->sg is reached and the device expects |
2714 | * more data to transfer. In order not to overrun qc->sg | 2721 | * more data to transfer. In order not to overrun qc->sg |
2715 | * and fulfill length specified in the byte count register, | 2722 | * and fulfill length specified in the byte count register, |
@@ -2721,7 +2728,7 @@ next_sg: | |||
2721 | unsigned int i; | 2728 | unsigned int i; |
2722 | 2729 | ||
2723 | if (words) /* warning if bytes > 1 */ | 2730 | if (words) /* warning if bytes > 1 */ |
2724 | printk(KERN_WARNING "ata%u: %u bytes trailing data\n", | 2731 | printk(KERN_WARNING "ata%u: %u bytes trailing data\n", |
2725 | ap->id, bytes); | 2732 | ap->id, bytes); |
2726 | 2733 | ||
2727 | for (i = 0; i < words; i++) | 2734 | for (i = 0; i < words; i++) |
@@ -2849,9 +2856,7 @@ static void ata_pio_block(struct ata_port *ap) | |||
2849 | if (is_atapi_taskfile(&qc->tf)) { | 2856 | if (is_atapi_taskfile(&qc->tf)) { |
2850 | /* no more data to transfer or unsupported ATAPI command */ | 2857 | /* no more data to transfer or unsupported ATAPI command */ |
2851 | if ((status & ATA_DRQ) == 0) { | 2858 | if ((status & ATA_DRQ) == 0) { |
2852 | ap->pio_task_state = PIO_ST_IDLE; | 2859 | ap->pio_task_state = PIO_ST_LAST; |
2853 | |||
2854 | ata_poll_qc_complete(qc, status); | ||
2855 | return; | 2860 | return; |
2856 | } | 2861 | } |
2857 | 2862 | ||
@@ -2887,7 +2892,12 @@ static void ata_pio_error(struct ata_port *ap) | |||
2887 | static void ata_pio_task(void *_data) | 2892 | static void ata_pio_task(void *_data) |
2888 | { | 2893 | { |
2889 | struct ata_port *ap = _data; | 2894 | struct ata_port *ap = _data; |
2890 | unsigned long timeout = 0; | 2895 | unsigned long timeout; |
2896 | int qc_completed; | ||
2897 | |||
2898 | fsm_start: | ||
2899 | timeout = 0; | ||
2900 | qc_completed = 0; | ||
2891 | 2901 | ||
2892 | switch (ap->pio_task_state) { | 2902 | switch (ap->pio_task_state) { |
2893 | case PIO_ST_IDLE: | 2903 | case PIO_ST_IDLE: |
@@ -2898,7 +2908,7 @@ static void ata_pio_task(void *_data) | |||
2898 | break; | 2908 | break; |
2899 | 2909 | ||
2900 | case PIO_ST_LAST: | 2910 | case PIO_ST_LAST: |
2901 | ata_pio_complete(ap); | 2911 | qc_completed = ata_pio_complete(ap); |
2902 | break; | 2912 | break; |
2903 | 2913 | ||
2904 | case PIO_ST_POLL: | 2914 | case PIO_ST_POLL: |
@@ -2913,10 +2923,9 @@ static void ata_pio_task(void *_data) | |||
2913 | } | 2923 | } |
2914 | 2924 | ||
2915 | if (timeout) | 2925 | if (timeout) |
2916 | queue_delayed_work(ata_wq, &ap->pio_task, | 2926 | queue_delayed_work(ata_wq, &ap->pio_task, timeout); |
2917 | timeout); | 2927 | else if (!qc_completed) |
2918 | else | 2928 | goto fsm_start; |
2919 | queue_work(ata_wq, &ap->pio_task); | ||
2920 | } | 2929 | } |
2921 | 2930 | ||
2922 | static void atapi_request_sense(struct ata_port *ap, struct ata_device *dev, | 2931 | static void atapi_request_sense(struct ata_port *ap, struct ata_device *dev, |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 3e9b64137873..23d095d3817b 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -201,6 +201,7 @@ int | |||
201 | qla2100_pci_config(scsi_qla_host_t *ha) | 201 | qla2100_pci_config(scsi_qla_host_t *ha) |
202 | { | 202 | { |
203 | uint16_t w, mwi; | 203 | uint16_t w, mwi; |
204 | uint32_t d; | ||
204 | unsigned long flags; | 205 | unsigned long flags; |
205 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; | 206 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; |
206 | 207 | ||
@@ -215,9 +216,9 @@ qla2100_pci_config(scsi_qla_host_t *ha) | |||
215 | pci_write_config_word(ha->pdev, PCI_COMMAND, w); | 216 | pci_write_config_word(ha->pdev, PCI_COMMAND, w); |
216 | 217 | ||
217 | /* Reset expansion ROM address decode enable */ | 218 | /* Reset expansion ROM address decode enable */ |
218 | pci_read_config_word(ha->pdev, PCI_ROM_ADDRESS, &w); | 219 | pci_read_config_dword(ha->pdev, PCI_ROM_ADDRESS, &d); |
219 | w &= ~PCI_ROM_ADDRESS_ENABLE; | 220 | d &= ~PCI_ROM_ADDRESS_ENABLE; |
220 | pci_write_config_word(ha->pdev, PCI_ROM_ADDRESS, w); | 221 | pci_write_config_dword(ha->pdev, PCI_ROM_ADDRESS, d); |
221 | 222 | ||
222 | /* Get PCI bus information. */ | 223 | /* Get PCI bus information. */ |
223 | spin_lock_irqsave(&ha->hardware_lock, flags); | 224 | spin_lock_irqsave(&ha->hardware_lock, flags); |
@@ -237,6 +238,7 @@ int | |||
237 | qla2300_pci_config(scsi_qla_host_t *ha) | 238 | qla2300_pci_config(scsi_qla_host_t *ha) |
238 | { | 239 | { |
239 | uint16_t w, mwi; | 240 | uint16_t w, mwi; |
241 | uint32_t d; | ||
240 | unsigned long flags = 0; | 242 | unsigned long flags = 0; |
241 | uint32_t cnt; | 243 | uint32_t cnt; |
242 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; | 244 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; |
@@ -302,9 +304,9 @@ qla2300_pci_config(scsi_qla_host_t *ha) | |||
302 | pci_write_config_byte(ha->pdev, PCI_LATENCY_TIMER, 0x80); | 304 | pci_write_config_byte(ha->pdev, PCI_LATENCY_TIMER, 0x80); |
303 | 305 | ||
304 | /* Reset expansion ROM address decode enable */ | 306 | /* Reset expansion ROM address decode enable */ |
305 | pci_read_config_word(ha->pdev, PCI_ROM_ADDRESS, &w); | 307 | pci_read_config_dword(ha->pdev, PCI_ROM_ADDRESS, &d); |
306 | w &= ~PCI_ROM_ADDRESS_ENABLE; | 308 | d &= ~PCI_ROM_ADDRESS_ENABLE; |
307 | pci_write_config_word(ha->pdev, PCI_ROM_ADDRESS, w); | 309 | pci_write_config_dword(ha->pdev, PCI_ROM_ADDRESS, d); |
308 | 310 | ||
309 | /* Get PCI bus information. */ | 311 | /* Get PCI bus information. */ |
310 | spin_lock_irqsave(&ha->hardware_lock, flags); | 312 | spin_lock_irqsave(&ha->hardware_lock, flags); |
@@ -324,6 +326,7 @@ int | |||
324 | qla24xx_pci_config(scsi_qla_host_t *ha) | 326 | qla24xx_pci_config(scsi_qla_host_t *ha) |
325 | { | 327 | { |
326 | uint16_t w, mwi; | 328 | uint16_t w, mwi; |
329 | uint32_t d; | ||
327 | unsigned long flags = 0; | 330 | unsigned long flags = 0; |
328 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | 331 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; |
329 | int pcix_cmd_reg, pcie_dctl_reg; | 332 | int pcix_cmd_reg, pcie_dctl_reg; |
@@ -366,9 +369,9 @@ qla24xx_pci_config(scsi_qla_host_t *ha) | |||
366 | } | 369 | } |
367 | 370 | ||
368 | /* Reset expansion ROM address decode enable */ | 371 | /* Reset expansion ROM address decode enable */ |
369 | pci_read_config_word(ha->pdev, PCI_ROM_ADDRESS, &w); | 372 | pci_read_config_dword(ha->pdev, PCI_ROM_ADDRESS, &d); |
370 | w &= ~PCI_ROM_ADDRESS_ENABLE; | 373 | d &= ~PCI_ROM_ADDRESS_ENABLE; |
371 | pci_write_config_word(ha->pdev, PCI_ROM_ADDRESS, w); | 374 | pci_write_config_dword(ha->pdev, PCI_ROM_ADDRESS, d); |
372 | 375 | ||
373 | /* Get PCI bus information. */ | 376 | /* Get PCI bus information. */ |
374 | spin_lock_irqsave(&ha->hardware_lock, flags); | 377 | spin_lock_irqsave(&ha->hardware_lock, flags); |
diff --git a/drivers/scsi/sata_sis.c b/drivers/scsi/sata_sis.c index a63f93186e41..b227e51d12f4 100644 --- a/drivers/scsi/sata_sis.c +++ b/drivers/scsi/sata_sis.c | |||
@@ -161,7 +161,7 @@ static u32 sis_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg) | |||
161 | { | 161 | { |
162 | struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); | 162 | struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); |
163 | unsigned int cfg_addr = get_scr_cfg_addr(ap->port_no, sc_reg, pdev->device); | 163 | unsigned int cfg_addr = get_scr_cfg_addr(ap->port_no, sc_reg, pdev->device); |
164 | u32 val, val2; | 164 | u32 val, val2 = 0; |
165 | u8 pmr; | 165 | u8 pmr; |
166 | 166 | ||
167 | if (sc_reg == SCR_ERROR) /* doesn't exist in PCI cfg space */ | 167 | if (sc_reg == SCR_ERROR) /* doesn't exist in PCI cfg space */ |
@@ -289,7 +289,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
289 | if (ent->device != 0x182) { | 289 | if (ent->device != 0x182) { |
290 | if ((pmr & SIS_PMR_COMBINED) == 0) { | 290 | if ((pmr & SIS_PMR_COMBINED) == 0) { |
291 | printk(KERN_INFO "sata_sis: Detected SiS 180/181 chipset in SATA mode\n"); | 291 | printk(KERN_INFO "sata_sis: Detected SiS 180/181 chipset in SATA mode\n"); |
292 | port2_start=0x64; | 292 | port2_start = 64; |
293 | } | 293 | } |
294 | else { | 294 | else { |
295 | printk(KERN_INFO "sata_sis: Detected SiS 180/181 chipset in combined mode\n"); | 295 | printk(KERN_INFO "sata_sis: Detected SiS 180/181 chipset in combined mode\n"); |
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index a780546eda9c..1f0ebabf6d47 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c | |||
@@ -1265,9 +1265,8 @@ int scsi_device_cancel(struct scsi_device *sdev, int recovery) | |||
1265 | list_for_each_safe(lh, lh_sf, &active_list) { | 1265 | list_for_each_safe(lh, lh_sf, &active_list) { |
1266 | scmd = list_entry(lh, struct scsi_cmnd, eh_entry); | 1266 | scmd = list_entry(lh, struct scsi_cmnd, eh_entry); |
1267 | list_del_init(lh); | 1267 | list_del_init(lh); |
1268 | if (recovery) { | 1268 | if (recovery && |
1269 | scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD); | 1269 | !scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD)) { |
1270 | } else { | ||
1271 | scmd->result = (DID_ABORT << 16); | 1270 | scmd->result = (DID_ABORT << 16); |
1272 | scsi_finish_command(scmd); | 1271 | scsi_finish_command(scmd); |
1273 | } | 1272 | } |
diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c index 07b554affcf2..64fc9e21f35b 100644 --- a/drivers/scsi/scsi_devinfo.c +++ b/drivers/scsi/scsi_devinfo.c | |||
@@ -110,6 +110,7 @@ static struct { | |||
110 | {"RELISYS", "Scorpio", NULL, BLIST_NOLUN}, /* responds to all lun */ | 110 | {"RELISYS", "Scorpio", NULL, BLIST_NOLUN}, /* responds to all lun */ |
111 | {"SANKYO", "CP525", "6.64", BLIST_NOLUN}, /* causes failed REQ SENSE, extra reset */ | 111 | {"SANKYO", "CP525", "6.64", BLIST_NOLUN}, /* causes failed REQ SENSE, extra reset */ |
112 | {"TEXEL", "CD-ROM", "1.06", BLIST_NOLUN}, | 112 | {"TEXEL", "CD-ROM", "1.06", BLIST_NOLUN}, |
113 | {"transtec", "T5008", "0001", BLIST_NOREPORTLUN }, | ||
113 | {"YAMAHA", "CDR100", "1.00", BLIST_NOLUN}, /* locks up */ | 114 | {"YAMAHA", "CDR100", "1.00", BLIST_NOLUN}, /* locks up */ |
114 | {"YAMAHA", "CDR102", "1.00", BLIST_NOLUN}, /* locks up */ | 115 | {"YAMAHA", "CDR102", "1.00", BLIST_NOLUN}, /* locks up */ |
115 | {"YAMAHA", "CRW8424S", "1.0", BLIST_NOLUN}, /* locks up */ | 116 | {"YAMAHA", "CRW8424S", "1.0", BLIST_NOLUN}, /* locks up */ |
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 895c9452be4c..ad5342165079 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -50,7 +50,7 @@ | |||
50 | void scsi_eh_wakeup(struct Scsi_Host *shost) | 50 | void scsi_eh_wakeup(struct Scsi_Host *shost) |
51 | { | 51 | { |
52 | if (shost->host_busy == shost->host_failed) { | 52 | if (shost->host_busy == shost->host_failed) { |
53 | up(shost->eh_wait); | 53 | wake_up_process(shost->ehandler); |
54 | SCSI_LOG_ERROR_RECOVERY(5, | 54 | SCSI_LOG_ERROR_RECOVERY(5, |
55 | printk("Waking error handler thread\n")); | 55 | printk("Waking error handler thread\n")); |
56 | } | 56 | } |
@@ -68,19 +68,24 @@ int scsi_eh_scmd_add(struct scsi_cmnd *scmd, int eh_flag) | |||
68 | { | 68 | { |
69 | struct Scsi_Host *shost = scmd->device->host; | 69 | struct Scsi_Host *shost = scmd->device->host; |
70 | unsigned long flags; | 70 | unsigned long flags; |
71 | int ret = 0; | ||
71 | 72 | ||
72 | if (shost->eh_wait == NULL) | 73 | if (!shost->ehandler) |
73 | return 0; | 74 | return 0; |
74 | 75 | ||
75 | spin_lock_irqsave(shost->host_lock, flags); | 76 | spin_lock_irqsave(shost->host_lock, flags); |
77 | if (scsi_host_set_state(shost, SHOST_RECOVERY)) | ||
78 | if (scsi_host_set_state(shost, SHOST_CANCEL_RECOVERY)) | ||
79 | goto out_unlock; | ||
76 | 80 | ||
81 | ret = 1; | ||
77 | scmd->eh_eflags |= eh_flag; | 82 | scmd->eh_eflags |= eh_flag; |
78 | list_add_tail(&scmd->eh_entry, &shost->eh_cmd_q); | 83 | list_add_tail(&scmd->eh_entry, &shost->eh_cmd_q); |
79 | scsi_host_set_state(shost, SHOST_RECOVERY); | ||
80 | shost->host_failed++; | 84 | shost->host_failed++; |
81 | scsi_eh_wakeup(shost); | 85 | scsi_eh_wakeup(shost); |
86 | out_unlock: | ||
82 | spin_unlock_irqrestore(shost->host_lock, flags); | 87 | spin_unlock_irqrestore(shost->host_lock, flags); |
83 | return 1; | 88 | return ret; |
84 | } | 89 | } |
85 | 90 | ||
86 | /** | 91 | /** |
@@ -176,8 +181,8 @@ void scsi_times_out(struct scsi_cmnd *scmd) | |||
176 | } | 181 | } |
177 | 182 | ||
178 | if (unlikely(!scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD))) { | 183 | if (unlikely(!scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD))) { |
179 | panic("Error handler thread not present at %p %p %s %d", | 184 | scmd->result |= DID_TIME_OUT << 16; |
180 | scmd, scmd->device->host, __FILE__, __LINE__); | 185 | __scsi_done(scmd); |
181 | } | 186 | } |
182 | } | 187 | } |
183 | 188 | ||
@@ -196,8 +201,7 @@ int scsi_block_when_processing_errors(struct scsi_device *sdev) | |||
196 | { | 201 | { |
197 | int online; | 202 | int online; |
198 | 203 | ||
199 | wait_event(sdev->host->host_wait, (sdev->host->shost_state != | 204 | wait_event(sdev->host->host_wait, !scsi_host_in_recovery(sdev->host)); |
200 | SHOST_RECOVERY)); | ||
201 | 205 | ||
202 | online = scsi_device_online(sdev); | 206 | online = scsi_device_online(sdev); |
203 | 207 | ||
@@ -1441,6 +1445,7 @@ static void scsi_eh_lock_door(struct scsi_device *sdev) | |||
1441 | static void scsi_restart_operations(struct Scsi_Host *shost) | 1445 | static void scsi_restart_operations(struct Scsi_Host *shost) |
1442 | { | 1446 | { |
1443 | struct scsi_device *sdev; | 1447 | struct scsi_device *sdev; |
1448 | unsigned long flags; | ||
1444 | 1449 | ||
1445 | /* | 1450 | /* |
1446 | * If the door was locked, we need to insert a door lock request | 1451 | * If the door was locked, we need to insert a door lock request |
@@ -1460,7 +1465,11 @@ static void scsi_restart_operations(struct Scsi_Host *shost) | |||
1460 | SCSI_LOG_ERROR_RECOVERY(3, printk("%s: waking up host to restart\n", | 1465 | SCSI_LOG_ERROR_RECOVERY(3, printk("%s: waking up host to restart\n", |
1461 | __FUNCTION__)); | 1466 | __FUNCTION__)); |
1462 | 1467 | ||
1463 | scsi_host_set_state(shost, SHOST_RUNNING); | 1468 | spin_lock_irqsave(shost->host_lock, flags); |
1469 | if (scsi_host_set_state(shost, SHOST_RUNNING)) | ||
1470 | if (scsi_host_set_state(shost, SHOST_CANCEL)) | ||
1471 | BUG_ON(scsi_host_set_state(shost, SHOST_DEL)); | ||
1472 | spin_unlock_irqrestore(shost->host_lock, flags); | ||
1464 | 1473 | ||
1465 | wake_up(&shost->host_wait); | 1474 | wake_up(&shost->host_wait); |
1466 | 1475 | ||
@@ -1582,40 +1591,31 @@ int scsi_error_handler(void *data) | |||
1582 | { | 1591 | { |
1583 | struct Scsi_Host *shost = (struct Scsi_Host *) data; | 1592 | struct Scsi_Host *shost = (struct Scsi_Host *) data; |
1584 | int rtn; | 1593 | int rtn; |
1585 | DECLARE_MUTEX_LOCKED(sem); | ||
1586 | 1594 | ||
1587 | current->flags |= PF_NOFREEZE; | 1595 | current->flags |= PF_NOFREEZE; |
1588 | shost->eh_wait = &sem; | ||
1589 | 1596 | ||
1597 | |||
1590 | /* | 1598 | /* |
1591 | * Wake up the thread that created us. | 1599 | * Note - we always use TASK_INTERRUPTIBLE even if the module |
1600 | * was loaded as part of the kernel. The reason is that | ||
1601 | * UNINTERRUPTIBLE would cause this thread to be counted in | ||
1602 | * the load average as a running process, and an interruptible | ||
1603 | * wait doesn't. | ||
1592 | */ | 1604 | */ |
1593 | SCSI_LOG_ERROR_RECOVERY(3, printk("Wake up parent of" | 1605 | set_current_state(TASK_INTERRUPTIBLE); |
1594 | " scsi_eh_%d\n",shost->host_no)); | 1606 | while (!kthread_should_stop()) { |
1595 | 1607 | if (shost->host_failed == 0 || | |
1596 | while (1) { | 1608 | shost->host_failed != shost->host_busy) { |
1597 | /* | 1609 | SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler" |
1598 | * If we get a signal, it means we are supposed to go | 1610 | " scsi_eh_%d" |
1599 | * away and die. This typically happens if the user is | 1611 | " sleeping\n", |
1600 | * trying to unload a module. | 1612 | shost->host_no)); |
1601 | */ | 1613 | schedule(); |
1602 | SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler" | 1614 | set_current_state(TASK_INTERRUPTIBLE); |
1603 | " scsi_eh_%d" | 1615 | continue; |
1604 | " sleeping\n",shost->host_no)); | 1616 | } |
1605 | |||
1606 | /* | ||
1607 | * Note - we always use down_interruptible with the semaphore | ||
1608 | * even if the module was loaded as part of the kernel. The | ||
1609 | * reason is that down() will cause this thread to be counted | ||
1610 | * in the load average as a running process, and down | ||
1611 | * interruptible doesn't. Given that we need to allow this | ||
1612 | * thread to die if the driver was loaded as a module, using | ||
1613 | * semaphores isn't unreasonable. | ||
1614 | */ | ||
1615 | down_interruptible(&sem); | ||
1616 | if (kthread_should_stop()) | ||
1617 | break; | ||
1618 | 1617 | ||
1618 | __set_current_state(TASK_RUNNING); | ||
1619 | SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler" | 1619 | SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler" |
1620 | " scsi_eh_%d waking" | 1620 | " scsi_eh_%d waking" |
1621 | " up\n",shost->host_no)); | 1621 | " up\n",shost->host_no)); |
@@ -1642,7 +1642,7 @@ int scsi_error_handler(void *data) | |||
1642 | * which are still online. | 1642 | * which are still online. |
1643 | */ | 1643 | */ |
1644 | scsi_restart_operations(shost); | 1644 | scsi_restart_operations(shost); |
1645 | 1645 | set_current_state(TASK_INTERRUPTIBLE); | |
1646 | } | 1646 | } |
1647 | 1647 | ||
1648 | SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler scsi_eh_%d" | 1648 | SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler scsi_eh_%d" |
@@ -1651,7 +1651,7 @@ int scsi_error_handler(void *data) | |||
1651 | /* | 1651 | /* |
1652 | * Make sure that nobody tries to wake us up again. | 1652 | * Make sure that nobody tries to wake us up again. |
1653 | */ | 1653 | */ |
1654 | shost->eh_wait = NULL; | 1654 | shost->ehandler = NULL; |
1655 | return 0; | 1655 | return 0; |
1656 | } | 1656 | } |
1657 | 1657 | ||
diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c index b7fddac81347..de7f98cc38fe 100644 --- a/drivers/scsi/scsi_ioctl.c +++ b/drivers/scsi/scsi_ioctl.c | |||
@@ -458,7 +458,7 @@ int scsi_nonblockable_ioctl(struct scsi_device *sdev, int cmd, | |||
458 | * error processing, as long as the device was opened | 458 | * error processing, as long as the device was opened |
459 | * non-blocking */ | 459 | * non-blocking */ |
460 | if (filp && filp->f_flags & O_NONBLOCK) { | 460 | if (filp && filp->f_flags & O_NONBLOCK) { |
461 | if (sdev->host->shost_state == SHOST_RECOVERY) | 461 | if (scsi_host_in_recovery(sdev->host)) |
462 | return -ENODEV; | 462 | return -ENODEV; |
463 | } else if (!scsi_block_when_processing_errors(sdev)) | 463 | } else if (!scsi_block_when_processing_errors(sdev)) |
464 | return -ENODEV; | 464 | return -ENODEV; |
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 863bb6495daa..dc9c772bc874 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -118,7 +118,6 @@ static void scsi_unprep_request(struct request *req) | |||
118 | req->flags &= ~REQ_DONTPREP; | 118 | req->flags &= ~REQ_DONTPREP; |
119 | req->special = (req->flags & REQ_SPECIAL) ? cmd->sc_request : NULL; | 119 | req->special = (req->flags & REQ_SPECIAL) ? cmd->sc_request : NULL; |
120 | 120 | ||
121 | scsi_release_buffers(cmd); | ||
122 | scsi_put_command(cmd); | 121 | scsi_put_command(cmd); |
123 | } | 122 | } |
124 | 123 | ||
@@ -140,14 +139,12 @@ static void scsi_unprep_request(struct request *req) | |||
140 | * commands. | 139 | * commands. |
141 | * Notes: This could be called either from an interrupt context or a | 140 | * Notes: This could be called either from an interrupt context or a |
142 | * normal process context. | 141 | * normal process context. |
143 | * Notes: Upon return, cmd is a stale pointer. | ||
144 | */ | 142 | */ |
145 | int scsi_queue_insert(struct scsi_cmnd *cmd, int reason) | 143 | int scsi_queue_insert(struct scsi_cmnd *cmd, int reason) |
146 | { | 144 | { |
147 | struct Scsi_Host *host = cmd->device->host; | 145 | struct Scsi_Host *host = cmd->device->host; |
148 | struct scsi_device *device = cmd->device; | 146 | struct scsi_device *device = cmd->device; |
149 | struct request_queue *q = device->request_queue; | 147 | struct request_queue *q = device->request_queue; |
150 | struct request *req = cmd->request; | ||
151 | unsigned long flags; | 148 | unsigned long flags; |
152 | 149 | ||
153 | SCSI_LOG_MLQUEUE(1, | 150 | SCSI_LOG_MLQUEUE(1, |
@@ -188,9 +185,8 @@ int scsi_queue_insert(struct scsi_cmnd *cmd, int reason) | |||
188 | * function. The SCSI request function detects the blocked condition | 185 | * function. The SCSI request function detects the blocked condition |
189 | * and plugs the queue appropriately. | 186 | * and plugs the queue appropriately. |
190 | */ | 187 | */ |
191 | scsi_unprep_request(req); | ||
192 | spin_lock_irqsave(q->queue_lock, flags); | 188 | spin_lock_irqsave(q->queue_lock, flags); |
193 | blk_requeue_request(q, req); | 189 | blk_requeue_request(q, cmd->request); |
194 | spin_unlock_irqrestore(q->queue_lock, flags); | 190 | spin_unlock_irqrestore(q->queue_lock, flags); |
195 | 191 | ||
196 | scsi_run_queue(q); | 192 | scsi_run_queue(q); |
@@ -451,7 +447,7 @@ void scsi_device_unbusy(struct scsi_device *sdev) | |||
451 | 447 | ||
452 | spin_lock_irqsave(shost->host_lock, flags); | 448 | spin_lock_irqsave(shost->host_lock, flags); |
453 | shost->host_busy--; | 449 | shost->host_busy--; |
454 | if (unlikely((shost->shost_state == SHOST_RECOVERY) && | 450 | if (unlikely(scsi_host_in_recovery(shost) && |
455 | shost->host_failed)) | 451 | shost->host_failed)) |
456 | scsi_eh_wakeup(shost); | 452 | scsi_eh_wakeup(shost); |
457 | spin_unlock(shost->host_lock); | 453 | spin_unlock(shost->host_lock); |
@@ -1268,6 +1264,7 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req) | |||
1268 | } | 1264 | } |
1269 | } else { | 1265 | } else { |
1270 | memcpy(cmd->cmnd, req->cmd, sizeof(cmd->cmnd)); | 1266 | memcpy(cmd->cmnd, req->cmd, sizeof(cmd->cmnd)); |
1267 | cmd->cmd_len = req->cmd_len; | ||
1271 | if (rq_data_dir(req) == WRITE) | 1268 | if (rq_data_dir(req) == WRITE) |
1272 | cmd->sc_data_direction = DMA_TO_DEVICE; | 1269 | cmd->sc_data_direction = DMA_TO_DEVICE; |
1273 | else if (req->data_len) | 1270 | else if (req->data_len) |
@@ -1342,7 +1339,7 @@ static inline int scsi_host_queue_ready(struct request_queue *q, | |||
1342 | struct Scsi_Host *shost, | 1339 | struct Scsi_Host *shost, |
1343 | struct scsi_device *sdev) | 1340 | struct scsi_device *sdev) |
1344 | { | 1341 | { |
1345 | if (shost->shost_state == SHOST_RECOVERY) | 1342 | if (scsi_host_in_recovery(shost)) |
1346 | return 0; | 1343 | return 0; |
1347 | if (shost->host_busy == 0 && shost->host_blocked) { | 1344 | if (shost->host_busy == 0 && shost->host_blocked) { |
1348 | /* | 1345 | /* |
@@ -1514,7 +1511,6 @@ static void scsi_request_fn(struct request_queue *q) | |||
1514 | * cases (host limits or settings) should run the queue at some | 1511 | * cases (host limits or settings) should run the queue at some |
1515 | * later time. | 1512 | * later time. |
1516 | */ | 1513 | */ |
1517 | scsi_unprep_request(req); | ||
1518 | spin_lock_irq(q->queue_lock); | 1514 | spin_lock_irq(q->queue_lock); |
1519 | blk_requeue_request(q, req); | 1515 | blk_requeue_request(q, req); |
1520 | sdev->device_busy--; | 1516 | sdev->device_busy--; |
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index b86f170fa8ed..fcf9f6cbb142 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c | |||
@@ -1466,23 +1466,17 @@ EXPORT_SYMBOL(scsi_scan_single_target); | |||
1466 | 1466 | ||
1467 | void scsi_forget_host(struct Scsi_Host *shost) | 1467 | void scsi_forget_host(struct Scsi_Host *shost) |
1468 | { | 1468 | { |
1469 | struct scsi_target *starget, *tmp; | 1469 | struct scsi_device *sdev; |
1470 | unsigned long flags; | 1470 | unsigned long flags; |
1471 | 1471 | ||
1472 | /* | 1472 | restart: |
1473 | * Ok, this look a bit strange. We always look for the first device | ||
1474 | * on the list as scsi_remove_device removes them from it - thus we | ||
1475 | * also have to release the lock. | ||
1476 | * We don't need to get another reference to the device before | ||
1477 | * releasing the lock as we already own the reference from | ||
1478 | * scsi_register_device that's release in scsi_remove_device. And | ||
1479 | * after that we don't look at sdev anymore. | ||
1480 | */ | ||
1481 | spin_lock_irqsave(shost->host_lock, flags); | 1473 | spin_lock_irqsave(shost->host_lock, flags); |
1482 | list_for_each_entry_safe(starget, tmp, &shost->__targets, siblings) { | 1474 | list_for_each_entry(sdev, &shost->__devices, siblings) { |
1475 | if (sdev->sdev_state == SDEV_DEL) | ||
1476 | continue; | ||
1483 | spin_unlock_irqrestore(shost->host_lock, flags); | 1477 | spin_unlock_irqrestore(shost->host_lock, flags); |
1484 | scsi_remove_target(&starget->dev); | 1478 | __scsi_remove_device(sdev); |
1485 | spin_lock_irqsave(shost->host_lock, flags); | 1479 | goto restart; |
1486 | } | 1480 | } |
1487 | spin_unlock_irqrestore(shost->host_lock, flags); | 1481 | spin_unlock_irqrestore(shost->host_lock, flags); |
1488 | } | 1482 | } |
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index b8052d5206cc..72a6550a056c 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c | |||
@@ -57,6 +57,8 @@ static struct { | |||
57 | { SHOST_CANCEL, "cancel" }, | 57 | { SHOST_CANCEL, "cancel" }, |
58 | { SHOST_DEL, "deleted" }, | 58 | { SHOST_DEL, "deleted" }, |
59 | { SHOST_RECOVERY, "recovery" }, | 59 | { SHOST_RECOVERY, "recovery" }, |
60 | { SHOST_CANCEL_RECOVERY, "cancel/recovery" }, | ||
61 | { SHOST_DEL_RECOVERY, "deleted/recovery", }, | ||
60 | }; | 62 | }; |
61 | const char *scsi_host_state_name(enum scsi_host_state state) | 63 | const char *scsi_host_state_name(enum scsi_host_state state) |
62 | { | 64 | { |
@@ -707,9 +709,11 @@ void __scsi_remove_device(struct scsi_device *sdev) | |||
707 | **/ | 709 | **/ |
708 | void scsi_remove_device(struct scsi_device *sdev) | 710 | void scsi_remove_device(struct scsi_device *sdev) |
709 | { | 711 | { |
710 | down(&sdev->host->scan_mutex); | 712 | struct Scsi_Host *shost = sdev->host; |
713 | |||
714 | down(&shost->scan_mutex); | ||
711 | __scsi_remove_device(sdev); | 715 | __scsi_remove_device(sdev); |
712 | up(&sdev->host->scan_mutex); | 716 | up(&shost->scan_mutex); |
713 | } | 717 | } |
714 | EXPORT_SYMBOL(scsi_remove_device); | 718 | EXPORT_SYMBOL(scsi_remove_device); |
715 | 719 | ||
@@ -717,17 +721,20 @@ void __scsi_remove_target(struct scsi_target *starget) | |||
717 | { | 721 | { |
718 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); | 722 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); |
719 | unsigned long flags; | 723 | unsigned long flags; |
720 | struct scsi_device *sdev, *tmp; | 724 | struct scsi_device *sdev; |
721 | 725 | ||
722 | spin_lock_irqsave(shost->host_lock, flags); | 726 | spin_lock_irqsave(shost->host_lock, flags); |
723 | starget->reap_ref++; | 727 | starget->reap_ref++; |
724 | list_for_each_entry_safe(sdev, tmp, &shost->__devices, siblings) { | 728 | restart: |
729 | list_for_each_entry(sdev, &shost->__devices, siblings) { | ||
725 | if (sdev->channel != starget->channel || | 730 | if (sdev->channel != starget->channel || |
726 | sdev->id != starget->id) | 731 | sdev->id != starget->id || |
732 | sdev->sdev_state == SDEV_DEL) | ||
727 | continue; | 733 | continue; |
728 | spin_unlock_irqrestore(shost->host_lock, flags); | 734 | spin_unlock_irqrestore(shost->host_lock, flags); |
729 | scsi_remove_device(sdev); | 735 | scsi_remove_device(sdev); |
730 | spin_lock_irqsave(shost->host_lock, flags); | 736 | spin_lock_irqsave(shost->host_lock, flags); |
737 | goto restart; | ||
731 | } | 738 | } |
732 | spin_unlock_irqrestore(shost->host_lock, flags); | 739 | spin_unlock_irqrestore(shost->host_lock, flags); |
733 | scsi_target_reap(starget); | 740 | scsi_target_reap(starget); |
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index de564b386052..9a1dc0cea03c 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -235,6 +235,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) | |||
235 | return 0; | 235 | return 0; |
236 | 236 | ||
237 | memcpy(SCpnt->cmnd, rq->cmd, sizeof(SCpnt->cmnd)); | 237 | memcpy(SCpnt->cmnd, rq->cmd, sizeof(SCpnt->cmnd)); |
238 | SCpnt->cmd_len = rq->cmd_len; | ||
238 | if (rq_data_dir(rq) == WRITE) | 239 | if (rq_data_dir(rq) == WRITE) |
239 | SCpnt->sc_data_direction = DMA_TO_DEVICE; | 240 | SCpnt->sc_data_direction = DMA_TO_DEVICE; |
240 | else if (rq->data_len) | 241 | else if (rq->data_len) |
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 9ea4765d1d12..4d09a6e4dd2e 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c | |||
@@ -1027,7 +1027,7 @@ sg_ioctl(struct inode *inode, struct file *filp, | |||
1027 | if (sdp->detached) | 1027 | if (sdp->detached) |
1028 | return -ENODEV; | 1028 | return -ENODEV; |
1029 | if (filp->f_flags & O_NONBLOCK) { | 1029 | if (filp->f_flags & O_NONBLOCK) { |
1030 | if (sdp->device->host->shost_state == SHOST_RECOVERY) | 1030 | if (scsi_host_in_recovery(sdp->device->host)) |
1031 | return -EBUSY; | 1031 | return -EBUSY; |
1032 | } else if (!scsi_block_when_processing_errors(sdp->device)) | 1032 | } else if (!scsi_block_when_processing_errors(sdp->device)) |
1033 | return -EBUSY; | 1033 | return -EBUSY; |
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index ce63fc8312dc..561901b1cf11 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c | |||
@@ -326,6 +326,7 @@ static int sr_init_command(struct scsi_cmnd * SCpnt) | |||
326 | return 0; | 326 | return 0; |
327 | 327 | ||
328 | memcpy(SCpnt->cmnd, rq->cmd, sizeof(SCpnt->cmnd)); | 328 | memcpy(SCpnt->cmnd, rq->cmd, sizeof(SCpnt->cmnd)); |
329 | SCpnt->cmd_len = rq->cmd_len; | ||
329 | if (!rq->data_len) | 330 | if (!rq->data_len) |
330 | SCpnt->sc_data_direction = DMA_NONE; | 331 | SCpnt->sc_data_direction = DMA_NONE; |
331 | else if (rq_data_dir(rq) == WRITE) | 332 | else if (rq_data_dir(rq) == WRITE) |
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index a93308ae9736..d001c046551b 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c | |||
@@ -4206,6 +4206,7 @@ static int st_init_command(struct scsi_cmnd *SCpnt) | |||
4206 | return 0; | 4206 | return 0; |
4207 | 4207 | ||
4208 | memcpy(SCpnt->cmnd, rq->cmd, sizeof(SCpnt->cmnd)); | 4208 | memcpy(SCpnt->cmnd, rq->cmd, sizeof(SCpnt->cmnd)); |
4209 | SCpnt->cmd_len = rq->cmd_len; | ||
4209 | 4210 | ||
4210 | if (rq_data_dir(rq) == WRITE) | 4211 | if (rq_data_dir(rq) == WRITE) |
4211 | SCpnt->sc_data_direction = DMA_TO_DEVICE; | 4212 | SCpnt->sc_data_direction = DMA_TO_DEVICE; |