aboutsummaryrefslogtreecommitdiff
path: root/drivers/scsi/aacraid
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/aacraid')
-rw-r--r--drivers/scsi/aacraid/Makefile2
-rw-r--r--drivers/scsi/aacraid/aachba.c602
-rw-r--r--drivers/scsi/aacraid/aacraid.h46
-rw-r--r--drivers/scsi/aacraid/comminit.c14
-rw-r--r--drivers/scsi/aacraid/commsup.c40
-rw-r--r--drivers/scsi/aacraid/linit.c17
-rw-r--r--drivers/scsi/aacraid/nark.c87
-rw-r--r--drivers/scsi/aacraid/rkt.c64
-rw-r--r--drivers/scsi/aacraid/rx.c263
-rw-r--r--drivers/scsi/aacraid/sa.c33
10 files changed, 707 insertions, 461 deletions
diff --git a/drivers/scsi/aacraid/Makefile b/drivers/scsi/aacraid/Makefile
index 28d133a3094..f1cca4ee541 100644
--- a/drivers/scsi/aacraid/Makefile
+++ b/drivers/scsi/aacraid/Makefile
@@ -3,6 +3,6 @@
obj-$(CONFIG_SCSI_AACRAID) := aacraid.o
aacraid-objs := linit.o aachba.o commctrl.o comminit.o commsup.o \
- dpcsup.o rx.o sa.o rkt.o
+ dpcsup.o rx.o sa.o rkt.o nark.o
EXTRA_CFLAGS := -Idrivers/scsi
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index 426cd6f49f5..ddb33b06e0e 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -170,9 +170,9 @@ 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 expose_physicals = 0;
+int expose_physicals = -1;
module_param(expose_physicals, int, S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(expose_physicals, "Expose physical components of the arrays. 0=off, 1=on");
+MODULE_PARM_DESC(expose_physicals, "Expose physical components of the arrays. -1=protect 0=off, 1=on");
/**
* aac_get_config_status - check the adapter configuration
* @common: adapter to query
@@ -706,6 +706,309 @@ static void set_sense(u8 *sense_buf, u8 sense_key, u8 sense_code,
}
}
+static int aac_bounds_32(struct aac_dev * dev, struct scsi_cmnd * cmd, u64 lba)
+{
+ if (lba & 0xffffffff00000000LL) {
+ int cid = scmd_id(cmd);
+ dprintk((KERN_DEBUG "aacraid: Illegal lba\n"));
+ cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
+ SAM_STAT_CHECK_CONDITION;
+ set_sense((u8 *) &dev->fsa_dev[cid].sense_data,
+ HARDWARE_ERROR,
+ SENCODE_INTERNAL_TARGET_FAILURE,
+ ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0,
+ 0, 0);
+ memcpy(cmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
+ (sizeof(dev->fsa_dev[cid].sense_data) > sizeof(cmd->sense_buffer))
+ ? sizeof(cmd->sense_buffer)
+ : sizeof(dev->fsa_dev[cid].sense_data));
+ cmd->scsi_done(cmd);
+ return 1;
+ }
+ return 0;
+}
+
+static int aac_bounds_64(struct aac_dev * dev, struct scsi_cmnd * cmd, u64 lba)
+{
+ return 0;
+}
+
+static void io_callback(void *context, struct fib * fibptr);
+
+static int aac_read_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count)
+{
+ u16 fibsize;
+ struct aac_raw_io *readcmd;
+ aac_fib_init(fib);
+ readcmd = (struct aac_raw_io *) fib_data(fib);
+ readcmd->block[0] = cpu_to_le32((u32)(lba&0xffffffff));
+ 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->bpTotal = 0;
+ readcmd->bpComplete = 0;
+
+ aac_build_sgraw(cmd, &readcmd->sg);
+ fibsize = sizeof(struct aac_raw_io) + ((le32_to_cpu(readcmd->sg.count) - 1) * sizeof (struct sgentryraw));
+ BUG_ON(fibsize > (fib->dev->max_fib_size - sizeof(struct aac_fibhdr)));
+ /*
+ * Now send the Fib to the adapter
+ */
+ return aac_fib_send(ContainerRawIo,
+ fib,
+ fibsize,
+ FsaNormal,
+ 0, 1,
+ (fib_callback) io_callback,
+ (void *) cmd);
+}
+
+static int aac_read_block64(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count)
+{
+ u16 fibsize;
+ struct aac_read64 *readcmd;
+ aac_fib_init(fib);
+ readcmd = (struct aac_read64 *) fib_data(fib);
+ readcmd->command = cpu_to_le32(VM_CtHostRead64);
+ readcmd->cid = cpu_to_le16(scmd_id(cmd));
+ readcmd->sector_count = cpu_to_le16(count);
+ readcmd->block = cpu_to_le32((u32)(lba&0xffffffff));
+ readcmd->pad = 0;
+ readcmd->flags = 0;
+
+ aac_build_sg64(cmd, &readcmd->sg);
+ fibsize = sizeof(struct aac_read64) +
+ ((le32_to_cpu(readcmd->sg.count) - 1) *
+ sizeof (struct sgentry64));
+ BUG_ON (fibsize > (fib->dev->max_fib_size -
+ sizeof(struct aac_fibhdr)));
+ /*
+ * Now send the Fib to the adapter
+ */
+ return aac_fib_send(ContainerCommand64,
+ fib,
+ fibsize,
+ FsaNormal,
+ 0, 1,
+ (fib_callback) io_callback,
+ (void *) cmd);
+}
+
+static int aac_read_block(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count)
+{
+ u16 fibsize;
+ struct aac_read *readcmd;
+ aac_fib_init(fib);
+ readcmd = (struct aac_read *) fib_data(fib);
+ readcmd->command = cpu_to_le32(VM_CtBlockRead);
+ readcmd->cid = cpu_to_le16(scmd_id(cmd));
+ readcmd->block = cpu_to_le32((u32)(lba&0xffffffff));
+ readcmd->count = cpu_to_le32(count * 512);
+
+ aac_build_sg(cmd, &readcmd->sg);
+ fibsize = sizeof(struct aac_read) +
+ ((le32_to_cpu(readcmd->sg.count) - 1) *
+ sizeof (struct sgentry));
+ BUG_ON (fibsize > (fib->dev->max_fib_size -
+ sizeof(struct aac_fibhdr)));
+ /*
+ * Now send the Fib to the adapter
+ */
+ return aac_fib_send(ContainerCommand,
+ fib,
+ fibsize,
+ FsaNormal,
+ 0, 1,
+ (fib_callback) io_callback,
+ (void *) cmd);
+}
+
+static int aac_write_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count)
+{
+ u16 fibsize;
+ struct aac_raw_io *writecmd;
+ aac_fib_init(fib);
+ writecmd = (struct aac_raw_io *) fib_data(fib);
+ writecmd->block[0] = cpu_to_le32((u32)(lba&0xffffffff));
+ 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->bpTotal = 0;
+ writecmd->bpComplete = 0;
+
+ aac_build_sgraw(cmd, &writecmd->sg);
+ fibsize = sizeof(struct aac_raw_io) + ((le32_to_cpu(writecmd->sg.count) - 1) * sizeof (struct sgentryraw));
+ BUG_ON(fibsize > (fib->dev->max_fib_size - sizeof(struct aac_fibhdr)));
+ /*
+ * Now send the Fib to the adapter
+ */
+ return aac_fib_send(ContainerRawIo,
+ fib,
+ fibsize,
+ FsaNormal,
+ 0, 1,
+ (fib_callback) io_callback,
+ (void *) cmd);
+}
+
+static int aac_write_block64(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count)
+{
+ u16 fibsize;
+ struct aac_write64 *writecmd;
+ aac_fib_init(fib);
+ writecmd = (struct aac_write64 *) fib_data(fib);
+ writecmd->command = cpu_to_le32(VM_CtHostWrite64);
+ writecmd->cid = cpu_to_le16(scmd_id(cmd));
+ writecmd->sector_count = cpu_to_le16(count);
+ writecmd->block = cpu_to_le32((u32)(lba&0xffffffff));
+ writecmd->pad = 0;
+ writecmd->flags = 0;
+
+ aac_build_sg64(cmd, &writecmd->sg);
+ fibsize = sizeof(struct aac_write64) +
+ ((le32_to_cpu(writecmd->sg.count) - 1) *
+ sizeof (struct sgentry64));
+ BUG_ON (fibsize > (fib->dev->max_fib_size -
+ sizeof(struct aac_fibhdr)));
+ /*
+ * Now send the Fib to the adapter
+ */
+ return aac_fib_send(ContainerCommand64,
+ fib,
+ fibsize,
+ FsaNormal,
+ 0, 1,
+ (fib_callback) io_callback,
+ (void *) cmd);
+}
+
+static int aac_write_block(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count)
+{
+ u16 fibsize;
+ struct aac_write *writecmd;
+ aac_fib_init(fib);
+ writecmd = (struct aac_write *) fib_data(fib);
+ writecmd->command = cpu_to_le32(VM_CtBlockWrite);
+ writecmd->cid = cpu_to_le16(scmd_id(cmd));
+ writecmd->block = cpu_to_le32((u32)(lba&0xffffffff));
+ writecmd->count = cpu_to_le32(count * 512);
+ writecmd->sg.count = cpu_to_le32(1);
+ /* ->stable is not used - it did mean which type of write */
+
+ aac_build_sg(cmd, &writecmd->sg);
+ fibsize = sizeof(struct aac_write) +
+ ((le32_to_cpu(writecmd->sg.count) - 1) *
+ sizeof (struct sgentry));
+ BUG_ON (fibsize > (fib->dev->max_fib_size -
+ sizeof(struct aac_fibhdr)));
+ /*
+ * Now send the Fib to the adapter
+ */
+ return aac_fib_send(ContainerCommand,
+ fib,
+ fibsize,
+ FsaNormal,
+ 0, 1,
+ (fib_callback) io_callback,
+ (void *) cmd);
+}
+
+static struct aac_srb * aac_scsi_common(struct fib * fib, struct scsi_cmnd * cmd)
+{
+ struct aac_srb * srbcmd;
+ u32 flag;
+ u32 timeout;
+
+ aac_fib_init(fib);
+ switch(cmd->sc_data_direction){
+ case DMA_TO_DEVICE:
+ flag = SRB_DataOut;
+ break;
+ case DMA_BIDIRECTIONAL:
+ flag = SRB_DataIn | SRB_DataOut;
+ break;
+ case DMA_FROM_DEVICE:
+ flag = SRB_DataIn;
+ break;
+ case DMA_NONE:
+ default: /* shuts up some versions of gcc */
+ flag = SRB_NoDataXfer;
+ break;
+ }
+
+ srbcmd = (struct aac_srb*) fib_data(fib);
+ srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi);
+ srbcmd->channel = cpu_to_le32(aac_logical_to_phys(scmd_channel(cmd)));
+ srbcmd->id = cpu_to_le32(scmd_id(cmd));
+ srbcmd->lun = cpu_to_le32(cmd->device->lun);
+ srbcmd->flags = cpu_to_le32(flag);
+ timeout = cmd->timeout_per_command/HZ;
+ if (timeout == 0)
+ timeout = 1;
+ srbcmd->timeout = cpu_to_le32(timeout); // timeout in seconds
+ srbcmd->retry_limit = 0; /* Obsolete parameter */
+ srbcmd->cdb_size = cpu_to_le32(cmd->cmd_len);
+ return srbcmd;
+}
+
+static void aac_srb_callback(void *context, struct fib * fibptr);
+
+static int aac_scsi_64(struct fib * fib, struct scsi_cmnd * cmd)
+{
+ u16 fibsize;
+ 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);
+
+ memset(srbcmd->cdb, 0, sizeof(srbcmd->cdb));
+ memcpy(srbcmd->cdb, cmd->cmnd, cmd->cmd_len);
+ /*
+ * Build Scatter/Gather list
+ */
+ fibsize = sizeof (struct aac_srb) - sizeof (struct sgentry) +
+ ((le32_to_cpu(srbcmd->sg.count) & 0xff) *
+ sizeof (struct sgentry64));
+ BUG_ON (fibsize > (fib->dev->max_fib_size -
+ sizeof(struct aac_fibhdr)));
+
+ /*
+ * Now send the Fib to the adapter
+ */
+ return aac_fib_send(ScsiPortCommand64, fib,
+ fibsize, FsaNormal, 0, 1,
+ (fib_callback) aac_srb_callback,
+ (void *) cmd);
+}
+
+static int aac_scsi_32(struct fib * fib, struct scsi_cmnd * cmd)
+{
+ u16 fibsize;
+ 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);
+
+ memset(srbcmd->cdb, 0, sizeof(srbcmd->cdb));
+ memcpy(srbcmd->cdb, cmd->cmnd, cmd->cmd_len);
+ /*
+ * Build Scatter/Gather list
+ */
+ fibsize = sizeof (struct aac_srb) +
+ (((le32_to_cpu(srbcmd->sg.count) & 0xff) - 1) *
+ sizeof (struct sgentry));
+ BUG_ON (fibsize > (fib->dev->max_fib_size -
+ sizeof(struct aac_fibhdr)));
+
+ /*
+ * Now send the Fib to the adapter
+ */
+ return aac_fib_send(ScsiPortCommand, fib, fibsize, FsaNormal, 0, 1,
+ (fib_callback) aac_srb_callback, (void *) cmd);
+}
+
int aac_get_adapter_info(struct aac_dev* dev)
{
struct fib* fibptr;
@@ -874,14 +1177,27 @@ int aac_get_adapter_info(struct aac_dev* dev)
}
}
/*
- * 57 scatter gather elements
+ * Deal with configuring for the individualized limits of each packet
+ * interface.
*/
- if (!(dev->raw_io_interface)) {
+ dev->a_ops.adapter_scsi = (dev->dac_support)
+ ? aac_scsi_64
+ : aac_scsi_32;
+ if (dev->raw_io_interface) {
+ dev->a_ops.adapter_bounds = (dev->raw_io_64)
+ ? aac_bounds_64
+ : aac_bounds_32;
+ dev->a_ops.adapter_read = aac_read_raw_io;
+ dev->a_ops.adapter_write = aac_write_raw_io;
+ } else {
+ dev->a_ops.adapter_bounds = aac_bounds_32;
dev->scsi_host_ptr->sg_tablesize = (dev->max_fib_size -
sizeof(struct aac_fibhdr) -
sizeof(struct aac_write) + sizeof(struct sgentry)) /
sizeof(struct sgentry);
if (dev->dac_support) {
+ dev->a_ops.adapter_read = aac_read_block64;
+ dev->a_ops.adapter_write = aac_write_block64;
/*
* 38 scatter gather elements
*/
@@ -891,6 +1207,9 @@ int aac_get_adapter_info(struct aac_dev* dev)
sizeof(struct aac_write64) +
sizeof(struct sgentry64)) /
sizeof(struct sgentry64);
+ } else {
+ dev->a_ops.adapter_read = aac_read_block;
+ dev->a_ops.adapter_write = aac_write_block;
}
dev->scsi_host_ptr->max_sectors = AAC_MAX_32BIT_SGBCOUNT;
if(!(dev->adapter_info.options & AAC_OPT_NEW_COMM)) {
@@ -1004,8 +1323,6 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid)
u64 lba;
u32 count;
int status;
-
- u16 fibsize;
struct aac_dev *dev;
struct fib * cmd_fibcontext;
@@ -1059,23 +1376,8 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid)
}
dprintk((KERN_DEBUG "aac_read[cpu %d]: lba = %llu, t = %ld.\n",
smp_processor_id(), (unsigned long long)lba, jiffies));
- if ((!(dev->raw_io_interface) || !(dev->raw_io_64)) &&
- (lba & 0xffffffff00000000LL)) {
- dprintk((KERN_DEBUG "aac_read: Illegal lba\n"));
- scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
- SAM_STAT_CHECK_CONDITION;
- set_sense((u8 *) &dev->fsa_dev[cid].sense_data,
- HARDWARE_ERROR,
- SENCODE_INTERNAL_TARGET_FAILURE,
- ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0,
- 0, 0);
- memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
- (sizeof(dev->fsa_dev[cid].sense_data) > sizeof(scsicmd->sense_buffer))
- ? sizeof(scsicmd->sense_buffer)
- : sizeof(dev->fsa_dev[cid].sense_data));
- scsicmd->scsi_done(scsicmd);
+ if (aac_adapter_bounds(dev,scsicmd,lba))
return 0;
- }
/*
* Alocate and initialize a Fib
*/
@@ -1083,85 +1385,7 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid)
return -1;
}
- aac_fib_init(cmd_fibcontext);
-
- if (dev->raw_io_interface) {
- struct aac_raw_io *readcmd;
- readcmd = (struct aac_raw_io *) fib_data(cmd_fibcontext);
- readcmd->block[0] = cpu_to_le32((u32)(lba&0xffffffff));
- readcmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32));
- readcmd->count = cpu_to_le32(count<<9);
- readcmd->cid = cpu_to_le16(cid);
- readcmd->flags = cpu_to_le16(1);
- readcmd->bpTotal = 0;
- readcmd->bpComplete = 0;
-
- aac_build_sgraw(scsicmd, &readcmd->sg);
- fibsize = sizeof(struct aac_raw_io) + ((le32_to_cpu(readcmd->sg.count) - 1) * sizeof (struct sgentryraw));
- BUG_ON(fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr)));
- /*
- * Now send the Fib to the adapter
- */
- status = aac_fib_send(ContainerRawIo,
- cmd_fibcontext,
- fibsize,
- FsaNormal,
- 0, 1,
- (fib_callback) io_callback,
- (void *) scsicmd);
- } else if (dev->dac_support == 1) {
- struct aac_read64 *readcmd;
- readcmd = (struct aac_read64 *) fib_data(cmd_fibcontext);
- readcmd->command = cpu_to_le32(VM_CtHostRead64);
- readcmd->cid = cpu_to_le16(cid);
- readcmd->sector_count = cpu_to_le16(count);
- readcmd->block = cpu_to_le32((u32)(lba&0xffffffff));
- readcmd->pad = 0;
- readcmd->flags = 0;
-
- aac_build_sg64(scsicmd, &readcmd->sg);
- fibsize = sizeof(struct aac_read64) +
- ((le32_to_cpu(readcmd->sg.count) - 1) *
- sizeof (struct sgentry64));
- BUG_ON (fibsize > (dev->max_fib_size -
- sizeof(struct aac_fibhdr)));
- /*
- * Now send the Fib to the adapter
- */
- status = aac_fib_send(ContainerCommand64,
- cmd_fibcontext,
- fibsize,
- FsaNormal,
- 0, 1,
- (fib_callback) io_callback,
- (void *) scsicmd);
- } else {
- struct aac_read *readcmd;
- readcmd = (struct aac_read *) fib_data(cmd_fibcontext);
- readcmd->command = cpu_to_le32(VM_CtBlockRead);
- readcmd->cid = cpu_to_le32(cid);
- readcmd->block = cpu_to_le32((u32)(lba&0xffffffff));
- readcmd->count = cpu_to_le32(count * 512);
-
- aac_build_sg(scsicmd, &readcmd->sg);
- fibsize = sizeof(struct aac_read) +
- ((le32_to_cpu(readcmd->sg.count) - 1) *
- sizeof (struct sgentry));
- BUG_ON (fibsize > (dev->max_fib_size -
- sizeof(struct aac_fibhdr)));
- /*
- * Now send the Fib to the adapter
- */
- status = aac_fib_send(ContainerCommand,
- cmd_fibcontext,
- fibsize,
- FsaNormal,
- 0, 1,
- (fib_callback) io_callback,
- (void *) scsicmd);
- }
-
-
+ status = aac_adapter_read(cmd_fibcontext, scsicmd, lba, count);
/*
* Check that the command queued to the controller
@@ -1187,7 +1411,6 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid)
u64 lba;
u32 count;
int status;
- u16 fibsize;
struct aac_dev *dev;
struct fib * cmd_fibcontext;
@@ -1227,22 +1450,8 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid)
}
dprintk((KERN_DEBUG "aac_write[cpu %d]: lba = %llu, t = %ld.\n",
smp_processor_id(), (unsigned long long)lba, jiffies));
- if ((!(dev->raw_io_interface) || !(dev->raw_io_64))
- && (lba & 0xffffffff00000000LL)) {
- dprintk((KERN_DEBUG "aac_write: Illegal lba\n"));
- scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION;
- set_sense((u8 *) &dev->fsa_dev[cid].sense_data,
- HARDWARE_ERROR,
- SENCODE_INTERNAL_TARGET_FAILURE,
- ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0,
- 0, 0);
- memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
- (sizeof(dev->fsa_dev[cid].sense_data) > sizeof(scsicmd->sense_buffer))
- ? sizeof(scsicmd->sense_buffer)
- : sizeof(dev->fsa_dev[cid].sense_data));
- scsicmd->scsi_done(scsicmd);
+ if (aac_adapter_bounds(dev,scsicmd,lba))
return 0;
- }
/*
* Allocate and initialize a Fib then setup a BlockWrite command
*/
@@ -1251,85 +1460,8 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid)
scsicmd->scsi_done(scsicmd);
return 0;
}
- aac_fib_init(cmd_fibcontext);
- if (dev->raw_io_interface) {
- struct aac_raw_io *writecmd;
- writecmd = (struct aac_raw_io *) fib_data(cmd_fibcontext);
- writecmd->block[0] = cpu_to_le32((u32)(lba&0xffffffff));
- writecmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32));
- writecmd->count = cpu_to_le32(count<<9);
- writecmd->cid = cpu_to_le16(cid);
- writecmd->flags = 0;
- writecmd->bpTotal = 0;
- writecmd->bpComplete = 0;
-
- aac_build_sgraw(scsicmd, &writecmd->sg);
- fibsize = sizeof(struct aac_raw_io) + ((le32_to_cpu(writecmd->sg.count) - 1) * sizeof (struct sgentryraw));
- BUG_ON(fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr)));
- /*
- * Now send the Fib to the adapter
- */
- status = aac_fib_send(ContainerRawIo,
- cmd_fibcontext,
- fibsize,
- FsaNormal,
- 0, 1,
- (fib_callback) io_callback,
- (void *) scsicmd);
- } else if (dev->dac_support == 1) {
- struct aac_write64 *writecmd;
- writecmd = (struct aac_write64 *) fib_data(cmd_fibcontext);
- writecmd->command = cpu_to_le32(VM_CtHostWrite64);
- writecmd->cid = cpu_to_le16(cid);
- writecmd->sector_count = cpu_to_le16(count);
- writecmd->block = cpu_to_le32((u32)(lba&0xffffffff));
- writecmd->pad = 0;
- writecmd->flags = 0;
-
- aac_build_sg64(scsicmd, &writecmd->sg);
- fibsize = sizeof(struct aac_write64) +
- ((le32_to_cpu(writecmd->sg.count) - 1) *
- sizeof (struct sgentry64));
- BUG_ON (fibsize > (dev->max_fib_size -
- sizeof(struct aac_fibhdr)));
- /*
- * Now send the Fib to the adapter
- */
- status = aac_fib_send(ContainerCommand64,
- cmd_fibcontext,
- fibsize,
- FsaNormal,
- 0, 1,
- (fib_callback) io_callback,
- (void *) scsicmd);
- } else {
- struct aac_write *writecmd;
- writecmd = (struct aac_write *) fib_data(cmd_fibcontext);
- writecmd->command = cpu_to_le32(VM_CtBlockWrite);
- writecmd->cid = cpu_to_le32(cid);
- writecmd->block = cpu_to_le32((u32)(lba&0xffffffff));
- writecmd->count = cpu_to_le32(count * 512);
- writecmd->sg.count = cpu_to_le32(1);
- /* ->stable is not used - it did mean which type of write */
-
- aac_build_sg(scsicmd, &writecmd->sg);
- fibsize = sizeof(struct aac_write) +
- ((le32_to_cpu(writecmd->sg.count) - 1) *
- sizeof (struct sgentry));
- BUG_ON (fibsize > (dev->max_fib_size -
- sizeof(struct aac_fibhdr)));
- /*
- * Now send the Fib to the adapter
- */
- status = aac_fib_send(ContainerCommand,
- cmd_fibcontext,
- fibsize,
- FsaNormal,
- 0, 1,
- (fib_callback) io_callback,
- (void *) scsicmd);
- }
+ status = aac_adapter_write(cmd_fibcontext, scsicmd, lba, count);
/*
* Check that the command queued to the controller
@@ -2099,10 +2231,6 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd)
struct fib* cmd_fibcontext;
struct aac_dev* dev;
int status;
- struct aac_srb *srbcmd;
- u16 fibsize;
- u32 flag;
- u32 timeout;
dev = (struct aac_dev *)scsicmd->device->host->hostdata;
if (scmd_id(scsicmd) >= dev->maximum_num_physicals ||
@@ -2112,88 +2240,14 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd)
return 0;
}
- switch(scsicmd->sc_data_direction){
- case DMA_TO_DEVICE:
- flag = SRB_DataOut;
- break;
- case DMA_BIDIRECTIONAL:
- flag = SRB_DataIn | SRB_DataOut;
- break;
- case DMA_FROM_DEVICE:
- flag = SRB_DataIn;
- break;
- case DMA_NONE:
- default: /* shuts up some versions of gcc */
- flag = SRB_NoDataXfer;
- break;
- }
-
-
/*
* Allocate and initialize a Fib then setup a BlockWrite command
*/
if (!(cmd_fibcontext = aac_fib_alloc(dev))) {
return -1;
}
- aac_fib_init(cmd_fibcontext);
-
- srbcmd = (struct aac_srb*) fib_data(cmd_fibcontext);
- srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi);
- srbcmd->channel = cpu_to_le32(aac_logical_to_phys(scmd_channel(scsicmd)));
- srbcmd->id = cpu_to_le32(scmd_id(scsicmd));
- srbcmd->lun = cpu_to_le32(scsicmd->device->lun);
- srbcmd->flags = cpu_to_le32(flag);
- timeout = scsicmd->timeout_per_command/HZ;
- if(timeout == 0){
- timeout = 1;
- }
- srbcmd->timeout = cpu_to_le32(timeout); // timeout in seconds
- srbcmd->retry_limit = 0; /* Obsolete parameter */
- srbcmd->cdb_size = cpu_to_le32(scsicmd->cmd_len);
-
- if( dev->dac_support == 1 ) {
- aac_build_sg64(scsicmd, (struct sgmap64*) &srbcmd->sg);
- srbcmd->count = cpu_to_le32(scsicmd->request_bufflen);
-
- memset(srbcmd->cdb, 0, sizeof(srbcmd->cdb));
- memcpy(srbcmd->cdb, scsicmd->cmnd, scsicmd->cmd_len);
- /*
- * Build Scatter/Gather list
- */
- fibsize = sizeof (struct aac_srb) - sizeof (struct sgentry) +
- ((le32_to_cpu(srbcmd->sg.count) & 0xff) *
- sizeof (struct sgentry64));
- BUG_ON (fibsize > (dev->max_fib_size -
- sizeof(struct aac_fibhdr)));
+ status = aac_adapter_scsi(cmd_fibcontext, scsicmd);
- /*
- * Now send the Fib to the adapter
- */
- status = aac_fib_send(ScsiPortCommand64, cmd_fibcontext,
- fibsize, FsaNormal, 0, 1,
- (fib_callback) aac_srb_callback,
- (void *) scsicmd);
- } else {
- aac_build_sg(scsicmd, (struct sgmap*)&srbcmd->sg);
- srbcmd->count = cpu_to_le32(scsicmd->request_bufflen);
-
- memset(srbcmd->cdb, 0, sizeof(srbcmd->cdb));
- memcpy(srbcmd->cdb, scsicmd->cmnd, scsicmd->cmd_len);
- /*
- * Build Scatter/Gather list
- */
- fibsize = sizeof (struct aac_srb) +
- (((le32_to_cpu(srbcmd->sg.count) & 0xff) - 1) *
- sizeof (struct sgentry));
- BUG_ON (fibsize > (dev->max_fib_size -
- sizeof(struct aac_fibhdr)));
-
- /*
- * Now send the Fib to the adapter
- */
- status = aac_fib_send(ScsiPortCommand, cmd_fibcontext, fibsize, FsaNormal, 0, 1,
- (fib_callback) aac_srb_callback, (void *) scsicmd);
- }
/*
* Check that the command queued to the controller
*/
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index 4f8b4c53d43..39ecd0d22eb 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -5,6 +5,7 @@
#define _nblank(x) #x
#define nblank(x) _nblank(x)[0]
+#include <linux/interrupt.h>
/*------------------------------------------------------------------------------
* D E F I N E S
@@ -485,16 +486,28 @@ enum aac_log_level {
struct aac_dev;
struct fib;
+struct scsi_cmnd;
struct adapter_ops
{
+ /* Low level operations */
void (*adapter_interrupt)(struct aac_dev *dev);
void (*adapter_notify)(struct aac_dev *dev, u32 event);
void (*adapter_disable_int)(struct aac_dev *dev);
+ void (*adapter_enable_int)(struct aac_dev *dev);
int (*adapter_sync_cmd)(struct aac_dev *dev, u32 command, u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6, u32 *status, u32 *r1, u32 *r2, u32 *r3, u32 *r4);
int (*adapter_check_health)(struct aac_dev *dev);
- int (*adapter_send)(struct fib * fib);
+ /* Transport operations */
int (*adapter_ioremap)(struct aac_dev * dev, u32 size);
+ irqreturn_t (*adapter_intr)(int irq, void *dev_id);
+ /* 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_scsi)(struct fib * fib, struct scsi_cmnd * cmd);
+ /* Administrative operations */
+ int (*adapter_comm)(struct aac_dev * dev, int comm);
};
/*
@@ -1018,7 +1031,9 @@ struct aac_dev
u8 nondasd_support;
u8 dac_support;
u8 raid_scsi_mode;
- u8 new_comm_interface;
+ u8 comm_interface;
+# define AAC_COMM_PRODUCER 0
+# define AAC_COMM_MESSAGE 1
/* macro side-effects BEWARE */
# define raw_io_interface \
init->InitStructRevision==cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_4)
@@ -1036,18 +1051,36 @@ struct aac_dev
#define aac_adapter_disable_int(dev) \
(dev)->a_ops.adapter_disable_int(dev)
+#define aac_adapter_enable_int(dev) \
+ (dev)->a_ops.adapter_enable_int(dev)
+
#define aac_adapter_sync_cmd(dev, command, p1, p2, p3, p4, p5, p6, status, r1, r2, r3, r4) \
(dev)->a_ops.adapter_sync_cmd(dev, command, p1, p2, p3, p4, p5, p6, status, r1, r2, r3, r4)
#define aac_adapter_check_health(dev) \
(dev)->a_ops.adapter_check_health(dev)
-#define aac_adapter_send(fib) \
- ((fib)->dev)->a_ops.adapter_send(fib)
-
#define aac_adapter_ioremap(dev, size) \
(dev)->a_ops.adapter_ioremap(dev, size)
+#define aac_adapter_deliver(fib) \
+ ((fib)->dev)->a_ops.adapter_deliver(fib)
+
+#define aac_adapter_bounds(dev,cmd,lba) \
+ dev->a_ops.adapter_bounds(dev,cmd,lba)
+
+#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_scsi(fib,cmd) \
+ ((fib)->dev)->a_ops.adapter_scsi(fib,cmd)
+
+#define aac_adapter_comm(dev,comm) \
+ (dev)->a_ops.adapter_comm(dev, comm)
+
#define FIB_CONTEXT_FLAG_TIMED_OUT (0x00000001)
/*
@@ -1767,7 +1800,6 @@ static inline u32 cap_to_cyls(sector_t capacity, u32 divisor)
return (u32)capacity;
}
-struct scsi_cmnd;
/* SCp.phase values */
#define AAC_OWNER_MIDLEVEL 0x101
#define AAC_OWNER_LOWLEVEL 0x102
@@ -1794,7 +1826,9 @@ int aac_dev_ioctl(struct aac_dev *dev, int cmd, void __user *arg);
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);
+int aac_nark_init(struct aac_dev *dev);
int aac_sa_init(struct aac_dev *dev);
+int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_fib * hw_fib, int wait, struct fib * fibptr, unsigned long *nonotify);
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);
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c
index 6d305b2f854..df67ba68602 100644
--- a/drivers/scsi/aacraid/comminit.c
+++ b/drivers/scsi/aacraid/comminit.c
@@ -95,7 +95,7 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
init->HostPhysMemPages = cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES);
init->InitFlags = 0;
- if (dev->new_comm_interface) {
+ if (dev->comm_interface == AAC_COMM_MESSAGE) {
init->InitFlags = cpu_to_le32(INITFLAGS_NEW_COMM_SUPPORTED);
dprintk((KERN_WARNING"aacraid: New Comm Interface enabled\n"));
}
@@ -297,21 +297,23 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
- sizeof(struct aac_fibhdr)
- sizeof(struct aac_write) + sizeof(struct sgentry))
/ sizeof(struct sgentry);
- dev->new_comm_interface = 0;
+ dev->comm_interface = AAC_COMM_PRODUCER;
dev->raw_io_64 = 0;
if ((!aac_adapter_sync_cmd(dev, GET_ADAPTER_PROPERTIES,
0, 0, 0, 0, 0, 0, status+0, status+1, status+2, NULL, NULL)) &&
(status[0] == 0x00000001)) {
if (status[1] & AAC_OPT_NEW_COMM_64)
dev->raw_io_64 = 1;
- if (status[1] & AAC_OPT_NEW_COMM)
- dev->new_comm_interface = dev->a_ops.adapter_send != 0;
- if (dev->new_comm_interface && (status[2] > dev->base_size)) {
+ if (dev->a_ops.adapter_comm &&
+ (status[1] & AAC_OPT_NEW_COMM))
+ dev->comm_interface = AAC_COMM_MESSAGE;
+ if ((dev->comm_interface == AAC_COMM_MESSAGE) &&
+ (status[2] > dev->base_size)) {
aac_adapter_ioremap(dev, 0);
dev->base_size = status[2];
if (aac_adapter_ioremap(dev, status[2])) {
/* remap failed, go back ... */
- dev->new_comm_interface = 0;
+ dev->comm_interface = AAC_COMM_PRODUCER;
if (aac_adapter_ioremap(dev, AAC_MIN_FOOTPRINT_SIZE)) {
printk(KERN_WARNING
"aacraid: unable to map adapter.\n");
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index 4893a6d06a3..1b97f60652b 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -317,7 +317,7 @@ static int aac_get_entry (struct aac_dev * dev, u32 qid, struct aac_entry **entr
* success.
*/
-static int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_fib * hw_fib, int wait, struct fib * fibptr, unsigned long *nonotify)
+int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_fib * hw_fib, int wait, struct fib * fibptr, unsigned long *nonotify)
{
struct aac_entry * entry = NULL;
int map = 0;
@@ -387,7 +387,6 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
{
struct aac_dev * dev = fibptr->dev;
struct hw_fib * hw_fib = fibptr->hw_fib;
- struct aac_queue * q;
unsigned long flags = 0;
unsigned long qflags;
@@ -469,38 +468,10 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
if (!dev->queues)
return -EBUSY;
- q = &dev->queues->queue[AdapNormCmdQueue];
if(wait)
spin_lock_irqsave(&fibptr->event_lock, flags);
- spin_lock_irqsave(q->lock, qflags);
- if (dev->new_comm_interface) {
- unsigned long count = 10000000L; /* 50 seconds */
- q->numpending++;
- spin_unlock_irqrestore(q->lock, qflags);
- while (aac_adapter_send(fibptr) != 0) {
- if (--count == 0) {
- if (wait)
- spin_unlock_irqrestore(&fibptr->event_lock, flags);
- spin_lock_irqsave(q->lock, qflags);
- q->numpending--;
- spin_unlock_irqrestore(q->lock, qflags);
- return -ETIMEDOUT;
- }
- udelay(5);
- }
- } else {
- u32 index;
- unsigned long nointr = 0;
- aac_queue_get( dev, &index, AdapNormCmdQueue, hw_fib, 1, fibptr, &nointr);
-
- q->numpending++;
- *(q->headers.producer) = cpu_to_le32(index + 1);
- spin_unlock_irqrestore(q->lock, qflags);
- dprintk((KERN_DEBUG "aac_fib_send: inserting a queue entry at index %d.\n",index));
- if (!(nointr & aac_config.irq_mod))
- aac_adapter_notify(dev, AdapNormCmdQueue);
- }
+ aac_adapter_deliver(fibptr);
/*
* If the caller wanted us to wait for response wait now.
@@ -520,6 +491,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
while (down_trylock(&fibptr->event_wait)) {
int blink;
if (--count == 0) {
+ struct aac_queue * q = &dev->queues->queue[AdapNormCmdQueue];
spin_lock_irqsave(q->lock, qflags);
q->numpending--;
spin_unlock_irqrestore(q->lock, qflags);
@@ -659,7 +631,7 @@ int aac_fib_adapter_complete(struct fib *fibptr, unsigned short size)
unsigned long qflags;
if (hw_fib->header.XferState == 0) {
- if (dev->new_comm_interface)
+ if (dev->comm_interface == AAC_COMM_MESSAGE)
kfree (hw_fib);
return 0;
}
@@ -667,7 +639,7 @@ int aac_fib_adapter_complete(struct fib *fibptr, unsigned short size)
* If we plan to do anything check the structure type first.
*/
if ( hw_fib->header.StructType != FIB_MAGIC ) {
- if (dev->new_comm_interface)
+ if (dev->comm_interface == AAC_COMM_MESSAGE)
kfree (hw_fib);
return -EINVAL;
}
@@ -679,7 +651,7 @@ int aac_fib_adapter_complete(struct fib *fibptr, unsigned short size)
* send the completed cdb to the adapter.
*/
if (hw_fib->header.XferState & cpu_to_le32(SentFromAdapter)) {
- if (dev->new_comm_interface) {
+ if (dev->comm_interface == AAC_COMM_MESSAGE) {
kfree (hw_fib);
} else {
u32 index;
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index d2cf875af59..a9734e08fe2 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -157,6 +157,7 @@ static struct pci_device_id aac_pci_tbl[] = {
{ 0x9005, 0x0285, 0x17aa, PCI_ANY_ID, 0, 0, 58 }, /* Legend Catchall */
{ 0x9