aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2005-09-20 11:50:49 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-20 11:50:49 -0400
commit9600c11ba3602be161cd376f1460f3de561fc299 (patch)
treed071c2427a8f7ad601aec6d8ae76b0f61410becf /drivers/scsi
parent676d55ae30ea3b688f0386f70553489f25f24d55 (diff)
parent13e1e1f08c1c098c7574c1fa72bd8c67792dc89b (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-for-linus-2.6
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.c9
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.h2
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm_pci.c8
-rw-r--r--drivers/scsi/atp870u.c6
-rw-r--r--drivers/scsi/atp870u.h5
-rw-r--r--drivers/scsi/fd_mcs.c2
-rw-r--r--drivers/scsi/hosts.c35
-rw-r--r--drivers/scsi/ibmmca.c2
-rw-r--r--drivers/scsi/ibmvscsi/ibmvscsi.c10
-rw-r--r--drivers/scsi/scsi.c5
-rw-r--r--drivers/scsi/scsi_devinfo.c1
-rw-r--r--drivers/scsi/scsi_error.c78
-rw-r--r--drivers/scsi/scsi_ioctl.c2
-rw-r--r--drivers/scsi/scsi_lib.c12
-rw-r--r--drivers/scsi/scsi_scan.c20
-rw-r--r--drivers/scsi/scsi_sysfs.c17
-rw-r--r--drivers/scsi/sd.c1
-rw-r--r--drivers/scsi/sg.c2
-rw-r--r--drivers/scsi/sr.c1
-rw-r--r--drivers/scsi/st.c1
20 files changed, 129 insertions, 90 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
1112uint64_t
1113ahc_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)
494int ahc_linux_register_host(struct ahc_softc *, 494int ahc_linux_register_host(struct ahc_softc *,
495 struct scsi_host_template *); 495 struct scsi_host_template *);
496 496
497uint64_t ahc_linux_get_memsize(void);
498
499/*************************** Pretty Printing **********************************/ 497/*************************** Pretty Printing **********************************/
500struct info_str { 498struct 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
1364MODULE_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 **/
135void scsi_remove_host(struct Scsi_Host *shost) 155void 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");
460MODULE_PARM(normal, "1i"); 460MODULE_PARM(normal, "1i");
461MODULE_PARM(ansi, "1i"); 461MODULE_PARM(ansi, "1i");
462#endif 462#endif
463
464MODULE_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 */
465static int disk_rw_in_progress = 0; 467static 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/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 @@
50void scsi_eh_wakeup(struct Scsi_Host *shost) 50void 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)
1441static void scsi_restart_operations(struct Scsi_Host *shost) 1445static 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 */
145int scsi_queue_insert(struct scsi_cmnd *cmd, int reason) 143int 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
1467void scsi_forget_host(struct Scsi_Host *shost) 1467void 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};
61const char *scsi_host_state_name(enum scsi_host_state state) 63const 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 **/
708void scsi_remove_device(struct scsi_device *sdev) 710void 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}
714EXPORT_SYMBOL(scsi_remove_device); 718EXPORT_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;