Skip to content

Commit

Permalink
[SCSI] aacraid: Track command ownership in driver
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Mark Haverkamp authored and James Bottomley committed Apr 13, 2006
1 parent e571877 commit 77d644d
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 19 deletions.
41 changes: 23 additions & 18 deletions drivers/scsi/aacraid/aachba.c
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,7 @@ static void get_container_name_callback(void *context, struct fib * fibptr)
struct scsi_cmnd * scsicmd;

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));
if (fibptr == NULL)
Expand Down Expand Up @@ -453,8 +454,10 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd, int cid)
/*
* Check that the command queued to the controller
*/
if (status == -EINPROGRESS)
if (status == -EINPROGRESS) {
scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
return 0;
}

printk(KERN_WARNING "aac_get_container_name: aac_fib_send failed with status: %d.\n", status);
aac_fib_complete(cmd_fibcontext);
Expand Down Expand Up @@ -907,6 +910,7 @@ static void io_callback(void *context, struct fib * fibptr)
u32 cid;

scsicmd = (struct scsi_cmnd *) context;
scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL;

dev = (struct aac_dev *)scsicmd->device->host->hostdata;
cid = scmd_id(scsicmd);
Expand Down Expand Up @@ -1151,8 +1155,10 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid)
/*
* Check that the command queued to the controller
*/
if (status == -EINPROGRESS)
if (status == -EINPROGRESS) {
scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
return 0;
}

printk(KERN_WARNING "aac_read: aac_fib_send failed with status: %d.\n", status);
/*
Expand Down Expand Up @@ -1318,8 +1324,8 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid)
/*
* Check that the command queued to the controller
*/
if (status == -EINPROGRESS)
{
if (status == -EINPROGRESS) {
scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
return 0;
}

Expand All @@ -1341,6 +1347,7 @@ static void synchronize_callback(void *context, struct fib *fibptr)
struct scsi_cmnd *cmd;

cmd = context;
cmd->SCp.phase = AAC_OWNER_MIDLEVEL;

dprintk((KERN_DEBUG "synchronize_callback[cpu %d]: t = %ld.\n",
smp_processor_id(), jiffies));
Expand Down Expand Up @@ -1386,12 +1393,12 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd, int cid)
unsigned long flags;

/*
* Wait for all commands to complete to this specific
* target (block).
* Wait for all outstanding queued commands to complete to this
* specific target (block).
*/
spin_lock_irqsave(&sdev->list_lock, flags);
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;
break;
}
Expand Down Expand Up @@ -1434,8 +1441,10 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd, int cid)
/*
* Check that the command queued to the controller
*/
if (status == -EINPROGRESS)
if (status == -EINPROGRESS) {
scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
return 0;
}

printk(KERN_WARNING
"aac_synchronize: aac_fib_send failed with status: %d.\n", status);
Expand All @@ -1458,7 +1467,6 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
struct Scsi_Host *host = scsicmd->device->host;
struct aac_dev *dev = (struct aac_dev *)host->hostdata;
struct fsa_dev_info *fsa_dev_ptr = dev->fsa_dev;
int ret;

/*
* If the bus, id or lun is out of range, return fail
Expand Down Expand Up @@ -1729,24 +1737,19 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
* containers to /dev/sd device names
*/

spin_unlock_irq(host->host_lock);
if (scsicmd->request->rq_disk)
strlcpy(fsa_dev_ptr[cid].devname,
scsicmd->request->rq_disk->disk_name,
min(sizeof(fsa_dev_ptr[cid].devname),
sizeof(scsicmd->request->rq_disk->disk_name) + 1));
ret = aac_read(scsicmd, cid);
spin_lock_irq(host->host_lock);
return ret;

return aac_read(scsicmd, cid);

case WRITE_6:
case WRITE_10:
case WRITE_12:
case WRITE_16:
spin_unlock_irq(host->host_lock);
ret = aac_write(scsicmd, cid);
spin_lock_irq(host->host_lock);
return ret;
return aac_write(scsicmd, cid);

case SYNCHRONIZE_CACHE:
/* Issue FIB to tell Firmware to flush it's cache */
Expand Down Expand Up @@ -1891,6 +1894,7 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
struct scsi_cmnd *scsicmd;

scsicmd = (struct scsi_cmnd *) context;
scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL;
dev = (struct aac_dev *)scsicmd->device->host->hostdata;

if (fibptr == NULL)
Expand Down Expand Up @@ -2162,7 +2166,8 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd)
/*
* Check that the command queued to the controller
*/
if (status == -EINPROGRESS){
if (status == -EINPROGRESS) {
scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
return 0;
}

Expand Down
5 changes: 5 additions & 0 deletions drivers/scsi/aacraid/aacraid.h
Original file line number Diff line number Diff line change
Expand Up @@ -1770,6 +1770,11 @@ static inline u32 cap_to_cyls(sector_t capacity, u32 divisor)
}

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 *);
struct fib *aac_fib_alloc(struct aac_dev *dev);
Expand Down
4 changes: 3 additions & 1 deletion drivers/scsi/aacraid/linit.c
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ static struct aac_driver_ident aac_drivers[] = {
static int aac_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
{
cmd->scsi_done = done;
cmd->SCp.phase = AAC_OWNER_LOWLEVEL;
return (aac_scsi_cmd(cmd) ? FAILED : 0);
}

Expand Down Expand Up @@ -471,7 +472,8 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
__shost_for_each_device(dev, host) {
spin_lock_irqsave(&dev->list_lock, flags);
list_for_each_entry(command, &dev->cmd_list, list) {
if (command->serial_number) {
if ((command != cmd) &&
(command->SCp.phase == AAC_OWNER_FIRMWARE)) {
active++;
break;
}
Expand Down

0 comments on commit 77d644d

Please sign in to comment.