aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Haverkamp <markh@osdl.org>2006-03-27 12:43:40 -0500
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-04-13 11:13:17 -0400
commit77d644d4d70c9ad5df51792575f43a950525c9aa (patch)
tree84dd02706a7554e26820ff98586844ad4e996d68
parente5718774f12234c7c9be8944001cfd109ba955e1 (diff)
[SCSI] aacraid: Track command ownership in driver
Received from Mark Salyzyn The loss of the ownership flags, despite their flaws, in the scsi command were sorely missed and are reinstated more accurately in the aacraid driver to track commands and permit us to properly handle error recovery actions. Signed-off-by: Mark Haverkamp <markh@osdl.org> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r--drivers/scsi/aacraid/aachba.c41
-rw-r--r--drivers/scsi/aacraid/aacraid.h5
-rw-r--r--drivers/scsi/aacraid/linit.c4
3 files changed, 31 insertions, 19 deletions
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index a1e473003671..31319d052102 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -387,6 +387,7 @@ static void get_container_name_callback(void *context, struct fib * fibptr)
387 struct scsi_cmnd * scsicmd; 387 struct scsi_cmnd * scsicmd;
388 388
389 scsicmd = (struct scsi_cmnd *) context; 389 scsicmd = (struct scsi_cmnd *) context;
390 scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL;
390 391
391 dprintk((KERN_DEBUG "get_container_name_callback[cpu %d]: t = %ld.\n", smp_processor_id(), jiffies)); 392 dprintk((KERN_DEBUG "get_container_name_callback[cpu %d]: t = %ld.\n", smp_processor_id(), jiffies));
392 if (fibptr == NULL) 393 if (fibptr == NULL)
@@ -453,8 +454,10 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd, int cid)
453 /* 454 /*
454 * Check that the command queued to the controller 455 * Check that the command queued to the controller
455 */ 456 */
456 if (status == -EINPROGRESS) 457 if (status == -EINPROGRESS) {
458 scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
457 return 0; 459 return 0;
460 }
458 461
459 printk(KERN_WARNING "aac_get_container_name: aac_fib_send failed with status: %d.\n", status); 462 printk(KERN_WARNING "aac_get_container_name: aac_fib_send failed with status: %d.\n", status);
460 aac_fib_complete(cmd_fibcontext); 463 aac_fib_complete(cmd_fibcontext);
@@ -907,6 +910,7 @@ static void io_callback(void *context, struct fib * fibptr)
907 u32 cid; 910 u32 cid;
908 911
909 scsicmd = (struct scsi_cmnd *) context; 912 scsicmd = (struct scsi_cmnd *) context;
913 scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL;
910 914
911 dev = (struct aac_dev *)scsicmd->device->host->hostdata; 915 dev = (struct aac_dev *)scsicmd->device->host->hostdata;
912 cid = scmd_id(scsicmd); 916 cid = scmd_id(scsicmd);
@@ -1151,8 +1155,10 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid)
1151 /* 1155 /*
1152 * Check that the command queued to the controller 1156 * Check that the command queued to the controller
1153 */ 1157 */
1154 if (status == -EINPROGRESS) 1158 if (status == -EINPROGRESS) {
1159 scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
1155 return 0; 1160 return 0;
1161 }
1156 1162
1157 printk(KERN_WARNING "aac_read: aac_fib_send failed with status: %d.\n", status); 1163 printk(KERN_WARNING "aac_read: aac_fib_send failed with status: %d.\n", status);
1158 /* 1164 /*
@@ -1318,8 +1324,8 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid)
1318 /* 1324 /*
1319 * Check that the command queued to the controller 1325 * Check that the command queued to the controller
1320 */ 1326 */
1321 if (status == -EINPROGRESS) 1327 if (status == -EINPROGRESS) {
1322 { 1328 scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
1323 return 0; 1329 return 0;
1324 } 1330 }
1325 1331
@@ -1341,6 +1347,7 @@ static void synchronize_callback(void *context, struct fib *fibptr)
1341 struct scsi_cmnd *cmd; 1347 struct scsi_cmnd *cmd;
1342 1348
1343 cmd = context; 1349 cmd = context;
1350 cmd->SCp.phase = AAC_OWNER_MIDLEVEL;
1344 1351
1345 dprintk((KERN_DEBUG "synchronize_callback[cpu %d]: t = %ld.\n", 1352 dprintk((KERN_DEBUG "synchronize_callback[cpu %d]: t = %ld.\n",
1346 smp_processor_id(), jiffies)); 1353 smp_processor_id(), jiffies));
@@ -1386,12 +1393,12 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd, int cid)
1386 unsigned long flags; 1393 unsigned long flags;
1387 1394
1388 /* 1395 /*
1389 * Wait for all commands to complete to this specific 1396 * Wait for all outstanding queued commands to complete to this
1390 * target (block). 1397 * specific target (block).
1391 */ 1398 */
1392 spin_lock_irqsave(&sdev->list_lock, flags); 1399 spin_lock_irqsave(&sdev->list_lock, flags);
1393 list_for_each_entry(cmd, &sdev->cmd_list, list) 1400 list_for_each_entry(cmd, &sdev->cmd_list, list)
1394 if (cmd != scsicmd && cmd->serial_number != 0) { 1401 if (cmd != scsicmd && cmd->SCp.phase == AAC_OWNER_FIRMWARE) {
1395 ++active; 1402 ++active;
1396 break; 1403 break;
1397 } 1404 }
@@ -1434,8 +1441,10 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd, int cid)
1434 /* 1441 /*
1435 * Check that the command queued to the controller 1442 * Check that the command queued to the controller
1436 */ 1443 */
1437 if (status == -EINPROGRESS) 1444 if (status == -EINPROGRESS) {
1445 scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
1438 return 0; 1446 return 0;
1447 }
1439 1448
1440 printk(KERN_WARNING 1449 printk(KERN_WARNING
1441 "aac_synchronize: aac_fib_send failed with status: %d.\n", status); 1450 "aac_synchronize: aac_fib_send failed with status: %d.\n", status);
@@ -1458,7 +1467,6 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
1458 struct Scsi_Host *host = scsicmd->device->host; 1467 struct Scsi_Host *host = scsicmd->device->host;
1459 struct aac_dev *dev = (struct aac_dev *)host->hostdata; 1468 struct aac_dev *dev = (struct aac_dev *)host->hostdata;
1460 struct fsa_dev_info *fsa_dev_ptr = dev->fsa_dev; 1469 struct fsa_dev_info *fsa_dev_ptr = dev->fsa_dev;
1461 int ret;
1462 1470
1463 /* 1471 /*
1464 * If the bus, id or lun is out of range, return fail 1472 * If the bus, id or lun is out of range, return fail
@@ -1729,24 +1737,19 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
1729 * containers to /dev/sd device names 1737 * containers to /dev/sd device names
1730 */ 1738 */
1731 1739
1732 spin_unlock_irq(host->host_lock);
1733 if (scsicmd->request->rq_disk) 1740 if (scsicmd->request->rq_disk)
1734 strlcpy(fsa_dev_ptr[cid].devname, 1741 strlcpy(fsa_dev_ptr[cid].devname,
1735 scsicmd->request->rq_disk->disk_name, 1742 scsicmd->request->rq_disk->disk_name,
1736 min(sizeof(fsa_dev_ptr[cid].devname), 1743 min(sizeof(fsa_dev_ptr[cid].devname),
1737 sizeof(scsicmd->request->rq_disk->disk_name) + 1)); 1744 sizeof(scsicmd->request->rq_disk->disk_name) + 1));
1738 ret = aac_read(scsicmd, cid); 1745
1739 spin_lock_irq(host->host_lock); 1746 return aac_read(scsicmd, cid);
1740 return ret;
1741 1747
1742 case WRITE_6: 1748 case WRITE_6:
1743 case WRITE_10: 1749 case WRITE_10:
1744 case WRITE_12: 1750 case WRITE_12:
1745 case WRITE_16: 1751 case WRITE_16:
1746 spin_unlock_irq(host->host_lock); 1752 return aac_write(scsicmd, cid);
1747 ret = aac_write(scsicmd, cid);
1748 spin_lock_irq(host->host_lock);
1749 return ret;
1750 1753
1751 case SYNCHRONIZE_CACHE: 1754 case SYNCHRONIZE_CACHE:
1752 /* Issue FIB to tell Firmware to flush it's cache */ 1755 /* Issue FIB to tell Firmware to flush it's cache */
@@ -1891,6 +1894,7 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
1891 struct scsi_cmnd *scsicmd; 1894 struct scsi_cmnd *scsicmd;
1892 1895
1893 scsicmd = (struct scsi_cmnd *) context; 1896 scsicmd = (struct scsi_cmnd *) context;
1897 scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL;
1894 dev = (struct aac_dev *)scsicmd->device->host->hostdata; 1898 dev = (struct aac_dev *)scsicmd->device->host->hostdata;
1895 1899
1896 if (fibptr == NULL) 1900 if (fibptr == NULL)
@@ -2162,7 +2166,8 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd)
2162 /* 2166 /*
2163 * Check that the command queued to the controller 2167 * Check that the command queued to the controller
2164 */ 2168 */
2165 if (status == -EINPROGRESS){ 2169 if (status == -EINPROGRESS) {
2170 scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
2166 return 0; 2171 return 0;
2167 } 2172 }
2168 2173
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index fcf046ca9965..51c96cac484e 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -1770,6 +1770,11 @@ static inline u32 cap_to_cyls(sector_t capacity, u32 divisor)
1770} 1770}
1771 1771
1772struct scsi_cmnd; 1772struct scsi_cmnd;
1773/* SCp.phase values */
1774#define AAC_OWNER_MIDLEVEL 0x101
1775#define AAC_OWNER_LOWLEVEL 0x102
1776#define AAC_OWNER_ERROR_HANDLER 0x103
1777#define AAC_OWNER_FIRMWARE 0x106
1773 1778
1774const char *aac_driverinfo(struct Scsi_Host *); 1779const char *aac_driverinfo(struct Scsi_Host *);
1775struct fib *aac_fib_alloc(struct aac_dev *dev); 1780struct fib *aac_fib_alloc(struct aac_dev *dev);
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 720330778648..9f3cc7b7123d 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -243,6 +243,7 @@ static struct aac_driver_ident aac_drivers[] = {
243static int aac_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) 243static int aac_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
244{ 244{
245 cmd->scsi_done = done; 245 cmd->scsi_done = done;
246 cmd->SCp.phase = AAC_OWNER_LOWLEVEL;
246 return (aac_scsi_cmd(cmd) ? FAILED : 0); 247 return (aac_scsi_cmd(cmd) ? FAILED : 0);
247} 248}
248 249
@@ -471,7 +472,8 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
471 __shost_for_each_device(dev, host) { 472 __shost_for_each_device(dev, host) {
472 spin_lock_irqsave(&dev->list_lock, flags); 473 spin_lock_irqsave(&dev->list_lock, flags);
473 list_for_each_entry(command, &dev->cmd_list, list) { 474 list_for_each_entry(command, &dev->cmd_list, list) {
474 if (command->serial_number) { 475 if ((command != cmd) &&
476 (command->SCp.phase == AAC_OWNER_FIRMWARE)) {
475 active++; 477 active++;
476 break; 478 break;
477 } 479 }