summaryrefslogtreecommitdiff
path: root/drivers/scsi/aacraid
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/aacraid')
-rw-r--r--drivers/scsi/aacraid/aachba.c400
-rw-r--r--drivers/scsi/aacraid/aacraid.h335
-rw-r--r--drivers/scsi/aacraid/commctrl.c112
-rw-r--r--drivers/scsi/aacraid/comminit.c4
-rw-r--r--drivers/scsi/aacraid/commsup.c394
-rw-r--r--drivers/scsi/aacraid/dpcsup.c10
-rw-r--r--drivers/scsi/aacraid/linit.c242
-rw-r--r--drivers/scsi/aacraid/rx.c6
8 files changed, 862 insertions, 641 deletions
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index a77ab8d693d4..d7235f42cf5f 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -31,9 +31,9 @@
#include <linux/slab.h>
#include <linux/completion.h>
#include <linux/blkdev.h>
-#include <linux/dma-mapping.h>
#include <asm/semaphore.h>
#include <asm/uaccess.h>
+#include <linux/highmem.h> /* For flush_kernel_dcache_page */
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
@@ -56,54 +56,54 @@
/*
* Sense codes
*/
-
-#define SENCODE_NO_SENSE 0x00
-#define SENCODE_END_OF_DATA 0x00
-#define SENCODE_BECOMING_READY 0x04
-#define SENCODE_INIT_CMD_REQUIRED 0x04
-#define SENCODE_PARAM_LIST_LENGTH_ERROR 0x1A
-#define SENCODE_INVALID_COMMAND 0x20
-#define SENCODE_LBA_OUT_OF_RANGE 0x21
-#define SENCODE_INVALID_CDB_FIELD 0x24
-#define SENCODE_LUN_NOT_SUPPORTED 0x25
-#define SENCODE_INVALID_PARAM_FIELD 0x26
-#define SENCODE_PARAM_NOT_SUPPORTED 0x26
-#define SENCODE_PARAM_VALUE_INVALID 0x26
-#define SENCODE_RESET_OCCURRED 0x29
-#define SENCODE_LUN_NOT_SELF_CONFIGURED_YET 0x3E
-#define SENCODE_INQUIRY_DATA_CHANGED 0x3F
-#define SENCODE_SAVING_PARAMS_NOT_SUPPORTED 0x39
-#define SENCODE_DIAGNOSTIC_FAILURE 0x40
-#define SENCODE_INTERNAL_TARGET_FAILURE 0x44
-#define SENCODE_INVALID_MESSAGE_ERROR 0x49
-#define SENCODE_LUN_FAILED_SELF_CONFIG 0x4c
-#define SENCODE_OVERLAPPED_COMMAND 0x4E
+
+#define SENCODE_NO_SENSE 0x00
+#define SENCODE_END_OF_DATA 0x00
+#define SENCODE_BECOMING_READY 0x04
+#define SENCODE_INIT_CMD_REQUIRED 0x04
+#define SENCODE_PARAM_LIST_LENGTH_ERROR 0x1A
+#define SENCODE_INVALID_COMMAND 0x20
+#define SENCODE_LBA_OUT_OF_RANGE 0x21
+#define SENCODE_INVALID_CDB_FIELD 0x24
+#define SENCODE_LUN_NOT_SUPPORTED 0x25
+#define SENCODE_INVALID_PARAM_FIELD 0x26
+#define SENCODE_PARAM_NOT_SUPPORTED 0x26
+#define SENCODE_PARAM_VALUE_INVALID 0x26
+#define SENCODE_RESET_OCCURRED 0x29
+#define SENCODE_LUN_NOT_SELF_CONFIGURED_YET 0x3E
+#define SENCODE_INQUIRY_DATA_CHANGED 0x3F
+#define SENCODE_SAVING_PARAMS_NOT_SUPPORTED 0x39
+#define SENCODE_DIAGNOSTIC_FAILURE 0x40
+#define SENCODE_INTERNAL_TARGET_FAILURE 0x44
+#define SENCODE_INVALID_MESSAGE_ERROR 0x49
+#define SENCODE_LUN_FAILED_SELF_CONFIG 0x4c
+#define SENCODE_OVERLAPPED_COMMAND 0x4E
/*
* Additional sense codes
*/
-
-#define ASENCODE_NO_SENSE 0x00
-#define ASENCODE_END_OF_DATA 0x05
-#define ASENCODE_BECOMING_READY 0x01
-#define ASENCODE_INIT_CMD_REQUIRED 0x02
-#define ASENCODE_PARAM_LIST_LENGTH_ERROR 0x00
-#define ASENCODE_INVALID_COMMAND 0x00
-#define ASENCODE_LBA_OUT_OF_RANGE 0x00
-#define ASENCODE_INVALID_CDB_FIELD 0x00
-#define ASENCODE_LUN_NOT_SUPPORTED 0x00
-#define ASENCODE_INVALID_PARAM_FIELD 0x00
-#define ASENCODE_PARAM_NOT_SUPPORTED 0x01
-#define ASENCODE_PARAM_VALUE_INVALID 0x02
-#define ASENCODE_RESET_OCCURRED 0x00
-#define ASENCODE_LUN_NOT_SELF_CONFIGURED_YET 0x00
-#define ASENCODE_INQUIRY_DATA_CHANGED 0x03
-#define ASENCODE_SAVING_PARAMS_NOT_SUPPORTED 0x00
-#define ASENCODE_DIAGNOSTIC_FAILURE 0x80
-#define ASENCODE_INTERNAL_TARGET_FAILURE 0x00
-#define ASENCODE_INVALID_MESSAGE_ERROR 0x00
-#define ASENCODE_LUN_FAILED_SELF_CONFIG 0x00
-#define ASENCODE_OVERLAPPED_COMMAND 0x00
+
+#define ASENCODE_NO_SENSE 0x00
+#define ASENCODE_END_OF_DATA 0x05
+#define ASENCODE_BECOMING_READY 0x01
+#define ASENCODE_INIT_CMD_REQUIRED 0x02
+#define ASENCODE_PARAM_LIST_LENGTH_ERROR 0x00
+#define ASENCODE_INVALID_COMMAND 0x00
+#define ASENCODE_LBA_OUT_OF_RANGE 0x00
+#define ASENCODE_INVALID_CDB_FIELD 0x00
+#define ASENCODE_LUN_NOT_SUPPORTED 0x00
+#define ASENCODE_INVALID_PARAM_FIELD 0x00
+#define ASENCODE_PARAM_NOT_SUPPORTED 0x01
+#define ASENCODE_PARAM_VALUE_INVALID 0x02
+#define ASENCODE_RESET_OCCURRED 0x00
+#define ASENCODE_LUN_NOT_SELF_CONFIGURED_YET 0x00
+#define ASENCODE_INQUIRY_DATA_CHANGED 0x03
+#define ASENCODE_SAVING_PARAMS_NOT_SUPPORTED 0x00
+#define ASENCODE_DIAGNOSTIC_FAILURE 0x80
+#define ASENCODE_INTERNAL_TARGET_FAILURE 0x00
+#define ASENCODE_INVALID_MESSAGE_ERROR 0x00
+#define ASENCODE_LUN_FAILED_SELF_CONFIG 0x00
+#define ASENCODE_OVERLAPPED_COMMAND 0x00
#define BYTE0(x) (unsigned char)(x)
#define BYTE1(x) (unsigned char)((x) >> 8)
@@ -115,8 +115,8 @@
*----------------------------------------------------------------------------*/
/* SCSI inquiry data */
struct inquiry_data {
- u8 inqd_pdt; /* Peripheral qualifier | Peripheral Device Type */
- u8 inqd_dtq; /* RMB | Device Type Qualifier */
+ u8 inqd_pdt; /* Peripheral qualifier | Peripheral Device Type */
+ u8 inqd_dtq; /* RMB | Device Type Qualifier */
u8 inqd_ver; /* ISO version | ECMA version | ANSI-approved version */
u8 inqd_rdf; /* AENC | TrmIOP | Response data format */
u8 inqd_len; /* Additional length (n-4) */
@@ -130,7 +130,7 @@ struct inquiry_data {
/*
* M O D U L E G L O B A L S
*/
-
+
static unsigned long aac_build_sg(struct scsi_cmnd* scsicmd, struct sgmap* sgmap);
static unsigned long aac_build_sg64(struct scsi_cmnd* scsicmd, struct sgmap64* psg);
static unsigned long aac_build_sgraw(struct scsi_cmnd* scsicmd, struct sgmapraw* psg);
@@ -141,9 +141,10 @@ static char *aac_get_status_string(u32 status);
/*
* Non dasd selection is handled entirely in aachba now
- */
-
+ */
+
static int nondasd = -1;
+static int aac_cache = 0;
static int dacmode = -1;
int aac_commit = -1;
@@ -152,6 +153,8 @@ int aif_timeout = 120;
module_param(nondasd, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(nondasd, "Control scanning of hba for nondasd devices. 0=off, 1=on");
+module_param_named(cache, aac_cache, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(cache, "Disable Queue Flush commands:\n\tbit 0 - Disable FUA in WRITE SCSI commands\n\tbit 1 - Disable SYNCHRONIZE_CACHE SCSI command\n\tbit 2 - Disable only if Battery not protecting Cache");
module_param(dacmode, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(dacmode, "Control whether dma addressing is using 64 bit DAC. 0=off, 1=on");
module_param_named(commit, aac_commit, int, S_IRUGO|S_IWUSR);
@@ -179,7 +182,7 @@ MODULE_PARM_DESC(check_interval, "Interval in seconds between adapter health che
int aac_check_reset = 1;
module_param_named(check_reset, aac_check_reset, int, S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(aac_check_reset, "If adapter fails health check, reset the adapter.");
+MODULE_PARM_DESC(aac_check_reset, "If adapter fails health check, reset the adapter. a value of -1 forces the reset to adapters programmed to ignore it.");
int expose_physicals = -1;
module_param(expose_physicals, int, S_IRUGO|S_IWUSR);
@@ -193,12 +196,12 @@ static inline int aac_valid_context(struct scsi_cmnd *scsicmd,
struct fib *fibptr) {
struct scsi_device *device;
- if (unlikely(!scsicmd || !scsicmd->scsi_done )) {
+ if (unlikely(!scsicmd || !scsicmd->scsi_done)) {
dprintk((KERN_WARNING "aac_valid_context: scsi command corrupt\n"));
- aac_fib_complete(fibptr);
- aac_fib_free(fibptr);
- return 0;
- }
+ aac_fib_complete(fibptr);
+ aac_fib_free(fibptr);
+ return 0;
+ }
scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL;
device = scsicmd->device;
if (unlikely(!device || !scsi_device_online(device))) {
@@ -240,7 +243,7 @@ int aac_get_config_status(struct aac_dev *dev, int commit_flag)
FsaNormal,
1, 1,
NULL, NULL);
- if (status < 0 ) {
+ if (status < 0) {
printk(KERN_WARNING "aac_get_config_status: SendFIB failed.\n");
} else {
struct aac_get_config_status_resp *reply
@@ -264,10 +267,10 @@ int aac_get_config_status(struct aac_dev *dev, int commit_flag)
struct aac_commit_config * dinfo;
aac_fib_init(fibptr);
dinfo = (struct aac_commit_config *) fib_data(fibptr);
-
+
dinfo->command = cpu_to_le32(VM_ContainerConfig);
dinfo->type = cpu_to_le32(CT_COMMIT_CONFIG);
-
+
status = aac_fib_send(ContainerCommand,
fibptr,
sizeof (struct aac_commit_config),
@@ -293,7 +296,7 @@ int aac_get_config_status(struct aac_dev *dev, int commit_flag)
int aac_get_containers(struct aac_dev *dev)
{
struct fsa_dev_info *fsa_dev_ptr;
- u32 index;
+ u32 index;
int status = 0;
struct fib * fibptr;
struct aac_get_container_count *dinfo;
@@ -363,6 +366,7 @@ static void aac_internal_transfer(struct scsi_cmnd *scsicmd, void *data, unsigne
if (buf && transfer_len > 0)
memcpy(buf + offset, data, transfer_len);
+ flush_kernel_dcache_page(kmap_atomic_to_page(buf - sg->offset));
kunmap_atomic(buf - sg->offset, KM_IRQ0);
}
@@ -395,7 +399,7 @@ static void get_container_name_callback(void *context, struct fib * fibptr)
do {
*dp++ = (*sp) ? *sp++ : ' ';
} while (--count > 0);
- aac_internal_transfer(scsicmd, d,
+ aac_internal_transfer(scsicmd, d,
offsetof(struct inquiry_data, inqd_pid), sizeof(d));
}
}
@@ -431,13 +435,13 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd)
dinfo->count = cpu_to_le32(sizeof(((struct aac_get_name_resp *)NULL)->data));
status = aac_fib_send(ContainerCommand,
- cmd_fibcontext,
+ cmd_fibcontext,
sizeof (struct aac_get_name),
- FsaNormal,
- 0, 1,
- (fib_callback) get_container_name_callback,
+ FsaNormal,
+ 0, 1,
+ (fib_callback)get_container_name_callback,
(void *) scsicmd);
-
+
/*
* Check that the command queued to the controller
*/
@@ -445,7 +449,7 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd)
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);
aac_fib_free(cmd_fibcontext);
@@ -652,42 +656,47 @@ struct scsi_inq {
* @a: string to copy from
* @b: string to copy to
*
- * Copy a String from one location to another
+ * Copy a String from one location to another
* without copying \0
*/
static void inqstrcpy(char *a, char *b)
{
- while(*a != (char)0)
+ while (*a != (char)0)
*b++ = *a++;
}
static char *container_types[] = {
- "None",
- "Volume",
- "Mirror",
- "Stripe",
- "RAID5",
- "SSRW",
- "SSRO",
- "Morph",
- "Legacy",
- "RAID4",
- "RAID10",
- "RAID00",
- "V-MIRRORS",
- "PSEUDO R4",
+ "None",
+ "Volume",
+ "Mirror",
+ "Stripe",
+ "RAID5",
+ "SSRW",
+ "SSRO",
+ "Morph",
+ "Legacy",
+ "RAID4",
+ "RAID10",
+ "RAID00",
+ "V-MIRRORS",
+ "PSEUDO R4",
"RAID50",
"RAID5D",
"RAID5D0",
"RAID1E",
"RAID6",
"RAID60",
- "Unknown"
+ "Unknown"
};
-
+char * get_container_type(unsigned tindex)
+{
+ if (tindex >= ARRAY_SIZE(container_types))
+ tindex = ARRAY_SIZE(container_types) - 1;
+ return container_types[tindex];
+}
/* Function: setinqstr
*
@@ -707,16 +716,21 @@ static void setinqstr(struct aac_dev *dev, void *data, int tindex)
if (dev->supplement_adapter_info.AdapterTypeText[0]) {
char * cp = dev->supplement_adapter_info.AdapterTypeText;
- int c = sizeof(str->vid);
- while (*cp && *cp != ' ' && --c)
- ++cp;
- c = *cp;
- *cp = '\0';
- inqstrcpy (dev->supplement_adapter_info.AdapterTypeText,
- str->vid);
- *cp = c;
- while (*cp && *cp != ' ')
- ++cp;
+ int c;
+ if ((cp[0] == 'A') && (cp[1] == 'O') && (cp[2] == 'C'))
+ inqstrcpy("SMC", str->vid);
+ else {
+ c = sizeof(str->vid);
+ while (*cp && *cp != ' ' && --c)
+ ++cp;
+ c = *cp;
+ *cp = '\0';
+ inqstrcpy (dev->supplement_adapter_info.AdapterTypeText,
+ str->vid);
+ *cp = c;
+ while (*cp && *cp != ' ')
+ ++cp;
+ }
while (*cp == ' ')
++cp;
/* last six chars reserved for vol type */
@@ -898,9 +912,8 @@ static int aac_bounds_32(struct aac_dev * dev, struct scsi_cmnd * cmd, u64 lba)
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));
+ min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data),
+ SCSI_SENSE_BUFFERSIZE));
cmd->scsi_done(cmd);
return 1;
}
@@ -981,7 +994,7 @@ static int aac_read_block(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32
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->cid = cpu_to_le32(scmd_id(cmd));
readcmd->block = cpu_to_le32((u32)(lba&0xffffffff));
readcmd->count = cpu_to_le32(count * 512);
@@ -1013,7 +1026,8 @@ 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 = fua ?
+ writecmd->flags = (fua && ((aac_cache & 5) != 1) &&
+ (((aac_cache & 5) != 5) || !fib->dev->cache_protected)) ?
cpu_to_le16(IO_TYPE_WRITE|IO_SUREWRITE) :
cpu_to_le16(IO_TYPE_WRITE);
writecmd->bpTotal = 0;
@@ -1072,7 +1086,7 @@ static int aac_write_block(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u3
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->cid = cpu_to_le32(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);
@@ -1190,6 +1204,15 @@ static int aac_scsi_32(struct fib * fib, struct scsi_cmnd * cmd)
(fib_callback) aac_srb_callback, (void *) cmd);
}
+static int aac_scsi_32_64(struct fib * fib, struct scsi_cmnd * cmd)
+{
+ if ((sizeof(dma_addr_t) > 4) &&
+ (num_physpages > (0xFFFFFFFFULL >> PAGE_SHIFT)) &&
+ (fib->dev->adapter_info.options & AAC_OPT_SGMAP_HOST64))
+ return FAILED;
+ return aac_scsi_32(fib, cmd);
+}
+
int aac_get_adapter_info(struct aac_dev* dev)
{
struct fib* fibptr;
@@ -1207,11 +1230,11 @@ int aac_get_adapter_info(struct aac_dev* dev)
memset(info,0,sizeof(*info));
rcode = aac_fib_send(RequestAdapterInfo,
- fibptr,
+ fibptr,
sizeof(*info),
- FsaNormal,
+ FsaNormal,
-1, 1, /* First `interrupt' command uses special wait */
- NULL,
+ NULL,
NULL);
if (rcode < 0) {
@@ -1222,29 +1245,29 @@ int aac_get_adapter_info(struct aac_dev* dev)
memcpy(&dev->adapter_info, info, sizeof(*info));
if (dev->adapter_info.options & AAC_OPT_SUPPLEMENT_ADAPTER_INFO) {
- struct aac_supplement_adapter_info * info;
+ struct aac_supplement_adapter_info * sinfo;
aac_fib_init(fibptr);
- info = (struct aac_supplement_adapter_info *) fib_data(fibptr);
+ sinfo = (struct aac_supplement_adapter_info *) fib_data(fibptr);
- memset(info,0,sizeof(*info));
+ memset(sinfo,0,sizeof(*sinfo));
rcode = aac_fib_send(RequestSupplementAdapterInfo,
fibptr,
- sizeof(*info),
+ sizeof(*sinfo),
FsaNormal,
1, 1,
NULL,
NULL);
if (rcode >= 0)
- memcpy(&dev->supplement_adapter_info, info, sizeof(*info));
+ memcpy(&dev->supplement_adapter_info, sinfo, sizeof(*sinfo));
}
- /*
- * GetBusInfo
+ /*
+ * GetBusInfo
*/
aac_fib_init(fibptr);
@@ -1267,6 +1290,8 @@ int aac_get_adapter_info(struct aac_dev* dev)
1, 1,
NULL, NULL);
+ /* reasoned default */
+ dev->maximum_num_physicals = 16;
if (rcode >= 0 && le32_to_cpu(bus_info->Status) == ST_OK) {
dev->maximum_num_physicals = le32_to_cpu(bus_info->TargetsPerBus);
dev->maximum_num_channels = le32_to_cpu(bus_info->BusCount);
@@ -1276,7 +1301,7 @@ int aac_get_adapter_info(struct aac_dev* dev)
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,
+ dev->name,
dev->id,
tmp>>24,
(tmp>>16)&0xff,
@@ -1305,19 +1330,21 @@ int aac_get_adapter_info(struct aac_dev* dev)
(int)sizeof(dev->supplement_adapter_info.VpdInfo.Tsid),
dev->supplement_adapter_info.VpdInfo.Tsid);
}
- if (!aac_check_reset ||
+ if (!aac_check_reset || ((aac_check_reset != 1) &&
(dev->supplement_adapter_info.SupportedOptions2 &
- le32_to_cpu(AAC_OPTION_IGNORE_RESET))) {
+ AAC_OPTION_IGNORE_RESET))) {
printk(KERN_INFO "%s%d: Reset Adapter Ignored\n",
dev->name, dev->id);
}
}
+ dev->cache_protected = 0;
+ dev->jbod = ((dev->supplement_adapter_info.FeatureBits &
+ AAC_FEATURE_JBOD) != 0);
dev->nondasd_support = 0;
dev->raid_scsi_mode = 0;
- if(dev->adapter_info.options & AAC_OPT_NONDASD){
+ if(dev->adapter_info.options & AAC_OPT_NONDASD)
dev->nondasd_support = 1;
- }
/*
* If the firmware supports ROMB RAID/SCSI mode and we are currently
@@ -1338,11 +1365,10 @@ int aac_get_adapter_info(struct aac_dev* dev)
if (dev->raid_scsi_mode != 0)
printk(KERN_INFO "%s%d: ROMB RAID/SCSI mode enabled\n",
dev->name, dev->id);
-
- if(nondasd != -1) {
+
+ if (nondasd != -1)
dev->nondasd_support = (nondasd!=0);
- }
- if(dev->nondasd_support != 0){
+ if(dev->nondasd_support != 0) {
printk(KERN_INFO "%s%d: Non-DASD support enabled.\n",dev->name, dev->id);
}
@@ -1371,12 +1397,14 @@ int aac_get_adapter_info(struct aac_dev* dev)
rcode = -ENOMEM;
}
}
- /*
+ /*
* Deal with configuring for the individualized limits of each packet
* interface.
*/
dev->a_ops.adapter_scsi = (dev->dac_support)
- ? aac_scsi_64
+ ? ((aac_get_driver_ident(dev->cardtype)->quirks & AAC_QUIRK_SCSI_32)
+ ? aac_scsi_32_64
+ : aac_scsi_64)
: aac_scsi_32;
if (dev->raw_io_interface) {
dev->a_ops.adapter_bounds = (dev->raw_io_64)
@@ -1393,8 +1421,8 @@ int aac_get_adapter_info(struct aac_dev* dev)
if (dev->dac_support) {
dev->a_ops.adapter_read = aac_read_block64;
dev->a_ops.adapter_write = aac_write_block64;
- /*
- * 38 scatter gather elements
+ /*
+ * 38 scatter gather elements
*/
dev->scsi_host_ptr->sg_tablesize =
(dev->max_fib_size -
@@ -1498,9 +1526,8 @@ static void io_callback(void *context, struct fib * fibptr)
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));
+ min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data),
+ SCSI_SENSE_BUFFERSIZE));
}
aac_fib_complete(fibptr);
aac_fib_free(fibptr);
@@ -1524,7 +1551,7 @@ static int aac_read(struct scsi_cmnd * scsicmd)
case READ_6:
dprintk((KERN_DEBUG "aachba: received a read(6) command on id %d.\n", scmd_id(scsicmd)));
- lba = ((scsicmd->cmnd[1] & 0x1F) << 16) |
+ lba = ((scsicmd->cmnd[1] & 0x1F) << 16) |
(scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3];
count = scsicmd->cmnd[4];
@@ -1534,32 +1561,32 @@ static int aac_read(struct scsi_cmnd * scsicmd)
case READ_16:
dprintk((KERN_DEBUG "aachba: received a read(16) command on id %d.\n", scmd_id(scsicmd)));
- lba = ((u64)scsicmd->cmnd[2] << 56) |
- ((u64)scsicmd->cmnd[3] << 48) |
+ lba = ((u64)scsicmd->cmnd[2] << 56) |
+ ((u64)scsicmd->cmnd[3] << 48) |
((u64)scsicmd->cmnd[4] << 40) |
((u64)scsicmd->cmnd[5] << 32) |
- ((u64)scsicmd->cmnd[6] << 24) |
+ ((u64)scsicmd->cmnd[6] << 24) |
(scsicmd->cmnd[7] << 16) |
(scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9];
- count = (scsicmd->cmnd[10] << 24) |
+ count = (scsicmd->cmnd[10] << 24) |
(scsicmd->cmnd[11] << 16) |
(scsicmd->cmnd[12] << 8) | scsicmd->cmnd[13];
break;
case READ_12:
dprintk((KERN_DEBUG "aachba: received a read(12) command on id %d.\n", scmd_id(scsicmd)));
- lba = ((u64)scsicmd->cmnd[2] << 24) |
+ lba = ((u64)scsicmd->cmnd[2] << 24) |
(scsicmd->cmnd[3] << 16) |
- (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];
- count = (scsicmd->cmnd[6] << 24) |
+ (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];
+ count = (scsicmd->cmnd[6] << 24) |
(scsicmd->cmnd[7] << 16) |
- (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9];
+ (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9];
break;
default:
dprintk((KERN_DEBUG "aachba: received a read(10) command on id %d.\n", scmd_id(scsicmd)));
- lba = ((u64)scsicmd->cmnd[2] << 24) |
- (scsicmd->cmnd[3] << 16) |
+ 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];
break;
@@ -1584,7 +1611,7 @@ static int aac_read(struct scsi_cmnd * scsicmd)
scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
return 0;
}
-
+
printk(KERN_WARNING "aac_read: aac_fib_send failed with status: %d.\n", status);
/*
* For some reason, the Fib didn't queue, return QUEUE_FULL
@@ -1619,11 +1646,11 @@ static int aac_write(struct scsi_cmnd * scsicmd)
} 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)));
- lba = ((u64)scsicmd->cmnd[2] << 56) |
+ lba = ((u64)scsicmd->cmnd[2] << 56) |
((u64)scsicmd->cmnd[3] << 48) |
((u64)scsicmd->cmnd[4] << 40) |
((u64)scsicmd->cmnd[5] << 32) |
- ((u64)scsicmd->cmnd[6] << 24) |
+ ((u64)scsicmd->cmnd[6] << 24) |
(scsicmd->cmnd[7] << 16) |
(scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9];
count = (scsicmd->cmnd[10] << 24) | (scsicmd->cmnd[11] << 16) |
@@ -1712,8 +1739,8 @@ static void synchronize_callback(void *context, struct fib *fibptr)
ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0,
0, 0);
memcpy(cmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
- min(sizeof(dev->fsa_dev[cid].sense_data),
- sizeof(cmd->sense_buffer)));
+ min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data),
+ SCSI_SENSE_BUFFERSIZE));
}
aac_fib_complete(fibptr);
@@ -1798,7 +1825,7 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd)
if (active)
return SCSI_MLQUEUE_DEVICE_BUSY;
- aac = (struct aac_dev *)scsicmd->device->host->hostdata;
+ aac = (struct aac_dev *)sdev->host->hostdata;
if (aac->in_reset)
return SCSI_MLQUEUE_HOST_BUSY;
@@ -1850,14 +1877,14 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd)
* Emulate a SCSI command and queue the required request for the
* aacraid firmware.
*/
-
+
int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
{
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;
-
+
if (fsa_dev_ptr == NULL)
return -1;
/*
@@ -1898,7 +1925,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
}
}
} else { /* check for physical non-dasd devices */
- if ((dev->nondasd_support == 1) || expose_physicals) {
+ if (dev->nondasd_support || expose_physicals ||
+ dev->jbod) {
if (dev->in_reset)
return -1;
return aac_send_srb_fib(scsicmd);
@@ -1913,7 +1941,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
* else Command for the controller itself
*/
else if ((scsicmd->cmnd[0] != INQUIRY) && /* only INQUIRY & TUR cmnd supported for controller */
- (scsicmd->cmnd[0] != TEST_UNIT_READY))
+ (scsicmd->cmnd[0] != TEST_UNIT_READY))
{
dprintk((KERN_WARNING "Only INQUIRY & TUR command supported for controller, rcvd = 0x%x.\n", scsicmd->cmnd[0]));
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION;
@@ -1922,9 +1950,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
SENCODE_INVALID_COMMAND,
ASENCODE_INVALID_COMMAND, 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));
+ min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data),
+ SCSI_SENSE_BUFFERSIZE));
scsicmd->scsi_done(scsicmd);
return 0;
}
@@ -1939,7 +1966,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
dprintk((KERN_DEBUG "INQUIRY command, ID: %d.\n", cid));
memset(&inq_data, 0, sizeof (struct inquiry_data));
- if (scsicmd->cmnd[1] & 0x1 ) {
+ if (scsicmd->cmnd[1] & 0x1) {
char *arr = (char *)&inq_data;
/* EVPD bit set */
@@ -1974,10 +2001,9 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
ASENCODE_NO_SENSE, 0, 7, 2, 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));
+ min_t(size_t,
+ sizeof(dev->fsa_dev[cid].sense_data),
+ SCSI_SENSE_BUFFERSIZE));
}
scsicmd->scsi_done(scsicmd);
return 0;
@@ -2092,7 +2118,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
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)
+ if (dev->raw_io_interface && ((aac_cache & 5) != 1))
mode_buf[2] = 0x10;
mode_buf[3] = 0; /* Block descriptor length */
if (((scsicmd->cmnd[2] & 0x3f) == 8) ||
@@ -2100,7 +2126,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
mode_buf[0] = 6;
mode_buf[4] = 8;
mode_buf[5] = 1;
- mode_buf[6] = 0x04; /* WCE */
+ mode_buf[6] = ((aac_cache & 6) == 2)
+ ? 0 : 0x04; /* WCE */
mode_buf_length = 7;
if (mode_buf_length > scsicmd->cmnd[4])
mode_buf_length = scsicmd->cmnd[4];
@@ -2123,7 +2150,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
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)
+ if (dev->raw_io_interface && ((aac_cache & 5) != 1))
mode_buf[3] = 0x10;
mode_buf[4] = 0; /* reserved */
mode_buf[5] = 0; /* reserved */
@@ -2134,7 +2161,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
mode_buf[1] = 9;
mode_buf[8] = 8;
mode_buf[9] = 1;
- mode_buf[10] = 0x04; /* WCE */
+ mode_buf[10] = ((aac_cache & 6) == 2)
+ ? 0 : 0x04; /* WCE */
mode_buf_length = 11;
if (mode_buf_length > scsicmd->cmnd[8])
mode_buf_length = scsicmd->cmnd[8];
@@ -2179,7 +2207,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
return 0;
}
- switch (scsicmd->cmnd[0])
+ switch (scsicmd->cmnd[0])
{
case READ_6:
case READ_10:
@@ -2192,11 +2220,11 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
* corresponds to a container. Needed to convert
* containers to /dev/sd device names
*/
-
+
if (scsicmd->request->rq_disk)
strlcpy(fsa_dev_ptr[cid].devname,
scsicmd->request->rq_disk->disk_name,
- min(sizeof(fsa_dev_ptr[cid].devname),
+ min(sizeof(fsa_dev_ptr[cid].devname),
sizeof(scsicmd->request->rq_disk->disk_name) + 1));
return aac_read(scsicmd);
@@ -2210,9 +2238,16 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
return aac_write(scsicmd);
case SYNCHRONIZE_CACHE:
+ if (((aac_cache & 6) == 6) && dev->cache_protected) {
+ scsicmd->result = DID_OK << 16 |
+ COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
+ scsicmd->scsi_done(scsicmd);
+ return 0;
+ }
/* Issue FIB to tell Firmware to flush it's cache */
- return aac_synchronize(scsicmd);
-
+ if ((aac_cache & 6) != 2)
+ return aac_synchronize(scsicmd);
+ /* FALLTHRU */
default:
/*
* Unhandled commands
@@ -2223,9 +2258,9 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
ILLEGAL_REQUEST, SENCODE_INVALID_COMMAND,
ASENCODE_INVALID_COMMAND, 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));
+ min_t(size_t,
+ sizeof(dev->fsa_dev[cid].sense_data),
+ SCSI_SENSE_BUFFERSIZE));
scsicmd->scsi_done(scsicmd);
return 0;
}
@@ -2243,7 +2278,7 @@ static int query_disk(struct aac_dev *dev, void __user *arg)
return -EFAULT;
if (qd.cnum == -1)
qd.cnum = qd.id;
- else if ((qd.bus == -1) && (qd.id == -1) && (qd.lun == -1))
+ else if ((qd.bus == -1) && (qd.id == -1) && (qd.lun == -1))
{
if (qd.cnum < 0 || qd.cnum >= dev->maximum_num_containers)
return -EINVAL;
@@ -2370,7 +2405,7 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
scsicmd->sense_buffer[0] = '\0'; /* Initialize sense valid flag to false */
/*
- * Calculate resid for sg
+ * Calculate resid for sg
*/
scsi_set_resid(scsicmd, scsi_bufflen(scsicmd)
@@ -2385,10 +2420,8 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
if (le32_to_cpu(srbreply->status) != ST_OK){
int len;
printk(KERN_WARNING "aac_srb_callback: srb failed, status = %d\n", le32_to_cpu(srbreply->status));
- len = (le32_to_cpu(srbreply->sense_data_size) >
- sizeof(scsicmd->sense_buffer)) ?
- sizeof(scsicmd->sense_buffer) :
- le32_to_cpu(srbreply->sense_data_size);
+ len = min_t(u32, le32_to_cpu(srbreply->sense_data_size),
+ SCSI_SENSE_BUFFERSIZE);
scsicmd->result = DID_ERROR << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION;
memcpy(scsicmd->sense_buffer, srbreply->sense_data, len);
}
@@ -2412,7 +2445,7 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
case WRITE_12:
case READ_16:
case WRITE_16:
- if(le32_to_cpu(srbreply->data_xfer_length) < scsicmd->underflow ) {
+ if (le32_to_cpu(srbreply->data_xfer_length) < scsicmd->underflow) {
printk(KERN_WARNING"aacraid: SCSI CMD underflow\n");
} else {
printk(KERN_WARNING"aacraid: SCSI CMD Data Overrun\n");
@@ -2481,26 +2514,23 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
printk("aacraid: SRB ERROR(%u) %s scsi cmd 0x%x - scsi status 0x%x\n",
le32_to_cpu(srbreply->srb_status) & 0x3F,
aac_get_status_string(
- le32_to_cpu(srbreply->srb_status) & 0x3F),
- scsicmd->cmnd[0],
+ le32_to_cpu(srbreply->srb_status) & 0x3F),
+ scsicmd->cmnd[0],
le32_to_cpu(srbreply->scsi_status));
#endif
scsicmd->result = DID_ERROR << 16 | COMMAND_COMPLETE << 8;
break;
}
- if (le32_to_cpu(srbreply->scsi_status) == 0x02 ){ // Check Condition
+ if (le32_to_cpu(srbreply->scsi_status) == SAM_STAT_CHECK_CONDITION) {
int len;
scsicmd->result |= SAM_STAT_CHECK_CONDITION;
- len = (le32_to_cpu(srbreply->sense_data_size) >
- sizeof(scsicmd->sense_buffer)) ?
- sizeof(scsicmd->sense_buffer) :
- le32_to_cpu(srbreply->sense_data_size);
+ len = min_t(u32, le32_to_cpu(srbreply->sense_data_size),
+ SCSI_SENSE_BUFFERSIZE);
#ifdef AAC_DETAILED_STATUS_INFO
printk(KERN_WARNING "aac_srb_callback: check condition, status = %d len=%d\n",
le32_to_cpu(srbreply->status), len);
#endif
memcpy(scsicmd->sense_buffer, srbreply->sense_data, len);
-
}
/*
* OR in the scsi status (already shifted up a bit)
@@ -2517,7 +2547,7 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
* aac_send_scb_fib
* @scsicmd: the scsi command block
*
- * This routine will form a FIB and fill in the aac_srb from the
+ * This routine will form a FIB and fill in the aac_srb from the
* scsicmd passed in.
*/
@@ -2731,7 +2761,7 @@ static struct aac_srb_status_info srb_status_info[] = {
{ SRB_STATUS_ERROR_RECOVERY, "Error Recovery"},
{ SRB_STATUS_NOT_STARTED, "Not Started"},
{ SRB_STATUS_NOT_IN_USE, "Not In Use"},
- { SRB_STATUS_FORCE_ABORT, "Force Abort"},
+ { SRB_STATUS_FORCE_ABORT, "Force Abort"},
{ SRB_STATUS_DOMAIN_VALIDATION_FAIL,"Domain Validation Failure"},
{ 0xff, "Unknown Error"}
};
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index 9abba8b90f70..3195d29f2177 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -1,4 +1,4 @@
-#if (!defined(dprintk))
+#ifndef dprintk
# define dprintk(x)
#endif
/* eg: if (nblank(dprintk(x))) */
@@ -12,7 +12,7 @@
*----------------------------------------------------------------------------*/
#ifndef AAC_DRIVER_BUILD
-# define AAC_DRIVER_BUILD 2449
+# define AAC_DRIVER_BUILD 2455
# define AAC_DRIVER_BRANCH "-ms"
#endif
#define MAXIMUM_NUM_CONTAINERS 32
@@ -50,9 +50,9 @@ struct diskparm
/*
* Firmware constants
*/
-
+
#define CT_NONE 0
-#define CT_OK 218
+#define CT_OK 218
#define FT_FILESYS 8 /* ADAPTEC's "FSA"(tm) filesystem */
#define FT_DRIVE 9 /* physical disk - addressable in scsi by bus/id/lun */
@@ -107,12 +107,12 @@ struct user_sgentryraw {
struct sgmap {
__le32 count;
- struct sgentry sg[1];
+ struct sgentry sg[1];
};
struct user_sgmap {
u32 count;
- struct user_sgentry sg[1];
+ struct user_sgentry sg[1];
};
struct sgmap64 {
@@ -137,18 +137,18 @@ struct user_sgmapraw {
struct creation_info
{
- u8 buildnum; /* e.g., 588 */
- u8 usec; /* e.g., 588 */
- u8 via; /* e.g., 1 = FSU,
- * 2 = API
+ u8 buildnum; /* e.g., 588 */
+ u8 usec; /* e.g., 588 */
+ u8 via; /* e.g., 1 = FSU,
+ * 2 = API
*/
- u8 year; /* e.g., 1997 = 97 */
+ u8 year; /* e.g., 1997 = 97 */
__le32 date; /*
- * unsigned Month :4; // 1 - 12
- * unsigned Day :6; // 1 - 32
- * unsigned Hour :6; // 0 - 23
- * unsigned Minute :6; // 0 - 60
- * unsigned Second :6; // 0 - 60
+ * unsigned Month :4; // 1 - 12
+ * unsigned Day :6; // 1 - 32
+ * unsigned Hour :6; // 0 - 23
+ * unsigned Minute :6; // 0 - 60
+ * unsigned Second :6; // 0 - 60
*/
__le32 serial[2]; /* e.g., 0x1DEADB0BFAFAF001 */
};
@@ -184,7 +184,7 @@ struct creation_info
/*
* Set the queues on a 16 byte alignment
*/
-
+
#define QUEUE_ALIGNMENT 16
/*
@@ -203,9 +203,9 @@ struct aac_entry {
* The adapter assumes the ProducerIndex and ConsumerIndex are grouped
* adjacently and in that order.
*/
-
+
struct aac_qhdr {
- __le64 header_addr;/* Address to hand the adapter to access
+ __le64 header_addr;/* Address to hand the adapter to access
to this queue head */
__le32 *producer; /* The producer index for this queue (host address) */
__le32 *consumer; /* The consumer index for this queue (host address) */
@@ -215,7 +215,7 @@ struct aac_qhdr {
* Define all the events which the adapter would like to notify
* the host of.
*/
-
+
#define HostNormCmdQue 1 /* Change in host normal priority command queue */
#define HostHighCmdQue 2 /* Change in host high priority command queue */
#define HostNormRespQue 3 /* Change in host normal priority response queue */
@@ -286,17 +286,17 @@ struct aac_fibhdr {
u8 StructType; /* Type FIB */
u8 Flags; /* Flags for FIB */
__le16 Size; /* Size of this FIB in bytes */
- __le16 SenderSize; /* Size of the FIB in the sender
+ __le16 SenderSize; /* Size of the FIB in the sender
(for response sizing) */
__le32 SenderFibAddress; /* Host defined data in the FIB */
- __le32 ReceiverFibAddress;/* Logical address of this FIB for
+ __le32 ReceiverFibAddress;/* Logical address of this FIB for
the adapter */
u32 SenderData; /* Place holder for the sender to store data */
union {
struct {
- __le32 _ReceiverTimeStart; /* Timestamp for
+ __le32 _ReceiverTimeStart; /* Timestamp for
receipt of fib */
- __le32 _ReceiverTimeDone; /* Timestamp for
+ __le32 _ReceiverTimeDone; /* Timestamp for
completion of fib */
} _s;
} _u;
@@ -311,7 +311,7 @@ struct hw_fib {
* FIB commands
*/
-#define TestCommandResponse 1
+#define TestCommandResponse 1
#define TestAdapterCommand 2
/*
* Lowlevel and comm commands
@@ -350,10 +350,6 @@ struct hw_fib {
#define ContainerCommand64 501
#define ContainerRawIo 502
/*
- * Cluster Commands
- */
-#define ClusterCommand 550
-/*
* Scsi Port commands (scsi passthrough)
*/
#define ScsiPortCommand 600
@@ -375,19 +371,19 @@ struct hw_fib {
*/
enum fib_xfer_state {
- HostOwned = (1<<0),
- AdapterOwned = (1<<1),
- FibInitialized = (1<<2),
- FibEmpty = (1<<3),
- AllocatedFromPool = (1<<4),
- SentFromHost = (1<<5),
- SentFromAdapter = (1<<6),
- ResponseExpected = (1<<7),
- NoResponseExpected = (1<<8),
- AdapterProcessed = (1<<9),
- HostProcessed = (1<<10),
- HighPriority = (1<<11),
- NormalPriority = (1<<12),
+ HostOwned = (1<<0),
+ AdapterOwned = (1<<1),
+ FibInitialized = (1<<2),
+ FibEmpty = (1<<3),
+ AllocatedFromPool = (1<<4),
+ SentFromHost = (1<<5),
+ SentFromAdapter = (1<<6),
+ ResponseExpected = (1<<7),
+ NoResponseExpected = (1<<8),
+ AdapterProcessed = (1<<9),
+ HostProcessed = (1<<10),
+ HighPriority = (1<<11),
+ NormalPriority = (1<<12),
Async = (1<<13),
AsyncIo = (1<<13), // rpbfix: remove with new regime
PageFileIo = (1<<14), // rpbfix: remove with new regime
@@ -420,7 +416,7 @@ struct aac_init
__le32 AdapterFibAlign;
__le32 printfbuf;
__le32 printfbufsiz;
- __le32 HostPhysMemPages; /* number of 4k pages of host
+ __le32 HostPhysMemPages; /* number of 4k pages of host
physical memory */
__le32 HostElapsedSeconds; /* number of seconds since 1970. */
/*
@@ -481,7 +477,7 @@ struct adapter_ops
struct aac_driver_ident
{
- int (*init)(struct aac_dev *dev);
+ int (*init)(struct aac_dev *dev);
char * name;
char * vname;
char * model;
@@ -489,7 +485,7 @@ struct aac_driver_ident
int quirks;
};
/*
- * Some adapter firmware needs communication memory
+ * Some adapter firmware needs communication memory
* below 2gig. This tells the init function to set the
* dma mask such that fib memory will be allocated where the
* adapter firmware can get to it.
@@ -521,33 +517,39 @@ struct aac_driver_ident
#define AAC_QUIRK_17SG 0x0010
/*
+ * Some adapter firmware does not support 64 bit scsi passthrough
+ * commands.
+ */
+#define AAC_QUIRK_SCSI_32 0x0020
+
+/*
* The adapter interface specs all queues to be located in the same
* physically contigous block. The host structure that defines the
* commuication queues will assume they are each a separate physically
* contigous memory region that will support them all being one big
- * contigous block.
+ * contigous block.
* There is a command and response queue for each level and direction of
* commuication. These regions are accessed by both the host and adapter.
*/
-
+
struct aac_queue {
- u64 logical; /*address we give the adapter */
+ u64 logical; /*address we give the adapter */
struct aac_entry *base; /*system virtual address */
- struct aac_qhdr headers; /*producer,consumer q headers*/
- u32 entries; /*Number of queue entries */
+ struct aac_qhdr headers; /*producer,consumer q headers*/
+ u32 entries; /*Number of queue entries */
wait_queue_head_t qfull; /*Event to wait on if q full */
wait_queue_head_t cmdready; /*Cmd ready from the adapter */
- /* This is only valid for adapter to host command queues. */
- spinlock_t *lock; /* Spinlock for this queue must take this lock before accessing the lock */
+ /* This is only valid for adapter to host command queues. */
+ spinlock_t *lock; /* Spinlock for this queue must take this lock before accessing the lock */
spinlock_t lockdata; /* Actual lock (used only on one side of the lock) */
- struct list_head cmdq; /* A queue of FIBs which need to be prcessed by the FS thread. This is */
- /* only valid for command queues which receive entries from the adapter. */
+ struct list_head cmdq; /* A queue of FIBs which need to be prcessed by the FS thread. This is */
+ /* only valid for command queues which receive entries from the adapter. */
u32 numpending; /* Number of entries on outstanding queue. */
struct aac_dev * dev; /* Back pointer to adapter structure */
};
/*
- * Message queues. The order here is important, see also the
+ * Message queues. The order here is important, see also the
* queue type ordering
*/
@@ -559,12 +561,12 @@ struct aac_queue_block
/*
* SaP1 Message Unit Registers
*/
-
+
struct sa_drawbridge_CSR {
- /* Offset | Name */
+ /* Offset | Name */
__le32 reserved[10]; /* 00h-27h | Reserved */
u8 LUT_Offset; /* 28h | Lookup Table Offset */
- u8 reserved1[3]; /* 29h-2bh | Reserved */
+ u8 reserved1[3]; /* 29h-2bh | Reserved */
__le32 LUT_Data; /* 2ch | Looup Table Data */
__le32 reserved2[26]; /* 30h-97h | Reserved */
__le16 PRICLEARIRQ; /* 98h | Primary Clear Irq */
@@ -583,8 +585,8 @@ struct sa_drawbridge_CSR {
__le32 MAILBOX5; /* bch | Scratchpad 5 */
__le32 MAILBOX6; /* c0h | Scratchpad 6 */
__le32 MAILBOX7; /* c4h | Scratchpad 7 */
- __le32 ROM_Setup_Data; /* c8h | Rom Setup and Data */
- __le32 ROM_Control_Addr;/* cch | Rom Control and Address */
+ __le32 ROM_Setup_Data; /* c8h | Rom Setup and Data */
+ __le32 ROM_Control_Addr;/* cch | Rom Control and Address */
__le32 reserved3[12]; /* d0h-ffh | reserved */
__le32 LUT[64]; /* 100h-1ffh | Lookup Table Entries */
};
@@ -597,7 +599,7 @@ struct sa_drawbridge_CSR {
#define Mailbox5 SaDbCSR.MAILBOX5
#define Mailbox6 SaDbCSR.MAILBOX6
#define Mailbox7 SaDbCSR.MAILBOX7
-
+
#define DoorbellReg_p SaDbCSR.PRISETIRQ
#define DoorbellReg_s SaDbCSR.SECSETIRQ
#define DoorbellClrReg_p SaDbCSR.PRICLEARIRQ
@@ -611,19 +613,19 @@ struct sa_drawbridge_CSR {
#define DOORBELL_5 0x0020
#define DOORBELL_6 0x0040
-
+
#define PrintfReady DOORBELL_5
#define PrintfDone DOORBELL_5
-
+
struct sa_registers {
struct sa_drawbridge_CSR SaDbCSR; /* 98h - c4h */
};
-
+
#define Sa_MINIPORT_REVISION 1
#define sa_readw(AEP, CSR) readl(&((AEP)->regs.sa->CSR))
-#define sa_readl(AEP, CSR) readl(&((AEP)->regs.sa->CSR))
+#define sa_readl(AEP, CSR) readl(&((AEP)->regs.sa->CSR))
#define sa_writew(AEP, CSR, value) writew(value, &((AEP)->regs.sa->CSR))
#define sa_writel(AEP, CSR, value) writel(value, &((AEP)->regs.sa->CSR))
@@ -640,21 +642,21 @@ struct rx_mu_registers {
__le32 IMRx[2]; /* 1310h | 10h | Inbound Message Registers */
__le32 OMRx[2]; /* 1318h | 18h | Outbound Message Registers */
__le32 IDR; /* 1320h | 20h | Inbound Doorbell Register */
- __le32 IISR; /* 1324h | 24h | Inbound Interrupt
+ __le32 IISR; /* 1324h | 24h | Inbound Interrupt
Status Register */
- __le32 IIMR; /* 1328h | 28h | Inbound Interrupt
- Mask Register */
+ __le32 IIMR; /* 1328h | 28h | Inbound Interrupt
+ Mask Register */
__le32 ODR; /* 132Ch | 2Ch | Outbound Doorbell Register */
- __le32 OISR; /* 1330h | 30h | Outbound Interrupt
+ __le32 OISR; /* 1330h | 30h | Outbound Interrupt
Status Register */
- __le32 OIMR; /* 1334h | 34h | Outbound Interrupt
+ __le32 OIMR; /* 1334h | 34h | Outbound Interrupt
Mask Register */
__le32 reserved2; /* 1338h | 38h | Reserved */
__le32 reserved3; /* 133Ch | 3Ch | Reserved */
__le32 InboundQueue;/* 1340h | 40h | Inbound Queue Port relative to firmware */
__le32 OutboundQueue;/*1344h | 44h | Outbound Queue Port relative to firmware */
- /* * Must access through ATU Inbound
- Translation Window */
+ /* * Must access through ATU Inbound
+ Translation Window */
};
struct rx_inbound {
@@ -710,12 +712,12 @@ struct rkt_registers {
typedef void (*fib_callback)(void *ctxt, struct fib *fibctx);
struct aac_fib_context {
- s16 type; // used for verification of structure
- s16 size;
+ s16 type; // used for verification of structure
+ s16 size;
u32 unique; // unique value representing this context
ulong jiffies; // used for cleanup - dmb changed to ulong
struct list_head next; // used to link context's into a linked list
- struct semaphore wait_sem; // this is used to wait for the next fib to arrive.
+ struct semaphore wait_sem; // this is used to wait for the next fib to arrive.
int wait; // Set to true when thread is in WaitForSingleObject
unsigned long count; // total number of FIBs on FibList
struct list_head fib_list; // this holds fibs and their attachd hw_fibs
@@ -734,9 +736,9 @@ struct sense_data {
u8 EOM:1; /* End Of Medium - reserved for random access devices */
u8 filemark:1; /* Filemark - reserved for random access devices */
- u8 information[4]; /* for direct-access devices, contains the unsigned
- * logical block address or residue associated with
- * the sense key
+ u8 information[4]; /* for direct-access devices, contains the unsigned
+ * logical block address or residue associated with
+ * the sense key
*/
u8 add_sense_len; /* number of additional sense bytes to follow this field */
u8 cmnd_info[4]; /* not used */
@@ -746,7 +748,7 @@ struct sense_data {
u8 bit_ptr:3; /* indicates which byte of the CDB or parameter data
* was in error
*/
- u8 BPV:1; /* bit pointer valid (BPV): 1- indicates that
+ u8 BPV:1; /* bit pointer valid (BPV): 1- indicates that
* the bit_ptr field has valid value
*/
u8 reserved2:2;
@@ -780,24 +782,24 @@ struct fib {
/*
* The Adapter that this I/O is destined for.
*/
- struct aac_dev *dev;
+ struct aac_dev *dev;
/*
* This is the event the sendfib routine will wait on if the
* caller did not pass one and this is synch io.
*/
- struct semaphore event_wait;
+ struct semaphore event_wait;
spinlock_t event_lock;
u32 done; /* gets set to 1 when fib is complete */
- fib_callback callback;
- void *callback_data;
+ fib_callback callback;
+ void *callback_data;
u32 flags; // u32 dmb was ulong
/*
* And for the internal issue/reply queues (we may be able
* to merge these two)
*/
struct list_head fiblink;
- void *data;
+ void *data;
struct hw_fib *hw_fib_va; /* Actual shared object */
dma_addr_t hw_fib_pa; /* physical address of hw_fib*/
};
@@ -807,7 +809,7 @@ struct fib {
*
* This is returned by the RequestAdapterInfo block
*/
-
+
struct aac_adapter_info
{
__le32 platform;
@@ -826,7 +828,7 @@ struct aac_adapter_info
__le32 biosrev;
__le32 biosbuild;
__le32 cluster;
- __le32 clusterchannelmask;
+ __le32 clusterchannelmask;
__le32 serial[2];
__le32 battery;
__le32 options;
@@ -863,9 +865,10 @@ struct aac_supplement_adapter_info
__le32 SupportedOptions2;
__le32 ReservedGrowth[1];
};
-#define AAC_FEATURE_FALCON 0x00000010
-#define AAC_OPTION_MU_RESET 0x00000001
-#define AAC_OPTION_IGNORE_RESET 0x00000002
+#define AAC_FEATURE_FALCON cpu_to_le32(0x00000010)
+#define AAC_FEATURE_JBOD cpu_to_le32(0x08000000)
+#define AAC_OPTION_MU_RESET cpu_to_le32(0x00000001)
+#define AAC_OPTION_IGNORE_RESET cpu_to_le32(0x00000002)
#define AAC_SIS_VERSION_V3 3
#define AAC_SIS_SLOT_UNKNOWN 0xFF
@@ -916,13 +919,13 @@ struct aac_bus_info_response {
#define AAC_OPT_HOST_TIME_FIB cpu_to_le32(1<<4)
#define AAC_OPT_RAID50 cpu_to_le32(1<<5)
#define AAC_OPT_4GB_WINDOW cpu_to_le32(1<<6)
-#define AAC_OPT_SCSI_UPGRADEABLE cpu_to_le32(1<<7)
+#define AAC_OPT_SCSI_UPGRADEABLE cpu_to_le32(1<<7)
#define AAC_OPT_SOFT_ERR_REPORT cpu_to_le32(1<<8)
-#define AAC_OPT_SUPPORTED_RECONDITION cpu_to_le32(1<<9)
+#define AAC_OPT_SUPPORTED_RECONDITION cpu_to_le32(1<<9)
#define AAC_OPT_SGMAP_HOST64 cpu_to_le32(1<<10)
#define AAC_OPT_ALARM cpu_to_le32(1<<11)
#define AAC_OPT_NONDASD cpu_to_le32(1<<12)
-#define AAC_OPT_SCSI_MANAGED cpu_to_le32(1<<13)
+#define AAC_OPT_SCSI_MANAGED cpu_to_le32(1<<13)
#define AAC_OPT_RAID_SCSI_MODE cpu_to_le32(1<<14)
#define AAC_OPT_SUPPLEMENT_ADAPTER_INFO cpu_to_le32(1<<16)
#define AAC_OPT_NEW_COMM cpu_to_le32(1<<17)
@@ -942,7 +945,7 @@ struct aac_dev
/*
* Map for 128 fib objects (64k)
- */
+ */
dma_addr_t hw_fib_pa;
struct hw_fib *hw_fib_va;
struct hw_fib *aif_base_va;
@@ -953,24 +956,24 @@ struct aac_dev
struct fib *free_fib;
spinlock_t fib_lock;
-
+
struct aac_queue_block *queues;
/*
* The user API will use an IOCTL to register itself to receive
* FIBs from the adapter. The following list is used to keep
* track of all the threads that have requested these FIBs. The
- * mutex is used to synchronize access to all data associated
+ * mutex is used to synchronize access to all data associated
* with the adapter fibs.
*/
struct list_head fib_list;
struct adapter_ops a_ops;
unsigned long fsrev; /* Main driver's revision number */
-
+
unsigned base_size; /* Size of mapped in region */
struct aac_init *init; /* Holds initialization info to communicate with adapter */
- dma_addr_t init_pa; /* Holds physical address of the init struct */
-
+ dma_addr_t init_pa; /* Holds physical address of the init struct */
+
struct pci_dev *pdev; /* Our PCI interface */
void * printfbuf; /* pointer to buffer used for printf's from the adapter */
void * comm_addr; /* Base address of Comm area */
@@ -984,11 +987,11 @@ struct aac_dev
struct fsa_dev_info *fsa_dev;
struct task_struct *thread;
int cardtype;
-
+
/*
* The following is the device specific extension.
*/
-#if (!defined(AAC_MIN_FOOTPRINT_SIZE))
+#ifndef AAC_MIN_FOOTPRINT_SIZE
# define AAC_MIN_FOOTPRINT_SIZE 8192
#endif
union
@@ -1009,7 +1012,9 @@ struct aac_dev
/* These are in adapter info but they are in the io flow so
* lets break them out so we don't have to do an AND to check them
*/
- u8 nondasd_support;
+ u8 nondasd_support;
+ u8 jbod;
+ u8 cache_protected;
u8 dac_support;
u8 raid_scsi_mode;
u8 comm_interface;
@@ -1066,18 +1071,19 @@ struct aac_dev
(dev)->a_ops.adapter_comm(dev, comm)
#define FIB_CONTEXT_FLAG_TIMED_OUT (0x00000001)
+#define FIB_CONTEXT_FLAG (0x00000002)
/*
* Define the command values
*/
-
+
#define Null 0
-#define GetAttributes 1
-#define SetAttributes 2
-#define Lookup 3
-#define ReadLink 4
-#define Read 5
-#define Write 6
+#define GetAttributes 1
+#define SetAttributes 2
+#define Lookup 3
+#define ReadLink 4
+#define Read 5
+#define Write 6
#define Create 7
#define MakeDirectory 8
#define SymbolicLink 9
@@ -1173,19 +1179,19 @@ struct aac_dev
struct aac_read
{
- __le32 command;
- __le32 cid;
- __le32 block;
- __le32 count;
+ __le32 command;
+ __le32 cid;
+ __le32 block;
+ __le32 count;
struct sgmap sg; // Must be last in struct because it is variable
};
struct aac_read64
{
- __le32 command;
- __le16 cid;
- __le16 sector_count;
- __le32 block;
+ __le32 command;
+ __le16 cid;
+ __le16 sector_count;
+ __le32 block;
__le16 pad;
__le16 flags;
struct sgmap64 sg; // Must be last in struct because it is variable
@@ -1193,26 +1199,26 @@ struct aac_read64
struct aac_read_reply
{
- __le32 status;
- __le32 count;
+ __le32 status;
+ __le32 count;
};
struct aac_write
{
__le32 command;
- __le32 cid;
- __le32 block;
- __le32 count;
- __le32 stable; // Not used
+ __le32 cid;
+ __le32 block;
+ __le32 count;
+ __le32 stable; // Not used
struct sgmap sg; // Must be last in struct because it is variable
};
struct aac_write64
{
- __le32 command;
- __le16 cid;
- __le16 sector_count;
- __le32 block;
+ __le32 command;
+ __le16 cid;
+ __le16 sector_count;
+ __le32 block;
__le16 pad;
__le16 flags;
#define IO_TYPE_WRITE 0x00000000
@@ -1223,7 +1229,7 @@ struct aac_write64
struct aac_write_reply
{
__le32 status;
- __le32 count;
+ __le32 count;
__le32 committed;
};
@@ -1326,10 +1332,10 @@ struct aac_srb_reply
#define SRB_NoDataXfer 0x0000
#define SRB_DisableDisconnect 0x0004
#define SRB_DisableSynchTransfer 0x0008
-#define SRB_BypassFrozenQueue 0x0010
+#define SRB_BypassFrozenQueue 0x0010
#define SRB_DisableAutosense 0x0020
#define SRB_DataIn 0x0040
-#define SRB_DataOut 0x0080
+#define SRB_DataOut 0x0080
/*
* SRB Functions - set in aac_srb->function
@@ -1352,7 +1358,7 @@ struct aac_srb_reply
#define SRBF_RemoveDevice 0x0016
#define SRBF_DomainValidation 0x0017
-/*
+/*
* SRB SCSI Status - set in aac_srb->scsi_status
*/
#define SRB_STATUS_PENDING 0x00
@@ -1511,17 +1517,17 @@ struct aac_get_container_count_resp {
*/
struct aac_mntent {
- __le32 oid;
+ __le32 oid;
u8 name[16]; /* if applicable */
struct creation_info create_info; /* if applicable */
__le32 capacity;
- __le32 vol; /* substrate structure */
- __le32 obj; /* FT_FILESYS, etc. */
- __le32 state; /* unready for mounting,
+ __le32 vol; /* substrate structure */
+ __le32 obj; /* FT_FILESYS, etc. */
+ __le32 state; /* unready for mounting,
readonly, etc. */
- union aac_contentinfo fileinfo; /* Info specific to content
+ union aac_contentinfo fileinfo; /* Info specific to content
manager (eg, filesystem) */
- __le32 altoid; /* != oid <==> snapshot or
+ __le32 altoid; /* != oid <==> snapshot or
broken mirror exists */
__le32 capacityhigh;
};
@@ -1538,7 +1544,7 @@ struct aac_query_mount {
struct aac_mount {
__le32 status;
- __le32 type; /* should be same as that requested */
+ __le32 type; /* should be same as that requested */
__le32 count;
struct aac_mntent mnt[1];
};
@@ -1608,7 +1614,7 @@ struct aac_delete_disk {
u32 disknum;
u32 cnum;
};
-
+
struct fib_ioctl
{
u32 fibctx;
@@ -1622,10 +1628,10 @@ struct revision
__le32 version;
__le32 build;
};
-
+
/*
- * Ugly - non Linux like ioctl coding for back compat.
+ * Ugly - non Linux like ioctl coding for back compat.
*/
#define CTL_CODE(function, method) ( \
@@ -1633,7 +1639,7 @@ struct revision
)
/*
- * Define the method codes for how buffers are passed for I/O and FS
+ * Define the method codes for how buffers are passed for I/O and FS
* controls
*/
@@ -1644,15 +1650,15 @@ struct revision
* Filesystem ioctls
*/
-#define FSACTL_SENDFIB CTL_CODE(2050, METHOD_BUFFERED)
-#define FSACTL_SEND_RAW_SRB CTL_CODE(2067, METHOD_BUFFERED)
+#define FSACTL_SENDFIB CTL_CODE(2050, METHOD_BUFFERED)
+#define FSACTL_SEND_RAW_SRB CTL_CODE(2067, METHOD_BUFFERED)
#define FSACTL_DELETE_DISK 0x163
#define FSACTL_QUERY_DISK 0x173
#define FSACTL_OPEN_GET_ADAPTER_FIB CTL_CODE(2100, METHOD_BUFFERED)
#define FSACTL_GET_NEXT_ADAPTER_FIB CTL_CODE(2101, METHOD_BUFFERED)
#define FSACTL_CLOSE_GET_ADAPTER_FIB CTL_CODE(2102, METHOD_BUFFERED)
#define FSACTL_MINIPORT_REV_CHECK CTL_CODE(2107, METHOD_BUFFERED)
-#define FSACTL_GET_PCI_INFO CTL_CODE(2119, METHOD_BUFFERED)
+#define FSACTL_GET_PCI_INFO CTL_CODE(2119, METHOD_BUFFERED)
#define FSACTL_FORCE_DELETE_DISK CTL_CODE(2120, METHOD_NEITHER)
#define FSACTL_GET_CONTAINERS 2131
#define FSACTL_SEND_LARGE_FIB CTL_CODE(2138, METHOD_BUFFERED)
@@ -1661,7 +1667,7 @@ struct revision
struct aac_common
{
/*
- * If this value is set to 1 then interrupt moderation will occur
+ * If this value is set to 1 then interrupt moderation will occur
* in the base commuication support.
*/
u32 irq_mod;
@@ -1690,11 +1696,11 @@ extern struct aac_common aac_config;
* The following macro is used when sending and receiving FIBs. It is
* only used for debugging.
*/
-
+
#ifdef DBG
#define FIB_COUNTER_INCREMENT(counter) (counter)++
#else
-#define FIB_COUNTER_INCREMENT(counter)
+#define FIB_COUNTER_INCREMENT(counter)
#endif
/*
@@ -1726,17 +1732,17 @@ extern struct aac_common aac_config;
*
* The adapter reports is present state through the phase. Only
* a single phase should be ever be set. Each phase can have multiple
- * phase status bits to provide more detailed information about the
- * state of the board. Care should be taken to ensure that any phase
+ * phase status bits to provide more detailed information about the
+ * state of the board. Care should be taken to ensure that any phase
* status bits that are set when changing the phase are also valid
* for the new phase or be cleared out. Adapter software (monitor,
- * iflash, kernel) is responsible for properly maintining the phase
+ * iflash, kernel) is responsible for properly maintining the phase
* status mailbox when it is running.
- *
- * MONKER_API Phases
*
- * Phases are bit oriented. It is NOT valid to have multiple bits set
- */
+ * MONKER_API Phases
+ *
+ * Phases are bit oriented. It is NOT valid to have multiple bits set
+ */
#define SELF_TEST_FAILED 0x00000004
#define MONITOR_PANIC 0x00000020
@@ -1759,16 +1765,22 @@ extern struct aac_common aac_config;
* For FIB communication, we need all of the following things
* to send back to the user.
*/
-
-#define AifCmdEventNotify 1 /* Notify of event */
+
+#define AifCmdEventNotify 1 /* Notify of event */
#define AifEnConfigChange 3 /* Adapter configuration change */
#define AifEnContainerChange 4 /* Container configuration change */
#define AifEnDeviceFailure 5 /* SCSI device failed */
+#define AifEnEnclosureManagement 13 /* EM_DRIVE_* */
+#define EM_DRIVE_INSERTION 31
+#define EM_DRIVE_REMOVAL 32
+#define AifEnBatteryEvent 14 /* Change in Battery State */
#define AifEnAddContainer 15 /* A new array was created */
#define AifEnDeleteContainer 16 /* A container was deleted */
#define AifEnExpEvent 23 /* Firmware Event Log */
#define AifExeFirmwarePanic 3 /* Firmware Event Panic */
#define AifHighPriority 3 /* Highest Priority Event */
+#define AifEnAddJBOD 30 /* JBOD created */
+#define AifEnDeleteJBOD 31 /* JBOD deleted */
#define AifCmdJobProgress 2 /* Progress report */
#define AifJobCtrZero 101 /* Array Zero progress */
@@ -1780,11 +1792,11 @@ extern struct aac_common aac_config;
#define AifDenVolumeExtendComplete 201 /* A volume extend completed */
#define AifReqJobList 100 /* Gets back complete job list */
#define AifReqJobsForCtr 101 /* Gets back jobs for specific container */
-#define AifReqJobsForScsi 102 /* Gets back jobs for specific SCSI device */
-#define AifReqJobReport 103 /* Gets back a specific job report or list of them */
+#define AifReqJobsForScsi 102 /* Gets back jobs for specific SCSI device */
+#define AifReqJobReport 103 /* Gets back a specific job report or list of them */
#define AifReqTerminateJob 104 /* Terminates job */
#define AifReqSuspendJob 105 /* Suspends a job */
-#define AifReqResumeJob 106 /* Resumes a job */
+#define AifReqResumeJob 106 /* Resumes a job */
#define AifReqSendAPIReport 107 /* API generic report requests */
#define AifReqAPIJobStart 108 /* Start a job from the API */
#define AifReqAPIJobUpdate 109 /* Update a job report from the API */
@@ -1803,8 +1815,8 @@ struct aac_aifcmd {
};
/**
- * Convert capacity to cylinders
- * accounting for the fact capacity could be a 64 bit value
+ * Convert capacity to cylinders
+ * accounting for the fact capacity could be a 64 bit value
*
*/
static inline unsigned int cap_to_cyls(sector_t capacity, unsigned divisor)
@@ -1861,6 +1873,7 @@ int aac_probe_container(struct aac_dev *dev, int cid);
int _aac_rx_init(struct aac_dev *dev);
int aac_rx_select_comm(struct aac_dev *dev, int comm);
int aac_rx_deliver_producer(struct fib * fib);
+char * get_container_type(unsigned type);
extern int numacb;
extern int acbsize;
extern char aac_driver_version[];
diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c
index 1e6d7a9c75bf..851a7e599c50 100644
--- a/drivers/scsi/aacraid/commctrl.c
+++ b/drivers/scsi/aacraid/commctrl.c
@@ -48,13 +48,13 @@
* ioctl_send_fib - send a FIB from userspace
* @dev: adapter is being processed
* @arg: arguments to the ioctl call
- *
+ *
* This routine sends a fib to the adapter on behalf of a user level
* program.
*/
# define AAC_DEBUG_PREAMBLE KERN_INFO
# define AAC_DEBUG_POSTAMBLE
-
+
static int ioctl_send_fib(struct aac_dev * dev, void __user *arg)
{
struct hw_fib * kfib;
@@ -71,7 +71,7 @@ static int ioctl_send_fib(struct aac_dev * dev, void __user *arg)
if(fibptr == NULL) {
return -ENOMEM;
}
-
+
kfib = fibptr->hw_fib_va;
/*
* First copy in the header so that we can check the size field.
@@ -109,7 +109,7 @@ static int ioctl_send_fib(struct aac_dev * dev, void __user *arg)
if (kfib->header.Command == cpu_to_le16(TakeABreakPt)) {
aac_adapter_interrupt(dev);
/*
- * Since we didn't really send a fib, zero out the state to allow
+ * Since we didn't really send a fib, zero out the state to allow
* cleanup code not to assert.
*/
kfib->header.XferState = 0;
@@ -169,7 +169,7 @@ static int open_getadapter_fib(struct aac_dev * dev, void __user *arg)
fibctx->type = FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT;
fibctx->size = sizeof(struct aac_fib_context);
- /*
+ /*
* Yes yes, I know this could be an index, but we have a
* better guarantee of uniqueness for the locked loop below.
* Without the aid of a persistent history, this also helps
@@ -189,7 +189,7 @@ static int open_getadapter_fib(struct aac_dev * dev, void __user *arg)
INIT_LIST_HEAD(&fibctx->fib_list);
fibctx->jiffies = jiffies/HZ;
/*
- * Now add this context onto the adapter's
+ * Now add this context onto the adapter's
* AdapterFibContext list.
*/
spin_lock_irqsave(&dev->fib_lock, flags);
@@ -207,12 +207,12 @@ static int open_getadapter_fib(struct aac_dev * dev, void __user *arg)
}
list_add_tail(&fibctx->next, &dev->fib_list);
spin_unlock_irqrestore(&dev->fib_lock, flags);
- if (copy_to_user(arg, &fibctx->unique,
+ if (copy_to_user(arg, &fibctx->unique,
sizeof(fibctx->unique))) {
status = -EFAULT;
} else {
status = 0;
- }
+ }
}
return status;
}
@@ -221,8 +221,8 @@ static int open_getadapter_fib(struct aac_dev * dev, void __user *arg)
* next_getadapter_fib - get the next fib
* @dev: adapter to use
* @arg: ioctl argument
- *
- * This routine will get the next Fib, if available, from the AdapterFibContext
+ *
+ * This routine will get the next Fib, if available, from the AdapterFibContext
* passed in from the user.
*/
@@ -234,7 +234,7 @@ static int next_getadapter_fib(struct aac_dev * dev, void __user *arg)
int status;
struct list_head * entry;
unsigned long flags;
-
+
if(copy_from_user((void *)&f, arg, sizeof(struct fib_ioctl)))
return -EFAULT;
/*
@@ -243,6 +243,7 @@ static int next_getadapter_fib(struct aac_dev * dev, void __user *arg)
* Search the list of AdapterFibContext addresses on the adapter
* to be sure this is a valid address
*/
+ spin_lock_irqsave(&dev->fib_lock, flags);
entry = dev->fib_list.next;
fibctx = NULL;
@@ -251,37 +252,37 @@ static int next_getadapter_fib(struct aac_dev * dev, void __user *arg)
/*
* Extract the AdapterFibContext from the Input parameters.
*/
- if (fibctx->unique == f.fibctx) { /* We found a winner */
+ if (fibctx->unique == f.fibctx) { /* We found a winner */
break;
}
entry = entry->next;
fibctx = NULL;
}
if (!fibctx) {
+ spin_unlock_irqrestore(&dev->fib_lock, flags);
dprintk ((KERN_INFO "Fib Context not found\n"));
return -EINVAL;
}
if((fibctx->type != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
(fibctx->size != sizeof(struct aac_fib_context))) {
+ spin_unlock_irqrestore(&dev->fib_lock, flags);
dprintk ((KERN_INFO "Fib Context corrupt?\n"));
return -EINVAL;
}
status = 0;
- spin_lock_irqsave(&dev->fib_lock, flags);
/*
* If there are no fibs to send back, then either wait or return
* -EAGAIN
*/
return_fib:
if (!list_empty(&fibctx->fib_list)) {
- struct list_head * entry;
/*
* Pull the next fib from the fibs
*/
entry = fibctx->fib_list.next;
list_del(entry);
-
+
fib = list_entry(entry, struct fib, fiblink);
fibctx->count--;
spin_unlock_irqrestore(&dev->fib_lock, flags);
@@ -289,7 +290,7 @@ return_fib:
kfree(fib->hw_fib_va);
kfree(fib);
return -EFAULT;
- }
+ }
/*
* Free the space occupied by this copy of the fib.
*/
@@ -318,7 +319,7 @@ return_fib:
}
} else {
status = -EAGAIN;
- }
+ }
}
fibctx->jiffies = jiffies/HZ;
return status;
@@ -327,7 +328,9 @@ return_fib:
int aac_close_fib_context(struct aac_dev * dev, struct aac_fib_context * fibctx)
{
struct fib *fib;
+ unsigned long flags;
+ spin_lock_irqsave(&dev->fib_lock, flags);
/*
* First free any FIBs that have not been consumed.
*/
@@ -350,6 +353,7 @@ int aac_close_fib_context(struct aac_dev * dev, struct aac_fib_context * fibctx)
* Remove the Context from the AdapterFibContext List
*/
list_del(&fibctx->next);
+ spin_unlock_irqrestore(&dev->fib_lock, flags);
/*
* Invalidate context
*/
@@ -368,7 +372,7 @@ int aac_close_fib_context(struct aac_dev * dev, struct aac_fib_context * fibctx)
*
* This routine will close down the fibctx passed in from the user.
*/
-
+
static int close_getadapter_fib(struct aac_dev * dev, void __user *arg)
{
struct aac_fib_context *fibctx;
@@ -415,8 +419,8 @@ static int close_getadapter_fib(struct aac_dev * dev, void __user *arg)
* @arg: ioctl arguments
*
* This routine returns the driver version.
- * Under Linux, there have been no version incompatibilities, so this is
- * simple!
+ * Under Linux, there have been no version incompatibilities, so this is
+ * simple!
*/
static int check_revision(struct aac_dev *dev, void __user *arg)
@@ -426,12 +430,12 @@ static int check_revision(struct aac_dev *dev, void __user *arg)
u32 version;
response.compat = 1;
- version = (simple_strtol(driver_version,
+ version = (simple_strtol(driver_version,
&driver_version, 10) << 24) | 0x00000400;
version += simple_strtol(driver_version + 1, &driver_version, 10) << 16;
version += simple_strtol(driver_version + 1, NULL, 10);
response.version = cpu_to_le32(version);
-# if (defined(AAC_DRIVER_BUILD))
+# ifdef AAC_DRIVER_BUILD
response.build = cpu_to_le32(AAC_DRIVER_BUILD);
# else
response.build = cpu_to_le32(9999);
@@ -464,7 +468,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
u32 data_dir;
void __user *sg_user[32];
void *sg_list[32];
- u32 sg_indx = 0;
+ u32 sg_indx = 0;
u32 byte_count = 0;
u32 actual_fibsize64, actual_fibsize = 0;
int i;
@@ -475,7 +479,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
return -EBUSY;
}
if (!capable(CAP_SYS_ADMIN)){
- dprintk((KERN_DEBUG"aacraid: No permission to send raw srb\n"));
+ dprintk((KERN_DEBUG"aacraid: No permission to send raw srb\n"));
return -EPERM;
}
/*
@@ -490,7 +494,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
memset(sg_list, 0, sizeof(sg_list)); /* cleanup may take issue */
if(copy_from_user(&fibsize, &user_srb->count,sizeof(u32))){
- dprintk((KERN_DEBUG"aacraid: Could not copy data size from user\n"));
+ dprintk((KERN_DEBUG"aacraid: Could not copy data size from user\n"));
rcode = -EFAULT;
goto cleanup;
}
@@ -507,7 +511,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
goto cleanup;
}
if(copy_from_user(user_srbcmd, user_srb,fibsize)){
- dprintk((KERN_DEBUG"aacraid: Could not copy srb from user\n"));
+ dprintk((KERN_DEBUG"aacraid: Could not copy srb from user\n"));
rcode = -EFAULT;
goto cleanup;
}
@@ -518,15 +522,15 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
// Fix up srb for endian and force some values
srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi); // Force this
- srbcmd->channel = cpu_to_le32(user_srbcmd->channel);
+ srbcmd->channel = cpu_to_le32(user_srbcmd->channel);
srbcmd->id = cpu_to_le32(user_srbcmd->id);
- srbcmd->lun = cpu_to_le32(user_srbcmd->lun);
- srbcmd->timeout = cpu_to_le32(user_srbcmd->timeout);
- srbcmd->flags = cpu_to_le32(flags);
+ srbcmd->lun = cpu_to_le32(user_srbcmd->lun);
+ srbcmd->timeout = cpu_to_le32(user_srbcmd->timeout);
+ srbcmd->flags = cpu_to_le32(flags);
srbcmd->retry_limit = 0; // Obsolete parameter
srbcmd->cdb_size = cpu_to_le32(user_srbcmd->cdb_size);
memcpy(srbcmd->cdb, user_srbcmd->cdb, sizeof(srbcmd->cdb));
-
+
switch (flags & (SRB_DataIn | SRB_DataOut)) {
case SRB_DataOut:
data_dir = DMA_TO_DEVICE;
@@ -582,7 +586,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
void* p;
/* Does this really need to be GFP_DMA? */
p = kmalloc(upsg->sg[i].count,GFP_KERNEL|__GFP_DMA);
- if(p == 0) {
+ if(!p) {
dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
upsg->sg[i].count,i,upsg->count));
rcode = -ENOMEM;
@@ -594,7 +598,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
sg_list[i] = p; // save so we can clean up later
sg_indx = i;
- if( flags & SRB_DataOut ){
+ if (flags & SRB_DataOut) {
if(copy_from_user(p,sg_user[i],upsg->sg[i].count)){
dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n"));
rcode = -EFAULT;
@@ -626,7 +630,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
void* p;
/* Does this really need to be GFP_DMA? */
p = kmalloc(usg->sg[i].count,GFP_KERNEL|__GFP_DMA);
- if(p == 0) {
+ if(!p) {
kfree (usg);
dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
usg->sg[i].count,i,usg->count));
@@ -637,7 +641,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
sg_list[i] = p; // save so we can clean up later
sg_indx = i;
- if( flags & SRB_DataOut ){
+ if (flags & SRB_DataOut) {
if(copy_from_user(p,sg_user[i],upsg->sg[i].count)){
kfree (usg);
dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n"));
@@ -668,7 +672,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
void* p;
/* Does this really need to be GFP_DMA? */
p = kmalloc(usg->sg[i].count,GFP_KERNEL|__GFP_DMA);
- if(p == 0) {
+ if(!p) {
dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
usg->sg[i].count,i,usg->count));
rcode = -ENOMEM;
@@ -680,7 +684,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
sg_list[i] = p; // save so we can clean up later
sg_indx = i;
- if( flags & SRB_DataOut ){
+ if (flags & SRB_DataOut) {
if(copy_from_user(p,sg_user[i],usg->sg[i].count)){
dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n"));
rcode = -EFAULT;
@@ -698,7 +702,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
dma_addr_t addr;
void* p;
p = kmalloc(upsg->sg[i].count, GFP_KERNEL);
- if(p == 0) {
+ if (!p) {
dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
upsg->sg[i].count, i, upsg->count));
rcode = -ENOMEM;
@@ -708,7 +712,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
sg_list[i] = p; // save so we can clean up later
sg_indx = i;
- if( flags & SRB_DataOut ){
+ if (flags & SRB_DataOut) {
if(copy_from_user(p, sg_user[i],
upsg->sg[i].count)) {
dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n"));
@@ -734,19 +738,19 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
}
if (status != 0){
- dprintk((KERN_DEBUG"aacraid: Could not send raw srb fib to hba\n"));
+ dprintk((KERN_DEBUG"aacraid: Could not send raw srb fib to hba\n"));
rcode = -ENXIO;
goto cleanup;
}
- if( flags & SRB_DataIn ) {
+ if (flags & SRB_DataIn) {
for(i = 0 ; i <= sg_indx; i++){
byte_count = le32_to_cpu(
(dev->adapter_info.options & AAC_OPT_SGMAP_HOST64)
? ((struct sgmap64*)&srbcmd->sg)->sg[i].count
: srbcmd->sg.sg[i].count);
if(copy_to_user(sg_user[i], sg_list[i], byte_count)){
- dprintk((KERN_DEBUG"aacraid: Could not copy sg data to user\n"));
+ dprintk((KERN_DEBUG"aacraid: Could not copy sg data to user\n"));
rcode = -EFAULT;
goto cleanup;
@@ -756,7 +760,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
reply = (struct aac_srb_reply *) fib_data(srbfib);
if(copy_to_user(user_reply,reply,sizeof(struct aac_srb_reply))){
- dprintk((KERN_DEBUG"aacraid: Could not copy reply to user\n"));
+ dprintk((KERN_DEBUG"aacraid: Could not copy reply to user\n"));
rcode = -EFAULT;
goto cleanup;
}
@@ -775,34 +779,34 @@ cleanup:
}
struct aac_pci_info {
- u32 bus;
- u32 slot;
+ u32 bus;
+ u32 slot;
};
static int aac_get_pci_info(struct aac_dev* dev, void __user *arg)
{
- struct aac_pci_info pci_info;
+ struct aac_pci_info pci_info;
pci_info.bus = dev->pdev->bus->number;
pci_info.slot = PCI_SLOT(dev->pdev->devfn);
- if (copy_to_user(arg, &pci_info, sizeof(struct aac_pci_info))) {
- dprintk((KERN_DEBUG "aacraid: Could not copy pci info\n"));
- return -EFAULT;
+ if (copy_to_user(arg, &pci_info, sizeof(struct aac_pci_info))) {
+ dprintk((KERN_DEBUG "aacraid: Could not copy pci info\n"));
+ return -EFAULT;
}
- return 0;
+ return 0;
}
-
+
int aac_do_ioctl(struct aac_dev * dev, int cmd, void __user *arg)
{
int status;
-
+
/*
* HBA gets first crack
*/
-
+
status = aac_dev_ioctl(dev, cmd, arg);
if(status != -ENOTTY)
return status;
@@ -832,7 +836,7 @@ int aac_do_ioctl(struct aac_dev * dev, int cmd, void __user *arg)
break;
default:
status = -ENOTTY;
- break;
+ break;
}
return status;
}
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c
index 8736813a0296..89cc8b7b42a2 100644
--- a/drivers/scsi/aacraid/comminit.c
+++ b/drivers/scsi/aacraid/comminit.c
@@ -301,10 +301,10 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
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)
+ if (status[1] & le32_to_cpu(AAC_OPT_NEW_COMM_64))
dev->raw_io_64 = 1;
if (dev->a_ops.adapter_comm &&
- (status[1] & AAC_OPT_NEW_COMM))
+ (status[1] & le32_to_cpu(AAC_OPT_NEW_COMM)))
dev->comm_interface = AAC_COMM_MESSAGE;
if ((dev->comm_interface == AAC_COMM_MESSAGE) &&
(status[2] > dev->base_size)) {
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index abce48ccc85b..81b36923e0ef 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -56,7 +56,7 @@
* Allocate and map the shared PCI space for the FIB blocks used to
* talk to the Adaptec firmware.
*/
-
+
static int fib_map_alloc(struct aac_dev *dev)
{
dprintk((KERN_INFO
@@ -109,14 +109,16 @@ int aac_fib_setup(struct aac_dev * dev)
}
if (i<0)
return -ENOMEM;
-
+
hw_fib = dev->hw_fib_va;
hw_fib_pa = dev->hw_fib_pa;
memset(hw_fib, 0, dev->max_fib_size * (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB));
/*
* Initialise the fibs
*/
- for (i = 0, fibptr = &dev->fibs[i]; i < (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB); i++, fibptr++)
+ for (i = 0, fibptr = &dev->fibs[i];
+ i < (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB);
+ i++, fibptr++)
{
fibptr->dev = dev;
fibptr->hw_fib_va = hw_fib;
@@ -148,13 +150,13 @@ int aac_fib_setup(struct aac_dev * dev)
* Allocate a fib from the adapter fib pool. If the pool is empty we
* return NULL.
*/
-
+
struct fib *aac_fib_alloc(struct aac_dev *dev)
{
struct fib * fibptr;
unsigned long flags;
spin_lock_irqsave(&dev->fib_lock, flags);
- fibptr = dev->free_fib;
+ fibptr = dev->free_fib;
if(!fibptr){
spin_unlock_irqrestore(&dev->fib_lock, flags);
return fibptr;
@@ -171,6 +173,7 @@ struct fib *aac_fib_alloc(struct aac_dev *dev)
* each I/O
*/
fibptr->hw_fib_va->header.XferState = 0;
+ fibptr->flags = 0;
fibptr->callback = NULL;
fibptr->callback_data = NULL;
@@ -183,7 +186,7 @@ struct fib *aac_fib_alloc(struct aac_dev *dev)
*
* Frees up a fib and places it on the appropriate queue
*/
-
+
void aac_fib_free(struct fib *fibptr)
{
unsigned long flags;
@@ -204,10 +207,10 @@ void aac_fib_free(struct fib *fibptr)
/**
* aac_fib_init - initialise a fib
* @fibptr: The fib to initialize
- *
+ *
* Set up the generic fib fields ready for use
*/
-
+
void aac_fib_init(struct fib *fibptr)
{
struct hw_fib *hw_fib = fibptr->hw_fib_va;
@@ -227,12 +230,12 @@ void aac_fib_init(struct fib *fibptr)
* Will deallocate and return to the free pool the FIB pointed to by the
* caller.
*/
-
+
static void fib_dealloc(struct fib * fibptr)
{
struct hw_fib *hw_fib = fibptr->hw_fib_va;
BUG_ON(hw_fib->header.StructType != FIB_MAGIC);
- hw_fib->header.XferState = 0;
+ hw_fib->header.XferState = 0;
}
/*
@@ -241,7 +244,7 @@ static void fib_dealloc(struct fib * fibptr)
* these routines and are the only routines which have a knowledge of the
* how these queues are implemented.
*/
-
+
/**
* aac_get_entry - get a queue entry
* @dev: Adapter
@@ -254,7 +257,7 @@ static void fib_dealloc(struct fib * fibptr)
* is full(no free entries) than no entry is returned and the function returns 0 otherwise 1 is
* returned.
*/
-
+
static int aac_get_entry (struct aac_dev * dev, u32 qid, struct aac_entry **entry, u32 * index, unsigned long *nonotify)
{
struct aac_queue * q;
@@ -279,26 +282,27 @@ static int aac_get_entry (struct aac_dev * dev, u32 qid, struct aac_entry **entr
idx = ADAP_NORM_RESP_ENTRIES;
}
if (idx != le32_to_cpu(*(q->headers.consumer)))
- *nonotify = 1;
+ *nonotify = 1;
}
if (qid == AdapNormCmdQueue) {
- if (*index >= ADAP_NORM_CMD_ENTRIES)
+ if (*index >= ADAP_NORM_CMD_ENTRIES)
*index = 0; /* Wrap to front of the Producer Queue. */
} else {
- if (*index >= ADAP_NORM_RESP_ENTRIES)
+ if (*index >= ADAP_NORM_RESP_ENTRIES)
*index = 0; /* Wrap to front of the Producer Queue. */
}
- if ((*index + 1) == le32_to_cpu(*(q->headers.consumer))) { /* Queue is full */
+ /* Queue is full */
+ if ((*index + 1) == le32_to_cpu(*(q->headers.consumer))) {
printk(KERN_WARNING "Queue %d full, %u outstanding.\n",
qid, q->numpending);
return 0;
} else {
- *entry = q->base + *index;
+ *entry = q->base + *index;
return 1;
}
-}
+}
/**
* aac_queue_get - get the next free QE
@@ -320,31 +324,29 @@ int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_fib * hw
{
struct aac_entry * entry = NULL;
int map = 0;
-
+
if (qid == AdapNormCmdQueue) {
/* if no entries wait for some if caller wants to */
- while (!aac_get_entry(dev, qid, &entry, index, nonotify))
- {
+ while (!aac_get_entry(dev, qid, &entry, index, nonotify)) {
printk(KERN_ERR "GetEntries failed\n");
}
- /*
- * Setup queue entry with a command, status and fib mapped
- */
- entry->size = cpu_to_le32(le16_to_cpu(hw_fib->header.Size));
- map = 1;
+ /*
+ * Setup queue entry with a command, status and fib mapped
+ */
+ entry->size = cpu_to_le32(le16_to_cpu(hw_fib->header.Size));
+ map = 1;
} else {
- while(!aac_get_entry(dev, qid, &entry, index, nonotify))
- {
+ while (!aac_get_entry(dev, qid, &entry, index, nonotify)) {
/* if no entries wait for some if caller wants to */
}
- /*
- * Setup queue entry with command, status and fib mapped
- */
- entry->size = cpu_to_le32(le16_to_cpu(hw_fib->header.Size));
- entry->addr = hw_fib->header.SenderFibAddress;
- /* Restore adapters pointer to the FIB */
+ /*
+ * Setup queue entry with command, status and fib mapped
+ */
+ entry->size = cpu_to_le32(le16_to_cpu(hw_fib->header.Size));
+ entry->addr = hw_fib->header.SenderFibAddress;
+ /* Restore adapters pointer to the FIB */
hw_fib->header.ReceiverFibAddress = hw_fib->header.SenderFibAddress; /* Let the adapter now where to find its data */
- map = 0;
+ map = 0;
}
/*
* If MapFib is true than we need to map the Fib and put pointers
@@ -356,8 +358,8 @@ int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_fib * hw
}
/*
- * Define the highest level of host to adapter communication routines.
- * These routines will support host to adapter FS commuication. These
+ * Define the highest level of host to adapter communication routines.
+ * These routines will support host to adapter FS commuication. These
* routines have no knowledge of the commuication method used. This level
* sends and receives FIBs. This level has no knowledge of how these FIBs
* get passed back and forth.
@@ -379,7 +381,7 @@ int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_fib * hw
* an event to wait on must be supplied. This event will be set when a
* response FIB is received from the adapter.
*/
-
+
int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
int priority, int wait, int reply, fib_callback callback,
void *callback_data)
@@ -392,16 +394,17 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
if (!(hw_fib->header.XferState & cpu_to_le32(HostOwned)))
return -EBUSY;
/*
- * There are 5 cases with the wait and reponse requested flags.
+ * There are 5 cases with the wait and reponse requested flags.
* The only invalid cases are if the caller requests to wait and
* does not request a response and if the caller does not want a
* response and the Fib is not allocated from pool. If a response
* is not requesed the Fib will just be deallocaed by the DPC
* routine when the response comes back from the adapter. No
- * further processing will be done besides deleting the Fib. We
+ * further processing will be done besides deleting the Fib. We
* will have a debug mode where the adapter can notify the host
* it had a problem and the host can log that fact.
*/
+ fibptr->flags = 0;
if (wait && !reply) {
return -EINVAL;
} else if (!wait && reply) {
@@ -413,7 +416,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
} else if (wait && reply) {
hw_fib->header.XferState |= cpu_to_le32(ResponseExpected);
FIB_COUNTER_INCREMENT(aac_config.NormalSent);
- }
+ }
/*
* Map the fib into 32bits by using the fib number
*/
@@ -436,7 +439,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
hw_fib->header.Size = cpu_to_le16(sizeof(struct aac_fibhdr) + size);
if (le16_to_cpu(hw_fib->header.Size) > le16_to_cpu(hw_fib->header.SenderSize)) {
return -EMSGSIZE;
- }
+ }
/*
* Get a queue entry connect the FIB to it and send an notify
* the adapter a command is ready.
@@ -450,10 +453,10 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
if (!wait) {
fibptr->callback = callback;
fibptr->callback_data = callback_data;
+ fibptr->flags = FIB_CONTEXT_FLAG;
}
fibptr->done = 0;
- fibptr->flags = 0;
FIB_COUNTER_INCREMENT(aac_config.FibsSent);
@@ -473,9 +476,9 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
aac_adapter_deliver(fibptr);
/*
- * If the caller wanted us to wait for response wait now.
+ * If the caller wanted us to wait for response wait now.
*/
-
+
if (wait) {
spin_unlock_irqrestore(&fibptr->event_lock, flags);
/* Only set for first known interruptable command */
@@ -522,7 +525,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
}
spin_unlock_irqrestore(&fibptr->event_lock, flags);
BUG_ON(fibptr->done == 0);
-
+
if(unlikely(fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT))
return -ETIMEDOUT;
return 0;
@@ -537,15 +540,15 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
return 0;
}
-/**
+/**
* aac_consumer_get - get the top of the queue
* @dev: Adapter
* @q: Queue
* @entry: Return entry
*
* Will return a pointer to the entry on the top of the queue requested that
- * we are a consumer of, and return the address of the queue entry. It does
- * not change the state of the queue.
+ * we are a consumer of, and return the address of the queue entry. It does
+ * not change the state of the queue.
*/
int aac_consumer_get(struct aac_dev * dev, struct aac_queue * q, struct aac_entry **entry)
@@ -560,10 +563,10 @@ int aac_consumer_get(struct aac_dev * dev, struct aac_queue * q, struct aac_entr
* the end of the queue, else we just use the entry
* pointed to by the header index
*/
- if (le32_to_cpu(*q->headers.consumer) >= q->entries)
- index = 0;
+ if (le32_to_cpu(*q->headers.consumer) >= q->entries)
+ index = 0;
else
- index = le32_to_cpu(*q->headers.consumer);
+ index = le32_to_cpu(*q->headers.consumer);
*entry = q->base + index;
status = 1;
}
@@ -587,12 +590,12 @@ void aac_consumer_free(struct aac_dev * dev, struct aac_queue *q, u32 qid)
if ((le32_to_cpu(*q->headers.producer)+1) == le32_to_cpu(*q->headers.consumer))
wasfull = 1;
-
+
if (le32_to_cpu(*q->headers.consumer) >= q->entries)
*q->headers.consumer = cpu_to_le32(1);
else
*q->headers.consumer = cpu_to_le32(le32_to_cpu(*q->headers.consumer)+1);
-
+
if (wasfull) {
switch (qid) {
@@ -608,7 +611,7 @@ void aac_consumer_free(struct aac_dev * dev, struct aac_queue *q, u32 qid)
}
aac_adapter_notify(dev, notify);
}
-}
+}
/**
* aac_fib_adapter_complete - complete adapter issued fib
@@ -630,32 +633,32 @@ int aac_fib_adapter_complete(struct fib *fibptr, unsigned short size)
if (hw_fib->header.XferState == 0) {
if (dev->comm_interface == AAC_COMM_MESSAGE)
kfree (hw_fib);
- return 0;
+ return 0;
}
/*
* If we plan to do anything check the structure type first.
- */
- if ( hw_fib->header.StructType != FIB_MAGIC ) {
+ */
+ if (hw_fib->header.StructType != FIB_MAGIC) {
if (dev->comm_interface == AAC_COMM_MESSAGE)
kfree (hw_fib);
- return -EINVAL;
+ return -EINVAL;
}
/*
* This block handles the case where the adapter had sent us a
* command and we have finished processing the command. We
- * call completeFib when we are done processing the command
- * and want to send a response back to the adapter. This will
+ * call completeFib when we are done processing the command
+ * and want to send a response back to the adapter. This will
* send the completed cdb to the adapter.
*/
if (hw_fib->header.XferState & cpu_to_le32(SentFromAdapter)) {
if (dev->comm_interface == AAC_COMM_MESSAGE) {
kfree (hw_fib);
} else {
- u32 index;
- hw_fib->header.XferState |= cpu_to_le32(HostProcessed);
+ u32 index;
+ hw_fib->header.XferState |= cpu_to_le32(HostProcessed);
if (size) {
size += sizeof(struct aac_fibhdr);
- if (size > le16_to_cpu(hw_fib->header.SenderSize))
+ if (size > le16_to_cpu(hw_fib->header.SenderSize))
return -EMSGSIZE;
hw_fib->header.Size = cpu_to_le16(size);
}
@@ -667,12 +670,11 @@ int aac_fib_adapter_complete(struct fib *fibptr, unsigned short size)
if (!(nointr & (int)aac_config.irq_mod))
aac_adapter_notify(dev, AdapNormRespQueue);
}
+ } else {
+ printk(KERN_WARNING "aac_fib_adapter_complete: "
+ "Unknown xferstate detected.\n");
+ BUG();
}
- else
- {
- printk(KERN_WARNING "aac_fib_adapter_complete: Unknown xferstate detected.\n");
- BUG();
- }
return 0;
}
@@ -682,7 +684,7 @@ int aac_fib_adapter_complete(struct fib *fibptr, unsigned short size)
*
* Will do all necessary work to complete a FIB.
*/
-
+
int aac_fib_complete(struct fib *fibptr)
{
struct hw_fib * hw_fib = fibptr->hw_fib_va;
@@ -692,15 +694,15 @@ int aac_fib_complete(struct fib *fibptr)
*/
if (hw_fib->header.XferState == 0)
- return 0;
+ return 0;
/*
* If we plan to do anything check the structure type first.
- */
+ */
if (hw_fib->header.StructType != FIB_MAGIC)
- return -EINVAL;
+ return -EINVAL;
/*
- * This block completes a cdb which orginated on the host and we
+ * This block completes a cdb which orginated on the host and we
* just need to deallocate the cdb or reinit it. At this point the
* command is complete that we had sent to the adapter and this
* cdb could be reused.
@@ -721,7 +723,7 @@ int aac_fib_complete(struct fib *fibptr)
fib_dealloc(fibptr);
} else {
BUG();
- }
+ }
return 0;
}
@@ -741,7 +743,7 @@ void aac_printf(struct aac_dev *dev, u32 val)
{
int length = val & 0xffff;
int level = (val >> 16) & 0xffff;
-
+
/*
* The size of the printfbuf is set in port.c
* There is no variable or define for it
@@ -755,7 +757,7 @@ void aac_printf(struct aac_dev *dev, u32 val)
else
printk(KERN_INFO "%s:%s", dev->name, cp);
}
- memset(cp, 0, 256);
+ memset(cp, 0, 256);
}
@@ -773,20 +775,20 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
{
struct hw_fib * hw_fib = fibptr->hw_fib_va;
struct aac_aifcmd * aifcmd = (struct aac_aifcmd *)hw_fib->data;
- u32 container;
+ u32 channel, id, lun, container;
struct scsi_device *device;
enum {
NOTHING,
DELETE,
ADD,
CHANGE
- } device_config_needed;
+ } device_config_needed = NOTHING;
/* Sniff for container changes */
if (!dev || !dev->fsa_dev)
return;
- container = (u32)-1;
+ container = channel = id = lun = (u32)-1;
/*
* We have set this up to try and minimize the number of
@@ -796,13 +798,13 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
*/
switch (le32_to_cpu(aifcmd->command)) {
case AifCmdDriverNotify:
- switch (le32_to_cpu(((u32 *)aifcmd->data)[0])) {
+ switch (le32_to_cpu(((__le32 *)aifcmd->data)[0])) {
/*
* Morph or Expand complete
*/
case AifDenMorphComplete:
case AifDenVolumeExtendComplete:
- container = le32_to_cpu(((u32 *)aifcmd->data)[1]);
+ container = le32_to_cpu(((__le32 *)aifcmd->data)[1]);
if (container >= dev->maximum_num_containers)
break;
@@ -814,9 +816,9 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
*/
if ((dev != NULL) && (dev->scsi_host_ptr != NULL)) {
- device = scsi_device_lookup(dev->scsi_host_ptr,
- CONTAINER_TO_CHANNEL(container),
- CONTAINER_TO_ID(container),
+ device = scsi_device_lookup(dev->scsi_host_ptr,
+ CONTAINER_TO_CHANNEL(container),
+ CONTAINER_TO_ID(container),
CONTAINER_TO_LUN(container));
if (device) {
dev->fsa_dev[container].config_needed = CHANGE;
@@ -835,25 +837,29 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
if (container >= dev->maximum_num_containers)
break;
if ((dev->fsa_dev[container].config_waiting_on ==
- le32_to_cpu(*(u32 *)aifcmd->data)) &&
+ le32_to_cpu(*(__le32 *)aifcmd->data)) &&
time_before(jiffies, dev->fsa_dev[container].config_waiting_stamp + AIF_SNIFF_TIMEOUT))
dev->fsa_dev[container].config_waiting_on = 0;
} else for (container = 0;
container < dev->maximum_num_containers; ++container) {
if ((dev->fsa_dev[container].config_waiting_on ==
- le32_to_cpu(*(u32 *)aifcmd->data)) &&
+ le32_to_cpu(*(__le32 *)aifcmd->data)) &&
time_before(jiffies, dev->fsa_dev[container].config_waiting_stamp + AIF_SNIFF_TIMEOUT))
dev->fsa_dev[container].config_waiting_on = 0;
}
break;
case AifCmdEventNotify:
- switch (le32_to_cpu(((u32 *)aifcmd->data)[0])) {
+ switch (le32_to_cpu(((__le32 *)aifcmd->data)[0])) {
+ case AifEnBatteryEvent:
+ dev->cache_protected =
+ (((__le32 *)aifcmd->data)[1] == cpu_to_le32(3));
+ break;
/*
* Add an Array.
*/
case AifEnAddContainer:
- container = le32_to_cpu(((u32 *)aifcmd->data)[1]);
+ container = le32_to_cpu(((__le32 *)aifcmd->data)[1]);
if (container >= dev->maximum_num_containers)
break;
dev->fsa_dev[container].config_needed = ADD;
@@ -866,7 +872,7 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
* Delete an Array.
*/
case AifEnDeleteContainer:
- container = le32_to_cpu(((u32 *)aifcmd->data)[1]);
+ container = le32_to_cpu(((__le32 *)aifcmd->data)[1]);
if (container >= dev->maximum_num_containers)
break;
dev->fsa_dev[container].config_needed = DELETE;
@@ -880,7 +886,7 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
* waiting on something else, setup to wait on a Config Change.
*/
case AifEnContainerChange:
- container = le32_to_cpu(((u32 *)aifcmd->data)[1]);
+ container = le32_to_cpu(((__le32 *)aifcmd->data)[1]);
if (container >= dev->maximum_num_containers)
break;
if (dev->fsa_dev[container].config_waiting_on &&
@@ -895,6 +901,60 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
case AifEnConfigChange:
break;
+ case AifEnAddJBOD:
+ case AifEnDeleteJBOD:
+ container = le32_to_cpu(((__le32 *)aifcmd->data)[1]);
+ if ((container >> 28))
+ break;
+ channel = (container >> 24) & 0xF;
+ if (channel >= dev->maximum_num_channels)
+ break;
+ id = container & 0xFFFF;
+ if (id >= dev->maximum_num_physicals)
+ break;
+ lun = (container >> 16) & 0xFF;
+ channel = aac_phys_to_logical(channel);
+ device_config_needed =
+ (((__le32 *)aifcmd->data)[0] ==
+ cpu_to_le32(AifEnAddJBOD)) ? ADD : DELETE;
+ break;
+
+ case AifEnEnclosureManagement:
+ /*
+ * If in JBOD mode, automatic exposure of new
+ * physical target to be suppressed until configured.
+ */
+ if (dev->jbod)
+ break;
+ switch (le32_to_cpu(((__le32 *)aifcmd->data)[3])) {
+ case EM_DRIVE_INSERTION:
+ case EM_DRIVE_REMOVAL:
+ container = le32_to_cpu(
+ ((__le32 *)aifcmd->data)[2]);
+ if ((container >> 28))
+ break;
+ channel = (container >> 24) & 0xF;
+ if (channel >= dev->maximum_num_channels)
+ break;
+ id = container & 0xFFFF;
+ lun = (container >> 16) & 0xFF;
+ if (id >= dev->maximum_num_physicals) {
+ /* legacy dev_t ? */
+ if ((0x2000 <= id) || lun || channel ||
+ ((channel = (id >> 7) & 0x3F) >=
+ dev->maximum_num_channels))
+ break;
+ lun = (id >> 4) & 7;
+ id &= 0xF;
+ }
+ channel = aac_phys_to_logical(channel);
+ device_config_needed =
+ (((__le32 *)aifcmd->data)[3]
+ == cpu_to_le32(EM_DRIVE_INSERTION)) ?
+ ADD : DELETE;
+ break;
+ }
+ break;
}
/*
@@ -905,13 +965,13 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
if (container >= dev->maximum_num_containers)
break;
if ((dev->fsa_dev[container].config_waiting_on ==
- le32_to_cpu(*(u32 *)aifcmd->data)) &&
+ le32_to_cpu(*(__le32 *)aifcmd->data)) &&
time_before(jiffies, dev->fsa_dev[container].config_waiting_stamp + AIF_SNIFF_TIMEOUT))
dev->fsa_dev[container].config_waiting_on = 0;
} else for (container = 0;
container < dev->maximum_num_containers; ++container) {
if ((dev->fsa_dev[container].config_waiting_on ==
- le32_to_cpu(*(u32 *)aifcmd->data)) &&
+ le32_to_cpu(*(__le32 *)aifcmd->data)) &&
time_before(jiffies, dev->fsa_dev[container].config_waiting_stamp + AIF_SNIFF_TIMEOUT))
dev->fsa_dev[container].config_waiting_on = 0;
}
@@ -926,9 +986,9 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
* wait for a container change.
*/
- if ((((u32 *)aifcmd->data)[1] == cpu_to_le32(AifJobCtrZero))
- && ((((u32 *)aifcmd->data)[6] == ((u32 *)aifcmd->data)[5])
- || (((u32 *)aifcmd->data)[4] == cpu_to_le32(AifJobStsSuccess)))) {
+ if (((__le32 *)aifcmd->data)[1] == cpu_to_le32(AifJobCtrZero) &&
+ (((__le32 *)aifcmd->data)[6] == ((__le32 *)aifcmd->data)[5] ||
+ ((__le32 *)aifcmd->data)[4] == cpu_to_le32(AifJobStsSuccess))) {
for (container = 0;
container < dev->maximum_num_containers;
++container) {
@@ -943,9 +1003,9 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
jiffies;
}
}
- if ((((u32 *)aifcmd->data)[1] == cpu_to_le32(AifJobCtrZero))
- && (((u32 *)aifcmd->data)[6] == 0)
- && (((u32 *)aifcmd->data)[4] == cpu_to_le32(AifJobStsRunning))) {
+ if (((__le32 *)aifcmd->data)[1] == cpu_to_le32(AifJobCtrZero) &&
+ ((__le32 *)aifcmd->data)[6] == 0 &&
+ ((__le32 *)aifcmd->data)[4] == cpu_to_le32(AifJobStsRunning)) {
for (container = 0;
container < dev->maximum_num_containers;
++container) {
@@ -963,7 +1023,7 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
break;
}
- device_config_needed = NOTHING;
+ if (device_config_needed == NOTHING)
for (container = 0; container < dev->maximum_num_containers;
++container) {
if ((dev->fsa_dev[container].config_waiting_on == 0) &&
@@ -972,6 +1032,9 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
device_config_needed =
dev->fsa_dev[container].config_needed;
dev->fsa_dev[container].config_needed = NOTHING;
+ channel = CONTAINER_TO_CHANNEL(container);
+ id = CONTAINER_TO_ID(container);
+ lun = CONTAINER_TO_LUN(container);
break;
}
}
@@ -995,34 +1058,56 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
/*
* force reload of disk info via aac_probe_container
*/
- if ((device_config_needed == CHANGE)
- && (dev->fsa_dev[container].valid == 1))
- dev->fsa_dev[container].valid = 2;
- if ((device_config_needed == CHANGE) ||
- (device_config_needed == ADD))
+ if ((channel == CONTAINER_CHANNEL) &&
+ (device_config_needed != NOTHING)) {
+ if (dev->fsa_dev[container].valid == 1)
+ dev->fsa_dev[container].valid = 2;
aac_probe_container(dev, container);
- device = scsi_device_lookup(dev->scsi_host_ptr,
- CONTAINER_TO_CHANNEL(container),
- CONTAINER_TO_ID(container),
- CONTAINER_TO_LUN(container));
+ }
+ device = scsi_device_lookup(dev->scsi_host_ptr, channel, id, lun);
if (device) {
switch (device_config_needed) {
case DELETE:
+ if (scsi_device_online(device)) {
+ scsi_device_set_state(device, SDEV_OFFLINE);
+ sdev_printk(KERN_INFO, device,
+ "Device offlined - %s\n",
+ (channel == CONTAINER_CHANNEL) ?
+ "array deleted" :
+ "enclosure services event");
+ }
+ break;
+ case ADD:
+ if (!scsi_device_online(device)) {
+ sdev_printk(KERN_INFO, device,
+ "Device online - %s\n",
+ (channel == CONTAINER_CHANNEL) ?
+ "array created" :
+ "enclosure services event");
+ scsi_device_set_state(device, SDEV_RUNNING);
+ }
+ /* FALLTHRU */
case CHANGE:
+ if ((channel == CONTAINER_CHANNEL)
+ && (!dev->fsa_dev[container].valid)) {
+ if (!scsi_device_online(device))
+ break;
+ scsi_device_set_state(device, SDEV_OFFLINE);
+ sdev_printk(KERN_INFO, device,
+ "Device offlined - %s\n",
+ "array failed");
+ break;
+ }
scsi_rescan_device(&device->sdev_gendev);
default:
break;
}
scsi_device_put(device);
+ device_config_needed = NOTHING;
}
- if (device_config_needed == ADD) {
- scsi_add_device(dev->scsi_host_ptr,
- CONTAINER_TO_CHANNEL(container),
- CONTAINER_TO_ID(container),
- CONTAINER_TO_LUN(container));
- }
-
+ if (device_config_needed == ADD)
+ scsi_add_device(dev->scsi_host_ptr, channel, id, lun);
}
static int _aac_reset_adapter(struct aac_dev *aac, int forced)
@@ -1099,7 +1184,8 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced)
free_irq(aac->pdev->irq, aac);
kfree(aac->fsa_dev);
aac->fsa_dev = NULL;
- if (aac_get_driver_ident(index)->quirks & AAC_QUIRK_31BIT) {
+ quirks = aac_get_driver_ident(index)->quirks;
+ if (quirks & AAC_QUIRK_31BIT) {
if (((retval = pci_set_dma_mask(aac->pdev, DMA_31BIT_MASK))) ||
((retval = pci_set_consistent_dma_mask(aac->pdev, DMA_31BIT_MASK))))
goto out;
@@ -1110,7 +1196,7 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced)
}
if ((retval = (*(aac_get_driver_ident(index)->init))(aac)))
goto out;
- if (aac_get_driver_ident(index)->quirks & AAC_QUIRK_31BIT)
+ if (quirks & AAC_QUIRK_31BIT)
if ((retval = pci_set_dma_mask(aac->pdev, DMA_32BIT_MASK)))
goto out;
if (jafo) {
@@ -1121,15 +1207,14 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced)
}
}
(void)aac_get_adapter_info(aac);
- quirks = aac_get_driver_ident(index)->quirks;
if ((quirks & AAC_QUIRK_34SG) && (host->sg_tablesize > 34)) {
- host->sg_tablesize = 34;
- host->max_sectors = (host->sg_tablesize * 8) + 112;
- }
- if ((quirks & AAC_QUIRK_17SG) && (host->sg_tablesize > 17)) {
- host->sg_tablesize = 17;
- host->max_sectors = (host->sg_tablesize * 8) + 112;
- }
+ host->sg_tablesize = 34;
+ host->max_sectors = (host->sg_tablesize * 8) + 112;
+ }
+ if ((quirks & AAC_QUIRK_17SG) && (host->sg_tablesize > 17)) {
+ host->sg_tablesize = 17;
+ host->max_sectors = (host->sg_tablesize * 8) + 112;
+ }
aac_get_config_status(aac, 1);
aac_get_containers(aac);
/*
@@ -1217,12 +1302,13 @@ int aac_reset_adapter(struct aac_dev * aac, int forced)
}
/* Quiesce build, flush cache, write through mode */
- aac_send_shutdown(aac);
+ if (forced < 2)
+ aac_send_shutdown(aac);
spin_lock_irqsave(host->host_lock, flagv);
- retval = _aac_reset_adapter(aac, forced);
+ retval = _aac_reset_adapter(aac, forced ? forced : ((aac_check_reset != 0) && (aac_check_reset != 1)));
spin_unlock_irqrestore(host->host_lock, flagv);
- if (retval == -ENODEV) {
+ if ((forced < 2) && (retval == -ENODEV)) {
/* Unwind aac_send_shutdown() IOP_RESET unsupported/disabled */
struct fib * fibctx = aac_fib_alloc(aac);
if (fibctx) {
@@ -1338,11 +1424,11 @@ int aac_check_health(struct aac_dev * aac)
fib->data = hw_fib->data;
aif = (struct aac_aifcmd *)hw_fib->data;
aif->command = cpu_to_le32(AifCmdEventNotify);
- aif->seqnum = cpu_to_le32(0xFFFFFFFF);
- aif->data[0] = AifEnExpEvent;
- aif->data[1] = AifExeFirmwarePanic;
- aif->data[2] = AifHighPriority;
- aif->data[3] = BlinkLED;
+ aif->seqnum = cpu_to_le32(0xFFFFFFFF);
+ ((__le32 *)aif->data)[0] = cpu_to_le32(AifEnExpEvent);
+ ((__le32 *)aif->data)[1] = cpu_to_le32(AifExeFirmwarePanic);
+ ((__le32 *)aif->data)[2] = cpu_to_le32(AifHighPriority);
+ ((__le32 *)aif->data)[3] = cpu_to_le32(BlinkLED);
/*
* Put the FIB onto the
@@ -1372,14 +1458,14 @@ int aac_check_health(struct aac_dev * aac)
printk(KERN_ERR "%s: Host adapter BLINK LED 0x%x\n", aac->name, BlinkLED);
- if (!aac_check_reset ||
+ if (!aac_check_reset || ((aac_check_reset != 1) &&
(aac->supplement_adapter_info.SupportedOptions2 &
- le32_to_cpu(AAC_OPTION_IGNORE_RESET)))
+ AAC_OPTION_IGNORE_RESET)))
goto out;
host = aac->scsi_host_ptr;
if (aac->thread->pid != current->pid)
spin_lock_irqsave(host->host_lock, flagv);
- BlinkLED = _aac_reset_adapter(aac, 0);
+ BlinkLED = _aac_reset_adapter(aac, aac_check_reset != 1);
if (aac->thread->pid != current->pid)
spin_unlock_irqrestore(host->host_lock, flagv);
return BlinkLED;
@@ -1399,7 +1485,7 @@ out:
* until the queue is empty. When the queue is empty it will wait for
* more FIBs.
*/
-
+
int aac_command_thread(void *data)
{
struct aac_dev *dev = data;
@@ -1425,30 +1511,29 @@ int aac_command_thread(void *data)
add_wait_queue(&dev->queues->queue[HostNormCmdQueue].cmdready, &wait);
set_current_state(TASK_INTERRUPTIBLE);
dprintk ((KERN_INFO "aac_command_thread start\n"));
- while(1)
- {
+ while (1) {
spin_lock_irqsave(dev->queues->queue[HostNormCmdQueue].lock, flags);
while(!list_empty(&(dev->queues->queue[HostNormCmdQueue].cmdq))) {
struct list_head *entry;
struct aac_aifcmd * aifcmd;
set_current_state(TASK_RUNNING);
-
+
entry = dev->queues->queue[HostNormCmdQueue].cmdq.next;
list_del(entry);
-
+
spin_unlock_irqrestore(dev->queues->queue[HostNormCmdQueue].lock, flags);
fib = list_entry(entry, struct fib, fiblink);
/*
- * We will process the FIB here or pass it to a
- * worker thread that is TBD. We Really can't
+ * We will process the FIB here or pass it to a
+ * worker thread that is TBD. We Really can't
* do anything at this point since we don't have
* anything defined for this thread to do.
*/
hw_fib = fib->hw_fib_va;
memset(fib, 0, sizeof(struct fib));
fib->type = FSAFS_NTC_FIB_CONTEXT;
- fib->size = sizeof( struct fib );
+ fib->size = sizeof(struct fib);
fib->hw_fib_va = hw_fib;
fib->data = hw_fib->data;
fib->dev = dev;
@@ -1462,20 +1547,19 @@ int aac_command_thread(void *data)
*(__le32 *)hw_fib->data = cpu_to_le32(ST_OK);
aac_fib_adapter_complete(fib, (u16)sizeof(u32));
} else {
- struct list_head *entry;
/* The u32 here is important and intended. We are using
32bit wrapping time to fit the adapter field */
-
+
u32 time_now, time_last;
unsigned long flagv;
unsigned num;
struct hw_fib ** hw_fib_pool, ** hw_fib_p;
struct fib ** fib_pool, ** fib_p;
-
+
/* Sniff events */
- if ((aifcmd->command ==
+ if ((aifcmd->command ==
cpu_to_le32(AifCmdEventNotify)) ||
- (aifcmd->command ==
+ (aifcmd->command ==
cpu_to_le32(AifCmdJobProgress))) {
aac_handle_aif(dev, fib);
}
@@ -1527,7 +1611,7 @@ int aac_command_thread(void *data)
spin_lock_irqsave(&dev->fib_lock, flagv);
entry = dev->fib_list.next;
/*
- * For each Context that is on the
+ * For each Context that is on the
* fibctxList, make a copy of the
* fib, and then set the event to wake up the
* thread that is waiting for it.
@@ -1552,7 +1636,7 @@ int aac_command_thread(void *data)
*/
time_last = fibctx->jiffies;
/*
- * Has it been > 2 minutes
+ * Has it been > 2 minutes
* since the last read off
* the queue?
*/
@@ -1583,7 +1667,7 @@ int aac_command_thread(void *data)
*/
list_add_tail(&newfib->fiblink, &fibctx->fib_list);
fibctx->count++;
- /*
+ /*
* Set the event to wake up the
* thread that is waiting.
*/
@@ -1655,11 +1739,11 @@ int aac_command_thread(void *data)
struct fib *fibptr;
if ((fibptr = aac_fib_alloc(dev))) {
- u32 * info;
+ __le32 *info;
aac_fib_init(fibptr);
- info = (u32 *) fib_data(fibptr);
+ info = (__le32 *) fib_data(fibptr);
if (now.tv_usec > 500000)
++now.tv_sec;
diff --git a/drivers/scsi/aacraid/dpcsup.c b/drivers/scsi/aacraid/dpcsup.c
index e6032ffc66a6..d1163ded132b 100644
--- a/drivers/scsi/aacraid/dpcsup.c
+++ b/drivers/scsi/aacraid/dpcsup.c
@@ -120,6 +120,7 @@ unsigned int aac_response_normal(struct aac_queue * q)
* NOTE: we cannot touch the fib after this
* call, because it may have been deallocated.
*/
+ fib->flags = 0;
fib->callback(fib->callback_data, fib);
} else {
unsigned long flagv;
@@ -229,11 +230,9 @@ unsigned int aac_command_normal(struct aac_queue *q)
* all QE there are and wake up all the waiters before exiting.
*/
-unsigned int aac_intr_normal(struct aac_dev * dev, u32 Index)
+unsigned int aac_intr_normal(struct aac_dev * dev, u32 index)
{
- u32 index = le32_to_cpu(Index);
-
- dprintk((KERN_INFO "aac_intr_normal(%p,%x)\n", dev, Index));
+ dprintk((KERN_INFO "aac_intr_normal(%p,%x)\n", dev, index));
if ((index & 0x00000002L)) {
struct hw_fib * hw_fib;
struct fib * fib;
@@ -301,7 +300,7 @@ unsigned int aac_intr_normal(struct aac_dev * dev, u32 Index)
if (hwfib->header.Command == cpu_to_le16(NuFileSystem))
{
- u32 *pstatus = (u32 *)hwfib->data;
+ __le32 *pstatus = (__le32 *)hwfib->data;
if (*pstatus & cpu_to_le32(0xffff0000))
*pstatus = cpu_to_le32(ST_OK);
}
@@ -315,6 +314,7 @@ unsigned int aac_intr_normal(struct aac_dev * dev, u32 Index)
* NOTE: we cannot touch the fib after this
* call, because it may have been deallocated.
*/
+ fib->flags = 0;
fib->callback(fib->callback_data, fib);
} else {
unsigned long flagv;
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 9dd331bc29b0..61be22774e99 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -159,27 +159,27 @@ static struct pci_device_id aac_pci_tbl[] = {
MODULE_DEVICE_TABLE(pci, aac_pci_tbl);
/*
- * dmb - For now we add the number of channels to this structure.
+ * dmb - For now we add the number of channels to this structure.
* In the future we should add a fib that reports the number of channels
* for the card. At that time we can remove the channels from here
*/
static struct aac_driver_ident aac_drivers[] = {
- { aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* PERC 2/Si (Iguana/PERC2Si) */
- { aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* PERC 3/Di (Opal/PERC3Di) */
- { aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* PERC 3/Si (SlimFast/PERC3Si */
- { aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* PERC 3/Di (Iguana FlipChip/PERC3DiF */
- { aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* PERC 3/Di (Viper/PERC3DiV) */
- { aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* PERC 3/Di (Lexus/PERC3DiL) */
- { aac_rx_init, "percraid", "DELL ", "PERCRAID ", 1, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* PERC 3/Di (Jaguar/PERC3DiJ) */
- { aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* PERC 3/Di (Dagger/PERC3DiD) */
- { aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* PERC 3/Di (Boxster/PERC3DiB) */
- { aac_rx_init, "aacraid", "ADAPTEC ", "catapult ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* catapult */
- { aac_rx_init, "aacraid", "ADAPTEC ", "tomcat ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* tomcat */
- { aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 2120S ", 1, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Adaptec 2120S (Crusader) */
- { aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 2200S ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Adaptec 2200S (Vulcan) */
- { aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 2200S ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Adaptec 2200S (Vulcan-2m) */
- { aac_rx_init, "aacraid", "Legend ", "Legend S220 ", 1, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Legend S220 (Legend Crusader) */
- { aac_rx_init, "aacraid", "Legend ", "Legend S230 ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Legend S230 (Legend Vulcan) */
+ { aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* PERC 2/Si (Iguana/PERC2Si) */
+ { aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* PERC 3/Di (Opal/PERC3Di) */
+ { aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* PERC 3/Si (SlimFast/PERC3Si */
+ { aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* PERC 3/Di (Iguana FlipChip/PERC3DiF */
+ { aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* PERC 3/Di (Viper/PERC3DiV) */
+ { aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* PERC 3/Di (Lexus/PERC3DiL) */
+ { aac_rx_init, "percraid", "DELL ", "PERCRAID ", 1, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* PERC 3/Di (Jaguar/PERC3DiJ) */
+ { aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* PERC 3/Di (Dagger/PERC3DiD) */
+ { aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* PERC 3/Di (Boxster/PERC3DiB) */
+ { aac_rx_init, "aacraid", "ADAPTEC ", "catapult ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* catapult */
+ { aac_rx_init, "aacraid", "ADAPTEC ", "tomcat ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* tomcat */
+ { aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 2120S ", 1, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* Adaptec 2120S (Crusader) */
+ { aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 2200S ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* Adaptec 2200S (Vulcan) */
+ { aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 2200S ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* Adaptec 2200S (Vulcan-2m) */
+ { aac_rx_init, "aacraid", "Legend ", "Legend S220 ", 1, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* Legend S220 (Legend Crusader) */
+ { aac_rx_init, "aacraid", "Legend ", "Legend S230 ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* Legend S230 (Legend Vulcan) */
{ aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 3230S ", 2 }, /* Adaptec 3230S (Harrier) */
{ aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 3240S ", 2 }, /* Adaptec 3240S (Tornado) */
@@ -224,8 +224,8 @@ static struct aac_driver_ident aac_drivers[] = {
{ 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", "DELL ", "RAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* Dell Catchall */
+ { aac_rx_init, "aacraid", "Legend ", "RAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* Legend Catchall */
{ 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 */
@@ -239,7 +239,7 @@ static struct aac_driver_ident aac_drivers[] = {
* Queues a command for execution by the associated Host Adapter.
*
* TODO: unify with aac_scsi_cmd().
- */
+ */
static int aac_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
{
@@ -258,7 +258,7 @@ static int aac_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd
}
cmd->SCp.phase = AAC_OWNER_LOWLEVEL;
return (aac_scsi_cmd(cmd) ? FAILED : 0);
-}
+}
/**
* aac_info - Returns the host adapter name
@@ -292,21 +292,21 @@ struct aac_driver_ident* aac_get_driver_ident(int devtype)
* @capacity: the sector capacity of the disk
* @geom: geometry block to fill in
*
- * Return the Heads/Sectors/Cylinders BIOS Disk Parameters for Disk.
- * The default disk geometry is 64 heads, 32 sectors, and the appropriate
- * number of cylinders so as not to exceed drive capacity. In order for
+ * Return the Heads/Sectors/Cylinders BIOS Disk Parameters for Disk.
+ * The default disk geometry is 64 heads, 32 sectors, and the appropriate
+ * number of cylinders so as not to exceed drive capacity. In order for
* disks equal to or larger than 1 GB to be addressable by the BIOS
- * without exceeding the BIOS limitation of 1024 cylinders, Extended
- * Translation should be enabled. With Extended Translation enabled,
- * drives between 1 GB inclusive and 2 GB exclusive are given a disk
- * geometry of 128 heads and 32 sectors, and drives above 2 GB inclusive
- * are given a disk geometry of 255 heads and 63 sectors. However, if
- * the BIOS detects that the Extended Translation setting does not match
- * the geometry in the partition table, then the translation inferred
- * from the partition table will be used by the BIOS, and a warning may
+ * without exceeding the BIOS limitation of 1024 cylinders, Extended
+ * Translation should be enabled. With Extended Translation enabled,
+ * drives between 1 GB inclusive and 2 GB exclusive are given a disk
+ * geometry of 128 heads and 32 sectors, and drives above 2 GB inclusive
+ * are given a disk geometry of 255 heads and 63 sectors. However, if
+ * the BIOS detects that the Extended Translation setting does not match
+ * the geometry in the partition table, then the translation inferred
+ * from the partition table will be used by the BIOS, and a warning may
* be displayed.
*/
-
+
static int aac_biosparm(struct scsi_device *sdev, struct block_device *bdev,
sector_t capacity, int *geom)
{
@@ -333,10 +333,10 @@ static int aac_biosparm(struct scsi_device *sdev, struct block_device *bdev,
param->cylinders = cap_to_cyls(capacity, param->heads * param->sectors);
- /*
+ /*
* Read the first 1024 bytes from the disk device, if the boot
* sector partition table is valid, search for a partition table
- * entry whose end_head matches one of the standard geometry
+ * entry whose end_head matches one of the standard geometry
* translations ( 64/32, 128/32, 255/63 ).
*/
buf = scsi_bios_ptable(bdev);
@@ -401,30 +401,44 @@ static int aac_biosparm(struct scsi_device *sdev, struct block_device *bdev,
static int aac_slave_configure(struct scsi_device *sdev)
{
+ struct aac_dev *aac = (struct aac_dev *)sdev->host->hostdata;
if ((sdev->type == TYPE_DISK) &&
- (sdev_channel(sdev) != CONTAINER_CHANNEL)) {
+ (sdev_channel(sdev) != CONTAINER_CHANNEL) &&
+ (!aac->jbod || sdev->inq_periph_qual) &&
+ (!aac->raid_scsi_mode || (sdev_channel(sdev) != 2))) {
if (expose_physicals == 0)
return -ENXIO;
- if (expose_physicals < 0) {
- struct aac_dev *aac =
- (struct aac_dev *)sdev->host->hostdata;
- if (!aac->raid_scsi_mode || (sdev_channel(sdev) != 2))
- sdev->no_uld_attach = 1;
- }
+ if (expose_physicals < 0)
+ sdev->no_uld_attach = 1;
}
if (sdev->tagged_supported && (sdev->type == TYPE_DISK) &&
- (sdev_channel(sdev) == CONTAINER_CHANNEL)) {
+ (!aac->raid_scsi_mode || (sdev_channel(sdev) != 2)) &&
+ !sdev->no_uld_attach) {
struct scsi_device * dev;
struct Scsi_Host *host = sdev->host;
unsigned num_lsu = 0;
unsigned num_one = 0;
unsigned depth;
+ unsigned cid;
+ /*
+ * Firmware has an individual device recovery time typically
+ * of 35 seconds, give us a margin.
+ */
+ if (sdev->timeout < (45 * HZ))
+ sdev->timeout = 45 * HZ;
+ for (cid = 0; cid < aac->maximum_num_containers; ++cid)
+ if (aac->fsa_dev[cid].valid)
+ ++num_lsu;
__shost_for_each_device(dev, host) {
if (dev->tagged_supported && (dev->type == TYPE_DISK) &&
- (sdev_channel(dev) == CONTAINER_CHANNEL))
- ++num_lsu;
- else
+ (!aac->raid_scsi_mode ||
+ (sdev_channel(sdev) != 2)) &&
+ !dev->no_uld_attach) {
+ if ((sdev_channel(dev) != CONTAINER_CHANNEL)
+ || !aac->fsa_dev[sdev_id(dev)].valid)
+ ++num_lsu;
+ } else
++num_one;
}
if (num_lsu == 0)
@@ -481,9 +495,35 @@ static int aac_change_queue_depth(struct scsi_device *sdev, int depth)
return sdev->queue_depth;
}
+static ssize_t aac_show_raid_level(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct scsi_device * sdev = to_scsi_device(dev);
+ if (sdev_channel(sdev) != CONTAINER_CHANNEL)
+ return snprintf(buf, PAGE_SIZE, sdev->no_uld_attach
+ ? "Hidden\n" : "JBOD");
+ return snprintf(buf, PAGE_SIZE, "%s\n",
+ get_container_type(((struct aac_dev *)(sdev->host->hostdata))
+ ->fsa_dev[sdev_id(sdev)].type));
+}
+
+static struct device_attribute aac_raid_level_attr = {
+ .attr = {
+ .name = "level",
+ .mode = S_IRUGO,
+ },
+ .show = aac_show_raid_level
+};
+
+static struct device_attribute *aac_dev_attrs[] = {
+ &aac_raid_level_attr,
+ NULL,
+};
+
static int aac_ioctl(struct scsi_device *sdev, int cmd, void __user * arg)
{
struct aac_dev *dev = (struct aac_dev *)sdev->host->hostdata;
+ if (!capable(CAP_SYS_RAWIO))
+ return -EPERM;
return aac_do_ioctl(dev, cmd, arg);
}
@@ -506,17 +546,33 @@ static int aac_eh_abort(struct scsi_cmnd* cmd)
break;
case INQUIRY:
case READ_CAPACITY:
- case TEST_UNIT_READY:
/* Mark associated FIB to not complete, eh handler does this */
for (count = 0; count < (host->can_queue + AAC_NUM_MGT_FIB); ++count) {
struct fib * fib = &aac->fibs[count];
if (fib->hw_fib_va->header.XferState &&
+ (fib->flags & FIB_CONTEXT_FLAG) &&
(fib->callback_data == cmd)) {
fib->flags |= FIB_CONTEXT_FLAG_TIMED_OUT;
cmd->SCp.phase = AAC_OWNER_ERROR_HANDLER;
ret = SUCCESS;
}
}
+ break;
+ case TEST_UNIT_READY:
+ /* Mark associated FIB to not complete, eh handler does this */
+ for (count = 0; count < (host->can_queue + AAC_NUM_MGT_FIB); ++count) {
+ struct scsi_cmnd * command;
+ struct fib * fib = &aac->fibs[count];
+ if ((fib->hw_fib_va->header.XferState & cpu_to_le32(Async | NoResponseExpected)) &&
+ (fib->flags & FIB_CONTEXT_FLAG) &&
+ ((command = fib->callback_data)) &&
+ (command->device == cmd->device)) {
+ fib->flags |= FIB_CONTEXT_FLAG_TIMED_OUT;
+ command->SCp.phase = AAC_OWNER_ERROR_HANDLER;
+ if (command == cmd)
+ ret = SUCCESS;
+ }
+ }
}
return ret;
}
@@ -539,12 +595,13 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
for (count = 0; count < (host->can_queue + AAC_NUM_MGT_FIB); ++count) {
struct fib * fib = &aac->fibs[count];
if (fib->hw_fib_va->header.XferState &&
+ (fib->flags & FIB_CONTEXT_FLAG) &&
(fib->callback_data == cmd)) {
fib->flags |= FIB_CONTEXT_FLAG_TIMED_OUT;
cmd->SCp.phase = AAC_OWNER_ERROR_HANDLER;
}
}
- printk(KERN_ERR "%s: Host adapter reset request. SCSI hang ?\n",
+ printk(KERN_ERR "%s: Host adapter reset request. SCSI hang ?\n",
AAC_DRIVERNAME);
if ((count = aac_check_health(aac)))
@@ -584,8 +641,11 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
* 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_OPTION_MU_RESET) &&
+ aac_check_reset &&
+ ((aac_check_reset != 1) ||
+ (aac->supplement_adapter_info.SupportedOptions2 &
+ AAC_OPTION_IGNORE_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 */
}
@@ -632,8 +692,8 @@ static int aac_cfg_open(struct inode *inode, struct file *file)
* Bugs: Needs locking against parallel ioctls lower down
* Bugs: Needs to handle hot plugging
*/
-
-static int aac_cfg_ioctl(struct inode *inode, struct file *file,
+
+static int aac_cfg_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
if (!capable(CAP_SYS_RAWIO))
@@ -646,7 +706,7 @@ static long aac_compat_do_ioctl(struct aac_dev *dev, unsigned cmd, unsigned long
{
long ret;
lock_kernel();
- switch (cmd) {
+ switch (cmd) {
case FSACTL_MINIPORT_REV_CHECK:
case FSACTL_SENDFIB:
case FSACTL_OPEN_GET_ADAPTER_FIB:
@@ -656,14 +716,14 @@ static long aac_compat_do_ioctl(struct aac_dev *dev, unsigned cmd, unsigned long
case FSACTL_QUERY_DISK:
case FSACTL_DELETE_DISK:
case FSACTL_FORCE_DELETE_DISK:
- case FSACTL_GET_CONTAINERS:
+ case FSACTL_GET_CONTAINERS:
case FSACTL_SEND_LARGE_FIB:
ret = aac_do_ioctl(dev, cmd, (void __user *)arg);
break;
case FSACTL_GET_NEXT_ADAPTER_FIB: {
struct fib_ioctl __user *f;
-
+
f = compat_alloc_user_space(sizeof(*f));
ret = 0;
if (clear_user(f, sizeof(*f)))
@@ -676,9 +736,9 @@ static long aac_compat_do_ioctl(struct aac_dev *dev, unsigned cmd, unsigned long
}
default:
- ret = -ENOIOCTLCMD;
+ ret = -ENOIOCTLCMD;
break;
- }
+ }
unlock_kernel();
return ret;
}
@@ -735,6 +795,25 @@ static ssize_t aac_show_vendor(struct class_device *class_dev,
return len;
}
+static ssize_t aac_show_flags(struct class_device *class_dev, char *buf)
+{
+ int len = 0;
+ struct aac_dev *dev = (struct aac_dev*)class_to_shost(class_dev)->hostdata;
+
+ if (nblank(dprintk(x)))
+ len = snprintf(buf, PAGE_SIZE, "dprintk\n");
+#ifdef AAC_DETAILED_STATUS_INFO
+ len += snprintf(buf + len, PAGE_SIZE - len,
+ "AAC_DETAILED_STATUS_INFO\n");
+#endif
+ if (dev->raw_io_interface && dev->raw_io_64)
+ len += snprintf(buf + len, PAGE_SIZE - len,
+ "SAI_READ_CAPACITY_16\n");
+ if (dev->jbod)
+ len += snprintf(buf + len, PAGE_SIZE - len, "SUPPORTED_JBOD\n");
+ return len;
+}
+
static ssize_t aac_show_kernel_version(struct class_device *class_dev,
char *buf)
{
@@ -742,7 +821,7 @@ static ssize_t aac_show_kernel_version(struct class_device *class_dev,
int len, tmp;
tmp = le32_to_cpu(dev->adapter_info.kernelrev);
- len = snprintf(buf, PAGE_SIZE, "%d.%d-%d[%d]\n",
+ len = snprintf(buf, PAGE_SIZE, "%d.%d-%d[%d]\n",
tmp >> 24, (tmp >> 16) & 0xff, tmp & 0xff,
le32_to_cpu(dev->adapter_info.kernelbuild));
return len;
@@ -755,7 +834,7 @@ static ssize_t aac_show_monitor_version(struct class_device *class_dev,
int len, tmp;
tmp = le32_to_cpu(dev->adapter_info.monitorrev);
- len = snprintf(buf, PAGE_SIZE, "%d.%d-%d[%d]\n",
+ len = snprintf(buf, PAGE_SIZE, "%d.%d-%d[%d]\n",
tmp >> 24, (tmp >> 16) & 0xff, tmp & 0xff,
le32_to_cpu(dev->adapter_info.monitorbuild));
return len;
@@ -768,7 +847,7 @@ static ssize_t aac_show_bios_version(struct class_device *class_dev,
int len, tmp;
tmp = le32_to_cpu(dev->adapter_info.biosrev);
- len = snprintf(buf, PAGE_SIZE, "%d.%d-%d[%d]\n",
+ len = snprintf(buf, PAGE_SIZE, "%d.%d-%d[%d]\n",
tmp >> 24, (tmp >> 16) & 0xff, tmp & 0xff,
le32_to_cpu(dev->adapter_info.biosbuild));
return len;
@@ -844,6 +923,13 @@ static struct class_device_attribute aac_vendor = {
},
.show = aac_show_vendor,
};
+static struct class_device_attribute aac_flags = {
+ .attr = {
+ .name = "flags",
+ .mode = S_IRUGO,
+ },
+ .show = aac_show_flags,
+};
static struct class_device_attribute aac_kernel_version = {
.attr = {
.name = "hba_kernel_version",
@@ -898,6 +984,7 @@ static struct class_device_attribute aac_reset = {
static struct class_device_attribute *aac_attrs[] = {
&aac_model,
&aac_vendor,
+ &aac_flags,
&aac_kernel_version,
&aac_monitor_version,
&aac_bios_version,
@@ -928,21 +1015,22 @@ static struct scsi_host_template aac_driver_template = {
.compat_ioctl = aac_compat_ioctl,
#endif
.queuecommand = aac_queuecommand,
- .bios_param = aac_biosparm,
+ .bios_param = aac_biosparm,
.shost_attrs = aac_attrs,
.slave_configure = aac_slave_configure,
.change_queue_depth = aac_change_queue_depth,
+ .sdev_attrs = aac_dev_attrs,
.eh_abort_handler = aac_eh_abort,
.eh_host_reset_handler = aac_eh_reset,
- .can_queue = AAC_NUM_IO_FIB,
+ .can_queue = AAC_NUM_IO_FIB,
.this_id = MAXIMUM_NUM_CONTAINERS,
.sg_tablesize = 16,
.max_sectors = 128,
#if (AAC_NUM_IO_FIB > 256)
.cmd_per_lun = 256,
-#else
- .cmd_per_lun = AAC_NUM_IO_FIB,
-#endif
+#else
+ .cmd_per_lun = AAC_NUM_IO_FIB,
+#endif
.use_clustering = ENABLE_CLUSTERING,
.use_sg_chaining = ENABLE_SG_CHAINING,
.emulated = 1,
@@ -979,18 +1067,18 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
goto out;
error = -ENODEV;
- if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) ||
+ if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) ||
pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK))
goto out_disable_pdev;
/*
* If the quirk31 bit is set, the adapter needs adapter
* to driver communication memory to be allocated below 2gig
*/
- if (aac_drivers[index].quirks & AAC_QUIRK_31BIT)
+ if (aac_drivers[index].quirks & AAC_QUIRK_31BIT)
if (pci_set_dma_mask(pdev, DMA_31BIT_MASK) ||
pci_set_consistent_dma_mask(pdev, DMA_31BIT_MASK))
goto out_disable_pdev;
-
+
pci_set_master(pdev);
shost = scsi_host_alloc(&aac_driver_template, sizeof(struct aac_dev));
@@ -1003,7 +1091,7 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
shost->max_cmd_len = 16;
aac = (struct aac_dev *)shost->hostdata;
- aac->scsi_host_ptr = shost;
+ aac->scsi_host_ptr = shost;
aac->pdev = pdev;
aac->name = aac_driver_template.name;
aac->id = shost->unique_id;
@@ -1040,7 +1128,7 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
if (aac_drivers[index].quirks & AAC_QUIRK_31BIT)
if (pci_set_dma_mask(pdev, DMA_32BIT_MASK))
goto out_deinit;
-
+
aac->maximum_num_channels = aac_drivers[index].channels;
error = aac_get_adapter_info(aac);
if (error < 0)
@@ -1049,7 +1137,7 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
/*
* Lets override negotiations and drop the maximum SG limit to 34
*/
- if ((aac_drivers[index].quirks & AAC_QUIRK_34SG) &&
+ if ((aac_drivers[index].quirks & AAC_QUIRK_34SG) &&
(aac->scsi_host_ptr->sg_tablesize > 34)) {
aac->scsi_host_ptr->sg_tablesize = 34;
aac->scsi_host_ptr->max_sectors
@@ -1066,17 +1154,17 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
/*
* Firware printf works only with older firmware.
*/
- if (aac_drivers[index].quirks & AAC_QUIRK_34SG)
+ if (aac_drivers[index].quirks & AAC_QUIRK_34SG)
aac->printf_enabled = 1;
else
aac->printf_enabled = 0;
-
+
/*
* max channel will be the physical channels plus 1 virtual channel
* all containers are on the virtual channel 0 (CONTAINER_CHANNEL)
* physical channels are address by their actual physical number+1
*/
- if ((aac->nondasd_support == 1) || expose_physicals)
+ if (aac->nondasd_support || expose_physicals || aac->jbod)
shost->max_channel = aac->maximum_num_channels;
else
shost->max_channel = 0;
@@ -1148,10 +1236,10 @@ static void __devexit aac_remove_one(struct pci_dev *pdev)
kfree(aac->queues);
aac_adapter_ioremap(aac, 0);
-
+
kfree(aac->fibs);
kfree(aac->fsa_dev);
-
+
list_del(&aac->entry);
scsi_host_put(shost);
pci_disable_device(pdev);
@@ -1172,7 +1260,7 @@ static struct pci_driver aac_pci_driver = {
static int __init aac_init(void)
{
int error;
-
+
printk(KERN_INFO "Adaptec %s driver %s\n",
AAC_DRIVERNAME, aac_driver_version);
diff --git a/drivers/scsi/aacraid/rx.c b/drivers/scsi/aacraid/rx.c
index 73eef3dc5dc6..a08bbf1fd76c 100644
--- a/drivers/scsi/aacraid/rx.c
+++ b/drivers/scsi/aacraid/rx.c
@@ -465,7 +465,7 @@ static int aac_rx_restart_adapter(struct aac_dev *dev, int bled)
u32 var;
if (!(dev->supplement_adapter_info.SupportedOptions2 &
- le32_to_cpu(AAC_OPTION_MU_RESET)) || (bled >= 0) || (bled == -2)) {
+ 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);
@@ -549,7 +549,9 @@ int _aac_rx_init(struct aac_dev *dev)
dev->OIMR = status = rx_readb (dev, MUnit.OIMR);
if ((((status & 0x0c) != 0x0c) || aac_reset_devices || reset_devices) &&
!aac_rx_restart_adapter(dev, 0))
- ++restart;
+ /* Make sure the Hardware FIFO is empty */
+ while ((++restart < 512) &&
+ (rx_readl(dev, MUnit.OutboundQueue) != 0xFFFFFFFFL));
/*
* Check to see if the board panic'd while booting.
*/