Skip to content

Commit

Permalink
[SCSI] aacraid: Reset adapter in recovery timeout
Browse files Browse the repository at this point in the history
Received from Mark Salyzyn

If the adapter is in blinkled (Firmware Assert) when error recovery
timeout actions have been triggered, perform an adapter warm reset and
restart the initialization.

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 Aug 19, 2006
1 parent 90ee346 commit 8c867b2
Show file tree
Hide file tree
Showing 5 changed files with 296 additions and 21 deletions.
39 changes: 27 additions & 12 deletions drivers/scsi/aacraid/aachba.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ MODULE_PARM_DESC(acbsize, "Request a specific adapter control block (FIB) size.
*
* Query config status, and commit the configuration if needed.
*/
int aac_get_config_status(struct aac_dev *dev)
int aac_get_config_status(struct aac_dev *dev, int commit_flag)
{
int status = 0;
struct fib * fibptr;
Expand Down Expand Up @@ -219,7 +219,7 @@ int aac_get_config_status(struct aac_dev *dev)
aac_fib_complete(fibptr);
/* Send a CT_COMMIT_CONFIG to enable discovery of devices */
if (status >= 0) {
if (commit == 1) {
if ((commit == 1) || commit_flag) {
struct aac_commit_config * dinfo;
aac_fib_init(fibptr);
dinfo = (struct aac_commit_config *) fib_data(fibptr);
Expand Down Expand Up @@ -784,8 +784,9 @@ int aac_get_adapter_info(struct aac_dev* dev)
dev->maximum_num_channels = le32_to_cpu(bus_info->BusCount);
}

tmp = le32_to_cpu(dev->adapter_info.kernelrev);
printk(KERN_INFO "%s%d: kernel %d.%d-%d[%d] %.*s\n",
if (!dev->in_reset) {
tmp = le32_to_cpu(dev->adapter_info.kernelrev);
printk(KERN_INFO "%s%d: kernel %d.%d-%d[%d] %.*s\n",
dev->name,
dev->id,
tmp>>24,
Expand All @@ -794,20 +795,21 @@ int aac_get_adapter_info(struct aac_dev* dev)
le32_to_cpu(dev->adapter_info.kernelbuild),
(int)sizeof(dev->supplement_adapter_info.BuildDate),
dev->supplement_adapter_info.BuildDate);
tmp = le32_to_cpu(dev->adapter_info.monitorrev);
printk(KERN_INFO "%s%d: monitor %d.%d-%d[%d]\n",
tmp = le32_to_cpu(dev->adapter_info.monitorrev);
printk(KERN_INFO "%s%d: monitor %d.%d-%d[%d]\n",
dev->name, dev->id,
tmp>>24,(tmp>>16)&0xff,tmp&0xff,
le32_to_cpu(dev->adapter_info.monitorbuild));
tmp = le32_to_cpu(dev->adapter_info.biosrev);
printk(KERN_INFO "%s%d: bios %d.%d-%d[%d]\n",
tmp = le32_to_cpu(dev->adapter_info.biosrev);
printk(KERN_INFO "%s%d: bios %d.%d-%d[%d]\n",
dev->name, dev->id,
tmp>>24,(tmp>>16)&0xff,tmp&0xff,
le32_to_cpu(dev->adapter_info.biosbuild));
if (le32_to_cpu(dev->adapter_info.serial[0]) != 0xBAD0)
printk(KERN_INFO "%s%d: serial %x\n",
dev->name, dev->id,
le32_to_cpu(dev->adapter_info.serial[0]));
if (le32_to_cpu(dev->adapter_info.serial[0]) != 0xBAD0)
printk(KERN_INFO "%s%d: serial %x\n",
dev->name, dev->id,
le32_to_cpu(dev->adapter_info.serial[0]));
}

dev->nondasd_support = 0;
dev->raid_scsi_mode = 0;
Expand Down Expand Up @@ -1417,6 +1419,9 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd, int cid)
return SCSI_MLQUEUE_DEVICE_BUSY;

aac = (struct aac_dev *)scsicmd->device->host->hostdata;
if (aac->in_reset)
return SCSI_MLQUEUE_HOST_BUSY;

/*
* Allocate and initialize a Fib
*/
Expand Down Expand Up @@ -1504,6 +1509,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
case INQUIRY:
case READ_CAPACITY:
case TEST_UNIT_READY:
if (dev->in_reset)
return -1;
spin_unlock_irq(host->host_lock);
aac_probe_container(dev, cid);
if ((fsa_dev_ptr[cid].valid & 1) == 0)
Expand All @@ -1529,6 +1536,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
}
} else { /* check for physical non-dasd devices */
if(dev->nondasd_support == 1){
if (dev->in_reset)
return -1;
return aac_send_srb_fib(scsicmd);
} else {
scsicmd->result = DID_NO_CONNECT << 16;
Expand Down Expand Up @@ -1584,6 +1593,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
scsicmd->scsi_done(scsicmd);
return 0;
}
if (dev->in_reset)
return -1;
setinqstr(dev, (void *) (inq_data.inqd_vid), fsa_dev_ptr[cid].type);
inq_data.inqd_pdt = INQD_PDT_DA; /* Direct/random access device */
aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data));
Expand Down Expand Up @@ -1739,6 +1750,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
case READ_10:
case READ_12:
case READ_16:
if (dev->in_reset)
return -1;
/*
* Hack to keep track of ordinal number of the device that
* corresponds to a container. Needed to convert
Expand All @@ -1757,6 +1770,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
case WRITE_10:
case WRITE_12:
case WRITE_16:
if (dev->in_reset)
return -1;
return aac_write(scsicmd, cid);

case SYNCHRONIZE_CACHE:
Expand Down
4 changes: 3 additions & 1 deletion drivers/scsi/aacraid/aacraid.h
Original file line number Diff line number Diff line change
Expand Up @@ -1029,6 +1029,7 @@ struct aac_dev
init->InitStructRevision==cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_4)
u8 raw_io_64;
u8 printf_enabled;
u8 in_reset;
};

#define aac_adapter_interrupt(dev) \
Expand Down Expand Up @@ -1789,7 +1790,7 @@ void aac_consumer_free(struct aac_dev * dev, struct aac_queue * q, u32 qnum);
int aac_fib_complete(struct fib * context);
#define fib_data(fibctx) ((void *)(fibctx)->hw_fib->data)
struct aac_dev *aac_init_adapter(struct aac_dev *dev);
int aac_get_config_status(struct aac_dev *dev);
int aac_get_config_status(struct aac_dev *dev, int commit_flag);
int aac_get_containers(struct aac_dev *dev);
int aac_scsi_cmd(struct scsi_cmnd *cmd);
int aac_dev_ioctl(struct aac_dev *dev, int cmd, void __user *arg);
Expand All @@ -1800,6 +1801,7 @@ int aac_sa_init(struct aac_dev *dev);
unsigned int aac_response_normal(struct aac_queue * q);
unsigned int aac_command_normal(struct aac_queue * q);
unsigned int aac_intr_normal(struct aac_dev * dev, u32 Index);
int aac_check_health(struct aac_dev * dev);
int aac_command_thread(void *data);
int aac_close_fib_context(struct aac_dev * dev, struct aac_fib_context *fibctx);
int aac_fib_adapter_complete(struct fib * fibptr, unsigned short size);
Expand Down
2 changes: 1 addition & 1 deletion drivers/scsi/aacraid/commctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ static int next_getadapter_fib(struct aac_dev * dev, void __user *arg)
spin_unlock_irqrestore(&dev->fib_lock, flags);
/* If someone killed the AIF aacraid thread, restart it */
status = !dev->aif_thread;
if (status && dev->queues && dev->fsa_dev) {
if (status && !dev->in_reset && dev->queues && dev->fsa_dev) {
/* Be paranoid, be very paranoid! */
kthread_stop(dev->thread);
ssleep(1);
Expand Down
Loading

0 comments on commit 8c867b2

Please sign in to comment.