Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (166 commits)
[SCSI] ibmvscsi: convert to use the data buffer accessors
[SCSI] dc395x: convert to use the data buffer accessors
[SCSI] ncr53c8xx: convert to use the data buffer accessors
[SCSI] sym53c8xx: convert to use the data buffer accessors
[SCSI] ppa: coding police and printk levels
[SCSI] aic7xxx_old: remove redundant GFP_ATOMIC from kmalloc
[SCSI] i2o: remove redundant GFP_ATOMIC from kmalloc from device.c
[SCSI] remove the dead CYBERSTORMIII_SCSI option
[SCSI] don't build scsi_dma_{map,unmap} for !HAS_DMA
[SCSI] Clean up scsi_add_lun a bit
[SCSI] 53c700: Remove printk, which triggers because of low scsi clock on SNI RMs
[SCSI] sni_53c710: Cleanup
[SCSI] qla4xxx: Fix underrun/overrun conditions
[SCSI] megaraid_mbox: use mutex instead of semaphore
[SCSI] aacraid: add 51245, 51645 and 52245 adapters to documentation.
[SCSI] qla2xxx: update version to 8.02.00-k1.
[SCSI] qla2xxx: add support for NPIV
[SCSI] stex: use resid for xfer len information
[SCSI] Add Brownie 1200U3P to blacklist
[SCSI] scsi.c: convert to use the data buffer accessors
...
This commit is contained in:
+153
-167
@@ -169,6 +169,18 @@ int acbsize = -1;
|
||||
module_param(acbsize, int, S_IRUGO|S_IWUSR);
|
||||
MODULE_PARM_DESC(acbsize, "Request a specific adapter control block (FIB) size. Valid values are 512, 2048, 4096 and 8192. Default is to use suggestion from Firmware.");
|
||||
|
||||
int update_interval = 30 * 60;
|
||||
module_param(update_interval, int, S_IRUGO|S_IWUSR);
|
||||
MODULE_PARM_DESC(update_interval, "Interval in seconds between time sync updates issued to adapter.");
|
||||
|
||||
int check_interval = 24 * 60 * 60;
|
||||
module_param(check_interval, int, S_IRUGO|S_IWUSR);
|
||||
MODULE_PARM_DESC(check_interval, "Interval in seconds between adapter health checks.");
|
||||
|
||||
int check_reset = 1;
|
||||
module_param(check_reset, int, S_IRUGO|S_IWUSR);
|
||||
MODULE_PARM_DESC(check_reset, "If adapter fails health check, reset the adapter.");
|
||||
|
||||
int expose_physicals = -1;
|
||||
module_param(expose_physicals, int, S_IRUGO|S_IWUSR);
|
||||
MODULE_PARM_DESC(expose_physicals, "Expose physical components of the arrays. -1=protect 0=off, 1=on");
|
||||
@@ -312,11 +324,10 @@ int aac_get_containers(struct aac_dev *dev)
|
||||
|
||||
if (maximum_num_containers < MAXIMUM_NUM_CONTAINERS)
|
||||
maximum_num_containers = MAXIMUM_NUM_CONTAINERS;
|
||||
fsa_dev_ptr = kmalloc(sizeof(*fsa_dev_ptr) * maximum_num_containers,
|
||||
fsa_dev_ptr = kzalloc(sizeof(*fsa_dev_ptr) * maximum_num_containers,
|
||||
GFP_KERNEL);
|
||||
if (!fsa_dev_ptr)
|
||||
return -ENOMEM;
|
||||
memset(fsa_dev_ptr, 0, sizeof(*fsa_dev_ptr) * maximum_num_containers);
|
||||
|
||||
dev->fsa_dev = fsa_dev_ptr;
|
||||
dev->maximum_num_containers = maximum_num_containers;
|
||||
@@ -344,21 +355,16 @@ static void aac_internal_transfer(struct scsi_cmnd *scsicmd, void *data, unsigne
|
||||
{
|
||||
void *buf;
|
||||
int transfer_len;
|
||||
struct scatterlist *sg = scsicmd->request_buffer;
|
||||
struct scatterlist *sg = scsi_sglist(scsicmd);
|
||||
|
||||
buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
|
||||
transfer_len = min(sg->length, len + offset);
|
||||
|
||||
if (scsicmd->use_sg) {
|
||||
buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
|
||||
transfer_len = min(sg->length, len + offset);
|
||||
} else {
|
||||
buf = scsicmd->request_buffer;
|
||||
transfer_len = min(scsicmd->request_bufflen, len + offset);
|
||||
}
|
||||
transfer_len -= offset;
|
||||
if (buf && transfer_len > 0)
|
||||
memcpy(buf + offset, data, transfer_len);
|
||||
|
||||
if (scsicmd->use_sg)
|
||||
kunmap_atomic(buf - sg->offset, KM_IRQ0);
|
||||
kunmap_atomic(buf - sg->offset, KM_IRQ0);
|
||||
|
||||
}
|
||||
|
||||
@@ -451,7 +457,7 @@ static int aac_probe_container_callback2(struct scsi_cmnd * scsicmd)
|
||||
{
|
||||
struct fsa_dev_info *fsa_dev_ptr = ((struct aac_dev *)(scsicmd->device->host->hostdata))->fsa_dev;
|
||||
|
||||
if (fsa_dev_ptr[scmd_id(scsicmd)].valid)
|
||||
if ((fsa_dev_ptr[scmd_id(scsicmd)].valid & 1))
|
||||
return aac_scsi_cmd(scsicmd);
|
||||
|
||||
scsicmd->result = DID_NO_CONNECT << 16;
|
||||
@@ -459,18 +465,18 @@ static int aac_probe_container_callback2(struct scsi_cmnd * scsicmd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _aac_probe_container2(void * context, struct fib * fibptr)
|
||||
static void _aac_probe_container2(void * context, struct fib * fibptr)
|
||||
{
|
||||
struct fsa_dev_info *fsa_dev_ptr;
|
||||
int (*callback)(struct scsi_cmnd *);
|
||||
struct scsi_cmnd * scsicmd = (struct scsi_cmnd *)context;
|
||||
|
||||
if (!aac_valid_context(scsicmd, fibptr))
|
||||
return 0;
|
||||
|
||||
fsa_dev_ptr = ((struct aac_dev *)(scsicmd->device->host->hostdata))->fsa_dev;
|
||||
if (!aac_valid_context(scsicmd, fibptr))
|
||||
return;
|
||||
|
||||
scsicmd->SCp.Status = 0;
|
||||
fsa_dev_ptr = fibptr->dev->fsa_dev;
|
||||
if (fsa_dev_ptr) {
|
||||
struct aac_mount * dresp = (struct aac_mount *) fib_data(fibptr);
|
||||
fsa_dev_ptr += scmd_id(scsicmd);
|
||||
@@ -493,10 +499,11 @@ static int _aac_probe_container2(void * context, struct fib * fibptr)
|
||||
aac_fib_free(fibptr);
|
||||
callback = (int (*)(struct scsi_cmnd *))(scsicmd->SCp.ptr);
|
||||
scsicmd->SCp.ptr = NULL;
|
||||
return (*callback)(scsicmd);
|
||||
(*callback)(scsicmd);
|
||||
return;
|
||||
}
|
||||
|
||||
static int _aac_probe_container1(void * context, struct fib * fibptr)
|
||||
static void _aac_probe_container1(void * context, struct fib * fibptr)
|
||||
{
|
||||
struct scsi_cmnd * scsicmd;
|
||||
struct aac_mount * dresp;
|
||||
@@ -506,13 +513,14 @@ static int _aac_probe_container1(void * context, struct fib * fibptr)
|
||||
dresp = (struct aac_mount *) fib_data(fibptr);
|
||||
dresp->mnt[0].capacityhigh = 0;
|
||||
if ((le32_to_cpu(dresp->status) != ST_OK) ||
|
||||
(le32_to_cpu(dresp->mnt[0].vol) != CT_NONE))
|
||||
return _aac_probe_container2(context, fibptr);
|
||||
(le32_to_cpu(dresp->mnt[0].vol) != CT_NONE)) {
|
||||
_aac_probe_container2(context, fibptr);
|
||||
return;
|
||||
}
|
||||
scsicmd = (struct scsi_cmnd *) context;
|
||||
scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL;
|
||||
|
||||
if (!aac_valid_context(scsicmd, fibptr))
|
||||
return 0;
|
||||
return;
|
||||
|
||||
aac_fib_init(fibptr);
|
||||
|
||||
@@ -527,21 +535,18 @@ static int _aac_probe_container1(void * context, struct fib * fibptr)
|
||||
sizeof(struct aac_query_mount),
|
||||
FsaNormal,
|
||||
0, 1,
|
||||
(fib_callback) _aac_probe_container2,
|
||||
_aac_probe_container2,
|
||||
(void *) scsicmd);
|
||||
/*
|
||||
* Check that the command queued to the controller
|
||||
*/
|
||||
if (status == -EINPROGRESS) {
|
||||
if (status == -EINPROGRESS)
|
||||
scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
|
||||
return 0;
|
||||
}
|
||||
if (status < 0) {
|
||||
else if (status < 0) {
|
||||
/* Inherit results from VM_NameServe, if any */
|
||||
dresp->status = cpu_to_le32(ST_OK);
|
||||
return _aac_probe_container2(context, fibptr);
|
||||
_aac_probe_container2(context, fibptr);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _aac_probe_container(struct scsi_cmnd * scsicmd, int (*callback)(struct scsi_cmnd *))
|
||||
@@ -566,7 +571,7 @@ static int _aac_probe_container(struct scsi_cmnd * scsicmd, int (*callback)(stru
|
||||
sizeof(struct aac_query_mount),
|
||||
FsaNormal,
|
||||
0, 1,
|
||||
(fib_callback) _aac_probe_container1,
|
||||
_aac_probe_container1,
|
||||
(void *) scsicmd);
|
||||
/*
|
||||
* Check that the command queued to the controller
|
||||
@@ -620,7 +625,7 @@ int aac_probe_container(struct aac_dev *dev, int cid)
|
||||
return -ENOMEM;
|
||||
}
|
||||
scsicmd->list.next = NULL;
|
||||
scsicmd->scsi_done = (void (*)(struct scsi_cmnd*))_aac_probe_container1;
|
||||
scsicmd->scsi_done = (void (*)(struct scsi_cmnd*))aac_probe_container_callback1;
|
||||
|
||||
scsicmd->device = scsidev;
|
||||
scsidev->sdev_state = 0;
|
||||
@@ -825,7 +830,7 @@ static int aac_read_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u3
|
||||
readcmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32));
|
||||
readcmd->count = cpu_to_le32(count<<9);
|
||||
readcmd->cid = cpu_to_le16(scmd_id(cmd));
|
||||
readcmd->flags = cpu_to_le16(1);
|
||||
readcmd->flags = cpu_to_le16(IO_TYPE_READ);
|
||||
readcmd->bpTotal = 0;
|
||||
readcmd->bpComplete = 0;
|
||||
|
||||
@@ -904,7 +909,7 @@ static int aac_read_block(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32
|
||||
(void *) cmd);
|
||||
}
|
||||
|
||||
static int aac_write_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count)
|
||||
static int aac_write_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count, int fua)
|
||||
{
|
||||
u16 fibsize;
|
||||
struct aac_raw_io *writecmd;
|
||||
@@ -914,7 +919,9 @@ static int aac_write_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u
|
||||
writecmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32));
|
||||
writecmd->count = cpu_to_le32(count<<9);
|
||||
writecmd->cid = cpu_to_le16(scmd_id(cmd));
|
||||
writecmd->flags = 0;
|
||||
writecmd->flags = fua ?
|
||||
cpu_to_le16(IO_TYPE_WRITE|IO_SUREWRITE) :
|
||||
cpu_to_le16(IO_TYPE_WRITE);
|
||||
writecmd->bpTotal = 0;
|
||||
writecmd->bpComplete = 0;
|
||||
|
||||
@@ -933,7 +940,7 @@ static int aac_write_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u
|
||||
(void *) cmd);
|
||||
}
|
||||
|
||||
static int aac_write_block64(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count)
|
||||
static int aac_write_block64(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count, int fua)
|
||||
{
|
||||
u16 fibsize;
|
||||
struct aac_write64 *writecmd;
|
||||
@@ -964,7 +971,7 @@ static int aac_write_block64(struct fib * fib, struct scsi_cmnd * cmd, u64 lba,
|
||||
(void *) cmd);
|
||||
}
|
||||
|
||||
static int aac_write_block(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count)
|
||||
static int aac_write_block(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count, int fua)
|
||||
{
|
||||
u16 fibsize;
|
||||
struct aac_write *writecmd;
|
||||
@@ -1041,7 +1048,7 @@ static int aac_scsi_64(struct fib * fib, struct scsi_cmnd * cmd)
|
||||
struct aac_srb * srbcmd = aac_scsi_common(fib, cmd);
|
||||
|
||||
aac_build_sg64(cmd, (struct sgmap64*) &srbcmd->sg);
|
||||
srbcmd->count = cpu_to_le32(cmd->request_bufflen);
|
||||
srbcmd->count = cpu_to_le32(scsi_bufflen(cmd));
|
||||
|
||||
memset(srbcmd->cdb, 0, sizeof(srbcmd->cdb));
|
||||
memcpy(srbcmd->cdb, cmd->cmnd, cmd->cmd_len);
|
||||
@@ -1069,7 +1076,7 @@ static int aac_scsi_32(struct fib * fib, struct scsi_cmnd * cmd)
|
||||
struct aac_srb * srbcmd = aac_scsi_common(fib, cmd);
|
||||
|
||||
aac_build_sg(cmd, (struct sgmap*)&srbcmd->sg);
|
||||
srbcmd->count = cpu_to_le32(cmd->request_bufflen);
|
||||
srbcmd->count = cpu_to_le32(scsi_bufflen(cmd));
|
||||
|
||||
memset(srbcmd->cdb, 0, sizeof(srbcmd->cdb));
|
||||
memcpy(srbcmd->cdb, cmd->cmnd, cmd->cmd_len);
|
||||
@@ -1172,6 +1179,7 @@ int aac_get_adapter_info(struct aac_dev* dev)
|
||||
}
|
||||
|
||||
if (!dev->in_reset) {
|
||||
char buffer[16];
|
||||
tmp = le32_to_cpu(dev->adapter_info.kernelrev);
|
||||
printk(KERN_INFO "%s%d: kernel %d.%d-%d[%d] %.*s\n",
|
||||
dev->name,
|
||||
@@ -1192,16 +1200,23 @@ int aac_get_adapter_info(struct aac_dev* dev)
|
||||
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]));
|
||||
buffer[0] = '\0';
|
||||
if (aac_show_serial_number(
|
||||
shost_to_class(dev->scsi_host_ptr), buffer))
|
||||
printk(KERN_INFO "%s%d: serial %s",
|
||||
dev->name, dev->id, buffer);
|
||||
if (dev->supplement_adapter_info.VpdInfo.Tsid[0]) {
|
||||
printk(KERN_INFO "%s%d: TSID %.*s\n",
|
||||
dev->name, dev->id,
|
||||
(int)sizeof(dev->supplement_adapter_info.VpdInfo.Tsid),
|
||||
dev->supplement_adapter_info.VpdInfo.Tsid);
|
||||
}
|
||||
if (!check_reset ||
|
||||
(dev->supplement_adapter_info.SupportedOptions2 &
|
||||
le32_to_cpu(AAC_OPTION_IGNORE_RESET))) {
|
||||
printk(KERN_INFO "%s%d: Reset Adapter Ignored\n",
|
||||
dev->name, dev->id);
|
||||
}
|
||||
}
|
||||
|
||||
dev->nondasd_support = 0;
|
||||
@@ -1332,7 +1347,7 @@ static void io_callback(void *context, struct fib * fibptr)
|
||||
if (!aac_valid_context(scsicmd, fibptr))
|
||||
return;
|
||||
|
||||
dev = (struct aac_dev *)scsicmd->device->host->hostdata;
|
||||
dev = fibptr->dev;
|
||||
cid = scmd_id(scsicmd);
|
||||
|
||||
if (nblank(dprintk(x))) {
|
||||
@@ -1371,16 +1386,9 @@ static void io_callback(void *context, struct fib * fibptr)
|
||||
}
|
||||
|
||||
BUG_ON(fibptr == NULL);
|
||||
|
||||
if(scsicmd->use_sg)
|
||||
pci_unmap_sg(dev->pdev,
|
||||
(struct scatterlist *)scsicmd->request_buffer,
|
||||
scsicmd->use_sg,
|
||||
scsicmd->sc_data_direction);
|
||||
else if(scsicmd->request_bufflen)
|
||||
pci_unmap_single(dev->pdev, scsicmd->SCp.dma_handle,
|
||||
scsicmd->request_bufflen,
|
||||
scsicmd->sc_data_direction);
|
||||
|
||||
scsi_dma_unmap(scsicmd);
|
||||
|
||||
readreply = (struct aac_read_reply *)fib_data(fibptr);
|
||||
if (le32_to_cpu(readreply->status) == ST_OK)
|
||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
|
||||
@@ -1498,6 +1506,7 @@ static int aac_write(struct scsi_cmnd * scsicmd)
|
||||
{
|
||||
u64 lba;
|
||||
u32 count;
|
||||
int fua;
|
||||
int status;
|
||||
struct aac_dev *dev;
|
||||
struct fib * cmd_fibcontext;
|
||||
@@ -1512,6 +1521,7 @@ static int aac_write(struct scsi_cmnd * scsicmd)
|
||||
count = scsicmd->cmnd[4];
|
||||
if (count == 0)
|
||||
count = 256;
|
||||
fua = 0;
|
||||
} else if (scsicmd->cmnd[0] == WRITE_16) { /* 16 byte command */
|
||||
dprintk((KERN_DEBUG "aachba: received a write(16) command on id %d.\n", scmd_id(scsicmd)));
|
||||
|
||||
@@ -1524,6 +1534,7 @@ static int aac_write(struct scsi_cmnd * scsicmd)
|
||||
(scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9];
|
||||
count = (scsicmd->cmnd[10] << 24) | (scsicmd->cmnd[11] << 16) |
|
||||
(scsicmd->cmnd[12] << 8) | scsicmd->cmnd[13];
|
||||
fua = scsicmd->cmnd[1] & 0x8;
|
||||
} else if (scsicmd->cmnd[0] == WRITE_12) { /* 12 byte command */
|
||||
dprintk((KERN_DEBUG "aachba: received a write(12) command on id %d.\n", scmd_id(scsicmd)));
|
||||
|
||||
@@ -1531,10 +1542,12 @@ static int aac_write(struct scsi_cmnd * scsicmd)
|
||||
| (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];
|
||||
count = (scsicmd->cmnd[6] << 24) | (scsicmd->cmnd[7] << 16)
|
||||
| (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9];
|
||||
fua = scsicmd->cmnd[1] & 0x8;
|
||||
} else {
|
||||
dprintk((KERN_DEBUG "aachba: received a write(10) command on id %d.\n", scmd_id(scsicmd)));
|
||||
lba = ((u64)scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];
|
||||
count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8];
|
||||
fua = scsicmd->cmnd[1] & 0x8;
|
||||
}
|
||||
dprintk((KERN_DEBUG "aac_write[cpu %d]: lba = %llu, t = %ld.\n",
|
||||
smp_processor_id(), (unsigned long long)lba, jiffies));
|
||||
@@ -1549,7 +1562,7 @@ static int aac_write(struct scsi_cmnd * scsicmd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
status = aac_adapter_write(cmd_fibcontext, scsicmd, lba, count);
|
||||
status = aac_adapter_write(cmd_fibcontext, scsicmd, lba, count, fua);
|
||||
|
||||
/*
|
||||
* Check that the command queued to the controller
|
||||
@@ -1592,7 +1605,7 @@ static void synchronize_callback(void *context, struct fib *fibptr)
|
||||
COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
|
||||
else {
|
||||
struct scsi_device *sdev = cmd->device;
|
||||
struct aac_dev *dev = (struct aac_dev *)sdev->host->hostdata;
|
||||
struct aac_dev *dev = fibptr->dev;
|
||||
u32 cid = sdev_id(sdev);
|
||||
printk(KERN_WARNING
|
||||
"synchronize_callback: synchronize failed, status = %d\n",
|
||||
@@ -1699,7 +1712,7 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd)
|
||||
|
||||
int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
||||
{
|
||||
u32 cid = 0;
|
||||
u32 cid;
|
||||
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;
|
||||
@@ -1711,15 +1724,15 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
||||
* Test does not apply to ID 16, the pseudo id for the controller
|
||||
* itself.
|
||||
*/
|
||||
if (scmd_id(scsicmd) != host->this_id) {
|
||||
if ((scmd_channel(scsicmd) == CONTAINER_CHANNEL)) {
|
||||
if((scmd_id(scsicmd) >= dev->maximum_num_containers) ||
|
||||
cid = scmd_id(scsicmd);
|
||||
if (cid != host->this_id) {
|
||||
if (scmd_channel(scsicmd) == CONTAINER_CHANNEL) {
|
||||
if((cid >= dev->maximum_num_containers) ||
|
||||
(scsicmd->device->lun != 0)) {
|
||||
scsicmd->result = DID_NO_CONNECT << 16;
|
||||
scsicmd->scsi_done(scsicmd);
|
||||
return 0;
|
||||
}
|
||||
cid = scmd_id(scsicmd);
|
||||
|
||||
/*
|
||||
* If the target container doesn't exist, it may have
|
||||
@@ -1782,7 +1795,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
||||
{
|
||||
struct inquiry_data inq_data;
|
||||
|
||||
dprintk((KERN_DEBUG "INQUIRY command, ID: %d.\n", scmd_id(scsicmd)));
|
||||
dprintk((KERN_DEBUG "INQUIRY command, ID: %d.\n", cid));
|
||||
memset(&inq_data, 0, sizeof (struct inquiry_data));
|
||||
|
||||
inq_data.inqd_ver = 2; /* claim compliance to SCSI-2 */
|
||||
@@ -1794,7 +1807,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
||||
* Set the Vendor, Product, and Revision Level
|
||||
* see: <vendor>.c i.e. aac.c
|
||||
*/
|
||||
if (scmd_id(scsicmd) == host->this_id) {
|
||||
if (cid == host->this_id) {
|
||||
setinqstr(dev, (void *) (inq_data.inqd_vid), ARRAY_SIZE(container_types));
|
||||
inq_data.inqd_pdt = INQD_PDT_PROC; /* Processor device */
|
||||
aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data));
|
||||
@@ -1886,15 +1899,29 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
||||
|
||||
case MODE_SENSE:
|
||||
{
|
||||
char mode_buf[4];
|
||||
char mode_buf[7];
|
||||
int mode_buf_length = 4;
|
||||
|
||||
dprintk((KERN_DEBUG "MODE SENSE command.\n"));
|
||||
mode_buf[0] = 3; /* Mode data length */
|
||||
mode_buf[1] = 0; /* Medium type - default */
|
||||
mode_buf[2] = 0; /* Device-specific param, bit 8: 0/1 = write enabled/protected */
|
||||
mode_buf[2] = 0; /* Device-specific param,
|
||||
bit 8: 0/1 = write enabled/protected
|
||||
bit 4: 0/1 = FUA enabled */
|
||||
if (dev->raw_io_interface)
|
||||
mode_buf[2] = 0x10;
|
||||
mode_buf[3] = 0; /* Block descriptor length */
|
||||
|
||||
aac_internal_transfer(scsicmd, mode_buf, 0, sizeof(mode_buf));
|
||||
if (((scsicmd->cmnd[2] & 0x3f) == 8) ||
|
||||
((scsicmd->cmnd[2] & 0x3f) == 0x3f)) {
|
||||
mode_buf[0] = 6;
|
||||
mode_buf[4] = 8;
|
||||
mode_buf[5] = 1;
|
||||
mode_buf[6] = 0x04; /* WCE */
|
||||
mode_buf_length = 7;
|
||||
if (mode_buf_length > scsicmd->cmnd[4])
|
||||
mode_buf_length = scsicmd->cmnd[4];
|
||||
}
|
||||
aac_internal_transfer(scsicmd, mode_buf, 0, mode_buf_length);
|
||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
|
||||
scsicmd->scsi_done(scsicmd);
|
||||
|
||||
@@ -1902,18 +1929,33 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
||||
}
|
||||
case MODE_SENSE_10:
|
||||
{
|
||||
char mode_buf[8];
|
||||
char mode_buf[11];
|
||||
int mode_buf_length = 8;
|
||||
|
||||
dprintk((KERN_DEBUG "MODE SENSE 10 byte command.\n"));
|
||||
mode_buf[0] = 0; /* Mode data length (MSB) */
|
||||
mode_buf[1] = 6; /* Mode data length (LSB) */
|
||||
mode_buf[2] = 0; /* Medium type - default */
|
||||
mode_buf[3] = 0; /* Device-specific param, bit 8: 0/1 = write enabled/protected */
|
||||
mode_buf[3] = 0; /* Device-specific param,
|
||||
bit 8: 0/1 = write enabled/protected
|
||||
bit 4: 0/1 = FUA enabled */
|
||||
if (dev->raw_io_interface)
|
||||
mode_buf[3] = 0x10;
|
||||
mode_buf[4] = 0; /* reserved */
|
||||
mode_buf[5] = 0; /* reserved */
|
||||
mode_buf[6] = 0; /* Block descriptor length (MSB) */
|
||||
mode_buf[7] = 0; /* Block descriptor length (LSB) */
|
||||
aac_internal_transfer(scsicmd, mode_buf, 0, sizeof(mode_buf));
|
||||
if (((scsicmd->cmnd[2] & 0x3f) == 8) ||
|
||||
((scsicmd->cmnd[2] & 0x3f) == 0x3f)) {
|
||||
mode_buf[1] = 9;
|
||||
mode_buf[8] = 8;
|
||||
mode_buf[9] = 1;
|
||||
mode_buf[10] = 0x04; /* WCE */
|
||||
mode_buf_length = 11;
|
||||
if (mode_buf_length > scsicmd->cmnd[8])
|
||||
mode_buf_length = scsicmd->cmnd[8];
|
||||
}
|
||||
aac_internal_transfer(scsicmd, mode_buf, 0, mode_buf_length);
|
||||
|
||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
|
||||
scsicmd->scsi_done(scsicmd);
|
||||
@@ -2136,28 +2178,21 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
|
||||
if (!aac_valid_context(scsicmd, fibptr))
|
||||
return;
|
||||
|
||||
dev = (struct aac_dev *)scsicmd->device->host->hostdata;
|
||||
|
||||
BUG_ON(fibptr == NULL);
|
||||
|
||||
dev = fibptr->dev;
|
||||
|
||||
srbreply = (struct aac_srb_reply *) fib_data(fibptr);
|
||||
|
||||
scsicmd->sense_buffer[0] = '\0'; /* Initialize sense valid flag to false */
|
||||
/*
|
||||
* Calculate resid for sg
|
||||
*/
|
||||
|
||||
scsicmd->resid = scsicmd->request_bufflen -
|
||||
le32_to_cpu(srbreply->data_xfer_length);
|
||||
|
||||
if(scsicmd->use_sg)
|
||||
pci_unmap_sg(dev->pdev,
|
||||
(struct scatterlist *)scsicmd->request_buffer,
|
||||
scsicmd->use_sg,
|
||||
scsicmd->sc_data_direction);
|
||||
else if(scsicmd->request_bufflen)
|
||||
pci_unmap_single(dev->pdev, scsicmd->SCp.dma_handle, scsicmd->request_bufflen,
|
||||
scsicmd->sc_data_direction);
|
||||
scsi_set_resid(scsicmd, scsi_bufflen(scsicmd)
|
||||
- le32_to_cpu(srbreply->data_xfer_length));
|
||||
|
||||
scsi_dma_unmap(scsicmd);
|
||||
|
||||
/*
|
||||
* First check the fib status
|
||||
@@ -2233,7 +2268,7 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
|
||||
break;
|
||||
|
||||
case SRB_STATUS_BUSY:
|
||||
scsicmd->result = DID_NO_CONNECT << 16 | COMMAND_COMPLETE << 8;
|
||||
scsicmd->result = DID_BUS_BUSY << 16 | COMMAND_COMPLETE << 8;
|
||||
break;
|
||||
|
||||
case SRB_STATUS_BUS_RESET:
|
||||
@@ -2343,34 +2378,33 @@ static unsigned long aac_build_sg(struct scsi_cmnd* scsicmd, struct sgmap* psg)
|
||||
{
|
||||
struct aac_dev *dev;
|
||||
unsigned long byte_count = 0;
|
||||
int nseg;
|
||||
|
||||
dev = (struct aac_dev *)scsicmd->device->host->hostdata;
|
||||
// Get rid of old data
|
||||
psg->count = 0;
|
||||
psg->sg[0].addr = 0;
|
||||
psg->sg[0].count = 0;
|
||||
if (scsicmd->use_sg) {
|
||||
psg->sg[0].count = 0;
|
||||
|
||||
nseg = scsi_dma_map(scsicmd);
|
||||
BUG_ON(nseg < 0);
|
||||
if (nseg) {
|
||||
struct scatterlist *sg;
|
||||
int i;
|
||||
int sg_count;
|
||||
sg = (struct scatterlist *) scsicmd->request_buffer;
|
||||
|
||||
sg_count = pci_map_sg(dev->pdev, sg, scsicmd->use_sg,
|
||||
scsicmd->sc_data_direction);
|
||||
psg->count = cpu_to_le32(sg_count);
|
||||
psg->count = cpu_to_le32(nseg);
|
||||
|
||||
for (i = 0; i < sg_count; i++) {
|
||||
scsi_for_each_sg(scsicmd, sg, nseg, i) {
|
||||
psg->sg[i].addr = cpu_to_le32(sg_dma_address(sg));
|
||||
psg->sg[i].count = cpu_to_le32(sg_dma_len(sg));
|
||||
byte_count += sg_dma_len(sg);
|
||||
sg++;
|
||||
}
|
||||
/* hba wants the size to be exact */
|
||||
if(byte_count > scsicmd->request_bufflen){
|
||||
u32 temp = le32_to_cpu(psg->sg[i-1].count) -
|
||||
(byte_count - scsicmd->request_bufflen);
|
||||
if (byte_count > scsi_bufflen(scsicmd)) {
|
||||
u32 temp = le32_to_cpu(psg->sg[i-1].count) -
|
||||
(byte_count - scsi_bufflen(scsicmd));
|
||||
psg->sg[i-1].count = cpu_to_le32(temp);
|
||||
byte_count = scsicmd->request_bufflen;
|
||||
byte_count = scsi_bufflen(scsicmd);
|
||||
}
|
||||
/* Check for command underflow */
|
||||
if(scsicmd->underflow && (byte_count < scsicmd->underflow)){
|
||||
@@ -2378,18 +2412,6 @@ static unsigned long aac_build_sg(struct scsi_cmnd* scsicmd, struct sgmap* psg)
|
||||
byte_count, scsicmd->underflow);
|
||||
}
|
||||
}
|
||||
else if(scsicmd->request_bufflen) {
|
||||
u32 addr;
|
||||
scsicmd->SCp.dma_handle = pci_map_single(dev->pdev,
|
||||
scsicmd->request_buffer,
|
||||
scsicmd->request_bufflen,
|
||||
scsicmd->sc_data_direction);
|
||||
addr = scsicmd->SCp.dma_handle;
|
||||
psg->count = cpu_to_le32(1);
|
||||
psg->sg[0].addr = cpu_to_le32(addr);
|
||||
psg->sg[0].count = cpu_to_le32(scsicmd->request_bufflen);
|
||||
byte_count = scsicmd->request_bufflen;
|
||||
}
|
||||
return byte_count;
|
||||
}
|
||||
|
||||
@@ -2399,6 +2421,7 @@ static unsigned long aac_build_sg64(struct scsi_cmnd* scsicmd, struct sgmap64* p
|
||||
struct aac_dev *dev;
|
||||
unsigned long byte_count = 0;
|
||||
u64 addr;
|
||||
int nseg;
|
||||
|
||||
dev = (struct aac_dev *)scsicmd->device->host->hostdata;
|
||||
// Get rid of old data
|
||||
@@ -2406,31 +2429,28 @@ static unsigned long aac_build_sg64(struct scsi_cmnd* scsicmd, struct sgmap64* p
|
||||
psg->sg[0].addr[0] = 0;
|
||||
psg->sg[0].addr[1] = 0;
|
||||
psg->sg[0].count = 0;
|
||||
if (scsicmd->use_sg) {
|
||||
|
||||
nseg = scsi_dma_map(scsicmd);
|
||||
BUG_ON(nseg < 0);
|
||||
if (nseg) {
|
||||
struct scatterlist *sg;
|
||||
int i;
|
||||
int sg_count;
|
||||
sg = (struct scatterlist *) scsicmd->request_buffer;
|
||||
|
||||
sg_count = pci_map_sg(dev->pdev, sg, scsicmd->use_sg,
|
||||
scsicmd->sc_data_direction);
|
||||
|
||||
for (i = 0; i < sg_count; i++) {
|
||||
scsi_for_each_sg(scsicmd, sg, nseg, i) {
|
||||
int count = sg_dma_len(sg);
|
||||
addr = sg_dma_address(sg);
|
||||
psg->sg[i].addr[0] = cpu_to_le32(addr & 0xffffffff);
|
||||
psg->sg[i].addr[1] = cpu_to_le32(addr>>32);
|
||||
psg->sg[i].count = cpu_to_le32(count);
|
||||
byte_count += count;
|
||||
sg++;
|
||||
}
|
||||
psg->count = cpu_to_le32(sg_count);
|
||||
psg->count = cpu_to_le32(nseg);
|
||||
/* hba wants the size to be exact */
|
||||
if(byte_count > scsicmd->request_bufflen){
|
||||
u32 temp = le32_to_cpu(psg->sg[i-1].count) -
|
||||
(byte_count - scsicmd->request_bufflen);
|
||||
if (byte_count > scsi_bufflen(scsicmd)) {
|
||||
u32 temp = le32_to_cpu(psg->sg[i-1].count) -
|
||||
(byte_count - scsi_bufflen(scsicmd));
|
||||
psg->sg[i-1].count = cpu_to_le32(temp);
|
||||
byte_count = scsicmd->request_bufflen;
|
||||
byte_count = scsi_bufflen(scsicmd);
|
||||
}
|
||||
/* Check for command underflow */
|
||||
if(scsicmd->underflow && (byte_count < scsicmd->underflow)){
|
||||
@@ -2438,26 +2458,13 @@ static unsigned long aac_build_sg64(struct scsi_cmnd* scsicmd, struct sgmap64* p
|
||||
byte_count, scsicmd->underflow);
|
||||
}
|
||||
}
|
||||
else if(scsicmd->request_bufflen) {
|
||||
scsicmd->SCp.dma_handle = pci_map_single(dev->pdev,
|
||||
scsicmd->request_buffer,
|
||||
scsicmd->request_bufflen,
|
||||
scsicmd->sc_data_direction);
|
||||
addr = scsicmd->SCp.dma_handle;
|
||||
psg->count = cpu_to_le32(1);
|
||||
psg->sg[0].addr[0] = cpu_to_le32(addr & 0xffffffff);
|
||||
psg->sg[0].addr[1] = cpu_to_le32(addr >> 32);
|
||||
psg->sg[0].count = cpu_to_le32(scsicmd->request_bufflen);
|
||||
byte_count = scsicmd->request_bufflen;
|
||||
}
|
||||
return byte_count;
|
||||
}
|
||||
|
||||
static unsigned long aac_build_sgraw(struct scsi_cmnd* scsicmd, struct sgmapraw* psg)
|
||||
{
|
||||
struct Scsi_Host *host = scsicmd->device->host;
|
||||
struct aac_dev *dev = (struct aac_dev *)host->hostdata;
|
||||
unsigned long byte_count = 0;
|
||||
int nseg;
|
||||
|
||||
// Get rid of old data
|
||||
psg->count = 0;
|
||||
@@ -2467,16 +2474,14 @@ static unsigned long aac_build_sgraw(struct scsi_cmnd* scsicmd, struct sgmapraw*
|
||||
psg->sg[0].addr[1] = 0;
|
||||
psg->sg[0].count = 0;
|
||||
psg->sg[0].flags = 0;
|
||||
if (scsicmd->use_sg) {
|
||||
|
||||
nseg = scsi_dma_map(scsicmd);
|
||||
BUG_ON(nseg < 0);
|
||||
if (nseg) {
|
||||
struct scatterlist *sg;
|
||||
int i;
|
||||
int sg_count;
|
||||
sg = (struct scatterlist *) scsicmd->request_buffer;
|
||||
|
||||
sg_count = pci_map_sg(dev->pdev, sg, scsicmd->use_sg,
|
||||
scsicmd->sc_data_direction);
|
||||
|
||||
for (i = 0; i < sg_count; i++) {
|
||||
scsi_for_each_sg(scsicmd, sg, nseg, i) {
|
||||
int count = sg_dma_len(sg);
|
||||
u64 addr = sg_dma_address(sg);
|
||||
psg->sg[i].next = 0;
|
||||
@@ -2486,15 +2491,14 @@ static unsigned long aac_build_sgraw(struct scsi_cmnd* scsicmd, struct sgmapraw*
|
||||
psg->sg[i].count = cpu_to_le32(count);
|
||||
psg->sg[i].flags = 0;
|
||||
byte_count += count;
|
||||
sg++;
|
||||
}
|
||||
psg->count = cpu_to_le32(sg_count);
|
||||
psg->count = cpu_to_le32(nseg);
|
||||
/* hba wants the size to be exact */
|
||||
if(byte_count > scsicmd->request_bufflen){
|
||||
u32 temp = le32_to_cpu(psg->sg[i-1].count) -
|
||||
(byte_count - scsicmd->request_bufflen);
|
||||
if (byte_count > scsi_bufflen(scsicmd)) {
|
||||
u32 temp = le32_to_cpu(psg->sg[i-1].count) -
|
||||
(byte_count - scsi_bufflen(scsicmd));
|
||||
psg->sg[i-1].count = cpu_to_le32(temp);
|
||||
byte_count = scsicmd->request_bufflen;
|
||||
byte_count = scsi_bufflen(scsicmd);
|
||||
}
|
||||
/* Check for command underflow */
|
||||
if(scsicmd->underflow && (byte_count < scsicmd->underflow)){
|
||||
@@ -2502,24 +2506,6 @@ static unsigned long aac_build_sgraw(struct scsi_cmnd* scsicmd, struct sgmapraw*
|
||||
byte_count, scsicmd->underflow);
|
||||
}
|
||||
}
|
||||
else if(scsicmd->request_bufflen) {
|
||||
int count;
|
||||
u64 addr;
|
||||
scsicmd->SCp.dma_handle = pci_map_single(dev->pdev,
|
||||
scsicmd->request_buffer,
|
||||
scsicmd->request_bufflen,
|
||||
scsicmd->sc_data_direction);
|
||||
addr = scsicmd->SCp.dma_handle;
|
||||
count = scsicmd->request_bufflen;
|
||||
psg->count = cpu_to_le32(1);
|
||||
psg->sg[0].next = 0;
|
||||
psg->sg[0].prev = 0;
|
||||
psg->sg[0].addr[1] = cpu_to_le32((u32)(addr>>32));
|
||||
psg->sg[0].addr[0] = cpu_to_le32((u32)(addr & 0xffffffff));
|
||||
psg->sg[0].count = cpu_to_le32(count);
|
||||
psg->sg[0].flags = 0;
|
||||
byte_count = scsicmd->request_bufflen;
|
||||
}
|
||||
return byte_count;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef AAC_DRIVER_BUILD
|
||||
# define AAC_DRIVER_BUILD 2437
|
||||
# define AAC_DRIVER_BRANCH "-mh4"
|
||||
# define AAC_DRIVER_BUILD 2447
|
||||
# define AAC_DRIVER_BRANCH "-ms"
|
||||
#endif
|
||||
#define MAXIMUM_NUM_CONTAINERS 32
|
||||
|
||||
@@ -464,12 +464,12 @@ struct adapter_ops
|
||||
int (*adapter_restart)(struct aac_dev *dev, int bled);
|
||||
/* Transport operations */
|
||||
int (*adapter_ioremap)(struct aac_dev * dev, u32 size);
|
||||
irqreturn_t (*adapter_intr)(int irq, void *dev_id);
|
||||
irq_handler_t adapter_intr;
|
||||
/* Packet operations */
|
||||
int (*adapter_deliver)(struct fib * fib);
|
||||
int (*adapter_bounds)(struct aac_dev * dev, struct scsi_cmnd * cmd, u64 lba);
|
||||
int (*adapter_read)(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count);
|
||||
int (*adapter_write)(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count);
|
||||
int (*adapter_write)(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count, int fua);
|
||||
int (*adapter_scsi)(struct fib * fib, struct scsi_cmnd * cmd);
|
||||
/* Administrative operations */
|
||||
int (*adapter_comm)(struct aac_dev * dev, int comm);
|
||||
@@ -860,10 +860,12 @@ struct aac_supplement_adapter_info
|
||||
__le32 FlashFirmwareBootBuild;
|
||||
u8 MfgPcbaSerialNo[12];
|
||||
u8 MfgWWNName[8];
|
||||
__le32 MoreFeatureBits;
|
||||
__le32 SupportedOptions2;
|
||||
__le32 ReservedGrowth[1];
|
||||
};
|
||||
#define AAC_FEATURE_FALCON 0x00000010
|
||||
#define AAC_OPTION_MU_RESET 0x00000001
|
||||
#define AAC_OPTION_IGNORE_RESET 0x00000002
|
||||
#define AAC_SIS_VERSION_V3 3
|
||||
#define AAC_SIS_SLOT_UNKNOWN 0xFF
|
||||
|
||||
@@ -1054,8 +1056,8 @@ struct aac_dev
|
||||
#define aac_adapter_read(fib,cmd,lba,count) \
|
||||
((fib)->dev)->a_ops.adapter_read(fib,cmd,lba,count)
|
||||
|
||||
#define aac_adapter_write(fib,cmd,lba,count) \
|
||||
((fib)->dev)->a_ops.adapter_write(fib,cmd,lba,count)
|
||||
#define aac_adapter_write(fib,cmd,lba,count,fua) \
|
||||
((fib)->dev)->a_ops.adapter_write(fib,cmd,lba,count,fua)
|
||||
|
||||
#define aac_adapter_scsi(fib,cmd) \
|
||||
((fib)->dev)->a_ops.adapter_scsi(fib,cmd)
|
||||
@@ -1213,6 +1215,9 @@ struct aac_write64
|
||||
__le32 block;
|
||||
__le16 pad;
|
||||
__le16 flags;
|
||||
#define IO_TYPE_WRITE 0x00000000
|
||||
#define IO_TYPE_READ 0x00000001
|
||||
#define IO_SUREWRITE 0x00000008
|
||||
struct sgmap64 sg; // Must be last in struct because it is variable
|
||||
};
|
||||
struct aac_write_reply
|
||||
@@ -1257,6 +1262,19 @@ struct aac_synchronize_reply {
|
||||
u8 data[16];
|
||||
};
|
||||
|
||||
#define CT_PAUSE_IO 65
|
||||
#define CT_RELEASE_IO 66
|
||||
struct aac_pause {
|
||||
__le32 command; /* VM_ContainerConfig */
|
||||
__le32 type; /* CT_PAUSE_IO */
|
||||
__le32 timeout; /* 10ms ticks */
|
||||
__le32 min;
|
||||
__le32 noRescan;
|
||||
__le32 parm3;
|
||||
__le32 parm4;
|
||||
__le32 count; /* sizeof(((struct aac_pause_reply *)NULL)->data) */
|
||||
};
|
||||
|
||||
struct aac_srb
|
||||
{
|
||||
__le32 function;
|
||||
@@ -1804,6 +1822,10 @@ 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);
|
||||
#ifndef shost_to_class
|
||||
#define shost_to_class(shost) &shost->shost_classdev
|
||||
#endif
|
||||
ssize_t aac_show_serial_number(struct class_device *class_dev, char *buf);
|
||||
int aac_do_ioctl(struct aac_dev * dev, int cmd, void __user *arg);
|
||||
int aac_rx_init(struct aac_dev *dev);
|
||||
int aac_rkt_init(struct aac_dev *dev);
|
||||
@@ -1813,6 +1835,7 @@ int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_fib * hw
|
||||
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_reset_adapter(struct aac_dev * dev, int forced);
|
||||
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);
|
||||
@@ -1832,3 +1855,6 @@ extern int aif_timeout;
|
||||
extern int expose_physicals;
|
||||
extern int aac_reset_devices;
|
||||
extern int aac_commit;
|
||||
extern int update_interval;
|
||||
extern int check_interval;
|
||||
extern int check_reset;
|
||||
|
||||
+193
-17
@@ -1021,7 +1021,7 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
|
||||
|
||||
}
|
||||
|
||||
static int _aac_reset_adapter(struct aac_dev *aac)
|
||||
static int _aac_reset_adapter(struct aac_dev *aac, int forced)
|
||||
{
|
||||
int index, quirks;
|
||||
int retval;
|
||||
@@ -1029,25 +1029,32 @@ static int _aac_reset_adapter(struct aac_dev *aac)
|
||||
struct scsi_device *dev;
|
||||
struct scsi_cmnd *command;
|
||||
struct scsi_cmnd *command_list;
|
||||
int jafo = 0;
|
||||
|
||||
/*
|
||||
* Assumptions:
|
||||
* - host is locked.
|
||||
* - host is locked, unless called by the aacraid thread.
|
||||
* (a matter of convenience, due to legacy issues surrounding
|
||||
* eh_host_adapter_reset).
|
||||
* - in_reset is asserted, so no new i/o is getting to the
|
||||
* card.
|
||||
* - The card is dead.
|
||||
* - The card is dead, or will be very shortly ;-/ so no new
|
||||
* commands are completing in the interrupt service.
|
||||
*/
|
||||
host = aac->scsi_host_ptr;
|
||||
scsi_block_requests(host);
|
||||
aac_adapter_disable_int(aac);
|
||||
spin_unlock_irq(host->host_lock);
|
||||
kthread_stop(aac->thread);
|
||||
if (aac->thread->pid != current->pid) {
|
||||
spin_unlock_irq(host->host_lock);
|
||||
kthread_stop(aac->thread);
|
||||
jafo = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* If a positive health, means in a known DEAD PANIC
|
||||
* state and the adapter could be reset to `try again'.
|
||||
*/
|
||||
retval = aac_adapter_restart(aac, aac_adapter_check_health(aac));
|
||||
retval = aac_adapter_restart(aac, forced ? 0 : aac_adapter_check_health(aac));
|
||||
|
||||
if (retval)
|
||||
goto out;
|
||||
@@ -1104,10 +1111,12 @@ static int _aac_reset_adapter(struct aac_dev *aac)
|
||||
if (aac_get_driver_ident(index)->quirks & AAC_QUIRK_31BIT)
|
||||
if ((retval = pci_set_dma_mask(aac->pdev, DMA_32BIT_MASK)))
|
||||
goto out;
|
||||
aac->thread = kthread_run(aac_command_thread, aac, aac->name);
|
||||
if (IS_ERR(aac->thread)) {
|
||||
retval = PTR_ERR(aac->thread);
|
||||
goto out;
|
||||
if (jafo) {
|
||||
aac->thread = kthread_run(aac_command_thread, aac, aac->name);
|
||||
if (IS_ERR(aac->thread)) {
|
||||
retval = PTR_ERR(aac->thread);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
(void)aac_get_adapter_info(aac);
|
||||
quirks = aac_get_driver_ident(index)->quirks;
|
||||
@@ -1150,7 +1159,98 @@ static int _aac_reset_adapter(struct aac_dev *aac)
|
||||
out:
|
||||
aac->in_reset = 0;
|
||||
scsi_unblock_requests(host);
|
||||
spin_lock_irq(host->host_lock);
|
||||
if (jafo) {
|
||||
spin_lock_irq(host->host_lock);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
int aac_reset_adapter(struct aac_dev * aac, int forced)
|
||||
{
|
||||
unsigned long flagv = 0;
|
||||
int retval;
|
||||
struct Scsi_Host * host;
|
||||
|
||||
if (spin_trylock_irqsave(&aac->fib_lock, flagv) == 0)
|
||||
return -EBUSY;
|
||||
|
||||
if (aac->in_reset) {
|
||||
spin_unlock_irqrestore(&aac->fib_lock, flagv);
|
||||
return -EBUSY;
|
||||
}
|
||||
aac->in_reset = 1;
|
||||
spin_unlock_irqrestore(&aac->fib_lock, flagv);
|
||||
|
||||
/*
|
||||
* Wait for all commands to complete to this specific
|
||||
* target (block maximum 60 seconds). Although not necessary,
|
||||
* it does make us a good storage citizen.
|
||||
*/
|
||||
host = aac->scsi_host_ptr;
|
||||
scsi_block_requests(host);
|
||||
if (forced < 2) for (retval = 60; retval; --retval) {
|
||||
struct scsi_device * dev;
|
||||
struct scsi_cmnd * command;
|
||||
int active = 0;
|
||||
|
||||
__shost_for_each_device(dev, host) {
|
||||
spin_lock_irqsave(&dev->list_lock, flagv);
|
||||
list_for_each_entry(command, &dev->cmd_list, list) {
|
||||
if (command->SCp.phase == AAC_OWNER_FIRMWARE) {
|
||||
active++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&dev->list_lock, flagv);
|
||||
if (active)
|
||||
break;
|
||||
|
||||
}
|
||||
/*
|
||||
* We can exit If all the commands are complete
|
||||
*/
|
||||
if (active == 0)
|
||||
break;
|
||||
ssleep(1);
|
||||
}
|
||||
|
||||
/* Quiesce build, flush cache, write through mode */
|
||||
aac_send_shutdown(aac);
|
||||
spin_lock_irqsave(host->host_lock, flagv);
|
||||
retval = _aac_reset_adapter(aac, forced);
|
||||
spin_unlock_irqrestore(host->host_lock, flagv);
|
||||
|
||||
if (retval == -ENODEV) {
|
||||
/* Unwind aac_send_shutdown() IOP_RESET unsupported/disabled */
|
||||
struct fib * fibctx = aac_fib_alloc(aac);
|
||||
if (fibctx) {
|
||||
struct aac_pause *cmd;
|
||||
int status;
|
||||
|
||||
aac_fib_init(fibctx);
|
||||
|
||||
cmd = (struct aac_pause *) fib_data(fibctx);
|
||||
|
||||
cmd->command = cpu_to_le32(VM_ContainerConfig);
|
||||
cmd->type = cpu_to_le32(CT_PAUSE_IO);
|
||||
cmd->timeout = cpu_to_le32(1);
|
||||
cmd->min = cpu_to_le32(1);
|
||||
cmd->noRescan = cpu_to_le32(1);
|
||||
cmd->count = cpu_to_le32(0);
|
||||
|
||||
status = aac_fib_send(ContainerCommand,
|
||||
fibctx,
|
||||
sizeof(struct aac_pause),
|
||||
FsaNormal,
|
||||
-2 /* Timeout silently */, 1,
|
||||
NULL, NULL);
|
||||
|
||||
if (status >= 0)
|
||||
aac_fib_complete(fibctx);
|
||||
aac_fib_free(fibctx);
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
@@ -1270,10 +1370,15 @@ int aac_check_health(struct aac_dev * aac)
|
||||
|
||||
printk(KERN_ERR "%s: Host adapter BLINK LED 0x%x\n", aac->name, BlinkLED);
|
||||
|
||||
if (!check_reset || (aac->supplement_adapter_info.SupportedOptions2 &
|
||||
le32_to_cpu(AAC_OPTION_IGNORE_RESET)))
|
||||
goto out;
|
||||
host = aac->scsi_host_ptr;
|
||||
spin_lock_irqsave(host->host_lock, flagv);
|
||||
BlinkLED = _aac_reset_adapter(aac);
|
||||
spin_unlock_irqrestore(host->host_lock, flagv);
|
||||
if (aac->thread->pid != current->pid)
|
||||
spin_lock_irqsave(host->host_lock, flagv);
|
||||
BlinkLED = _aac_reset_adapter(aac, 0);
|
||||
if (aac->thread->pid != current->pid)
|
||||
spin_unlock_irqrestore(host->host_lock, flagv);
|
||||
return BlinkLED;
|
||||
|
||||
out:
|
||||
@@ -1300,6 +1405,9 @@ int aac_command_thread(void *data)
|
||||
struct aac_fib_context *fibctx;
|
||||
unsigned long flags;
|
||||
DECLARE_WAITQUEUE(wait, current);
|
||||
unsigned long next_jiffies = jiffies + HZ;
|
||||
unsigned long next_check_jiffies = next_jiffies;
|
||||
long difference = HZ;
|
||||
|
||||
/*
|
||||
* We can only have one thread per adapter for AIF's.
|
||||
@@ -1368,7 +1476,7 @@ int aac_command_thread(void *data)
|
||||
cpu_to_le32(AifCmdJobProgress))) {
|
||||
aac_handle_aif(dev, fib);
|
||||
}
|
||||
|
||||
|
||||
time_now = jiffies/HZ;
|
||||
|
||||
/*
|
||||
@@ -1507,11 +1615,79 @@ int aac_command_thread(void *data)
|
||||
* There are no more AIF's
|
||||
*/
|
||||
spin_unlock_irqrestore(dev->queues->queue[HostNormCmdQueue].lock, flags);
|
||||
schedule();
|
||||
|
||||
/*
|
||||
* Background activity
|
||||
*/
|
||||
if ((time_before(next_check_jiffies,next_jiffies))
|
||||
&& ((difference = next_check_jiffies - jiffies) <= 0)) {
|
||||
next_check_jiffies = next_jiffies;
|
||||
if (aac_check_health(dev) == 0) {
|
||||
difference = ((long)(unsigned)check_interval)
|
||||
* HZ;
|
||||
next_check_jiffies = jiffies + difference;
|
||||
} else if (!dev->queues)
|
||||
break;
|
||||
}
|
||||
if (!time_before(next_check_jiffies,next_jiffies)
|
||||
&& ((difference = next_jiffies - jiffies) <= 0)) {
|
||||
struct timeval now;
|
||||
int ret;
|
||||
|
||||
/* Don't even try to talk to adapter if its sick */
|
||||
ret = aac_check_health(dev);
|
||||
if (!ret && !dev->queues)
|
||||
break;
|
||||
next_check_jiffies = jiffies
|
||||
+ ((long)(unsigned)check_interval)
|
||||
* HZ;
|
||||
do_gettimeofday(&now);
|
||||
|
||||
/* Synchronize our watches */
|
||||
if (((1000000 - (1000000 / HZ)) > now.tv_usec)
|
||||
&& (now.tv_usec > (1000000 / HZ)))
|
||||
difference = (((1000000 - now.tv_usec) * HZ)
|
||||
+ 500000) / 1000000;
|
||||
else if (ret == 0) {
|
||||
struct fib *fibptr;
|
||||
|
||||
if ((fibptr = aac_fib_alloc(dev))) {
|
||||
u32 * info;
|
||||
|
||||
aac_fib_init(fibptr);
|
||||
|
||||
info = (u32 *) fib_data(fibptr);
|
||||
if (now.tv_usec > 500000)
|
||||
++now.tv_sec;
|
||||
|
||||
*info = cpu_to_le32(now.tv_sec);
|
||||
|
||||
(void)aac_fib_send(SendHostTime,
|
||||
fibptr,
|
||||
sizeof(*info),
|
||||
FsaNormal,
|
||||
1, 1,
|
||||
NULL,
|
||||
NULL);
|
||||
aac_fib_complete(fibptr);
|
||||
aac_fib_free(fibptr);
|
||||
}
|
||||
difference = (long)(unsigned)update_interval*HZ;
|
||||
} else {
|
||||
/* retry shortly */
|
||||
difference = 10 * HZ;
|
||||
}
|
||||
next_jiffies = jiffies + difference;
|
||||
if (time_before(next_check_jiffies,next_jiffies))
|
||||
difference = next_check_jiffies - jiffies;
|
||||
}
|
||||
if (difference <= 0)
|
||||
difference = 1;
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
schedule_timeout(difference);
|
||||
|
||||
if (kthread_should_stop())
|
||||
break;
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
}
|
||||
if (dev->queues)
|
||||
remove_wait_queue(&dev->queues->queue[HostNormCmdQueue].cmdready, &wait);
|
||||
|
||||
@@ -39,10 +39,8 @@
|
||||
#include <linux/pci.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/smp_lock.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <asm/semaphore.h>
|
||||
|
||||
@@ -223,12 +221,12 @@ static struct aac_driver_ident aac_drivers[] = {
|
||||
{ aac_rx_init, "percraid", "DELL ", "PERC 320/DC ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Perc 320/DC*/
|
||||
{ aac_sa_init, "aacraid", "ADAPTEC ", "Adaptec 5400S ", 4, AAC_QUIRK_34SG }, /* Adaptec 5400S (Mustang)*/
|
||||
{ aac_sa_init, "aacraid", "ADAPTEC ", "AAC-364 ", 4, AAC_QUIRK_34SG }, /* Adaptec 5400S (Mustang)*/
|
||||
{ aac_sa_init, "percraid", "DELL ", "PERCRAID ", 4, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Dell PERC2/QC */
|
||||
{ aac_sa_init, "percraid", "DELL ", "PERCRAID ", 4, AAC_QUIRK_34SG }, /* Dell PERC2/QC */
|
||||
{ aac_sa_init, "hpnraid", "HP ", "NetRAID ", 4, AAC_QUIRK_34SG }, /* HP NetRAID-4M */
|
||||
|
||||
{ aac_rx_init, "aacraid", "DELL ", "RAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Dell Catchall */
|
||||
{ aac_rx_init, "aacraid", "Legend ", "RAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Legend Catchall */
|
||||
{ aac_rx_init, "aacraid", "ADAPTEC ", "RAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Adaptec Catch All */
|
||||
{ aac_rx_init, "aacraid", "ADAPTEC ", "RAID ", 2 }, /* Adaptec Catch All */
|
||||
{ aac_rkt_init, "aacraid", "ADAPTEC ", "RAID ", 2 }, /* Adaptec Rocket Catch All */
|
||||
{ aac_nark_init, "aacraid", "ADAPTEC ", "RAID ", 2 } /* Adaptec NEMER/ARK Catch All */
|
||||
};
|
||||
@@ -403,10 +401,6 @@ static int aac_biosparm(struct scsi_device *sdev, struct block_device *bdev,
|
||||
|
||||
static int aac_slave_configure(struct scsi_device *sdev)
|
||||
{
|
||||
if (sdev_channel(sdev) == CONTAINER_CHANNEL) {
|
||||
sdev->skip_ms_page_8 = 1;
|
||||
sdev->skip_ms_page_3f = 1;
|
||||
}
|
||||
if ((sdev->type == TYPE_DISK) &&
|
||||
(sdev_channel(sdev) != CONTAINER_CHANNEL)) {
|
||||
if (expose_physicals == 0)
|
||||
@@ -450,6 +444,43 @@ static int aac_slave_configure(struct scsi_device *sdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* aac_change_queue_depth - alter queue depths
|
||||
* @sdev: SCSI device we are considering
|
||||
* @depth: desired queue depth
|
||||
*
|
||||
* Alters queue depths for target device based on the host adapter's
|
||||
* total capacity and the queue depth supported by the target device.
|
||||
*/
|
||||
|
||||
static int aac_change_queue_depth(struct scsi_device *sdev, int depth)
|
||||
{
|
||||
if (sdev->tagged_supported && (sdev->type == TYPE_DISK) &&
|
||||
(sdev_channel(sdev) == CONTAINER_CHANNEL)) {
|
||||
struct scsi_device * dev;
|
||||
struct Scsi_Host *host = sdev->host;
|
||||
unsigned num = 0;
|
||||
|
||||
__shost_for_each_device(dev, host) {
|
||||
if (dev->tagged_supported && (dev->type == TYPE_DISK) &&
|
||||
(sdev_channel(dev) == CONTAINER_CHANNEL))
|
||||
++num;
|
||||
++num;
|
||||
}
|
||||
if (num >= host->can_queue)
|
||||
num = host->can_queue - 1;
|
||||
if (depth > (host->can_queue - num))
|
||||
depth = host->can_queue - num;
|
||||
if (depth > 256)
|
||||
depth = 256;
|
||||
else if (depth < 2)
|
||||
depth = 2;
|
||||
scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, depth);
|
||||
} else
|
||||
scsi_adjust_queue_depth(sdev, 0, 1);
|
||||
return sdev->queue_depth;
|
||||
}
|
||||
|
||||
static int aac_ioctl(struct scsi_device *sdev, int cmd, void __user * arg)
|
||||
{
|
||||
struct aac_dev *dev = (struct aac_dev *)sdev->host->hostdata;
|
||||
@@ -548,6 +579,14 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
|
||||
ssleep(1);
|
||||
}
|
||||
printk(KERN_ERR "%s: SCSI bus appears hung\n", AAC_DRIVERNAME);
|
||||
/*
|
||||
* This adapter needs a blind reset, only do so for Adapters that
|
||||
* support a register, instead of a commanded, reset.
|
||||
*/
|
||||
if ((aac->supplement_adapter_info.SupportedOptions2 &
|
||||
le32_to_cpu(AAC_OPTION_MU_RESET|AAC_OPTION_IGNORE_RESET)) ==
|
||||
le32_to_cpu(AAC_OPTION_MU_RESET))
|
||||
aac_reset_adapter(aac, 2); /* Bypass wait for command quiesce */
|
||||
return SUCCESS; /* Cause an immediate retry of the command with a ten second delay after successful tur */
|
||||
}
|
||||
|
||||
@@ -731,15 +770,21 @@ static ssize_t aac_show_bios_version(struct class_device *class_dev,
|
||||
return len;
|
||||
}
|
||||
|
||||
static ssize_t aac_show_serial_number(struct class_device *class_dev,
|
||||
char *buf)
|
||||
ssize_t aac_show_serial_number(struct class_device *class_dev, char *buf)
|
||||
{
|
||||
struct aac_dev *dev = (struct aac_dev*)class_to_shost(class_dev)->hostdata;
|
||||
int len = 0;
|
||||
|
||||
if (le32_to_cpu(dev->adapter_info.serial[0]) != 0xBAD0)
|
||||
len = snprintf(buf, PAGE_SIZE, "%x\n",
|
||||
len = snprintf(buf, PAGE_SIZE, "%06X\n",
|
||||
le32_to_cpu(dev->adapter_info.serial[0]));
|
||||
if (len &&
|
||||
!memcmp(&dev->supplement_adapter_info.MfgPcbaSerialNo[
|
||||
sizeof(dev->supplement_adapter_info.MfgPcbaSerialNo)+2-len],
|
||||
buf, len))
|
||||
len = snprintf(buf, PAGE_SIZE, "%.*s\n",
|
||||
(int)sizeof(dev->supplement_adapter_info.MfgPcbaSerialNo),
|
||||
dev->supplement_adapter_info.MfgPcbaSerialNo);
|
||||
return len;
|
||||
}
|
||||
|
||||
@@ -755,6 +800,31 @@ static ssize_t aac_show_max_id(struct class_device *class_dev, char *buf)
|
||||
class_to_shost(class_dev)->max_id);
|
||||
}
|
||||
|
||||
static ssize_t aac_store_reset_adapter(struct class_device *class_dev,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int retval = -EACCES;
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
return retval;
|
||||
retval = aac_reset_adapter((struct aac_dev*)class_to_shost(class_dev)->hostdata, buf[0] == '!');
|
||||
if (retval >= 0)
|
||||
retval = count;
|
||||
return retval;
|
||||
}
|
||||
|
||||
static ssize_t aac_show_reset_adapter(struct class_device *class_dev,
|
||||
char *buf)
|
||||
{
|
||||
struct aac_dev *dev = (struct aac_dev*)class_to_shost(class_dev)->hostdata;
|
||||
int len, tmp;
|
||||
|
||||
tmp = aac_adapter_check_health(dev);
|
||||
if ((tmp == 0) && dev->in_reset)
|
||||
tmp = -EBUSY;
|
||||
len = snprintf(buf, PAGE_SIZE, "0x%x", tmp);
|
||||
return len;
|
||||
}
|
||||
|
||||
static struct class_device_attribute aac_model = {
|
||||
.attr = {
|
||||
@@ -812,6 +882,14 @@ static struct class_device_attribute aac_max_id = {
|
||||
},
|
||||
.show = aac_show_max_id,
|
||||
};
|
||||
static struct class_device_attribute aac_reset = {
|
||||
.attr = {
|
||||
.name = "reset_host",
|
||||
.mode = S_IWUSR|S_IRUGO,
|
||||
},
|
||||
.store = aac_store_reset_adapter,
|
||||
.show = aac_show_reset_adapter,
|
||||
};
|
||||
|
||||
static struct class_device_attribute *aac_attrs[] = {
|
||||
&aac_model,
|
||||
@@ -822,6 +900,7 @@ static struct class_device_attribute *aac_attrs[] = {
|
||||
&aac_serial_number,
|
||||
&aac_max_channel,
|
||||
&aac_max_id,
|
||||
&aac_reset,
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -848,6 +927,7 @@ static struct scsi_host_template aac_driver_template = {
|
||||
.bios_param = aac_biosparm,
|
||||
.shost_attrs = aac_attrs,
|
||||
.slave_configure = aac_slave_configure,
|
||||
.change_queue_depth = aac_change_queue_depth,
|
||||
.eh_abort_handler = aac_eh_abort,
|
||||
.eh_host_reset_handler = aac_eh_reset,
|
||||
.can_queue = AAC_NUM_IO_FIB,
|
||||
@@ -1086,7 +1166,7 @@ static int __init aac_init(void)
|
||||
{
|
||||
int error;
|
||||
|
||||
printk(KERN_INFO "Adaptec %s driver (%s)\n",
|
||||
printk(KERN_INFO "Adaptec %s driver %s\n",
|
||||
AAC_DRIVERNAME, aac_driver_version);
|
||||
|
||||
error = pci_register_driver(&aac_pci_driver);
|
||||
|
||||
+18
-15
@@ -464,21 +464,24 @@ static int aac_rx_restart_adapter(struct aac_dev *dev, int bled)
|
||||
{
|
||||
u32 var;
|
||||
|
||||
if (bled)
|
||||
printk(KERN_ERR "%s%d: adapter kernel panic'd %x.\n",
|
||||
dev->name, dev->id, bled);
|
||||
else {
|
||||
bled = aac_adapter_sync_cmd(dev, IOP_RESET_ALWAYS,
|
||||
0, 0, 0, 0, 0, 0, &var, NULL, NULL, NULL, NULL);
|
||||
if (!bled && (var != 0x00000001))
|
||||
bled = -EINVAL;
|
||||
}
|
||||
if (bled && (bled != -ETIMEDOUT))
|
||||
bled = aac_adapter_sync_cmd(dev, IOP_RESET,
|
||||
0, 0, 0, 0, 0, 0, &var, NULL, NULL, NULL, NULL);
|
||||
if (!(dev->supplement_adapter_info.SupportedOptions2 &
|
||||
le32_to_cpu(AAC_OPTION_MU_RESET)) || (bled >= 0) || (bled == -2)) {
|
||||
if (bled)
|
||||
printk(KERN_ERR "%s%d: adapter kernel panic'd %x.\n",
|
||||
dev->name, dev->id, bled);
|
||||
else {
|
||||
bled = aac_adapter_sync_cmd(dev, IOP_RESET_ALWAYS,
|
||||
0, 0, 0, 0, 0, 0, &var, NULL, NULL, NULL, NULL);
|
||||
if (!bled && (var != 0x00000001))
|
||||
bled = -EINVAL;
|
||||
}
|
||||
if (bled && (bled != -ETIMEDOUT))
|
||||
bled = aac_adapter_sync_cmd(dev, IOP_RESET,
|
||||
0, 0, 0, 0, 0, 0, &var, NULL, NULL, NULL, NULL);
|
||||
|
||||
if (bled && (bled != -ETIMEDOUT))
|
||||
return -EINVAL;
|
||||
if (bled && (bled != -ETIMEDOUT))
|
||||
return -EINVAL;
|
||||
}
|
||||
if (bled || (var == 0x3803000F)) { /* USE_OTHER_METHOD */
|
||||
rx_writel(dev, MUnit.reserved2, 3);
|
||||
msleep(5000); /* Delay 5 seconds */
|
||||
@@ -596,7 +599,7 @@ int _aac_rx_init(struct aac_dev *dev)
|
||||
}
|
||||
msleep(1);
|
||||
}
|
||||
if (restart)
|
||||
if (restart && aac_commit)
|
||||
aac_commit = 1;
|
||||
/*
|
||||
* Fill in the common function dispatch table.
|
||||
|
||||
Reference in New Issue
Block a user