Commit 77d644d4 authored by Mark Haverkamp's avatar Mark Haverkamp Committed by James Bottomley

[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: default avatarMark Haverkamp <markh@osdl.org>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent e5718774
...@@ -387,6 +387,7 @@ static void get_container_name_callback(void *context, struct fib * fibptr) ...@@ -387,6 +387,7 @@ static void get_container_name_callback(void *context, struct fib * fibptr)
struct scsi_cmnd * scsicmd; struct scsi_cmnd * scsicmd;
scsicmd = (struct scsi_cmnd *) context; scsicmd = (struct scsi_cmnd *) context;
scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL;
dprintk((KERN_DEBUG "get_container_name_callback[cpu %d]: t = %ld.\n", smp_processor_id(), jiffies)); dprintk((KERN_DEBUG "get_container_name_callback[cpu %d]: t = %ld.\n", smp_processor_id(), jiffies));
if (fibptr == NULL) if (fibptr == NULL)
...@@ -453,8 +454,10 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd, int cid) ...@@ -453,8 +454,10 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd, int cid)
/* /*
* Check that the command queued to the controller * Check that the command queued to the controller
*/ */
if (status == -EINPROGRESS) if (status == -EINPROGRESS) {
scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
return 0; return 0;
}
printk(KERN_WARNING "aac_get_container_name: aac_fib_send failed with status: %d.\n", status); printk(KERN_WARNING "aac_get_container_name: aac_fib_send failed with status: %d.\n", status);
aac_fib_complete(cmd_fibcontext); aac_fib_complete(cmd_fibcontext);
...@@ -907,6 +910,7 @@ static void io_callback(void *context, struct fib * fibptr) ...@@ -907,6 +910,7 @@ static void io_callback(void *context, struct fib * fibptr)
u32 cid; u32 cid;
scsicmd = (struct scsi_cmnd *) context; scsicmd = (struct scsi_cmnd *) context;
scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL;
dev = (struct aac_dev *)scsicmd->device->host->hostdata; dev = (struct aac_dev *)scsicmd->device->host->hostdata;
cid = scmd_id(scsicmd); cid = scmd_id(scsicmd);
...@@ -1151,8 +1155,10 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid) ...@@ -1151,8 +1155,10 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid)
/* /*
* Check that the command queued to the controller * Check that the command queued to the controller
*/ */
if (status == -EINPROGRESS) if (status == -EINPROGRESS) {
scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
return 0; return 0;
}
printk(KERN_WARNING "aac_read: aac_fib_send failed with status: %d.\n", status); printk(KERN_WARNING "aac_read: aac_fib_send failed with status: %d.\n", status);
/* /*
...@@ -1318,8 +1324,8 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid) ...@@ -1318,8 +1324,8 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid)
/* /*
* Check that the command queued to the controller * Check that the command queued to the controller
*/ */
if (status == -EINPROGRESS) if (status == -EINPROGRESS) {
{ scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
return 0; return 0;
} }
...@@ -1341,6 +1347,7 @@ static void synchronize_callback(void *context, struct fib *fibptr) ...@@ -1341,6 +1347,7 @@ static void synchronize_callback(void *context, struct fib *fibptr)
struct scsi_cmnd *cmd; struct scsi_cmnd *cmd;
cmd = context; cmd = context;
cmd->SCp.phase = AAC_OWNER_MIDLEVEL;
dprintk((KERN_DEBUG "synchronize_callback[cpu %d]: t = %ld.\n", dprintk((KERN_DEBUG "synchronize_callback[cpu %d]: t = %ld.\n",
smp_processor_id(), jiffies)); smp_processor_id(), jiffies));
...@@ -1386,12 +1393,12 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd, int cid) ...@@ -1386,12 +1393,12 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd, int cid)
unsigned long flags; unsigned long flags;
/* /*
* Wait for all commands to complete to this specific * Wait for all outstanding queued commands to complete to this
* target (block). * specific target (block).
*/ */
spin_lock_irqsave(&sdev->list_lock, flags); spin_lock_irqsave(&sdev->list_lock, flags);
list_for_each_entry(cmd, &sdev->cmd_list, list) list_for_each_entry(cmd, &sdev->cmd_list, list)
if (cmd != scsicmd && cmd->serial_number != 0) { if (cmd != scsicmd && cmd->SCp.phase == AAC_OWNER_FIRMWARE) {
++active; ++active;
break; break;
} }
...@@ -1434,8 +1441,10 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd, int cid) ...@@ -1434,8 +1441,10 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd, int cid)
/* /*
* Check that the command queued to the controller * Check that the command queued to the controller
*/ */
if (status == -EINPROGRESS) if (status == -EINPROGRESS) {
scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
return 0; return 0;
}
printk(KERN_WARNING printk(KERN_WARNING
"aac_synchronize: aac_fib_send failed with status: %d.\n", status); "aac_synchronize: aac_fib_send failed with status: %d.\n", status);
...@@ -1458,7 +1467,6 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) ...@@ -1458,7 +1467,6 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
struct Scsi_Host *host = scsicmd->device->host; struct Scsi_Host *host = scsicmd->device->host;
struct aac_dev *dev = (struct aac_dev *)host->hostdata; struct aac_dev *dev = (struct aac_dev *)host->hostdata;
struct fsa_dev_info *fsa_dev_ptr = dev->fsa_dev; struct fsa_dev_info *fsa_dev_ptr = dev->fsa_dev;
int ret;
/* /*
* If the bus, id or lun is out of range, return fail * 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,24 +1737,19 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
* containers to /dev/sd device names * containers to /dev/sd device names
*/ */
spin_unlock_irq(host->host_lock);
if (scsicmd->request->rq_disk) if (scsicmd->request->rq_disk)
strlcpy(fsa_dev_ptr[cid].devname, strlcpy(fsa_dev_ptr[cid].devname,
scsicmd->request->rq_disk->disk_name, scsicmd->request->rq_disk->disk_name,
min(sizeof(fsa_dev_ptr[cid].devname), min(sizeof(fsa_dev_ptr[cid].devname),
sizeof(scsicmd->request->rq_disk->disk_name) + 1)); sizeof(scsicmd->request->rq_disk->disk_name) + 1));
ret = aac_read(scsicmd, cid);
spin_lock_irq(host->host_lock); return aac_read(scsicmd, cid);
return ret;
case WRITE_6: case WRITE_6:
case WRITE_10: case WRITE_10:
case WRITE_12: case WRITE_12:
case WRITE_16: case WRITE_16:
spin_unlock_irq(host->host_lock); return aac_write(scsicmd, cid);
ret = aac_write(scsicmd, cid);
spin_lock_irq(host->host_lock);
return ret;
case SYNCHRONIZE_CACHE: case SYNCHRONIZE_CACHE:
/* Issue FIB to tell Firmware to flush it's cache */ /* 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,6 +1894,7 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
struct scsi_cmnd *scsicmd; struct scsi_cmnd *scsicmd;
scsicmd = (struct scsi_cmnd *) context; scsicmd = (struct scsi_cmnd *) context;
scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL;
dev = (struct aac_dev *)scsicmd->device->host->hostdata; dev = (struct aac_dev *)scsicmd->device->host->hostdata;
if (fibptr == NULL) if (fibptr == NULL)
...@@ -2162,7 +2166,8 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd) ...@@ -2162,7 +2166,8 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd)
/* /*
* Check that the command queued to the controller * Check that the command queued to the controller
*/ */
if (status == -EINPROGRESS){ if (status == -EINPROGRESS) {
scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
return 0; return 0;
} }
......
...@@ -1770,6 +1770,11 @@ static inline u32 cap_to_cyls(sector_t capacity, u32 divisor) ...@@ -1770,6 +1770,11 @@ static inline u32 cap_to_cyls(sector_t capacity, u32 divisor)
} }
struct scsi_cmnd; struct scsi_cmnd;
/* SCp.phase values */
#define AAC_OWNER_MIDLEVEL 0x101
#define AAC_OWNER_LOWLEVEL 0x102
#define AAC_OWNER_ERROR_HANDLER 0x103
#define AAC_OWNER_FIRMWARE 0x106
const char *aac_driverinfo(struct Scsi_Host *); const char *aac_driverinfo(struct Scsi_Host *);
struct fib *aac_fib_alloc(struct aac_dev *dev); struct fib *aac_fib_alloc(struct aac_dev *dev);
......
...@@ -243,6 +243,7 @@ static struct aac_driver_ident aac_drivers[] = { ...@@ -243,6 +243,7 @@ static struct aac_driver_ident aac_drivers[] = {
static int aac_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) static int aac_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
{ {
cmd->scsi_done = done; cmd->scsi_done = done;
cmd->SCp.phase = AAC_OWNER_LOWLEVEL;
return (aac_scsi_cmd(cmd) ? FAILED : 0); return (aac_scsi_cmd(cmd) ? FAILED : 0);
} }
...@@ -471,7 +472,8 @@ static int aac_eh_reset(struct scsi_cmnd* cmd) ...@@ -471,7 +472,8 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
__shost_for_each_device(dev, host) { __shost_for_each_device(dev, host) {
spin_lock_irqsave(&dev->list_lock, flags); spin_lock_irqsave(&dev->list_lock, flags);
list_for_each_entry(command, &dev->cmd_list, list) { list_for_each_entry(command, &dev->cmd_list, list) {
if (command->serial_number) { if ((command != cmd) &&
(command->SCp.phase == AAC_OWNER_FIRMWARE)) {
active++; active++;
break; break;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment