* [PATCH 0/7] aacraid driver updates
@ 2015-03-04 8:38 Mahesh Rajashekhara
2015-03-04 8:38 ` [PATCH 1/7] aacraid: AIF support for SES device add/remove Mahesh Rajashekhara
` (7 more replies)
0 siblings, 8 replies; 32+ messages in thread
From: Mahesh Rajashekhara @ 2015-03-04 8:38 UTC (permalink / raw)
To: JBottomley, linux-scsi
Cc: aacraid, Harry.Yang, Achim.Leubner, Rajinikanth.Pandurangan,
Rich.Bono, Mahesh.Rajashekhara
This patch set includes some important bug fixes and new feature supports.
Mahesh Rajashekhara (7):
aacraid: AIF support for SES device add/remove
aacraid: IOCTL pass-through command fix
aacraid: 4KB sector support
aacraid: MSI-x support
aacraid: vpd page code 0x83 support
aacraid: performance improvement changes
aacraid: AIF raw device remove support
drivers/scsi/aacraid/aachba.c | 355 +++++++++++++++++++++++++++++------
drivers/scsi/aacraid/aacraid.h | 102 +++++++++-
drivers/scsi/aacraid/commctrl.c | 10 +-
drivers/scsi/aacraid/comminit.c | 106 ++++++++++-
drivers/scsi/aacraid/commsup.c | 78 ++++++--
drivers/scsi/aacraid/dpcsup.c | 13 +-
drivers/scsi/aacraid/linit.c | 48 +++--
drivers/scsi/aacraid/rx.c | 14 +-
drivers/scsi/aacraid/src.c | 404 +++++++++++++++++++++++++++++----------
9 files changed, 894 insertions(+), 236 deletions(-)
--
1.7.7.3
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 1/7] aacraid: AIF support for SES device add/remove
2015-03-04 8:38 [PATCH 0/7] aacraid driver updates Mahesh Rajashekhara
@ 2015-03-04 8:38 ` Mahesh Rajashekhara
2015-03-17 7:05 ` Murthy Bhat
2015-03-17 15:24 ` Achim Leubner
2015-03-04 8:38 ` [PATCH 2/7] aacraid: IOCTL pass-through command fix Mahesh Rajashekhara
` (6 subsequent siblings)
7 siblings, 2 replies; 32+ messages in thread
From: Mahesh Rajashekhara @ 2015-03-04 8:38 UTC (permalink / raw)
To: JBottomley, linux-scsi
Cc: aacraid, Harry.Yang, Achim.Leubner, Rajinikanth.Pandurangan,
Rich.Bono, Mahesh.Rajashekhara
Add new AIF support for SES device add/remove
Signed-off-by: Mahesh Rajashekhara <Mahesh.Rajashekhara@pmcs.com>
---
drivers/scsi/aacraid/aacraid.h | 2 ++
drivers/scsi/aacraid/commsup.c | 8 ++++++--
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index eaaf870..284db39 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -1951,6 +1951,8 @@ extern struct aac_common aac_config;
#define AifEnEnclosureManagement 13 /* EM_DRIVE_* */
#define EM_DRIVE_INSERTION 31
#define EM_DRIVE_REMOVAL 32
+#define EM_SES_DRIVE_INSERTION 33
+#define EM_SES_DRIVE_REMOVAL 26
#define AifEnBatteryEvent 14 /* Change in Battery State */
#define AifEnAddContainer 15 /* A new array was created */
#define AifEnDeleteContainer 16 /* A container was deleted */
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index cab190a..090ba68 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -1044,6 +1044,8 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
switch (le32_to_cpu(((__le32 *)aifcmd->data)[3])) {
case EM_DRIVE_INSERTION:
case EM_DRIVE_REMOVAL:
+ case EM_SES_DRIVE_INSERTION:
+ case EM_SES_DRIVE_REMOVAL:
container = le32_to_cpu(
((__le32 *)aifcmd->data)[2]);
if ((container >> 28)) {
@@ -1069,8 +1071,10 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
}
channel = aac_phys_to_logical(channel);
device_config_needed =
- (((__le32 *)aifcmd->data)[3]
- == cpu_to_le32(EM_DRIVE_INSERTION)) ?
+ ((((__le32 *)aifcmd->data)[3]
+ == cpu_to_le32(EM_DRIVE_INSERTION)) ||
+ (((__le32 *)aifcmd->data)[3]
+ == cpu_to_le32(EM_SES_DRIVE_INSERTION))) ?
ADD : DELETE;
break;
}
--
1.7.7.3
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 2/7] aacraid: IOCTL pass-through command fix
2015-03-04 8:38 [PATCH 0/7] aacraid driver updates Mahesh Rajashekhara
2015-03-04 8:38 ` [PATCH 1/7] aacraid: AIF support for SES device add/remove Mahesh Rajashekhara
@ 2015-03-04 8:38 ` Mahesh Rajashekhara
2015-03-17 7:06 ` Murthy Bhat
2015-03-17 15:26 ` Achim Leubner
2015-03-04 8:38 ` [PATCH 3/7] aacraid: 4KB sector support Mahesh Rajashekhara
` (5 subsequent siblings)
7 siblings, 2 replies; 32+ messages in thread
From: Mahesh Rajashekhara @ 2015-03-04 8:38 UTC (permalink / raw)
To: JBottomley, linux-scsi
Cc: aacraid, Harry.Yang, Achim.Leubner, Rajinikanth.Pandurangan,
Rich.Bono, Mahesh.Rajashekhara
The Linux aacriad driver fails to detect the case of SG list count=0 on IOCTL pass-through command and cause intermittent fault.
The result is the Linux aacriad driver send down IOCTL pass-through command with one not initialized SG list to firmware when receiving SG list count =0 on pass-through command.
Signed-off-by: Mahesh Rajashekhara <Mahesh.Rajashekhara@pmcs.com>
---
drivers/scsi/aacraid/commctrl.c | 10 ++++++++--
1 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c
index fbcd48d..54195a1 100644
--- a/drivers/scsi/aacraid/commctrl.c
+++ b/drivers/scsi/aacraid/commctrl.c
@@ -689,7 +689,10 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
kfree (usg);
}
srbcmd->count = cpu_to_le32(byte_count);
- psg->count = cpu_to_le32(sg_indx+1);
+ if (user_srbcmd->sg.count)
+ psg->count = cpu_to_le32(sg_indx+1);
+ else
+ psg->count = 0;
status = aac_fib_send(ScsiPortCommand64, srbfib, actual_fibsize, FsaNormal, 1, 1,NULL,NULL);
} else {
struct user_sgmap* upsg = &user_srbcmd->sg;
@@ -775,7 +778,10 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
}
}
srbcmd->count = cpu_to_le32(byte_count);
- psg->count = cpu_to_le32(sg_indx+1);
+ if (user_srbcmd->sg.count)
+ psg->count = cpu_to_le32(sg_indx+1);
+ else
+ psg->count = 0;
status = aac_fib_send(ScsiPortCommand, srbfib, actual_fibsize, FsaNormal, 1, 1, NULL, NULL);
}
if (status == -ERESTARTSYS) {
--
1.7.7.3
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 3/7] aacraid: 4KB sector support
2015-03-04 8:38 [PATCH 0/7] aacraid driver updates Mahesh Rajashekhara
2015-03-04 8:38 ` [PATCH 1/7] aacraid: AIF support for SES device add/remove Mahesh Rajashekhara
2015-03-04 8:38 ` [PATCH 2/7] aacraid: IOCTL pass-through command fix Mahesh Rajashekhara
@ 2015-03-04 8:38 ` Mahesh Rajashekhara
2015-03-17 7:06 ` Murthy Bhat
2015-03-17 15:26 ` Achim Leubner
2015-03-04 8:38 ` [PATCH 4/7] aacraid: MSI-x support Mahesh Rajashekhara
` (4 subsequent siblings)
7 siblings, 2 replies; 32+ messages in thread
From: Mahesh Rajashekhara @ 2015-03-04 8:38 UTC (permalink / raw)
To: JBottomley, linux-scsi
Cc: aacraid, Harry.Yang, Achim.Leubner, Rajinikanth.Pandurangan,
Rich.Bono, Mahesh.Rajashekhara
Add 4KB sector support
Signed-off-by: Mahesh Rajashekhara <Mahesh.Rajashekhara@pmcs.com>
---
drivers/scsi/aacraid/aachba.c | 195 +++++++++++++++++++++++++++++++---------
drivers/scsi/aacraid/aacraid.h | 10 ++-
2 files changed, 160 insertions(+), 45 deletions(-)
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index b32e77d..0819644 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -111,6 +111,41 @@
#define BYTE2(x) (unsigned char)((x) >> 16)
#define BYTE3(x) (unsigned char)((x) >> 24)
+/* MODE_SENSE data format */
+typedef struct {
+ struct {
+ u8 data_length;
+ u8 med_type;
+ u8 dev_par;
+ u8 bd_length;
+ } __attribute__((packed)) hd;
+ struct {
+ u8 dens_code;
+ u8 block_count[3];
+ u8 reserved;
+ u8 block_length[3];
+ } __attribute__((packed)) bd;
+ u8 mpc_buf[3];
+} __attribute__((packed)) aac_modep_data;
+
+/* MODE_SENSE_10 data format */
+typedef struct {
+ struct {
+ u8 data_length[2];
+ u8 med_type;
+ u8 dev_par;
+ u8 rsrvd[2];
+ u8 bd_length[2];
+ } __attribute__((packed)) hd;
+ struct {
+ u8 dens_code;
+ u8 block_count[3];
+ u8 reserved;
+ u8 block_length[3];
+ } __attribute__((packed)) bd;
+ u8 mpc_buf[3];
+} __attribute__((packed)) aac_modep10_data;
+
/*------------------------------------------------------------------------------
* S T R U C T S / T Y P E D E F S
*----------------------------------------------------------------------------*/
@@ -539,6 +574,13 @@ static void _aac_probe_container2(void * context, struct fib * fibptr)
if ((le32_to_cpu(dresp->status) == ST_OK) &&
(le32_to_cpu(dresp->mnt[0].vol) != CT_NONE) &&
(le32_to_cpu(dresp->mnt[0].state) != FSCS_HIDDEN)) {
+ if (!(fibptr->dev->supplement_adapter_info.SupportedOptions2 &
+ AAC_OPTION_VARIABLE_BLOCK_SIZE)) {
+ dresp->mnt[0].fileinfo.bdevinfo.block_size = 0x200;
+ fsa_dev_ptr->block_size = 0x200;
+ } else {
+ fsa_dev_ptr->block_size = le32_to_cpu(dresp->mnt[0].fileinfo.bdevinfo.block_size);
+ }
fsa_dev_ptr->valid = 1;
/* sense_key holds the current state of the spin-up */
if (dresp->mnt[0].state & cpu_to_le32(FSCS_NOT_READY))
@@ -586,7 +628,12 @@ static void _aac_probe_container1(void * context, struct fib * fibptr)
dinfo = (struct aac_query_mount *)fib_data(fibptr);
- dinfo->command = cpu_to_le32(VM_NameServe64);
+ if (fibptr->dev->supplement_adapter_info.SupportedOptions2 &
+ AAC_OPTION_VARIABLE_BLOCK_SIZE)
+ dinfo->command = cpu_to_le32(VM_NameServeAllBlk);
+ else
+ dinfo->command = cpu_to_le32(VM_NameServe64);
+
dinfo->count = cpu_to_le32(scmd_id(scsicmd));
dinfo->type = cpu_to_le32(FT_FILESYS);
@@ -621,7 +668,12 @@ static int _aac_probe_container(struct scsi_cmnd * scsicmd, int (*callback)(stru
dinfo = (struct aac_query_mount *)fib_data(fibptr);
- dinfo->command = cpu_to_le32(VM_NameServe);
+ if (fibptr->dev->supplement_adapter_info.SupportedOptions2 &
+ AAC_OPTION_VARIABLE_BLOCK_SIZE)
+ dinfo->command = cpu_to_le32(VM_NameServeAllBlk);
+ else
+ dinfo->command = cpu_to_le32(VM_NameServe);
+
dinfo->count = cpu_to_le32(scmd_id(scsicmd));
dinfo->type = cpu_to_le32(FT_FILESYS);
scsicmd->SCp.ptr = (char *)callback;
@@ -982,7 +1034,7 @@ static int aac_read_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u3
memset(readcmd2, 0, sizeof(struct aac_raw_io2));
readcmd2->blockLow = cpu_to_le32((u32)(lba&0xffffffff));
readcmd2->blockHigh = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32));
- readcmd2->byteCount = cpu_to_le32(count<<9);
+ readcmd2->byteCount = cpu_to_le32(count * dev->fsa_dev[scmd_id(cmd)].block_size);
readcmd2->cid = cpu_to_le16(scmd_id(cmd));
readcmd2->flags = cpu_to_le16(RIO2_IO_TYPE_READ);
ret = aac_build_sgraw2(cmd, readcmd2,
@@ -997,7 +1049,7 @@ static int aac_read_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u3
readcmd = (struct aac_raw_io *) fib_data(fib);
readcmd->block[0] = cpu_to_le32((u32)(lba&0xffffffff));
readcmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32));
- readcmd->count = cpu_to_le32(count<<9);
+ readcmd->count = cpu_to_le32(count * dev->fsa_dev[scmd_id(cmd)].block_size);
readcmd->cid = cpu_to_le16(scmd_id(cmd));
readcmd->flags = cpu_to_le16(RIO_TYPE_READ);
readcmd->bpTotal = 0;
@@ -1062,6 +1114,7 @@ static int aac_read_block(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32
{
u16 fibsize;
struct aac_read *readcmd;
+ struct aac_dev *dev = fib->dev;
long ret;
aac_fib_init(fib);
@@ -1069,7 +1122,7 @@ static int aac_read_block(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32
readcmd->command = cpu_to_le32(VM_CtBlockRead);
readcmd->cid = cpu_to_le32(scmd_id(cmd));
readcmd->block = cpu_to_le32((u32)(lba&0xffffffff));
- readcmd->count = cpu_to_le32(count * 512);
+ readcmd->count = cpu_to_le32(count * dev->fsa_dev[scmd_id(cmd)].block_size);
ret = aac_build_sg(cmd, &readcmd->sg);
if (ret < 0)
@@ -1104,7 +1157,7 @@ static int aac_write_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u
memset(writecmd2, 0, sizeof(struct aac_raw_io2));
writecmd2->blockLow = cpu_to_le32((u32)(lba&0xffffffff));
writecmd2->blockHigh = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32));
- writecmd2->byteCount = cpu_to_le32(count<<9);
+ writecmd2->byteCount = cpu_to_le32(count * dev->fsa_dev[scmd_id(cmd)].block_size);
writecmd2->cid = cpu_to_le16(scmd_id(cmd));
writecmd2->flags = (fua && ((aac_cache & 5) != 1) &&
(((aac_cache & 5) != 5) || !fib->dev->cache_protected)) ?
@@ -1122,7 +1175,7 @@ static int aac_write_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u
writecmd = (struct aac_raw_io *) fib_data(fib);
writecmd->block[0] = cpu_to_le32((u32)(lba&0xffffffff));
writecmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32));
- writecmd->count = cpu_to_le32(count<<9);
+ writecmd->count = cpu_to_le32(count * dev->fsa_dev[scmd_id(cmd)].block_size);
writecmd->cid = cpu_to_le16(scmd_id(cmd));
writecmd->flags = (fua && ((aac_cache & 5) != 1) &&
(((aac_cache & 5) != 5) || !fib->dev->cache_protected)) ?
@@ -1190,6 +1243,7 @@ static int aac_write_block(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u3
{
u16 fibsize;
struct aac_write *writecmd;
+ struct aac_dev *dev = fib->dev;
long ret;
aac_fib_init(fib);
@@ -1197,7 +1251,7 @@ static int aac_write_block(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u3
writecmd->command = cpu_to_le32(VM_CtBlockWrite);
writecmd->cid = cpu_to_le32(scmd_id(cmd));
writecmd->block = cpu_to_le32((u32)(lba&0xffffffff));
- writecmd->count = cpu_to_le32(count * 512);
+ writecmd->count = cpu_to_le32(count * dev->fsa_dev[scmd_id(cmd)].block_size);
writecmd->sg.count = cpu_to_le32(1);
/* ->stable is not used - it did mean which type of write */
@@ -2329,10 +2383,10 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
cp[5] = (capacity >> 16) & 0xff;
cp[6] = (capacity >> 8) & 0xff;
cp[7] = (capacity >> 0) & 0xff;
- cp[8] = 0;
- cp[9] = 0;
- cp[10] = 2;
- cp[11] = 0;
+ cp[8] = (fsa_dev_ptr[cid].block_size >> 24) & 0xff;
+ cp[9] = (fsa_dev_ptr[cid].block_size >> 16) & 0xff;
+ cp[10] = (fsa_dev_ptr[cid].block_size >> 8) & 0xff;
+ cp[11] = (fsa_dev_ptr[cid].block_size) & 0xff;
cp[12] = 0;
alloc_len = ((scsicmd->cmnd[10] << 24)
@@ -2369,10 +2423,10 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
cp[1] = (capacity >> 16) & 0xff;
cp[2] = (capacity >> 8) & 0xff;
cp[3] = (capacity >> 0) & 0xff;
- cp[4] = 0;
- cp[5] = 0;
- cp[6] = 2;
- cp[7] = 0;
+ cp[4] = (fsa_dev_ptr[cid].block_size >> 24) & 0xff;
+ cp[5] = (fsa_dev_ptr[cid].block_size >> 16) & 0xff;
+ cp[6] = (fsa_dev_ptr[cid].block_size >> 8) & 0xff;
+ cp[7] = (fsa_dev_ptr[cid].block_size) & 0xff;
scsi_sg_copy_from_buffer(scsicmd, cp, sizeof(cp));
/* Do not cache partition table for arrays */
scsicmd->device->removable = 1;
@@ -2385,30 +2439,55 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
case MODE_SENSE:
{
- char mode_buf[7];
int mode_buf_length = 4;
+ u32 capacity;
+ aac_modep_data mpd;
+
+ if (fsa_dev_ptr[cid].size <= 0x100000000ULL)
+ capacity = fsa_dev_ptr[cid].size - 1;
+ else
+ capacity = (u32)-1;
dprintk((KERN_DEBUG "MODE SENSE command.\n"));
- mode_buf[0] = 3; /* Mode data length */
- mode_buf[1] = 0; /* Medium type - default */
- mode_buf[2] = 0; /* Device-specific param,
+ memset((char *)&mpd, 0, sizeof(aac_modep_data));
+
+ mpd.hd.data_length = sizeof(mpd.hd) - 1; /* Mode data length */
+ mpd.hd.med_type = 0; /* Medium type - default */
+ mpd.hd.dev_par = 0; /* Device-specific param,
bit 8: 0/1 = write enabled/protected
bit 4: 0/1 = FUA enabled */
if (dev->raw_io_interface && ((aac_cache & 5) != 1))
- mode_buf[2] = 0x10;
- mode_buf[3] = 0; /* Block descriptor length */
+ mpd.hd.dev_par = 0x10;
+ if (scsicmd->cmnd[1] & 0x8) {
+ mpd.hd.bd_length = 0; /* Block descriptor length */
+ } else {
+ mpd.hd.bd_length = sizeof(mpd.bd);
+ mpd.hd.data_length += mpd.hd.bd_length;
+ mpd.bd.block_length[0] = (fsa_dev_ptr[cid].block_size >> 16) & 0xff;
+ mpd.bd.block_length[1] = (fsa_dev_ptr[cid].block_size >> 8) & 0xff;
+ mpd.bd.block_length[2] = fsa_dev_ptr[cid].block_size & 0xff;
+ if (capacity > 0xffffff) {
+ mpd.bd.block_count[0] = 0xff;
+ mpd.bd.block_count[1] = 0xff;
+ mpd.bd.block_count[2] = 0xff;
+ } else {
+ mpd.bd.block_count[0] = (capacity >> 16) & 0xff;
+ mpd.bd.block_count[1] = (capacity >> 8) & 0xff;
+ mpd.bd.block_count[2] = capacity & 0xff;
+ }
+ }
if (((scsicmd->cmnd[2] & 0x3f) == 8) ||
((scsicmd->cmnd[2] & 0x3f) == 0x3f)) {
- mode_buf[0] = 6;
- mode_buf[4] = 8;
- mode_buf[5] = 1;
- mode_buf[6] = ((aac_cache & 6) == 2)
+ mpd.hd.data_length += 3;
+ mpd.mpc_buf[0] = 8;
+ mpd.mpc_buf[1] = 1;
+ mpd.mpc_buf[2] = ((aac_cache & 6) == 2)
? 0 : 0x04; /* WCE */
- mode_buf_length = 7;
+ mode_buf_length = sizeof(mpd);
if (mode_buf_length > scsicmd->cmnd[4])
mode_buf_length = scsicmd->cmnd[4];
}
- scsi_sg_copy_from_buffer(scsicmd, mode_buf, mode_buf_length);
+ scsi_sg_copy_from_buffer(scsicmd, (char *)&mpd, mode_buf_length);
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
scsicmd->scsi_done(scsicmd);
@@ -2416,34 +2495,62 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
}
case MODE_SENSE_10:
{
- char mode_buf[11];
+ u32 capacity;
int mode_buf_length = 8;
+ aac_modep10_data mpd10;
+
+ if (fsa_dev_ptr[cid].size <= 0x100000000ULL)
+ capacity = fsa_dev_ptr[cid].size - 1;
+ else
+ capacity = (u32)-1;
dprintk((KERN_DEBUG "MODE SENSE 10 byte command.\n"));
- mode_buf[0] = 0; /* Mode data length (MSB) */
- mode_buf[1] = 6; /* Mode data length (LSB) */
- mode_buf[2] = 0; /* Medium type - default */
- mode_buf[3] = 0; /* Device-specific param,
+ memset((char *)&mpd10, 0, sizeof(aac_modep10_data));
+ mpd10.hd.data_length[0] = 0; /* Mode data length (MSB) */
+ mpd10.hd.data_length[1] = sizeof(mpd10.hd) - 1; /* Mode data length (LSB) */
+ mpd10.hd.med_type = 0; /* Medium type - default */
+ mpd10.hd.dev_par = 0; /* Device-specific param,
bit 8: 0/1 = write enabled/protected
bit 4: 0/1 = FUA enabled */
if (dev->raw_io_interface && ((aac_cache & 5) != 1))
- mode_buf[3] = 0x10;
- mode_buf[4] = 0; /* reserved */
- mode_buf[5] = 0; /* reserved */
- mode_buf[6] = 0; /* Block descriptor length (MSB) */
- mode_buf[7] = 0; /* Block descriptor length (LSB) */
+ mpd10.hd.dev_par = 0x10;
+ mpd10.hd.rsrvd[0] = 0; /* reserved */
+ mpd10.hd.rsrvd[1] = 0; /* reserved */
+ if (scsicmd->cmnd[1] & 0x8) {
+ mpd10.hd.bd_length[0] = 0; /* Block descriptor length (MSB) */
+ mpd10.hd.bd_length[1] = 0; /* Block descriptor length (LSB) */
+ } else {
+ mpd10.hd.bd_length[0] = 0;
+ mpd10.hd.bd_length[1] = sizeof(mpd10.bd);
+
+ mpd10.hd.data_length[1] += mpd10.hd.bd_length[1];
+
+ mpd10.bd.block_length[0] = (fsa_dev_ptr[cid].block_size >> 16) & 0xff;
+ mpd10.bd.block_length[1] = (fsa_dev_ptr[cid].block_size >> 8) & 0xff;
+ mpd10.bd.block_length[2] = fsa_dev_ptr[cid].block_size & 0xff;
+
+ if (capacity > 0xffffff) {
+ mpd10.bd.block_count[0] = 0xff;
+ mpd10.bd.block_count[1] = 0xff;
+ mpd10.bd.block_count[2] = 0xff;
+ } else {
+ mpd10.bd.block_count[0] = (capacity >> 16) & 0xff;
+ mpd10.bd.block_count[1] = (capacity >> 8) & 0xff;
+ mpd10.bd.block_count[2] = capacity & 0xff;
+ }
+ }
if (((scsicmd->cmnd[2] & 0x3f) == 8) ||
((scsicmd->cmnd[2] & 0x3f) == 0x3f)) {
- mode_buf[1] = 9;
- mode_buf[8] = 8;
- mode_buf[9] = 1;
- mode_buf[10] = ((aac_cache & 6) == 2)
+ mpd10.hd.data_length[1] += 3;
+ mpd10.mpc_buf[0] = 8;
+ mpd10.mpc_buf[1] = 1;
+ mpd10.mpc_buf[2] = ((aac_cache & 6) == 2)
? 0 : 0x04; /* WCE */
- mode_buf_length = 11;
+ mode_buf_length = sizeof(mpd10);
if (mode_buf_length > scsicmd->cmnd[8])
mode_buf_length = scsicmd->cmnd[8];
}
- scsi_sg_copy_from_buffer(scsicmd, mode_buf, mode_buf_length);
+ scsi_sg_copy_from_buffer(scsicmd, (char *)&mpd10, mode_buf_length);
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
scsicmd->scsi_done(scsicmd);
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index 284db39..93579f3 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -857,6 +857,7 @@ struct fsa_dev_info {
u8 deleted;
char devname[8];
struct sense_data sense_data;
+ u32 block_size;
};
struct fib {
@@ -960,6 +961,7 @@ struct aac_supplement_adapter_info
#define AAC_OPTION_IGNORE_RESET cpu_to_le32(0x00000002)
#define AAC_OPTION_POWER_MANAGEMENT cpu_to_le32(0x00000004)
#define AAC_OPTION_DOORBELL_RESET cpu_to_le32(0x00004000)
+#define AAC_OPTION_VARIABLE_BLOCK_SIZE cpu_to_le32(0x00040000) /* 4KB sector size */
#define AAC_SIS_VERSION_V3 3
#define AAC_SIS_SLOT_UNKNOWN 0xFF
@@ -1589,6 +1591,7 @@ struct aac_srb_reply
#define VM_CtHostWrite64 20
#define VM_DrvErrTblLog 21
#define VM_NameServe64 22
+#define VM_NameServeAllBlk 30
#define MAX_VMCOMMAND_NUM 23 /* used for sizing stats array - leave last */
@@ -1611,8 +1614,13 @@ struct aac_fsinfo {
__le32 fsInodeDensity;
}; /* valid iff ObjType == FT_FILESYS && !(ContentState & FSCS_NOTCLEAN) */
+struct aac_blockdevinfo {
+ __le32 block_size;
+};
+
union aac_contentinfo {
- struct aac_fsinfo filesys; /* valid iff ObjType == FT_FILESYS && !(ContentState & FSCS_NOTCLEAN) */
+ struct aac_fsinfo filesys; /* valid iff ObjType == FT_FILESYS && !(ContentState & FSCS_NOTCLEAN) */
+ struct aac_blockdevinfo bdevinfo;
};
/*
--
1.7.7.3
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 4/7] aacraid: MSI-x support
2015-03-04 8:38 [PATCH 0/7] aacraid driver updates Mahesh Rajashekhara
` (2 preceding siblings ...)
2015-03-04 8:38 ` [PATCH 3/7] aacraid: 4KB sector support Mahesh Rajashekhara
@ 2015-03-04 8:38 ` Mahesh Rajashekhara
2015-03-17 7:06 ` Murthy Bhat
2015-03-17 15:27 ` Achim Leubner
2015-03-04 8:38 ` [PATCH 5/7] aacraid: vpd page code 0x83 support Mahesh Rajashekhara
` (3 subsequent siblings)
7 siblings, 2 replies; 32+ messages in thread
From: Mahesh Rajashekhara @ 2015-03-04 8:38 UTC (permalink / raw)
To: JBottomley, linux-scsi
Cc: aacraid, Harry.Yang, Achim.Leubner, Rajinikanth.Pandurangan,
Rich.Bono, Mahesh.Rajashekhara
Add MSI-x interrupt mode support.
Signed-off-by: Mahesh Rajashekhara <Mahesh.Rajashekhara@pmcs.com>
---
drivers/scsi/aacraid/aachba.c | 6 +-
drivers/scsi/aacraid/aacraid.h | 79 ++++++++-
drivers/scsi/aacraid/comminit.c | 86 +++++++++-
drivers/scsi/aacraid/commsup.c | 19 ++-
drivers/scsi/aacraid/dpcsup.c | 9 +-
drivers/scsi/aacraid/linit.c | 18 ++-
drivers/scsi/aacraid/src.c | 365 +++++++++++++++++++++++++++++----------
7 files changed, 473 insertions(+), 109 deletions(-)
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index 0819644..eb524e6 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -473,7 +473,7 @@ static void get_container_name_callback(void *context, struct fib * fibptr)
if ((le32_to_cpu(get_name_reply->status) == CT_OK)
&& (get_name_reply->data[0] != '\0')) {
char *sp = get_name_reply->data;
- sp[sizeof(((struct aac_get_name_resp *)NULL)->data)-1] = '\0';
+ sp[sizeof(((struct aac_get_name_resp *)NULL)->data)] = '\0';
while (*sp == ' ')
++sp;
if (*sp) {
@@ -613,7 +613,9 @@ static void _aac_probe_container1(void * context, struct fib * fibptr)
int status;
dresp = (struct aac_mount *) fib_data(fibptr);
- dresp->mnt[0].capacityhigh = 0;
+ if (!(fibptr->dev->supplement_adapter_info.SupportedOptions2 &
+ AAC_OPTION_VARIABLE_BLOCK_SIZE))
+ dresp->mnt[0].capacityhigh = 0;
if ((le32_to_cpu(dresp->status) != ST_OK) ||
(le32_to_cpu(dresp->mnt[0].vol) != CT_NONE)) {
_aac_probe_container2(context, fibptr);
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index 93579f3..c162a65 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -6,11 +6,61 @@
#define nblank(x) _nblank(x)[0]
#include <linux/interrupt.h>
+#include <linux/pci.h>
/*------------------------------------------------------------------------------
* D E F I N E S
*----------------------------------------------------------------------------*/
+#define AAC_MAX_MSIX 32 /* vectors */
+#define AAC_PCI_MSI_ENABLE 0x8000
+
+enum {
+ AAC_ENABLE_INTERRUPT = 0x0,
+ AAC_DISABLE_INTERRUPT,
+ AAC_ENABLE_MSIX,
+ AAC_DISABLE_MSIX,
+ AAC_CLEAR_AIF_BIT,
+ AAC_CLEAR_SYNC_BIT,
+ AAC_ENABLE_INTX
+};
+
+#define AAC_INT_MODE_INTX (1<<0)
+#define AAC_INT_MODE_MSI (1<<1)
+#define AAC_INT_MODE_AIF (1<<2)
+#define AAC_INT_MODE_SYNC (1<<3)
+
+#define AAC_INT_ENABLE_TYPE1_INTX 0xfffffffb
+#define AAC_INT_ENABLE_TYPE1_MSIX 0xfffffffa
+#define AAC_INT_DISABLE_ALL 0xffffffff
+
+/* Bit definitions in IOA->Host Interrupt Register */
+#define PMC_TRANSITION_TO_OPERATIONAL (0x80000000 >> 0)
+#define PMC_IOARCB_TRANSFER_FAILED (0x80000000 >> 3)
+#define PMC_IOA_UNIT_CHECK (0x80000000 >> 4)
+#define PMC_NO_HOST_RRQ_FOR_CMD_RESPONSE (0x80000000 >> 5)
+#define PMC_CRITICAL_IOA_OP_IN_PROGRESS (0x80000000 >> 6)
+#define PMC_IOARRIN_LOST (0x80000000 >> 27)
+#define PMC_SYSTEM_BUS_MMIO_ERROR (0x80000000 >> 28)
+#define PMC_IOA_PROCESSOR_IN_ERROR_STATE (0x80000000 >> 29)
+#define PMC_HOST_RRQ_VALID (0x80000000 >> 30)
+#define PMC_OPERATIONAL_STATUS (0x80000000 >> 0)
+#define PMC_ALLOW_MSIX_VECTOR0 (0x80000000 >> 31)
+
+#define PMC_IOA_ERROR_INTERRUPTS (PMC_IOARCB_TRANSFER_FAILED | \
+ PMC_IOA_UNIT_CHECK | \
+ PMC_NO_HOST_RRQ_FOR_CMD_RESPONSE | \
+ PMC_IOARRIN_LOST | \
+ PMC_SYSTEM_BUS_MMIO_ERROR | \
+ PMC_IOA_PROCESSOR_IN_ERROR_STATE)
+
+#define PMC_ALL_INTERRUPT_BITS (PMC_IOA_ERROR_INTERRUPTS | \
+ PMC_HOST_RRQ_VALID | \
+ PMC_TRANSITION_TO_OPERATIONAL | \
+ PMC_ALLOW_MSIX_VECTOR0)
+#define PMC_GLOBAL_INT_BIT2 0x00000004
+#define PMC_GLOBAL_INT_BIT0 0x00000001
+
#ifndef AAC_DRIVER_BUILD
# define AAC_DRIVER_BUILD 30300
# define AAC_DRIVER_BRANCH "-ms"
@@ -36,6 +86,7 @@
#define CONTAINER_TO_ID(cont) (cont)
#define CONTAINER_TO_LUN(cont) (0)
+#define PMC_DEVICE_S6 0x28b
#define PMC_DEVICE_S7 0x28c
#define PMC_DEVICE_S8 0x28d
#define PMC_DEVICE_S9 0x28f
@@ -434,7 +485,7 @@ enum fib_xfer_state {
struct aac_init
{
__le32 InitStructRevision;
- __le32 MiniPortRevision;
+ __le32 NoOfMSIXVectors;
__le32 fsrev;
__le32 CommHeaderAddress;
__le32 FastIoCommAreaAddress;
@@ -755,7 +806,8 @@ struct rkt_registers {
struct src_mu_registers {
/* PCI*| Name */
- __le32 reserved0[8]; /* 00h | Reserved */
+ __le32 reserved0[6]; /* 00h | Reserved */
+ __le32 IOAR[2]; /* 18h | IOA->host interrupt register */
__le32 IDR; /* 20h | Inbound Doorbell Register */
__le32 IISR; /* 24h | Inbound Int. Status Register */
__le32 reserved1[3]; /* 28h | Reserved */
@@ -767,17 +819,18 @@ struct src_mu_registers {
__le32 OMR; /* bch | Outbound Message Register */
__le32 IQ_L; /* c0h | Inbound Queue (Low address) */
__le32 IQ_H; /* c4h | Inbound Queue (High address) */
+ __le32 ODR_MSI; /* c8h | MSI register for sync./AIF */
};
struct src_registers {
- struct src_mu_registers MUnit; /* 00h - c7h */
+ struct src_mu_registers MUnit; /* 00h - cbh */
union {
struct {
- __le32 reserved1[130790]; /* c8h - 7fc5fh */
+ __le32 reserved1[130789]; /* cch - 7fc5fh */
struct src_inbound IndexRegs; /* 7fc60h */
} tupelo;
struct {
- __le32 reserved1[974]; /* c8h - fffh */
+ __le32 reserved1[973]; /* cch - fffh */
struct src_inbound IndexRegs; /* 1000h */
} denali;
} u;
@@ -1028,6 +1081,11 @@ struct aac_bus_info_response {
#define AAC_OPT_NEW_COMM_TYPE3 cpu_to_le32(1<<30)
#define AAC_OPT_NEW_COMM_TYPE4 cpu_to_le32(1<<31)
+/* MSIX context */
+struct aac_msix_ctx {
+ int vector_no;
+ struct aac_dev *dev;
+};
struct aac_dev
{
@@ -1083,8 +1141,9 @@ struct aac_dev
* if AAC_COMM_MESSAGE_TYPE1 */
dma_addr_t host_rrq_pa; /* phys. address */
- u32 host_rrq_idx; /* index into rrq buffer */
-
+ u32 host_rrq_idx[AAC_MAX_MSIX]; /* index into rrq buffer */
+ atomic_t rrq_outstanding[AAC_MAX_MSIX];
+ u32 fibs_pushed_no;
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 */
@@ -1153,6 +1212,11 @@ struct aac_dev
int sync_mode;
struct fib *sync_fib;
struct list_head sync_fib_list;
+ u32 max_msix; /* max. MSI-X vectors */
+ u32 vector_cap; /* MSI-X vector capab.*/
+ int msi_enabled; /* MSI/MSI-X enabled */
+ struct msix_entry msixentry[AAC_MAX_MSIX];
+ struct aac_msix_ctx aac_msix[AAC_MAX_MSIX]; /* context */
};
#define aac_adapter_interrupt(dev) \
@@ -2035,6 +2099,7 @@ void aac_consumer_free(struct aac_dev * dev, struct aac_queue * q, u32 qnum);
int aac_fib_complete(struct fib * context);
#define fib_data(fibctx) ((void *)(fibctx)->hw_fib_va->data)
struct aac_dev *aac_init_adapter(struct aac_dev *dev);
+void aac_src_access_devreg(struct aac_dev *dev, int mode);
int aac_get_config_status(struct aac_dev *dev, int commit_flag);
int aac_get_containers(struct aac_dev *dev);
int aac_scsi_cmd(struct scsi_cmnd *cmd);
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c
index 177b094..29c35c8 100644
--- a/drivers/scsi/aacraid/comminit.c
+++ b/drivers/scsi/aacraid/comminit.c
@@ -43,6 +43,8 @@
#include "aacraid.h"
+static void aac_define_int_mode(struct aac_dev *dev);
+
struct aac_common aac_config = {
.irq_mod = 1
};
@@ -91,7 +93,7 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
init->InitStructRevision = cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION);
if (dev->max_fib_size != sizeof(struct hw_fib))
init->InitStructRevision = cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_4);
- init->MiniPortRevision = cpu_to_le32(Sa_MINIPORT_REVISION);
+ init->NoOfMSIXVectors = cpu_to_le32(Sa_MINIPORT_REVISION);
init->fsrev = cpu_to_le32(dev->fsrev);
/*
@@ -140,7 +142,7 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
INITFLAGS_NEW_COMM_TYPE2_SUPPORTED | INITFLAGS_FAST_JBOD_SUPPORTED);
init->HostRRQ_AddrHigh = cpu_to_le32((u32)((u64)dev->host_rrq_pa >> 32));
init->HostRRQ_AddrLow = cpu_to_le32((u32)(dev->host_rrq_pa & 0xffffffff));
- init->MiniPortRevision = cpu_to_le32(0L); /* number of MSI-X */
+ init->NoOfMSIXVectors = cpu_to_le32(dev->max_msix); /* number of MSI-X */
dprintk((KERN_WARNING"aacraid: New Comm Interface type2 enabled\n"));
}
@@ -228,6 +230,11 @@ int aac_send_shutdown(struct aac_dev * dev)
/* FIB should be freed only after getting the response from the F/W */
if (status != -ERESTARTSYS)
aac_fib_free(fibctx);
+ if ((dev->pdev->device == PMC_DEVICE_S7 ||
+ dev->pdev->device == PMC_DEVICE_S8 ||
+ dev->pdev->device == PMC_DEVICE_S9) &&
+ dev->msi_enabled)
+ aac_src_access_devreg(dev, AAC_ENABLE_INTX);
return status;
}
@@ -388,6 +395,8 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
}
}
}
+ dev->max_msix = 0;
+ dev->msi_enabled = 0;
if ((!aac_adapter_sync_cmd(dev, GET_COMM_PREFERRED_SETTINGS,
0, 0, 0, 0, 0, 0,
status+0, status+1, status+2, status+3, status+4))
@@ -461,6 +470,11 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
if (host->can_queue > AAC_NUM_IO_FIB)
host->can_queue = AAC_NUM_IO_FIB;
+ if (dev->pdev->device == PMC_DEVICE_S6 ||
+ dev->pdev->device == PMC_DEVICE_S7 ||
+ dev->pdev->device == PMC_DEVICE_S8 ||
+ dev->pdev->device == PMC_DEVICE_S9)
+ aac_define_int_mode(dev);
/*
* Ok now init the communication subsystem
*/
@@ -489,4 +503,70 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
return dev;
}
-
+static void aac_define_int_mode(struct aac_dev *dev)
+{
+
+ int i, msi_count;
+
+ /* max. vectors from GET_COMM_PREFERRED_SETTINGS */
+ if (dev->max_msix == 0 ||
+ dev->pdev->device == PMC_DEVICE_S6 ||
+ dev->sync_mode) {
+ dev->max_msix = 1;
+ dev->vector_cap = dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB;
+ return;
+ }
+
+ msi_count = min(dev->max_msix,
+ (unsigned int)num_online_cpus());
+
+ dev->max_msix = msi_count;
+
+ if (msi_count > AAC_MAX_MSIX)
+ msi_count = AAC_MAX_MSIX;
+
+ for (i = 0; i < msi_count; i++)
+ dev->msixentry[i].entry = i;
+
+ if (msi_count > 1 && pci_find_capability(dev->pdev, PCI_CAP_ID_MSIX)) {
+
+ i = pci_enable_msix(dev->pdev, dev->msixentry, msi_count);
+ /* Check how many MSIX vectors are allocated */
+ if (i >= 0) {
+ dev->msi_enabled = 1;
+ if (i) {
+ msi_count = i;
+ if (pci_enable_msix(dev->pdev, dev->msixentry, msi_count)) {
+ dev->msi_enabled = 0;
+ printk(KERN_ERR "%s%d: MSIX not supported!! Will try MSI 0x%x.\n",
+ dev->name, dev->id, i);
+ }
+ }
+ } else {
+ dev->msi_enabled = 0;
+ printk(KERN_ERR "%s%d: MSIX not supported!! Will try MSI 0x%x.\n",
+ dev->name, dev->id, i);
+ }
+ }
+
+ if (!dev->msi_enabled) {
+ msi_count = 1;
+ i = !pci_enable_msi(dev->pdev);
+
+ if (i) {
+ dev->msi_enabled = 1;
+ dev->msi = 1;
+ } else {
+ printk(KERN_ERR "%s%d: MSI not supported!! Will try INTx 0x%x.\n",
+ dev->name, dev->id, i);
+ }
+ }
+
+ if (!dev->msi_enabled)
+ dev->max_msix = msi_count = 1;
+ else {
+ if (dev->max_msix > msi_count)
+ dev->max_msix = msi_count;
+ }
+ dev->vector_cap = (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB) / msi_count;
+}
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index 090ba68..83c5d3f 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -868,7 +868,7 @@ void aac_printf(struct aac_dev *dev, u32 val)
* dispatches it to the appropriate routine for handling.
*/
-#define AIF_SNIFF_TIMEOUT (30*HZ)
+#define AIF_SNIFF_TIMEOUT (500*HZ)
static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
{
struct hw_fib * hw_fib = fibptr->hw_fib_va;
@@ -1251,7 +1251,7 @@ retry_next:
static int _aac_reset_adapter(struct aac_dev *aac, int forced)
{
int index, quirks;
- int retval;
+ int retval, i;
struct Scsi_Host *host;
struct scsi_device *dev;
struct scsi_cmnd *command;
@@ -1319,7 +1319,20 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced)
aac->comm_phys = 0;
kfree(aac->queues);
aac->queues = NULL;
- free_irq(aac->pdev->irq, aac);
+ if (aac->pdev->device == PMC_DEVICE_S6 ||
+ aac->pdev->device == PMC_DEVICE_S7 ||
+ aac->pdev->device == PMC_DEVICE_S8 ||
+ aac->pdev->device == PMC_DEVICE_S9) {
+ if (aac->max_msix > 1) {
+ for (i = 0; i < aac->max_msix; i++)
+ free_irq(aac->msixentry[i].vector, &(aac->aac_msix[i]));
+ pci_disable_msix(aac->pdev);
+ } else {
+ free_irq(aac->pdev->irq, &(aac->aac_msix[0]));
+ }
+ } else {
+ free_irq(aac->pdev->irq, aac);
+ }
if (aac->msi)
pci_disable_msi(aac->pdev);
kfree(aac->fsa_dev);
diff --git a/drivers/scsi/aacraid/dpcsup.c b/drivers/scsi/aacraid/dpcsup.c
index d81b281..2e39466 100644
--- a/drivers/scsi/aacraid/dpcsup.c
+++ b/drivers/scsi/aacraid/dpcsup.c
@@ -389,8 +389,13 @@ 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 &= FIB_CONTEXT_FLAG_FASTRESP;
- fib->callback(fib->callback_data, fib);
+ if (likely(fib->callback && fib->callback_data)) {
+ fib->flags &= FIB_CONTEXT_FLAG_FASTRESP;
+ fib->callback(fib->callback_data, fib);
+ } else {
+ aac_fib_complete(fib);
+ aac_fib_free(fib);
+ }
} else {
unsigned long flagv;
dprintk((KERN_INFO "event_wait up\n"));
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index fdcdf9f..7813a9b 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -1082,6 +1082,8 @@ static struct scsi_host_template aac_driver_template = {
static void __aac_shutdown(struct aac_dev * aac)
{
+ int i;
+
if (aac->aif_thread) {
int i;
/* Clear out events first */
@@ -1095,9 +1097,23 @@ static void __aac_shutdown(struct aac_dev * aac)
}
aac_send_shutdown(aac);
aac_adapter_disable_int(aac);
- free_irq(aac->pdev->irq, aac);
+ if (aac->pdev->device == PMC_DEVICE_S6 ||
+ aac->pdev->device == PMC_DEVICE_S7 ||
+ aac->pdev->device == PMC_DEVICE_S8 ||
+ aac->pdev->device == PMC_DEVICE_S9) {
+ if (aac->max_msix > 1) {
+ for (i = 0; i < aac->max_msix; i++)
+ free_irq(aac->msixentry[i].vector, &(aac->aac_msix[i]));
+ } else {
+ free_irq(aac->pdev->irq, &(aac->aac_msix[0]));
+ }
+ } else {
+ free_irq(aac->pdev->irq, aac);
+ }
if (aac->msi)
pci_disable_msi(aac->pdev);
+ else if (aac->max_msix > 1)
+ pci_disable_msix(aac->pdev);
}
static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c
index 9c65aed..c010248 100644
--- a/drivers/scsi/aacraid/src.c
+++ b/drivers/scsi/aacraid/src.c
@@ -44,98 +44,124 @@
#include "aacraid.h"
-static irqreturn_t aac_src_intr_message(int irq, void *dev_id)
+static int aac_src_get_sync_status(struct aac_dev *dev);
+
+irqreturn_t aac_src_intr_message(int irq, void *dev_id)
{
- struct aac_dev *dev = dev_id;
+ struct aac_msix_ctx *ctx;
+ struct aac_dev *dev;
unsigned long bellbits, bellbits_shifted;
- int our_interrupt = 0;
- int isFastResponse;
+ int vector_no;
+ int isFastResponse, mode;
u32 index, handle;
- bellbits = src_readl(dev, MUnit.ODR_R);
- if (bellbits & PmDoorBellResponseSent) {
- bellbits = PmDoorBellResponseSent;
- /* handle async. status */
- src_writel(dev, MUnit.ODR_C, bellbits);
- src_readl(dev, MUnit.ODR_C);
- our_interrupt = 1;
- index = dev->host_rrq_idx;
- for (;;) {
- isFastResponse = 0;
- /* remove toggle bit (31) */
- handle = le32_to_cpu(dev->host_rrq[index]) & 0x7fffffff;
- /* check fast response bit (30) */
- if (handle & 0x40000000)
- isFastResponse = 1;
- handle &= 0x0000ffff;
- if (handle == 0)
- break;
-
- aac_intr_normal(dev, handle-1, 0, isFastResponse, NULL);
-
- dev->host_rrq[index++] = 0;
- if (index == dev->scsi_host_ptr->can_queue +
- AAC_NUM_MGT_FIB)
- index = 0;
- dev->host_rrq_idx = index;
+ ctx = (struct aac_msix_ctx *)dev_id;
+ dev = ctx->dev;
+ vector_no = ctx->vector_no;
+
+ if (dev->msi_enabled) {
+ mode = AAC_INT_MODE_MSI;
+ if (vector_no == 0) {
+ bellbits = src_readl(dev, MUnit.ODR_MSI);
+ if (bellbits & 0x40000)
+ mode |= AAC_INT_MODE_AIF;
+ if (bellbits & 0x1000)
+ mode |= AAC_INT_MODE_SYNC;
}
} else {
- bellbits_shifted = (bellbits >> SRC_ODR_SHIFT);
- if (bellbits_shifted & DoorBellAifPending) {
+ mode = AAC_INT_MODE_INTX;
+ bellbits = src_readl(dev, MUnit.ODR_R);
+ if (bellbits & PmDoorBellResponseSent) {
+ bellbits = PmDoorBellResponseSent;
+ src_writel(dev, MUnit.ODR_C, bellbits);
+ src_readl(dev, MUnit.ODR_C);
+ } else {
+ bellbits_shifted = (bellbits >> SRC_ODR_SHIFT);
src_writel(dev, MUnit.ODR_C, bellbits);
src_readl(dev, MUnit.ODR_C);
- our_interrupt = 1;
- /* handle AIF */
- aac_intr_normal(dev, 0, 2, 0, NULL);
- } else if (bellbits_shifted & OUTBOUNDDOORBELL_0) {
- unsigned long sflags;
- struct list_head *entry;
- int send_it = 0;
- extern int aac_sync_mode;
+ if (bellbits_shifted & DoorBellAifPending)
+ mode |= AAC_INT_MODE_AIF;
+ else if (bellbits_shifted & OUTBOUNDDOORBELL_0)
+ mode |= AAC_INT_MODE_SYNC;
+ }
+ }
+
+ if (mode & AAC_INT_MODE_SYNC) {
+ unsigned long sflags;
+ struct list_head *entry;
+ int send_it = 0;
+ extern int aac_sync_mode;
+
+ if (!aac_sync_mode && !dev->msi_enabled) {
src_writel(dev, MUnit.ODR_C, bellbits);
src_readl(dev, MUnit.ODR_C);
+ }
- if (!aac_sync_mode) {
- src_writel(dev, MUnit.ODR_C, bellbits);
- src_readl(dev, MUnit.ODR_C);
- our_interrupt = 1;
+ if (dev->sync_fib) {
+ if (dev->sync_fib->callback)
+ dev->sync_fib->callback(dev->sync_fib->callback_data,
+ dev->sync_fib);
+ spin_lock_irqsave(&dev->sync_fib->event_lock, sflags);
+ if (dev->sync_fib->flags & FIB_CONTEXT_FLAG_WAIT) {
+ dev->management_fib_count--;
+ up(&dev->sync_fib->event_wait);
}
-
- if (dev->sync_fib) {
- our_interrupt = 1;
- if (dev->sync_fib->callback)
- dev->sync_fib->callback(dev->sync_fib->callback_data,
- dev->sync_fib);
- spin_lock_irqsave(&dev->sync_fib->event_lock, sflags);
- if (dev->sync_fib->flags & FIB_CONTEXT_FLAG_WAIT) {
- dev->management_fib_count--;
- up(&dev->sync_fib->event_wait);
- }
- spin_unlock_irqrestore(&dev->sync_fib->event_lock, sflags);
- spin_lock_irqsave(&dev->sync_lock, sflags);
- if (!list_empty(&dev->sync_fib_list)) {
- entry = dev->sync_fib_list.next;
- dev->sync_fib = list_entry(entry, struct fib, fiblink);
- list_del(entry);
- send_it = 1;
- } else {
- dev->sync_fib = NULL;
- }
- spin_unlock_irqrestore(&dev->sync_lock, sflags);
- if (send_it) {
- aac_adapter_sync_cmd(dev, SEND_SYNCHRONOUS_FIB,
- (u32)dev->sync_fib->hw_fib_pa, 0, 0, 0, 0, 0,
- NULL, NULL, NULL, NULL, NULL);
- }
+ spin_unlock_irqrestore(&dev->sync_fib->event_lock, sflags);
+ spin_lock_irqsave(&dev->sync_lock, sflags);
+ if (!list_empty(&dev->sync_fib_list)) {
+ entry = dev->sync_fib_list.next;
+ dev->sync_fib = list_entry(entry, struct fib, fiblink);
+ list_del(entry);
+ send_it = 1;
+ } else {
+ dev->sync_fib = NULL;
+ }
+ spin_unlock_irqrestore(&dev->sync_lock, sflags);
+ if (send_it) {
+ aac_adapter_sync_cmd(dev, SEND_SYNCHRONOUS_FIB,
+ (u32)dev->sync_fib->hw_fib_pa, 0, 0, 0, 0, 0,
+ NULL, NULL, NULL, NULL, NULL);
}
}
+ if (!dev->msi_enabled)
+ mode = 0;
+
}
- if (our_interrupt) {
- return IRQ_HANDLED;
+ if (mode & AAC_INT_MODE_AIF) {
+ /* handle AIF */
+ aac_intr_normal(dev, 0, 2, 0, NULL);
+ if (dev->msi_enabled)
+ aac_src_access_devreg(dev, AAC_CLEAR_AIF_BIT);
+ mode = 0;
}
- return IRQ_NONE;
+
+ if (mode) {
+ index = dev->host_rrq_idx[vector_no];
+
+ for (;;) {
+ isFastResponse = 0;
+ /* remove toggle bit (31) */
+ handle = (dev->host_rrq[index] & 0x7fffffff);
+ /* check fast response bit (30) */
+ if (handle & 0x40000000)
+ isFastResponse = 1;
+ handle &= 0x0000ffff;
+ if (handle == 0)
+ break;
+ if (dev->msi_enabled && dev->max_msix > 1)
+ atomic_dec(&dev->rrq_outstanding[vector_no]);
+ aac_intr_normal(dev, handle-1, 0, isFastResponse, NULL);
+ dev->host_rrq[index++] = 0;
+ if (index == (vector_no + 1) * dev->vector_cap)
+ index = vector_no * dev->vector_cap;
+ dev->host_rrq_idx[vector_no] = index;
+ }
+ mode = 0;
+ }
+
+ return IRQ_HANDLED;
}
/**
@@ -155,7 +181,7 @@ static void aac_src_disable_interrupt(struct aac_dev *dev)
static void aac_src_enable_interrupt_message(struct aac_dev *dev)
{
- src_writel(dev, MUnit.OIMR, dev->OIMR = 0xfffffff8);
+ aac_src_access_devreg(dev, AAC_ENABLE_INTERRUPT);
}
/**
@@ -191,7 +217,8 @@ static int src_sync_cmd(struct aac_dev *dev, u32 command,
/*
* Clear the synch command doorbell to start on a clean slate.
*/
- src_writel(dev, MUnit.ODR_C, OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
+ if (!dev->msi_enabled)
+ src_writel(dev, MUnit.ODR_C, OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
/*
* Disable doorbell interrupts
@@ -221,11 +248,14 @@ static int src_sync_cmd(struct aac_dev *dev, u32 command,
/*
* Mon960 will set doorbell0 bit when it has completed the command.
*/
- if ((src_readl(dev, MUnit.ODR_R) >> SRC_ODR_SHIFT) & OUTBOUNDDOORBELL_0) {
+ if (aac_src_get_sync_status(dev) & OUTBOUNDDOORBELL_0) {
/*
* Clear the doorbell.
*/
- src_writel(dev, MUnit.ODR_C, OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
+ if (dev->msi_enabled)
+ aac_src_access_devreg(dev, AAC_CLEAR_SYNC_BIT);
+ else
+ src_writel(dev, MUnit.ODR_C, OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
ok = 1;
break;
}
@@ -254,11 +284,13 @@ static int src_sync_cmd(struct aac_dev *dev, u32 command,
*r3 = readl(&dev->IndexRegs->Mailbox[3]);
if (r4)
*r4 = readl(&dev->IndexRegs->Mailbox[4]);
-
+ if (command == GET_COMM_PREFERRED_SETTINGS)
+ dev->max_msix = readl(&dev->IndexRegs->Mailbox[5]) & 0xFFFF;
/*
* Clear the synch command doorbell.
*/
- src_writel(dev, MUnit.ODR_C, OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
+ if (!dev->msi_enabled)
+ src_writel(dev, MUnit.ODR_C, OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
}
/*
@@ -335,9 +367,14 @@ static void aac_src_notify_adapter(struct aac_dev *dev, u32 event)
static void aac_src_start_adapter(struct aac_dev *dev)
{
struct aac_init *init;
+ int i;
/* reset host_rrq_idx first */
- dev->host_rrq_idx = 0;
+ for (i = 0; i < dev->max_msix; i++) {
+ dev->host_rrq_idx[i] = i * dev->vector_cap;
+ atomic_set(&dev->rrq_outstanding[i], 0);
+ }
+ dev->fibs_pushed_no = 0;
init = dev->init;
init->HostElapsedSeconds = cpu_to_le32(get_seconds());
@@ -400,6 +437,33 @@ static int aac_src_deliver_message(struct fib *fib)
q->numpending++;
spin_unlock_irqrestore(q->lock, qflags);
+ if (dev->msi_enabled && fib->hw_fib_va->header.Command != AifRequest &&
+ dev->max_msix > 1) {
+ u_int16_t vector_no, first_choice = 0xffff;
+
+ vector_no = dev->fibs_pushed_no % dev->max_msix;
+ do {
+ vector_no += 1;
+ if (vector_no == dev->max_msix)
+ vector_no = 1;
+ if (atomic_read(&dev->rrq_outstanding[vector_no]) <
+ dev->vector_cap)
+ break;
+ if (0xffff == first_choice)
+ first_choice = vector_no;
+ else if (vector_no == first_choice)
+ break;
+ } while (1);
+ if (vector_no == first_choice)
+ vector_no = 0;
+ atomic_inc(&dev->rrq_outstanding[vector_no]);
+ if (dev->fibs_pushed_no == 0xffffffff)
+ dev->fibs_pushed_no = 0;
+ else
+ dev->fibs_pushed_no++;
+ fib->hw_fib_va->header.Handle += (vector_no << 16);
+ }
+
if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE2) {
/* Calculate the amount to the fibsize bits */
fibsize = (hdr_size + 127) / 128 - 1;
@@ -502,10 +566,19 @@ static int aac_src_restart_adapter(struct aac_dev *dev, int bled)
0, 0, 0, 0, 0, 0, &var, &reset_mask, NULL, NULL, NULL);
if (bled || (var != 0x00000001))
return -EINVAL;
+
+ if ((dev->pdev->device == PMC_DEVICE_S7 ||
+ dev->pdev->device == PMC_DEVICE_S8 ||
+ dev->pdev->device == PMC_DEVICE_S9) && dev->msi_enabled) {
+ aac_src_access_devreg(dev, AAC_ENABLE_INTX);
+ dev->msi_enabled = 0;
+ msleep(5000); /* Delay 5 seconds */
+ }
+
if (dev->supplement_adapter_info.SupportedOptions2 &
AAC_OPTION_DOORBELL_RESET) {
src_writel(dev, MUnit.IDR, reset_mask);
- msleep(5000); /* Delay 5 seconds */
+ ssleep(45);
}
}
@@ -646,8 +719,11 @@ int aac_src_init(struct aac_dev *dev)
dev->msi = aac_msi && !pci_enable_msi(dev->pdev);
+ dev->aac_msix[0].vector_no = 0;
+ dev->aac_msix[0].dev = dev;
+
if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr,
- IRQF_SHARED, "aacraid", dev) < 0) {
+ IRQF_SHARED, "aacraid", &(dev->aac_msix[0])) < 0) {
if (dev->msi)
pci_disable_msi(dev->pdev);
@@ -688,6 +764,7 @@ int aac_srcv_init(struct aac_dev *dev)
unsigned long status;
int restart = 0;
int instance = dev->id;
+ int i, j;
const char *name = dev->name;
dev->a_ops.adapter_ioremap = aac_srcv_ioremap;
@@ -802,14 +879,36 @@ int aac_srcv_init(struct aac_dev *dev)
goto error_iounmap;
if (dev->comm_interface != AAC_COMM_MESSAGE_TYPE2)
goto error_iounmap;
- dev->msi = aac_msi && !pci_enable_msi(dev->pdev);
- if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr,
- IRQF_SHARED, "aacraid", dev) < 0) {
- if (dev->msi)
- pci_disable_msi(dev->pdev);
- printk(KERN_ERR "%s%d: Interrupt unavailable.\n",
- name, instance);
- goto error_iounmap;
+ if (dev->msi_enabled)
+ aac_src_access_devreg(dev, AAC_ENABLE_MSIX);
+ if (!dev->sync_mode && dev->msi_enabled && dev->max_msix > 1) {
+ for (i = 0; i < dev->max_msix; i++) {
+ dev->aac_msix[i].vector_no = i;
+ dev->aac_msix[i].dev = dev;
+
+ if (request_irq(dev->msixentry[i].vector, dev->a_ops.adapter_intr,
+ 0, "aacraid", &(dev->aac_msix[i]))) {
+ printk(KERN_ERR "%s%d: Failed to register IRQ for vector %d.\n",
+ name, instance, i);
+ for (j = 0 ; j < i ; j++)
+ free_irq(dev->msixentry[j].vector,
+ &(dev->aac_msix[j]));
+ pci_disable_msix(dev->pdev);
+ goto error_iounmap;
+ }
+ }
+ } else {
+ dev->aac_msix[0].vector_no = 0;
+ dev->aac_msix[0].dev = dev;
+
+ if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr,
+ IRQF_SHARED, "aacraid", &(dev->aac_msix[0])) < 0) {
+ if (dev->msi)
+ pci_disable_msi(dev->pdev);
+ printk(KERN_ERR "%s%d: Interrupt unavailable.\n",
+ name, instance);
+ goto error_iounmap;
+ }
}
dev->dbg_base = dev->base_start;
dev->dbg_base_mapped = dev->base;
@@ -831,3 +930,87 @@ error_iounmap:
return -1;
}
+void aac_src_access_devreg(struct aac_dev *dev, int mode)
+{
+ u_int32_t val;
+
+ switch (mode) {
+ case AAC_ENABLE_INTERRUPT:
+ src_writel(dev, MUnit.OIMR, dev->OIMR = (dev->msi_enabled ? AAC_INT_ENABLE_TYPE1_MSIX :
+ AAC_INT_ENABLE_TYPE1_INTX));
+ break;
+
+ case AAC_DISABLE_INTERRUPT:
+ src_writel(dev, MUnit.OIMR, dev->OIMR = AAC_INT_DISABLE_ALL);
+ break;
+
+ case AAC_ENABLE_MSIX:
+ /* set bit 6 */
+ val = src_readl(dev, MUnit.IDR);
+ val |= 0x40;
+ src_writel(dev, MUnit.IDR, val);
+ src_readl(dev, MUnit.IDR);
+ /* unmask int. */
+ val = PMC_ALL_INTERRUPT_BITS;
+ src_writel(dev, MUnit.IOAR, val);
+ val = src_readl(dev, MUnit.OIMR);
+ src_writel(dev, MUnit.OIMR,
+ val & (~(PMC_GLOBAL_INT_BIT2 | PMC_GLOBAL_INT_BIT0)));
+ break;
+
+ case AAC_DISABLE_MSIX:
+ /* reset bit 6 */
+ val = src_readl(dev, MUnit.IDR);
+ val &= ~0x40;
+ src_writel(dev, MUnit.IDR, val);
+ src_readl(dev, MUnit.IDR);
+ break;
+
+ case AAC_CLEAR_AIF_BIT:
+ /* set bit 5 */
+ val = src_readl(dev, MUnit.IDR);
+ val |= 0x20;
+ src_writel(dev, MUnit.IDR, val);
+ src_readl(dev, MUnit.IDR);
+ break;
+
+ case AAC_CLEAR_SYNC_BIT:
+ /* set bit 4 */
+ val = src_readl(dev, MUnit.IDR);
+ val |= 0x10;
+ src_writel(dev, MUnit.IDR, val);
+ src_readl(dev, MUnit.IDR);
+ break;
+
+ case AAC_ENABLE_INTX:
+ /* set bit 7 */
+ val = src_readl(dev, MUnit.IDR);
+ val |= 0x80;
+ src_writel(dev, MUnit.IDR, val);
+ src_readl(dev, MUnit.IDR);
+ /* unmask int. */
+ val = PMC_ALL_INTERRUPT_BITS;
+ src_writel(dev, MUnit.IOAR, val);
+ src_readl(dev, MUnit.IOAR);
+ val = src_readl(dev, MUnit.OIMR);
+ src_writel(dev, MUnit.OIMR,
+ val & (~(PMC_GLOBAL_INT_BIT2)));
+ break;
+
+ default:
+ break;
+ }
+}
+
+static int aac_src_get_sync_status(struct aac_dev *dev)
+{
+
+ int val;
+
+ if (dev->msi_enabled)
+ val = src_readl(dev, MUnit.ODR_MSI) & 0x1000 ? 1 : 0;
+ else
+ val = src_readl(dev, MUnit.ODR_R) >> SRC_ODR_SHIFT;
+
+ return val;
+}
--
1.7.7.3
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 5/7] aacraid: vpd page code 0x83 support
2015-03-04 8:38 [PATCH 0/7] aacraid driver updates Mahesh Rajashekhara
` (3 preceding siblings ...)
2015-03-04 8:38 ` [PATCH 4/7] aacraid: MSI-x support Mahesh Rajashekhara
@ 2015-03-04 8:38 ` Mahesh Rajashekhara
2015-03-17 7:06 ` Murthy Bhat
2015-03-17 15:27 ` Achim Leubner
2015-03-04 8:38 ` [PATCH 6/7] aacraid: performance improvement changes Mahesh Rajashekhara
` (2 subsequent siblings)
7 siblings, 2 replies; 32+ messages in thread
From: Mahesh Rajashekhara @ 2015-03-04 8:38 UTC (permalink / raw)
To: JBottomley, linux-scsi
Cc: aacraid, Harry.Yang, Achim.Leubner, Rajinikanth.Pandurangan,
Rich.Bono, Mahesh.Rajashekhara
Add vpd page code 0x83 support
Signed-off-by: Mahesh Rajashekhara <Mahesh.Rajashekhara@pmcs.com>
---
drivers/scsi/aacraid/aachba.c | 154 ++++++++++++++++++++++++++++++++++++---
drivers/scsi/aacraid/aacraid.h | 4 +
drivers/scsi/aacraid/comminit.c | 8 ++-
drivers/scsi/aacraid/commsup.c | 12 +---
drivers/scsi/aacraid/linit.c | 20 +----
drivers/scsi/aacraid/src.c | 34 +++++++--
6 files changed, 185 insertions(+), 47 deletions(-)
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index eb524e6..3e4e0c8 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -163,6 +163,45 @@ struct inquiry_data {
u8 inqd_prl[4]; /* Product Revision Level */
};
+/* Added for VPD 0x83 */
+typedef struct {
+ u8 CodeSet:4; /* VPD_CODE_SET */
+ u8 Reserved:4;
+ u8 IdentifierType:4; /* VPD_IDENTIFIER_TYPE */
+ u8 Reserved2:4;
+ u8 Reserved3;
+ u8 IdentifierLength;
+ u8 VendId[8];
+ u8 ProductId[16];
+ u8 SerialNumber[8]; /* SN in ASCII */
+} TVPD_ID_Descriptor_Type_1;
+
+typedef struct {
+ u8 CodeSet:4; /* VPD_CODE_SET */
+ u8 Reserved:4;
+ u8 IdentifierType:4; /* VPD_IDENTIFIER_TYPE */
+ u8 Reserved2:4;
+ u8 Reserved3;
+ u8 IdentifierLength;
+ struct TEU64Id {
+ u32 Serial;
+ /* The serial number supposed to be 40 bits,
+ * bit we only support 32, so make the last byte zero. */
+ u8 Reserved;
+ u8 VendId[3];
+ } EU64Id;
+} TVPD_ID_Descriptor_Type_2;
+
+typedef struct {
+ u8 DeviceType:5;
+ u8 DeviceTypeQualifier:3;
+ u8 PageCode;
+ u8 Reserved;
+ u8 PageLength;
+ TVPD_ID_Descriptor_Type_1 IdDescriptorType1;
+ TVPD_ID_Descriptor_Type_2 IdDescriptorType2;
+} TVPD_Page83;
+
/*
* M O D U L E G L O B A L S
*/
@@ -420,6 +459,9 @@ int aac_get_containers(struct aac_dev *dev)
if (status >= 0) {
dresp = (struct aac_get_container_count_resp *)fib_data(fibptr);
maximum_num_containers = le32_to_cpu(dresp->ContainerSwitchEntries);
+ if (fibptr->dev->supplement_adapter_info.SupportedOptions2 &
+ AAC_OPTION_SUPPORTED_240_VOLUMES)
+ maximum_num_containers = le32_to_cpu(dresp->MaxSimpleVolumes);
aac_fib_complete(fibptr);
}
/* FIB should be freed only after getting the response from the F/W */
@@ -889,14 +931,81 @@ static void get_container_serial_callback(void *context, struct fib * fibptr)
get_serial_reply = (struct aac_get_serial_resp *) fib_data(fibptr);
/* Failure is irrelevant, using default value instead */
if (le32_to_cpu(get_serial_reply->status) == CT_OK) {
- char sp[13];
- /* EVPD bit set */
- sp[0] = INQD_PDT_DA;
- sp[1] = scsicmd->cmnd[2];
- sp[2] = 0;
- sp[3] = snprintf(sp+4, sizeof(sp)-4, "%08X",
- le32_to_cpu(get_serial_reply->uid));
- scsi_sg_copy_from_buffer(scsicmd, sp, sizeof(sp));
+ /*Check to see if it's for VPD 0x83 or 0x80 */
+ if (scsicmd->cmnd[2] == 0x83) {
+ /* vpd page 0x83 - Device Identification Page */
+ int i;
+ TVPD_Page83 VPDPage83Data;
+
+ memset(((u8 *)&VPDPage83Data), 0,
+ sizeof(VPDPage83Data));
+
+ /* DIRECT_ACCESS_DEVIC */
+ VPDPage83Data.DeviceType = 0;
+ /* DEVICE_CONNECTED */
+ VPDPage83Data.DeviceTypeQualifier = 0;
+ /* VPD_DEVICE_IDENTIFIERS */
+ VPDPage83Data.PageCode = 0x83;
+ VPDPage83Data.Reserved = 0;
+ VPDPage83Data.PageLength = sizeof(VPDPage83Data.IdDescriptorType1) +
+ sizeof(VPDPage83Data.IdDescriptorType2);
+
+ /* T10 Vendor Identifier Field Format */
+ /* VpdCodeSetAscii */
+ VPDPage83Data.IdDescriptorType1.CodeSet = 2;
+ /* VpdIdentifierTypeVendorId */
+ VPDPage83Data.IdDescriptorType1.IdentifierType = 1;
+ VPDPage83Data.IdDescriptorType1.IdentifierLength = sizeof(VPDPage83Data.IdDescriptorType1) - 4;
+
+ /* "ADAPTEC " for adaptec */
+ memcpy(VPDPage83Data.IdDescriptorType1.VendId, "ADAPTEC ",
+ sizeof(VPDPage83Data.IdDescriptorType1.VendId));
+ memcpy(VPDPage83Data.IdDescriptorType1.ProductId, "ARRAY ",
+ sizeof(VPDPage83Data.IdDescriptorType1.ProductId));
+
+ /* Convert to ascii based serial number.
+ * The LSB is the the end.
+ */
+ for (i = 0; i < 8; i++) {
+ u8 temp = (u8)((get_serial_reply->uid >> ((7 - i) * 4)) & 0xF);
+ if (temp > 0x9) {
+ VPDPage83Data.IdDescriptorType1.SerialNumber[i] = 'A' + (temp - 0xA);
+ } else {
+ VPDPage83Data.IdDescriptorType1.SerialNumber[i] = '0' + temp;
+ }
+ }
+
+ /* EUI-64 Vendor Identifier Field Format,
+ * 24 bits for VendId and 40 bits for SN.
+ */
+ /* VpdCodeSetBinary */
+ VPDPage83Data.IdDescriptorType2.CodeSet = 1;
+ /* VpdIdentifierTypeEUI64 */
+ VPDPage83Data.IdDescriptorType2.IdentifierType = 2;
+ VPDPage83Data.IdDescriptorType2.IdentifierLength = sizeof(VPDPage83Data.IdDescriptorType2) - 4;
+
+ /* 0x0000055 for IBM, 0x0000D0 for Adaptec */
+ VPDPage83Data.IdDescriptorType2.EU64Id.VendId[0] = 0xD0;
+ VPDPage83Data.IdDescriptorType2.EU64Id.VendId[1] = 0;
+ VPDPage83Data.IdDescriptorType2.EU64Id.VendId[2] = 0;
+
+ VPDPage83Data.IdDescriptorType2.EU64Id.Serial = get_serial_reply->uid;
+ VPDPage83Data.IdDescriptorType2.EU64Id.Reserved = 0;
+
+ /* Move the inquiry data to the response buffer. */
+ scsi_sg_copy_from_buffer(scsicmd, &VPDPage83Data,
+ sizeof(VPDPage83Data));
+ } else {
+ /* It must be for VPD 0x80 */
+ char sp[13];
+ /* EVPD bit set */
+ sp[0] = INQD_PDT_DA;
+ sp[1] = scsicmd->cmnd[2];
+ sp[2] = 0;
+ sp[3] = snprintf(sp+4, sizeof(sp)-4, "%08X",
+ le32_to_cpu(get_serial_reply->uid));
+ scsi_sg_copy_from_buffer(scsicmd, sp, sizeof(sp));
+ }
}
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
@@ -2302,9 +2411,10 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
INQD_PDT_PROC : INQD_PDT_DA;
if (scsicmd->cmnd[2] == 0) {
/* supported vital product data pages */
- arr[3] = 2;
+ arr[3] = 3;
arr[4] = 0x0;
arr[5] = 0x80;
+ arr[6] = 0x83;
arr[1] = scsicmd->cmnd[2];
scsi_sg_copy_from_buffer(scsicmd, &inq_data,
sizeof(inq_data));
@@ -2323,6 +2433,16 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
/* SLES 10 SP1 special */
scsicmd->result = DID_OK << 16 |
COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
+ } else if (scsicmd->cmnd[2] == 0x83) {
+ /* vpd page 0x83 - Device Identification Page */
+ char *sno = (char *)&inq_data;
+ sno[3] = setinqserial(dev, &sno[4],
+ scmd_id(scsicmd));
+ if (aac_wwn != 2)
+ return aac_get_container_serial(
+ scsicmd);
+ scsicmd->result = DID_OK << 16 |
+ COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
} else {
/* vpd page not implemented */
scsicmd->result = DID_OK << 16 |
@@ -2468,6 +2588,15 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
mpd.bd.block_length[0] = (fsa_dev_ptr[cid].block_size >> 16) & 0xff;
mpd.bd.block_length[1] = (fsa_dev_ptr[cid].block_size >> 8) & 0xff;
mpd.bd.block_length[2] = fsa_dev_ptr[cid].block_size & 0xff;
+
+ mpd.mpc_buf[0] = scsicmd->cmnd[2];
+ if (scsicmd->cmnd[2] == 0x1C) {
+ mpd.mpc_buf[1] = 0xa; /* page length */
+ mpd.hd.data_length = 23; /* Mode data length */
+ } else {
+ mpd.hd.data_length = 15; /* Mode data length */
+ }
+
if (capacity > 0xffffff) {
mpd.bd.block_count[0] = 0xff;
mpd.bd.block_count[1] = 0xff;
@@ -2486,9 +2615,12 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
mpd.mpc_buf[2] = ((aac_cache & 6) == 2)
? 0 : 0x04; /* WCE */
mode_buf_length = sizeof(mpd);
- if (mode_buf_length > scsicmd->cmnd[4])
- mode_buf_length = scsicmd->cmnd[4];
}
+
+ if (mode_buf_length > scsicmd->cmnd[4])
+ mode_buf_length = scsicmd->cmnd[4];
+ else
+ mode_buf_length = sizeof(mpd);
scsi_sg_copy_from_buffer(scsicmd, (char *)&mpd, mode_buf_length);
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
scsicmd->scsi_done(scsicmd);
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index c162a65..a37762e 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -1015,6 +1015,7 @@ struct aac_supplement_adapter_info
#define AAC_OPTION_POWER_MANAGEMENT cpu_to_le32(0x00000004)
#define AAC_OPTION_DOORBELL_RESET cpu_to_le32(0x00004000)
#define AAC_OPTION_VARIABLE_BLOCK_SIZE cpu_to_le32(0x00040000) /* 4KB sector size */
+#define AAC_OPTION_SUPPORTED_240_VOLUMES cpu_to_le32(0x10000000)
#define AAC_SIS_VERSION_V3 3
#define AAC_SIS_SLOT_UNKNOWN 0xFF
@@ -1212,11 +1213,13 @@ struct aac_dev
int sync_mode;
struct fib *sync_fib;
struct list_head sync_fib_list;
+ u32 doorbell_mask; /* from GET_ADAPTER_PROP */
u32 max_msix; /* max. MSI-X vectors */
u32 vector_cap; /* MSI-X vector capab.*/
int msi_enabled; /* MSI/MSI-X enabled */
struct msix_entry msixentry[AAC_MAX_MSIX];
struct aac_msix_ctx aac_msix[AAC_MAX_MSIX]; /* context */
+ u8 adapter_shutdown;
};
#define aac_adapter_interrupt(dev) \
@@ -1749,6 +1752,7 @@ struct aac_get_container_count_resp {
__le32 MaxContainers;
__le32 ContainerSwitchEntries;
__le32 MaxPartitions;
+ __le32 MaxSimpleVolumes;
};
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c
index 29c35c8..c3e13ae 100644
--- a/drivers/scsi/aacraid/comminit.c
+++ b/drivers/scsi/aacraid/comminit.c
@@ -53,7 +53,7 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
{
unsigned char *base;
unsigned long size, align;
- const unsigned long fibsize = 4096;
+ const unsigned long fibsize = dev->max_fib_size;
const unsigned long printfbufsiz = 256;
unsigned long host_rrq_size = 0;
struct aac_init *init;
@@ -230,6 +230,7 @@ int aac_send_shutdown(struct aac_dev * dev)
/* FIB should be freed only after getting the response from the F/W */
if (status != -ERESTARTSYS)
aac_fib_free(fibctx);
+ dev->adapter_shutdown = 1;
if ((dev->pdev->device == PMC_DEVICE_S7 ||
dev->pdev->device == PMC_DEVICE_S8 ||
dev->pdev->device == PMC_DEVICE_S9) &&
@@ -357,8 +358,9 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
dev->raw_io_interface = dev->raw_io_64 = 0;
if ((!aac_adapter_sync_cmd(dev, GET_ADAPTER_PROPERTIES,
- 0, 0, 0, 0, 0, 0, status+0, status+1, status+2, NULL, NULL)) &&
+ 0, 0, 0, 0, 0, 0, status+0, status+1, status+2, status+3, NULL)) &&
(status[0] == 0x00000001)) {
+ dev->doorbell_mask = status[3];
if (status[1] & le32_to_cpu(AAC_OPT_NEW_COMM_64))
dev->raw_io_64 = 1;
dev->sync_mode = aac_sync_mode;
@@ -397,6 +399,7 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
}
dev->max_msix = 0;
dev->msi_enabled = 0;
+ dev->adapter_shutdown = 0;
if ((!aac_adapter_sync_cmd(dev, GET_COMM_PREFERRED_SETTINGS,
0, 0, 0, 0, 0, 0,
status+0, status+1, status+2, status+3, status+4))
@@ -508,6 +511,7 @@ static void aac_define_int_mode(struct aac_dev *dev)
int i, msi_count;
+ msi_count = i = 0;
/* max. vectors from GET_COMM_PREFERRED_SETTINGS */
if (dev->max_msix == 0 ||
dev->pdev->device == PMC_DEVICE_S6 ||
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index 83c5d3f..2bed445 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -208,14 +208,11 @@ struct fib *aac_fib_alloc(struct aac_dev *dev)
void aac_fib_free(struct fib *fibptr)
{
- unsigned long flags, flagsv;
+ unsigned long flags;
- spin_lock_irqsave(&fibptr->event_lock, flagsv);
if (fibptr->done == 2) {
- spin_unlock_irqrestore(&fibptr->event_lock, flagsv);
return;
}
- spin_unlock_irqrestore(&fibptr->event_lock, flagsv);
spin_lock_irqsave(&fibptr->dev->fib_lock, flags);
if (unlikely(fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT))
@@ -775,7 +772,6 @@ int aac_fib_adapter_complete(struct fib *fibptr, unsigned short size)
int aac_fib_complete(struct fib *fibptr)
{
- unsigned long flags;
struct hw_fib * hw_fib = fibptr->hw_fib_va;
/*
@@ -798,12 +794,6 @@ int aac_fib_complete(struct fib *fibptr)
* command is complete that we had sent to the adapter and this
* cdb could be reused.
*/
- spin_lock_irqsave(&fibptr->event_lock, flags);
- if (fibptr->done == 2) {
- spin_unlock_irqrestore(&fibptr->event_lock, flags);
- return 0;
- }
- spin_unlock_irqrestore(&fibptr->event_lock, flags);
if((hw_fib->header.XferState & cpu_to_le32(SentFromHost)) &&
(hw_fib->header.XferState & cpu_to_le32(AdapterProcessed)))
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 7813a9b..4c5ba9e 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -56,7 +56,7 @@
#include "aacraid.h"
-#define AAC_DRIVER_VERSION "1.2-0"
+#define AAC_DRIVER_VERSION "1.2-1"
#ifndef AAC_DRIVER_BRANCH
#define AAC_DRIVER_BRANCH ""
#endif
@@ -65,7 +65,7 @@
#ifdef AAC_DRIVER_BUILD
#define _str(x) #x
#define str(x) _str(x)
-#define AAC_DRIVER_FULL_VERSION AAC_DRIVER_VERSION "[" str(AAC_DRIVER_BUILD) "]" AAC_DRIVER_BRANCH
+#define AAC_DRIVER_FULL_VERSION AAC_DRIVER_VERSION "." str(AAC_DRIVER_BUILD) "" AAC_DRIVER_BRANCH
#else
#define AAC_DRIVER_FULL_VERSION AAC_DRIVER_VERSION AAC_DRIVER_BRANCH
#endif
@@ -253,19 +253,7 @@ static struct aac_driver_ident aac_drivers[] = {
static int aac_queuecommand_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
{
- struct Scsi_Host *host = cmd->device->host;
- struct aac_dev *dev = (struct aac_dev *)host->hostdata;
- u32 count = 0;
cmd->scsi_done = done;
- for (; count < (host->can_queue + AAC_NUM_MGT_FIB); ++count) {
- struct fib * fib = &dev->fibs[count];
- struct scsi_cmnd * command;
- if (fib->hw_fib_va->header.XferState &&
- ((command = fib->callback_data)) &&
- (command == cmd) &&
- (cmd->SCp.phase == AAC_OWNER_FIRMWARE))
- return 0; /* Already owned by Adapter */
- }
cmd->SCp.phase = AAC_OWNER_LOWLEVEL;
return (aac_scsi_cmd(cmd) ? FAILED : 0);
}
@@ -713,7 +701,9 @@ static long aac_cfg_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
{
int ret;
- if (!capable(CAP_SYS_RAWIO))
+ struct aac_dev *aac;
+ aac = (struct aac_dev *)file->private_data;
+ if (!capable(CAP_SYS_RAWIO) || aac->adapter_shutdown)
return -EPERM;
mutex_lock(&aac_mutex);
ret = aac_do_ioctl(file->private_data, cmd, (void __user *)arg);
diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c
index c010248..82ff025 100644
--- a/drivers/scsi/aacraid/src.c
+++ b/drivers/scsi/aacraid/src.c
@@ -200,6 +200,7 @@ static int src_sync_cmd(struct aac_dev *dev, u32 command,
u32 *status, u32 * r1, u32 * r2, u32 * r3, u32 * r4)
{
unsigned long start;
+ unsigned long delay;
int ok;
/*
@@ -240,10 +241,15 @@ static int src_sync_cmd(struct aac_dev *dev, u32 command,
ok = 0;
start = jiffies;
- /*
- * Wait up to 5 minutes
- */
- while (time_before(jiffies, start+300*HZ)) {
+ if (command == IOP_RESET_ALWAYS) {
+ /* Wait up to 10 sec */
+ delay = 10*HZ;
+ } else {
+ /* Wait up to 5 minutes */
+ delay = 300*HZ;
+ }
+ while (time_before(jiffies, start+delay)) {
+
udelay(5); /* Delay 5 microseconds to let Mon960 get info. */
/*
* Mon960 will set doorbell0 bit when it has completed the command.
@@ -562,10 +568,16 @@ static int aac_src_restart_adapter(struct aac_dev *dev, int bled)
if (bled)
printk(KERN_ERR "%s%d: adapter kernel panic'd %x.\n",
dev->name, dev->id, bled);
+ dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
bled = aac_adapter_sync_cmd(dev, IOP_RESET_ALWAYS,
0, 0, 0, 0, 0, 0, &var, &reset_mask, NULL, NULL, NULL);
- if (bled || (var != 0x00000001))
+ if ((bled || (var != 0x00000001)) && !dev->doorbell_mask)
return -EINVAL;
+ else if (dev->doorbell_mask) {
+ reset_mask = dev->doorbell_mask;
+ bled = 0;
+ var = 0x00000001;
+ }
if ((dev->pdev->device == PMC_DEVICE_S7 ||
dev->pdev->device == PMC_DEVICE_S8 ||
@@ -575,10 +587,13 @@ static int aac_src_restart_adapter(struct aac_dev *dev, int bled)
msleep(5000); /* Delay 5 seconds */
}
- if (dev->supplement_adapter_info.SupportedOptions2 &
- AAC_OPTION_DOORBELL_RESET) {
+ if (!bled && (dev->supplement_adapter_info.SupportedOptions2 &
+ AAC_OPTION_DOORBELL_RESET)) {
src_writel(dev, MUnit.IDR, reset_mask);
ssleep(45);
+ } else {
+ src_writel(dev, MUnit.IDR, 0x100);
+ ssleep(45);
}
}
@@ -600,7 +615,6 @@ int aac_src_select_comm(struct aac_dev *dev, int comm)
{
switch (comm) {
case AAC_COMM_MESSAGE:
- dev->a_ops.adapter_enable_int = aac_src_enable_interrupt_message;
dev->a_ops.adapter_intr = aac_src_intr_message;
dev->a_ops.adapter_deliver = aac_src_deliver_message;
break;
@@ -698,6 +712,7 @@ int aac_src_init(struct aac_dev *dev)
*/
dev->a_ops.adapter_interrupt = aac_src_interrupt_adapter;
dev->a_ops.adapter_disable_int = aac_src_disable_interrupt;
+ dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
dev->a_ops.adapter_notify = aac_src_notify_adapter;
dev->a_ops.adapter_sync_cmd = src_sync_cmd;
dev->a_ops.adapter_check_health = aac_src_check_health;
@@ -735,6 +750,7 @@ int aac_src_init(struct aac_dev *dev)
dev->dbg_base = pci_resource_start(dev->pdev, 2);
dev->dbg_base_mapped = dev->regs.src.bar1;
dev->dbg_size = AAC_MIN_SRC_BAR1_SIZE;
+ dev->a_ops.adapter_enable_int = aac_src_enable_interrupt_message;
aac_adapter_enable_int(dev);
@@ -861,6 +877,7 @@ int aac_srcv_init(struct aac_dev *dev)
*/
dev->a_ops.adapter_interrupt = aac_src_interrupt_adapter;
dev->a_ops.adapter_disable_int = aac_src_disable_interrupt;
+ dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
dev->a_ops.adapter_notify = aac_src_notify_adapter;
dev->a_ops.adapter_sync_cmd = src_sync_cmd;
dev->a_ops.adapter_check_health = aac_src_check_health;
@@ -913,6 +930,7 @@ int aac_srcv_init(struct aac_dev *dev)
dev->dbg_base = dev->base_start;
dev->dbg_base_mapped = dev->base;
dev->dbg_size = dev->base_size;
+ dev->a_ops.adapter_enable_int = aac_src_enable_interrupt_message;
aac_adapter_enable_int(dev);
--
1.7.7.3
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 6/7] aacraid: performance improvement changes
2015-03-04 8:38 [PATCH 0/7] aacraid driver updates Mahesh Rajashekhara
` (4 preceding siblings ...)
2015-03-04 8:38 ` [PATCH 5/7] aacraid: vpd page code 0x83 support Mahesh Rajashekhara
@ 2015-03-04 8:38 ` Mahesh Rajashekhara
2015-03-17 7:07 ` Murthy Bhat
2015-03-17 15:27 ` Achim Leubner
2015-03-04 8:38 ` [PATCH 7/7] aacraid: AIF raw device remove support Mahesh Rajashekhara
2015-03-16 11:24 ` [PATCH 0/7] aacraid driver updates Mahesh Rajashekhara
7 siblings, 2 replies; 32+ messages in thread
From: Mahesh Rajashekhara @ 2015-03-04 8:38 UTC (permalink / raw)
To: JBottomley, linux-scsi
Cc: aacraid, Harry.Yang, Achim.Leubner, Rajinikanth.Pandurangan,
Rich.Bono, Mahesh.Rajashekhara
Add performance improvement changes.
Signed-off-by: Mahesh Rajashekhara <Mahesh.Rajashekhara@pmcs.com>
---
drivers/scsi/aacraid/aacraid.h | 6 +++---
drivers/scsi/aacraid/comminit.c | 12 +++++++++++-
drivers/scsi/aacraid/commsup.c | 7 ++-----
drivers/scsi/aacraid/dpcsup.c | 4 ++--
drivers/scsi/aacraid/linit.c | 10 ++++------
drivers/scsi/aacraid/rx.c | 14 +++-----------
drivers/scsi/aacraid/src.c | 5 +----
7 files changed, 26 insertions(+), 32 deletions(-)
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index a37762e..74a0440 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -12,7 +12,7 @@
* D E F I N E S
*----------------------------------------------------------------------------*/
-#define AAC_MAX_MSIX 32 /* vectors */
+#define AAC_MAX_MSIX 8 /* vectors */
#define AAC_PCI_MSI_ENABLE 0x8000
enum {
@@ -62,7 +62,7 @@ enum {
#define PMC_GLOBAL_INT_BIT0 0x00000001
#ifndef AAC_DRIVER_BUILD
-# define AAC_DRIVER_BUILD 30300
+# define AAC_DRIVER_BUILD 40709
# define AAC_DRIVER_BRANCH "-ms"
#endif
#define MAXIMUM_NUM_CONTAINERS 32
@@ -633,7 +633,7 @@ struct aac_queue {
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. */
- u32 numpending; /* Number of entries on outstanding queue. */
+ atomic_t numpending; /* Number of entries on outstanding queue. */
struct aac_dev * dev; /* Back pointer to adapter structure */
};
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c
index c3e13ae..c16043e 100644
--- a/drivers/scsi/aacraid/comminit.c
+++ b/drivers/scsi/aacraid/comminit.c
@@ -181,7 +181,7 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
static void aac_queue_init(struct aac_dev * dev, struct aac_queue * q, u32 *mem, int qsize)
{
- q->numpending = 0;
+ atomic_set(&q->numpending, 0);
q->dev = dev;
init_waitqueue_head(&q->cmdready);
INIT_LIST_HEAD(&q->cmdq);
@@ -510,6 +510,7 @@ static void aac_define_int_mode(struct aac_dev *dev)
{
int i, msi_count;
+ int cpu;
msi_count = i = 0;
/* max. vectors from GET_COMM_PREFERRED_SETTINGS */
@@ -571,6 +572,15 @@ static void aac_define_int_mode(struct aac_dev *dev)
else {
if (dev->max_msix > msi_count)
dev->max_msix = msi_count;
+
+ /* Added to set IRQ affinity */
+ cpu = cpumask_first(cpu_online_mask);
+ cpu = cpumask_next(cpu, cpu_online_mask);
+
+ for (i = 0; i < dev->max_msix; i++) {
+ irq_set_affinity_hint(dev->msixentry[i].vector, get_cpu_mask(cpu));
+ cpu = cpumask_next(cpu, cpu_online_mask);
+ }
}
dev->vector_cap = (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB) / msi_count;
}
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index 2bed445..0555023 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -318,7 +318,7 @@ static int aac_get_entry (struct aac_dev * dev, u32 qid, struct aac_entry **entr
/* Queue is full */
if ((*index + 1) == le32_to_cpu(*(q->headers.consumer))) {
printk(KERN_WARNING "Queue %d full, %u outstanding.\n",
- qid, q->numpending);
+ qid, atomic_read(&q->numpending));
return 0;
} else {
*entry = q->base + *index;
@@ -411,7 +411,6 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
struct aac_dev * dev = fibptr->dev;
struct hw_fib * hw_fib = fibptr->hw_fib_va;
unsigned long flags = 0;
- unsigned long qflags;
unsigned long mflags = 0;
unsigned long sflags = 0;
@@ -565,9 +564,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
int blink;
if (time_is_before_eq_jiffies(timeout)) {
struct aac_queue * q = &dev->queues->queue[AdapNormCmdQueue];
- spin_lock_irqsave(q->lock, qflags);
- q->numpending--;
- spin_unlock_irqrestore(q->lock, qflags);
+ atomic_dec(&q->numpending);
if (wait == -1) {
printk(KERN_ERR "aacraid: aac_fib_send: first asynchronous command timed out.\n"
"Usually a result of a PCI interrupt routing problem;\n"
diff --git a/drivers/scsi/aacraid/dpcsup.c b/drivers/scsi/aacraid/dpcsup.c
index 2e39466..da9d993 100644
--- a/drivers/scsi/aacraid/dpcsup.c
+++ b/drivers/scsi/aacraid/dpcsup.c
@@ -84,7 +84,7 @@ unsigned int aac_response_normal(struct aac_queue * q)
* continue. The caller has already been notified that
* the fib timed out.
*/
- dev->queues->queue[AdapNormCmdQueue].numpending--;
+ atomic_dec(&dev->queues->queue[AdapNormCmdQueue].numpending);
if (unlikely(fib->flags & FIB_CONTEXT_FLAG_TIMED_OUT)) {
spin_unlock_irqrestore(q->lock, flags);
@@ -354,7 +354,7 @@ unsigned int aac_intr_normal(struct aac_dev *dev, u32 index,
* continue. The caller has already been notified that
* the fib timed out.
*/
- dev->queues->queue[AdapNormCmdQueue].numpending--;
+ atomic_dec(&dev->queues->queue[AdapNormCmdQueue].numpending);
if (unlikely(fib->flags & FIB_CONTEXT_FLAG_TIMED_OUT)) {
aac_fib_complete(fib);
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 4c5ba9e..e0f9f81 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -250,16 +250,14 @@ static struct aac_driver_ident aac_drivers[] = {
*
* TODO: unify with aac_scsi_cmd().
*/
-
-static int aac_queuecommand_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
+static int aac_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
{
- cmd->scsi_done = done;
+ int r = 0;
cmd->SCp.phase = AAC_OWNER_LOWLEVEL;
- return (aac_scsi_cmd(cmd) ? FAILED : 0);
+ r = (aac_scsi_cmd(cmd) ? FAILED : 0);
+ return r;
}
-static DEF_SCSI_QCMD(aac_queuecommand)
-
/**
* aac_info - Returns the host adapter name
* @shost: Scsi host to report on
diff --git a/drivers/scsi/aacraid/rx.c b/drivers/scsi/aacraid/rx.c
index 5c6a870..9570612 100644
--- a/drivers/scsi/aacraid/rx.c
+++ b/drivers/scsi/aacraid/rx.c
@@ -400,16 +400,13 @@ int aac_rx_deliver_producer(struct fib * fib)
{
struct aac_dev *dev = fib->dev;
struct aac_queue *q = &dev->queues->queue[AdapNormCmdQueue];
- unsigned long qflags;
u32 Index;
unsigned long nointr = 0;
- spin_lock_irqsave(q->lock, qflags);
aac_queue_get( dev, &Index, AdapNormCmdQueue, fib->hw_fib_va, 1, fib, &nointr);
- q->numpending++;
+ atomic_inc(&q->numpending);
*(q->headers.producer) = cpu_to_le32(Index + 1);
- spin_unlock_irqrestore(q->lock, qflags);
if (!(nointr & aac_config.irq_mod))
aac_adapter_notify(dev, AdapNormCmdQueue);
@@ -426,15 +423,12 @@ static int aac_rx_deliver_message(struct fib * fib)
{
struct aac_dev *dev = fib->dev;
struct aac_queue *q = &dev->queues->queue[AdapNormCmdQueue];
- unsigned long qflags;
u32 Index;
u64 addr;
volatile void __iomem *device;
unsigned long count = 10000000L; /* 50 seconds */
- spin_lock_irqsave(q->lock, qflags);
- q->numpending++;
- spin_unlock_irqrestore(q->lock, qflags);
+ atomic_inc(&q->numpending);
for(;;) {
Index = rx_readl(dev, MUnit.InboundQueue);
if (unlikely(Index == 0xFFFFFFFFL))
@@ -442,9 +436,7 @@ static int aac_rx_deliver_message(struct fib * fib)
if (likely(Index != 0xFFFFFFFFL))
break;
if (--count == 0) {
- spin_lock_irqsave(q->lock, qflags);
- q->numpending--;
- spin_unlock_irqrestore(q->lock, qflags);
+ atomic_dec(&q->numpending);
return -ETIMEDOUT;
}
udelay(5);
diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c
index 82ff025..bde26a2 100644
--- a/drivers/scsi/aacraid/src.c
+++ b/drivers/scsi/aacraid/src.c
@@ -433,15 +433,12 @@ static int aac_src_deliver_message(struct fib *fib)
{
struct aac_dev *dev = fib->dev;
struct aac_queue *q = &dev->queues->queue[AdapNormCmdQueue];
- unsigned long qflags;
u32 fibsize;
dma_addr_t address;
struct aac_fib_xporthdr *pFibX;
u16 hdr_size = le16_to_cpu(fib->hw_fib_va->header.Size);
- spin_lock_irqsave(q->lock, qflags);
- q->numpending++;
- spin_unlock_irqrestore(q->lock, qflags);
+ atomic_inc(&q->numpending);
if (dev->msi_enabled && fib->hw_fib_va->header.Command != AifRequest &&
dev->max_msix > 1) {
--
1.7.7.3
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 7/7] aacraid: AIF raw device remove support
2015-03-04 8:38 [PATCH 0/7] aacraid driver updates Mahesh Rajashekhara
` (5 preceding siblings ...)
2015-03-04 8:38 ` [PATCH 6/7] aacraid: performance improvement changes Mahesh Rajashekhara
@ 2015-03-04 8:38 ` Mahesh Rajashekhara
2015-03-17 7:07 ` Murthy Bhat
2015-03-17 15:28 ` Achim Leubner
2015-03-16 11:24 ` [PATCH 0/7] aacraid driver updates Mahesh Rajashekhara
7 siblings, 2 replies; 32+ messages in thread
From: Mahesh Rajashekhara @ 2015-03-04 8:38 UTC (permalink / raw)
To: JBottomley, linux-scsi
Cc: aacraid, Harry.Yang, Achim.Leubner, Rajinikanth.Pandurangan,
Rich.Bono, Mahesh.Rajashekhara
Add AIF raw device remove support
Signed-off-by: Mahesh Rajashekhara <Mahesh.Rajashekhara@pmcs.com>
---
drivers/scsi/aacraid/aacraid.h | 3 +++
drivers/scsi/aacraid/commsup.c | 32 ++++++++++++++++++++++++++++++++
2 files changed, 35 insertions(+), 0 deletions(-)
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index 74a0440..5aaa9a6 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -2061,6 +2061,9 @@ extern struct aac_common aac_config;
/* PMC NEW COMM: Request the event data */
#define AifReqEvent 200
+/* RAW device deleted */
+#define AifRawDeviceRemove 203
+
/*
* Adapter Initiated FIB command structures. Start with the adapter
* initiated FIBs that really come from the adapter, and get responded
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index 0555023..8bb9ee4 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -884,6 +884,38 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
switch (le32_to_cpu(aifcmd->command)) {
case AifCmdDriverNotify:
switch (le32_to_cpu(((__le32 *)aifcmd->data)[0])) {
+ case AifRawDeviceRemove:
+ container = le32_to_cpu(((__le32 *)aifcmd->data)[1]);
+ if ((container >> 28)) {
+ container = (u32)-1;
+ break;
+ }
+ channel = (container >> 24) & 0xF;
+ if (channel >= dev->maximum_num_channels) {
+ container = (u32)-1;
+ break;
+ }
+ id = container & 0xFFFF;
+ if (id >= dev->maximum_num_physicals) {
+ container = (u32)-1;
+ break;
+ }
+ lun = (container >> 16) & 0xFF;
+ container = (u32)-1;
+ channel = aac_phys_to_logical(channel);
+ device_config_needed =
+ (((__le32 *)aifcmd->data)[0] ==
+ cpu_to_le32(AifRawDeviceRemove)) ? DELETE : ADD;
+
+ if (device_config_needed == ADD) {
+ device = scsi_device_lookup(dev->scsi_host_ptr, channel, id, lun);
+ if (device) {
+ scsi_remove_device(device);
+ scsi_device_put(device);
+ }
+ }
+ break;
+
/*
* Morph or Expand complete
*/
--
1.7.7.3
^ permalink raw reply related [flat|nested] 32+ messages in thread
* RE: [PATCH 0/7] aacraid driver updates
2015-03-04 8:38 [PATCH 0/7] aacraid driver updates Mahesh Rajashekhara
` (6 preceding siblings ...)
2015-03-04 8:38 ` [PATCH 7/7] aacraid: AIF raw device remove support Mahesh Rajashekhara
@ 2015-03-16 11:24 ` Mahesh Rajashekhara
2015-03-16 12:49 ` James Bottomley
7 siblings, 1 reply; 32+ messages in thread
From: Mahesh Rajashekhara @ 2015-03-16 11:24 UTC (permalink / raw)
To: JBottomley, linux-scsi
Cc: aacraid, Harry Yang, Achim Leubner, Rajinikanth Pandurangan, Rich Bono
Hi James,
Can you please let me know the status of this patch set which I submitted sometime back.
Thanks,
Mahesh
-----Original Message-----
From: Mahesh Rajashekhara
Sent: Wednesday, March 04, 2015 2:08 PM
To: JBottomley@Parallels.com; linux-scsi@vger.kernel.org
Cc: aacraid@pmc-sierra.com; Harry Yang; Achim Leubner; Rajinikanth Pandurangan; Rich Bono; Mahesh Rajashekhara
Subject: [PATCH 0/7] aacraid driver updates
This patch set includes some important bug fixes and new feature supports.
Mahesh Rajashekhara (7):
aacraid: AIF support for SES device add/remove
aacraid: IOCTL pass-through command fix
aacraid: 4KB sector support
aacraid: MSI-x support
aacraid: vpd page code 0x83 support
aacraid: performance improvement changes
aacraid: AIF raw device remove support
drivers/scsi/aacraid/aachba.c | 355 +++++++++++++++++++++++++++++------
drivers/scsi/aacraid/aacraid.h | 102 +++++++++-
drivers/scsi/aacraid/commctrl.c | 10 +-
drivers/scsi/aacraid/comminit.c | 106 ++++++++++-
drivers/scsi/aacraid/commsup.c | 78 ++++++--
drivers/scsi/aacraid/dpcsup.c | 13 +-
drivers/scsi/aacraid/linit.c | 48 +++--
drivers/scsi/aacraid/rx.c | 14 +-
drivers/scsi/aacraid/src.c | 404 +++++++++++++++++++++++++++++----------
9 files changed, 894 insertions(+), 236 deletions(-)
--
1.7.7.3
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 0/7] aacraid driver updates
2015-03-16 11:24 ` [PATCH 0/7] aacraid driver updates Mahesh Rajashekhara
@ 2015-03-16 12:49 ` James Bottomley
0 siblings, 0 replies; 32+ messages in thread
From: James Bottomley @ 2015-03-16 12:49 UTC (permalink / raw)
To: Mahesh Rajashekhara
Cc: linux-scsi, aacraid, Harry Yang, Achim Leubner,
Rajinikanth Pandurangan, Rich Bono
On Mon, 2015-03-16 at 11:24 +0000, Mahesh Rajashekhara wrote:
> Hi James,
>
> Can you please let me know the status of this patch set which I
> submitted sometime back.
We're following this:
http://marc.info/?l=linux-scsi&m=142556689315114
So you need a review.
James
^ permalink raw reply [flat|nested] 32+ messages in thread
* RE: [PATCH 1/7] aacraid: AIF support for SES device add/remove
2015-03-04 8:38 ` [PATCH 1/7] aacraid: AIF support for SES device add/remove Mahesh Rajashekhara
@ 2015-03-17 7:05 ` Murthy Bhat
2015-03-17 15:24 ` Achim Leubner
1 sibling, 0 replies; 32+ messages in thread
From: Murthy Bhat @ 2015-03-17 7:05 UTC (permalink / raw)
To: Mahesh Rajashekhara, JBottomley, linux-scsi
Cc: aacraid, Harry Yang, Achim Leubner, Rajinikanth Pandurangan, Rich Bono
Reviewed-by: Murthy Bhat <Murthy.Bhat@pmcs.com>
-----Original Message-----
From: Mahesh Rajashekhara
Sent: Wednesday, March 04, 2015 2:08 PM
To: JBottomley@Parallels.com; linux-scsi@vger.kernel.org
Cc: aacraid@pmc-sierra.com; Harry Yang; Achim Leubner; Rajinikanth Pandurangan; Rich Bono; Mahesh Rajashekhara
Subject: [PATCH 1/7] aacraid: AIF support for SES device add/remove
Add new AIF support for SES device add/remove
Signed-off-by: Mahesh Rajashekhara <Mahesh.Rajashekhara@pmcs.com>
---
drivers/scsi/aacraid/aacraid.h | 2 ++
drivers/scsi/aacraid/commsup.c | 8 ++++++--
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index eaaf870..284db39 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -1951,6 +1951,8 @@ extern struct aac_common aac_config;
#define AifEnEnclosureManagement 13 /* EM_DRIVE_* */
#define EM_DRIVE_INSERTION 31
#define EM_DRIVE_REMOVAL 32
+#define EM_SES_DRIVE_INSERTION 33
+#define EM_SES_DRIVE_REMOVAL 26
#define AifEnBatteryEvent 14 /* Change in Battery State */
#define AifEnAddContainer 15 /* A new array was created */
#define AifEnDeleteContainer 16 /* A container was deleted */
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index cab190a..090ba68 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -1044,6 +1044,8 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
switch (le32_to_cpu(((__le32 *)aifcmd->data)[3])) {
case EM_DRIVE_INSERTION:
case EM_DRIVE_REMOVAL:
+ case EM_SES_DRIVE_INSERTION:
+ case EM_SES_DRIVE_REMOVAL:
container = le32_to_cpu(
((__le32 *)aifcmd->data)[2]);
if ((container >> 28)) {
@@ -1069,8 +1071,10 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
}
channel = aac_phys_to_logical(channel);
device_config_needed =
- (((__le32 *)aifcmd->data)[3]
- == cpu_to_le32(EM_DRIVE_INSERTION)) ?
+ ((((__le32 *)aifcmd->data)[3]
+ == cpu_to_le32(EM_DRIVE_INSERTION)) ||
+ (((__le32 *)aifcmd->data)[3]
+ == cpu_to_le32(EM_SES_DRIVE_INSERTION))) ?
ADD : DELETE;
break;
}
--
1.7.7.3
^ permalink raw reply related [flat|nested] 32+ messages in thread
* RE: [PATCH 2/7] aacraid: IOCTL pass-through command fix
2015-03-04 8:38 ` [PATCH 2/7] aacraid: IOCTL pass-through command fix Mahesh Rajashekhara
@ 2015-03-17 7:06 ` Murthy Bhat
2015-03-17 15:26 ` Achim Leubner
1 sibling, 0 replies; 32+ messages in thread
From: Murthy Bhat @ 2015-03-17 7:06 UTC (permalink / raw)
To: Mahesh Rajashekhara, JBottomley, linux-scsi
Cc: aacraid, Harry Yang, Achim Leubner, Rajinikanth Pandurangan, Rich Bono
Reviewed-by: Murthy Bhat <Murthy.Bhat@pmcs.com>
-----Original Message-----
From: Mahesh Rajashekhara
Sent: Wednesday, March 04, 2015 2:08 PM
To: JBottomley@Parallels.com; linux-scsi@vger.kernel.org
Cc: aacraid@pmc-sierra.com; Harry Yang; Achim Leubner; Rajinikanth Pandurangan; Rich Bono; Mahesh Rajashekhara
Subject: [PATCH 2/7] aacraid: IOCTL pass-through command fix
The Linux aacriad driver fails to detect the case of SG list count=0 on IOCTL pass-through command and cause intermittent fault.
The result is the Linux aacriad driver send down IOCTL pass-through command with one not initialized SG list to firmware when receiving SG list count =0 on pass-through command.
Signed-off-by: Mahesh Rajashekhara <Mahesh.Rajashekhara@pmcs.com>
---
drivers/scsi/aacraid/commctrl.c | 10 ++++++++--
1 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c
index fbcd48d..54195a1 100644
--- a/drivers/scsi/aacraid/commctrl.c
+++ b/drivers/scsi/aacraid/commctrl.c
@@ -689,7 +689,10 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
kfree (usg);
}
srbcmd->count = cpu_to_le32(byte_count);
- psg->count = cpu_to_le32(sg_indx+1);
+ if (user_srbcmd->sg.count)
+ psg->count = cpu_to_le32(sg_indx+1);
+ else
+ psg->count = 0;
status = aac_fib_send(ScsiPortCommand64, srbfib, actual_fibsize, FsaNormal, 1, 1,NULL,NULL);
} else {
struct user_sgmap* upsg = &user_srbcmd->sg;
@@ -775,7 +778,10 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
}
}
srbcmd->count = cpu_to_le32(byte_count);
- psg->count = cpu_to_le32(sg_indx+1);
+ if (user_srbcmd->sg.count)
+ psg->count = cpu_to_le32(sg_indx+1);
+ else
+ psg->count = 0;
status = aac_fib_send(ScsiPortCommand, srbfib, actual_fibsize, FsaNormal, 1, 1, NULL, NULL);
}
if (status == -ERESTARTSYS) {
--
1.7.7.3
^ permalink raw reply related [flat|nested] 32+ messages in thread
* RE: [PATCH 3/7] aacraid: 4KB sector support
2015-03-04 8:38 ` [PATCH 3/7] aacraid: 4KB sector support Mahesh Rajashekhara
@ 2015-03-17 7:06 ` Murthy Bhat
2015-03-17 15:26 ` Achim Leubner
1 sibling, 0 replies; 32+ messages in thread
From: Murthy Bhat @ 2015-03-17 7:06 UTC (permalink / raw)
To: Mahesh Rajashekhara, JBottomley, linux-scsi
Cc: aacraid, Harry Yang, Achim Leubner, Rajinikanth Pandurangan, Rich Bono
Reviewed-by: Murthy Bhat <Murthy.Bhat@pmcs.com>
-----Original Message-----
From: Mahesh Rajashekhara
Sent: Wednesday, March 04, 2015 2:08 PM
To: JBottomley@Parallels.com; linux-scsi@vger.kernel.org
Cc: aacraid@pmc-sierra.com; Harry Yang; Achim Leubner; Rajinikanth Pandurangan; Rich Bono; Mahesh Rajashekhara
Subject: [PATCH 3/7] aacraid: 4KB sector support
Add 4KB sector support
Signed-off-by: Mahesh Rajashekhara <Mahesh.Rajashekhara@pmcs.com>
---
drivers/scsi/aacraid/aachba.c | 195 +++++++++++++++++++++++++++++++---------
drivers/scsi/aacraid/aacraid.h | 10 ++-
2 files changed, 160 insertions(+), 45 deletions(-)
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index b32e77d..0819644 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -111,6 +111,41 @@
#define BYTE2(x) (unsigned char)((x) >> 16)
#define BYTE3(x) (unsigned char)((x) >> 24)
+/* MODE_SENSE data format */
+typedef struct {
+ struct {
+ u8 data_length;
+ u8 med_type;
+ u8 dev_par;
+ u8 bd_length;
+ } __attribute__((packed)) hd;
+ struct {
+ u8 dens_code;
+ u8 block_count[3];
+ u8 reserved;
+ u8 block_length[3];
+ } __attribute__((packed)) bd;
+ u8 mpc_buf[3];
+} __attribute__((packed)) aac_modep_data;
+
+/* MODE_SENSE_10 data format */
+typedef struct {
+ struct {
+ u8 data_length[2];
+ u8 med_type;
+ u8 dev_par;
+ u8 rsrvd[2];
+ u8 bd_length[2];
+ } __attribute__((packed)) hd;
+ struct {
+ u8 dens_code;
+ u8 block_count[3];
+ u8 reserved;
+ u8 block_length[3];
+ } __attribute__((packed)) bd;
+ u8 mpc_buf[3];
+} __attribute__((packed)) aac_modep10_data;
+
/*------------------------------------------------------------------------------
* S T R U C T S / T Y P E D E F S
*----------------------------------------------------------------------------*/
@@ -539,6 +574,13 @@ static void _aac_probe_container2(void * context, struct fib * fibptr)
if ((le32_to_cpu(dresp->status) == ST_OK) &&
(le32_to_cpu(dresp->mnt[0].vol) != CT_NONE) &&
(le32_to_cpu(dresp->mnt[0].state) != FSCS_HIDDEN)) {
+ if (!(fibptr->dev->supplement_adapter_info.SupportedOptions2 &
+ AAC_OPTION_VARIABLE_BLOCK_SIZE)) {
+ dresp->mnt[0].fileinfo.bdevinfo.block_size = 0x200;
+ fsa_dev_ptr->block_size = 0x200;
+ } else {
+ fsa_dev_ptr->block_size = le32_to_cpu(dresp->mnt[0].fileinfo.bdevinfo.block_size);
+ }
fsa_dev_ptr->valid = 1;
/* sense_key holds the current state of the spin-up */
if (dresp->mnt[0].state & cpu_to_le32(FSCS_NOT_READY))
@@ -586,7 +628,12 @@ static void _aac_probe_container1(void * context, struct fib * fibptr)
dinfo = (struct aac_query_mount *)fib_data(fibptr);
- dinfo->command = cpu_to_le32(VM_NameServe64);
+ if (fibptr->dev->supplement_adapter_info.SupportedOptions2 &
+ AAC_OPTION_VARIABLE_BLOCK_SIZE)
+ dinfo->command = cpu_to_le32(VM_NameServeAllBlk);
+ else
+ dinfo->command = cpu_to_le32(VM_NameServe64);
+
dinfo->count = cpu_to_le32(scmd_id(scsicmd));
dinfo->type = cpu_to_le32(FT_FILESYS);
@@ -621,7 +668,12 @@ static int _aac_probe_container(struct scsi_cmnd * scsicmd, int (*callback)(stru
dinfo = (struct aac_query_mount *)fib_data(fibptr);
- dinfo->command = cpu_to_le32(VM_NameServe);
+ if (fibptr->dev->supplement_adapter_info.SupportedOptions2 &
+ AAC_OPTION_VARIABLE_BLOCK_SIZE)
+ dinfo->command = cpu_to_le32(VM_NameServeAllBlk);
+ else
+ dinfo->command = cpu_to_le32(VM_NameServe);
+
dinfo->count = cpu_to_le32(scmd_id(scsicmd));
dinfo->type = cpu_to_le32(FT_FILESYS);
scsicmd->SCp.ptr = (char *)callback;
@@ -982,7 +1034,7 @@ static int aac_read_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u3
memset(readcmd2, 0, sizeof(struct aac_raw_io2));
readcmd2->blockLow = cpu_to_le32((u32)(lba&0xffffffff));
readcmd2->blockHigh = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32));
- readcmd2->byteCount = cpu_to_le32(count<<9);
+ readcmd2->byteCount = cpu_to_le32(count * dev->fsa_dev[scmd_id(cmd)].block_size);
readcmd2->cid = cpu_to_le16(scmd_id(cmd));
readcmd2->flags = cpu_to_le16(RIO2_IO_TYPE_READ);
ret = aac_build_sgraw2(cmd, readcmd2,
@@ -997,7 +1049,7 @@ static int aac_read_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u3
readcmd = (struct aac_raw_io *) fib_data(fib);
readcmd->block[0] = cpu_to_le32((u32)(lba&0xffffffff));
readcmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32));
- readcmd->count = cpu_to_le32(count<<9);
+ readcmd->count = cpu_to_le32(count * dev->fsa_dev[scmd_id(cmd)].block_size);
readcmd->cid = cpu_to_le16(scmd_id(cmd));
readcmd->flags = cpu_to_le16(RIO_TYPE_READ);
readcmd->bpTotal = 0;
@@ -1062,6 +1114,7 @@ static int aac_read_block(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32
{
u16 fibsize;
struct aac_read *readcmd;
+ struct aac_dev *dev = fib->dev;
long ret;
aac_fib_init(fib);
@@ -1069,7 +1122,7 @@ static int aac_read_block(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32
readcmd->command = cpu_to_le32(VM_CtBlockRead);
readcmd->cid = cpu_to_le32(scmd_id(cmd));
readcmd->block = cpu_to_le32((u32)(lba&0xffffffff));
- readcmd->count = cpu_to_le32(count * 512);
+ readcmd->count = cpu_to_le32(count * dev->fsa_dev[scmd_id(cmd)].block_size);
ret = aac_build_sg(cmd, &readcmd->sg);
if (ret < 0)
@@ -1104,7 +1157,7 @@ static int aac_write_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u
memset(writecmd2, 0, sizeof(struct aac_raw_io2));
writecmd2->blockLow = cpu_to_le32((u32)(lba&0xffffffff));
writecmd2->blockHigh = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32));
- writecmd2->byteCount = cpu_to_le32(count<<9);
+ writecmd2->byteCount = cpu_to_le32(count * dev->fsa_dev[scmd_id(cmd)].block_size);
writecmd2->cid = cpu_to_le16(scmd_id(cmd));
writecmd2->flags = (fua && ((aac_cache & 5) != 1) &&
(((aac_cache & 5) != 5) || !fib->dev->cache_protected)) ?
@@ -1122,7 +1175,7 @@ static int aac_write_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u
writecmd = (struct aac_raw_io *) fib_data(fib);
writecmd->block[0] = cpu_to_le32((u32)(lba&0xffffffff));
writecmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32));
- writecmd->count = cpu_to_le32(count<<9);
+ writecmd->count = cpu_to_le32(count * dev->fsa_dev[scmd_id(cmd)].block_size);
writecmd->cid = cpu_to_le16(scmd_id(cmd));
writecmd->flags = (fua && ((aac_cache & 5) != 1) &&
(((aac_cache & 5) != 5) || !fib->dev->cache_protected)) ?
@@ -1190,6 +1243,7 @@ static int aac_write_block(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u3
{
u16 fibsize;
struct aac_write *writecmd;
+ struct aac_dev *dev = fib->dev;
long ret;
aac_fib_init(fib);
@@ -1197,7 +1251,7 @@ static int aac_write_block(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u3
writecmd->command = cpu_to_le32(VM_CtBlockWrite);
writecmd->cid = cpu_to_le32(scmd_id(cmd));
writecmd->block = cpu_to_le32((u32)(lba&0xffffffff));
- writecmd->count = cpu_to_le32(count * 512);
+ writecmd->count = cpu_to_le32(count * dev->fsa_dev[scmd_id(cmd)].block_size);
writecmd->sg.count = cpu_to_le32(1);
/* ->stable is not used - it did mean which type of write */
@@ -2329,10 +2383,10 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
cp[5] = (capacity >> 16) & 0xff;
cp[6] = (capacity >> 8) & 0xff;
cp[7] = (capacity >> 0) & 0xff;
- cp[8] = 0;
- cp[9] = 0;
- cp[10] = 2;
- cp[11] = 0;
+ cp[8] = (fsa_dev_ptr[cid].block_size >> 24) & 0xff;
+ cp[9] = (fsa_dev_ptr[cid].block_size >> 16) & 0xff;
+ cp[10] = (fsa_dev_ptr[cid].block_size >> 8) & 0xff;
+ cp[11] = (fsa_dev_ptr[cid].block_size) & 0xff;
cp[12] = 0;
alloc_len = ((scsicmd->cmnd[10] << 24)
@@ -2369,10 +2423,10 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
cp[1] = (capacity >> 16) & 0xff;
cp[2] = (capacity >> 8) & 0xff;
cp[3] = (capacity >> 0) & 0xff;
- cp[4] = 0;
- cp[5] = 0;
- cp[6] = 2;
- cp[7] = 0;
+ cp[4] = (fsa_dev_ptr[cid].block_size >> 24) & 0xff;
+ cp[5] = (fsa_dev_ptr[cid].block_size >> 16) & 0xff;
+ cp[6] = (fsa_dev_ptr[cid].block_size >> 8) & 0xff;
+ cp[7] = (fsa_dev_ptr[cid].block_size) & 0xff;
scsi_sg_copy_from_buffer(scsicmd, cp, sizeof(cp));
/* Do not cache partition table for arrays */
scsicmd->device->removable = 1;
@@ -2385,30 +2439,55 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
case MODE_SENSE:
{
- char mode_buf[7];
int mode_buf_length = 4;
+ u32 capacity;
+ aac_modep_data mpd;
+
+ if (fsa_dev_ptr[cid].size <= 0x100000000ULL)
+ capacity = fsa_dev_ptr[cid].size - 1;
+ else
+ capacity = (u32)-1;
dprintk((KERN_DEBUG "MODE SENSE command.\n"));
- mode_buf[0] = 3; /* Mode data length */
- mode_buf[1] = 0; /* Medium type - default */
- mode_buf[2] = 0; /* Device-specific param,
+ memset((char *)&mpd, 0, sizeof(aac_modep_data));
+
+ mpd.hd.data_length = sizeof(mpd.hd) - 1; /* Mode data length */
+ mpd.hd.med_type = 0; /* Medium type - default */
+ mpd.hd.dev_par = 0; /* Device-specific param,
bit 8: 0/1 = write enabled/protected
bit 4: 0/1 = FUA enabled */
if (dev->raw_io_interface && ((aac_cache & 5) != 1))
- mode_buf[2] = 0x10;
- mode_buf[3] = 0; /* Block descriptor length */
+ mpd.hd.dev_par = 0x10;
+ if (scsicmd->cmnd[1] & 0x8) {
+ mpd.hd.bd_length = 0; /* Block descriptor length */
+ } else {
+ mpd.hd.bd_length = sizeof(mpd.bd);
+ mpd.hd.data_length += mpd.hd.bd_length;
+ mpd.bd.block_length[0] = (fsa_dev_ptr[cid].block_size >> 16) & 0xff;
+ mpd.bd.block_length[1] = (fsa_dev_ptr[cid].block_size >> 8) & 0xff;
+ mpd.bd.block_length[2] = fsa_dev_ptr[cid].block_size & 0xff;
+ if (capacity > 0xffffff) {
+ mpd.bd.block_count[0] = 0xff;
+ mpd.bd.block_count[1] = 0xff;
+ mpd.bd.block_count[2] = 0xff;
+ } else {
+ mpd.bd.block_count[0] = (capacity >> 16) & 0xff;
+ mpd.bd.block_count[1] = (capacity >> 8) & 0xff;
+ mpd.bd.block_count[2] = capacity & 0xff;
+ }
+ }
if (((scsicmd->cmnd[2] & 0x3f) == 8) ||
((scsicmd->cmnd[2] & 0x3f) == 0x3f)) {
- mode_buf[0] = 6;
- mode_buf[4] = 8;
- mode_buf[5] = 1;
- mode_buf[6] = ((aac_cache & 6) == 2)
+ mpd.hd.data_length += 3;
+ mpd.mpc_buf[0] = 8;
+ mpd.mpc_buf[1] = 1;
+ mpd.mpc_buf[2] = ((aac_cache & 6) == 2)
? 0 : 0x04; /* WCE */
- mode_buf_length = 7;
+ mode_buf_length = sizeof(mpd);
if (mode_buf_length > scsicmd->cmnd[4])
mode_buf_length = scsicmd->cmnd[4];
}
- scsi_sg_copy_from_buffer(scsicmd, mode_buf, mode_buf_length);
+ scsi_sg_copy_from_buffer(scsicmd, (char *)&mpd, mode_buf_length);
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
scsicmd->scsi_done(scsicmd);
@@ -2416,34 +2495,62 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
}
case MODE_SENSE_10:
{
- char mode_buf[11];
+ u32 capacity;
int mode_buf_length = 8;
+ aac_modep10_data mpd10;
+
+ if (fsa_dev_ptr[cid].size <= 0x100000000ULL)
+ capacity = fsa_dev_ptr[cid].size - 1;
+ else
+ capacity = (u32)-1;
dprintk((KERN_DEBUG "MODE SENSE 10 byte command.\n"));
- mode_buf[0] = 0; /* Mode data length (MSB) */
- mode_buf[1] = 6; /* Mode data length (LSB) */
- mode_buf[2] = 0; /* Medium type - default */
- mode_buf[3] = 0; /* Device-specific param,
+ memset((char *)&mpd10, 0, sizeof(aac_modep10_data));
+ mpd10.hd.data_length[0] = 0; /* Mode data length (MSB) */
+ mpd10.hd.data_length[1] = sizeof(mpd10.hd) - 1; /* Mode data length (LSB) */
+ mpd10.hd.med_type = 0; /* Medium type - default */
+ mpd10.hd.dev_par = 0; /* Device-specific param,
bit 8: 0/1 = write enabled/protected
bit 4: 0/1 = FUA enabled */
if (dev->raw_io_interface && ((aac_cache & 5) != 1))
- mode_buf[3] = 0x10;
- mode_buf[4] = 0; /* reserved */
- mode_buf[5] = 0; /* reserved */
- mode_buf[6] = 0; /* Block descriptor length (MSB) */
- mode_buf[7] = 0; /* Block descriptor length (LSB) */
+ mpd10.hd.dev_par = 0x10;
+ mpd10.hd.rsrvd[0] = 0; /* reserved */
+ mpd10.hd.rsrvd[1] = 0; /* reserved */
+ if (scsicmd->cmnd[1] & 0x8) {
+ mpd10.hd.bd_length[0] = 0; /* Block descriptor length (MSB) */
+ mpd10.hd.bd_length[1] = 0; /* Block descriptor length (LSB) */
+ } else {
+ mpd10.hd.bd_length[0] = 0;
+ mpd10.hd.bd_length[1] = sizeof(mpd10.bd);
+
+ mpd10.hd.data_length[1] += mpd10.hd.bd_length[1];
+
+ mpd10.bd.block_length[0] = (fsa_dev_ptr[cid].block_size >> 16) & 0xff;
+ mpd10.bd.block_length[1] = (fsa_dev_ptr[cid].block_size >> 8) & 0xff;
+ mpd10.bd.block_length[2] = fsa_dev_ptr[cid].block_size & 0xff;
+
+ if (capacity > 0xffffff) {
+ mpd10.bd.block_count[0] = 0xff;
+ mpd10.bd.block_count[1] = 0xff;
+ mpd10.bd.block_count[2] = 0xff;
+ } else {
+ mpd10.bd.block_count[0] = (capacity >> 16) & 0xff;
+ mpd10.bd.block_count[1] = (capacity >> 8) & 0xff;
+ mpd10.bd.block_count[2] = capacity & 0xff;
+ }
+ }
if (((scsicmd->cmnd[2] & 0x3f) == 8) ||
((scsicmd->cmnd[2] & 0x3f) == 0x3f)) {
- mode_buf[1] = 9;
- mode_buf[8] = 8;
- mode_buf[9] = 1;
- mode_buf[10] = ((aac_cache & 6) == 2)
+ mpd10.hd.data_length[1] += 3;
+ mpd10.mpc_buf[0] = 8;
+ mpd10.mpc_buf[1] = 1;
+ mpd10.mpc_buf[2] = ((aac_cache & 6) == 2)
? 0 : 0x04; /* WCE */
- mode_buf_length = 11;
+ mode_buf_length = sizeof(mpd10);
if (mode_buf_length > scsicmd->cmnd[8])
mode_buf_length = scsicmd->cmnd[8];
}
- scsi_sg_copy_from_buffer(scsicmd, mode_buf, mode_buf_length);
+ scsi_sg_copy_from_buffer(scsicmd, (char *)&mpd10, mode_buf_length);
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
scsicmd->scsi_done(scsicmd);
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index 284db39..93579f3 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -857,6 +857,7 @@ struct fsa_dev_info {
u8 deleted;
char devname[8];
struct sense_data sense_data;
+ u32 block_size;
};
struct fib {
@@ -960,6 +961,7 @@ struct aac_supplement_adapter_info
#define AAC_OPTION_IGNORE_RESET cpu_to_le32(0x00000002)
#define AAC_OPTION_POWER_MANAGEMENT cpu_to_le32(0x00000004)
#define AAC_OPTION_DOORBELL_RESET cpu_to_le32(0x00004000)
+#define AAC_OPTION_VARIABLE_BLOCK_SIZE cpu_to_le32(0x00040000) /* 4KB sector size */
#define AAC_SIS_VERSION_V3 3
#define AAC_SIS_SLOT_UNKNOWN 0xFF
@@ -1589,6 +1591,7 @@ struct aac_srb_reply
#define VM_CtHostWrite64 20
#define VM_DrvErrTblLog 21
#define VM_NameServe64 22
+#define VM_NameServeAllBlk 30
#define MAX_VMCOMMAND_NUM 23 /* used for sizing stats array - leave last */
@@ -1611,8 +1614,13 @@ struct aac_fsinfo {
__le32 fsInodeDensity;
}; /* valid iff ObjType == FT_FILESYS && !(ContentState & FSCS_NOTCLEAN) */
+struct aac_blockdevinfo {
+ __le32 block_size;
+};
+
union aac_contentinfo {
- struct aac_fsinfo filesys; /* valid iff ObjType == FT_FILESYS && !(ContentState & FSCS_NOTCLEAN) */
+ struct aac_fsinfo filesys; /* valid iff ObjType == FT_FILESYS && !(ContentState & FSCS_NOTCLEAN) */
+ struct aac_blockdevinfo bdevinfo;
};
/*
--
1.7.7.3
^ permalink raw reply related [flat|nested] 32+ messages in thread
* RE: [PATCH 4/7] aacraid: MSI-x support
2015-03-04 8:38 ` [PATCH 4/7] aacraid: MSI-x support Mahesh Rajashekhara
@ 2015-03-17 7:06 ` Murthy Bhat
2015-03-17 15:27 ` Achim Leubner
1 sibling, 0 replies; 32+ messages in thread
From: Murthy Bhat @ 2015-03-17 7:06 UTC (permalink / raw)
To: Mahesh Rajashekhara, JBottomley, linux-scsi
Cc: aacraid, Harry Yang, Achim Leubner, Rajinikanth Pandurangan, Rich Bono
Reviewed-by: Murthy Bhat <Murthy.Bhat@pmcs.com>
-----Original Message-----
From: Mahesh Rajashekhara
Sent: Wednesday, March 04, 2015 2:09 PM
To: JBottomley@Parallels.com; linux-scsi@vger.kernel.org
Cc: aacraid@pmc-sierra.com; Harry Yang; Achim Leubner; Rajinikanth Pandurangan; Rich Bono; Mahesh Rajashekhara
Subject: [PATCH 4/7] aacraid: MSI-x support
Add MSI-x interrupt mode support.
Signed-off-by: Mahesh Rajashekhara <Mahesh.Rajashekhara@pmcs.com>
---
drivers/scsi/aacraid/aachba.c | 6 +-
drivers/scsi/aacraid/aacraid.h | 79 ++++++++-
drivers/scsi/aacraid/comminit.c | 86 +++++++++-
drivers/scsi/aacraid/commsup.c | 19 ++-
drivers/scsi/aacraid/dpcsup.c | 9 +-
drivers/scsi/aacraid/linit.c | 18 ++-
drivers/scsi/aacraid/src.c | 365 +++++++++++++++++++++++++++++----------
7 files changed, 473 insertions(+), 109 deletions(-)
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index 0819644..eb524e6 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -473,7 +473,7 @@ static void get_container_name_callback(void *context, struct fib * fibptr)
if ((le32_to_cpu(get_name_reply->status) == CT_OK)
&& (get_name_reply->data[0] != '\0')) {
char *sp = get_name_reply->data;
- sp[sizeof(((struct aac_get_name_resp *)NULL)->data)-1] = '\0';
+ sp[sizeof(((struct aac_get_name_resp *)NULL)->data)] = '\0';
while (*sp == ' ')
++sp;
if (*sp) {
@@ -613,7 +613,9 @@ static void _aac_probe_container1(void * context, struct fib * fibptr)
int status;
dresp = (struct aac_mount *) fib_data(fibptr);
- dresp->mnt[0].capacityhigh = 0;
+ if (!(fibptr->dev->supplement_adapter_info.SupportedOptions2 &
+ AAC_OPTION_VARIABLE_BLOCK_SIZE))
+ dresp->mnt[0].capacityhigh = 0;
if ((le32_to_cpu(dresp->status) != ST_OK) ||
(le32_to_cpu(dresp->mnt[0].vol) != CT_NONE)) {
_aac_probe_container2(context, fibptr);
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index 93579f3..c162a65 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -6,11 +6,61 @@
#define nblank(x) _nblank(x)[0]
#include <linux/interrupt.h>
+#include <linux/pci.h>
/*------------------------------------------------------------------------------
* D E F I N E S
*----------------------------------------------------------------------------*/
+#define AAC_MAX_MSIX 32 /* vectors */
+#define AAC_PCI_MSI_ENABLE 0x8000
+
+enum {
+ AAC_ENABLE_INTERRUPT = 0x0,
+ AAC_DISABLE_INTERRUPT,
+ AAC_ENABLE_MSIX,
+ AAC_DISABLE_MSIX,
+ AAC_CLEAR_AIF_BIT,
+ AAC_CLEAR_SYNC_BIT,
+ AAC_ENABLE_INTX
+};
+
+#define AAC_INT_MODE_INTX (1<<0)
+#define AAC_INT_MODE_MSI (1<<1)
+#define AAC_INT_MODE_AIF (1<<2)
+#define AAC_INT_MODE_SYNC (1<<3)
+
+#define AAC_INT_ENABLE_TYPE1_INTX 0xfffffffb
+#define AAC_INT_ENABLE_TYPE1_MSIX 0xfffffffa
+#define AAC_INT_DISABLE_ALL 0xffffffff
+
+/* Bit definitions in IOA->Host Interrupt Register */
+#define PMC_TRANSITION_TO_OPERATIONAL (0x80000000 >> 0)
+#define PMC_IOARCB_TRANSFER_FAILED (0x80000000 >> 3)
+#define PMC_IOA_UNIT_CHECK (0x80000000 >> 4)
+#define PMC_NO_HOST_RRQ_FOR_CMD_RESPONSE (0x80000000 >> 5)
+#define PMC_CRITICAL_IOA_OP_IN_PROGRESS (0x80000000 >> 6)
+#define PMC_IOARRIN_LOST (0x80000000 >> 27)
+#define PMC_SYSTEM_BUS_MMIO_ERROR (0x80000000 >> 28)
+#define PMC_IOA_PROCESSOR_IN_ERROR_STATE (0x80000000 >> 29)
+#define PMC_HOST_RRQ_VALID (0x80000000 >> 30)
+#define PMC_OPERATIONAL_STATUS (0x80000000 >> 0)
+#define PMC_ALLOW_MSIX_VECTOR0 (0x80000000 >> 31)
+
+#define PMC_IOA_ERROR_INTERRUPTS (PMC_IOARCB_TRANSFER_FAILED | \
+ PMC_IOA_UNIT_CHECK | \
+ PMC_NO_HOST_RRQ_FOR_CMD_RESPONSE | \
+ PMC_IOARRIN_LOST | \
+ PMC_SYSTEM_BUS_MMIO_ERROR | \
+ PMC_IOA_PROCESSOR_IN_ERROR_STATE)
+
+#define PMC_ALL_INTERRUPT_BITS (PMC_IOA_ERROR_INTERRUPTS | \
+ PMC_HOST_RRQ_VALID | \
+ PMC_TRANSITION_TO_OPERATIONAL | \
+ PMC_ALLOW_MSIX_VECTOR0)
+#define PMC_GLOBAL_INT_BIT2 0x00000004
+#define PMC_GLOBAL_INT_BIT0 0x00000001
+
#ifndef AAC_DRIVER_BUILD
# define AAC_DRIVER_BUILD 30300
# define AAC_DRIVER_BRANCH "-ms"
@@ -36,6 +86,7 @@
#define CONTAINER_TO_ID(cont) (cont)
#define CONTAINER_TO_LUN(cont) (0)
+#define PMC_DEVICE_S6 0x28b
#define PMC_DEVICE_S7 0x28c
#define PMC_DEVICE_S8 0x28d
#define PMC_DEVICE_S9 0x28f
@@ -434,7 +485,7 @@ enum fib_xfer_state {
struct aac_init
{
__le32 InitStructRevision;
- __le32 MiniPortRevision;
+ __le32 NoOfMSIXVectors;
__le32 fsrev;
__le32 CommHeaderAddress;
__le32 FastIoCommAreaAddress;
@@ -755,7 +806,8 @@ struct rkt_registers {
struct src_mu_registers {
/* PCI*| Name */
- __le32 reserved0[8]; /* 00h | Reserved */
+ __le32 reserved0[6]; /* 00h | Reserved */
+ __le32 IOAR[2]; /* 18h | IOA->host interrupt register */
__le32 IDR; /* 20h | Inbound Doorbell Register */
__le32 IISR; /* 24h | Inbound Int. Status Register */
__le32 reserved1[3]; /* 28h | Reserved */
@@ -767,17 +819,18 @@ struct src_mu_registers {
__le32 OMR; /* bch | Outbound Message Register */
__le32 IQ_L; /* c0h | Inbound Queue (Low address) */
__le32 IQ_H; /* c4h | Inbound Queue (High address) */
+ __le32 ODR_MSI; /* c8h | MSI register for sync./AIF */
};
struct src_registers {
- struct src_mu_registers MUnit; /* 00h - c7h */
+ struct src_mu_registers MUnit; /* 00h - cbh */
union {
struct {
- __le32 reserved1[130790]; /* c8h - 7fc5fh */
+ __le32 reserved1[130789]; /* cch - 7fc5fh */
struct src_inbound IndexRegs; /* 7fc60h */
} tupelo;
struct {
- __le32 reserved1[974]; /* c8h - fffh */
+ __le32 reserved1[973]; /* cch - fffh */
struct src_inbound IndexRegs; /* 1000h */
} denali;
} u;
@@ -1028,6 +1081,11 @@ struct aac_bus_info_response {
#define AAC_OPT_NEW_COMM_TYPE3 cpu_to_le32(1<<30)
#define AAC_OPT_NEW_COMM_TYPE4 cpu_to_le32(1<<31)
+/* MSIX context */
+struct aac_msix_ctx {
+ int vector_no;
+ struct aac_dev *dev;
+};
struct aac_dev
{
@@ -1083,8 +1141,9 @@ struct aac_dev
* if AAC_COMM_MESSAGE_TYPE1 */
dma_addr_t host_rrq_pa; /* phys. address */
- u32 host_rrq_idx; /* index into rrq buffer */
-
+ u32 host_rrq_idx[AAC_MAX_MSIX]; /* index into rrq buffer */
+ atomic_t rrq_outstanding[AAC_MAX_MSIX];
+ u32 fibs_pushed_no;
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 */
@@ -1153,6 +1212,11 @@ struct aac_dev
int sync_mode;
struct fib *sync_fib;
struct list_head sync_fib_list;
+ u32 max_msix; /* max. MSI-X vectors */
+ u32 vector_cap; /* MSI-X vector capab.*/
+ int msi_enabled; /* MSI/MSI-X enabled */
+ struct msix_entry msixentry[AAC_MAX_MSIX];
+ struct aac_msix_ctx aac_msix[AAC_MAX_MSIX]; /* context */
};
#define aac_adapter_interrupt(dev) \
@@ -2035,6 +2099,7 @@ void aac_consumer_free(struct aac_dev * dev, struct aac_queue * q, u32 qnum);
int aac_fib_complete(struct fib * context);
#define fib_data(fibctx) ((void *)(fibctx)->hw_fib_va->data)
struct aac_dev *aac_init_adapter(struct aac_dev *dev);
+void aac_src_access_devreg(struct aac_dev *dev, int mode);
int aac_get_config_status(struct aac_dev *dev, int commit_flag);
int aac_get_containers(struct aac_dev *dev);
int aac_scsi_cmd(struct scsi_cmnd *cmd);
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c
index 177b094..29c35c8 100644
--- a/drivers/scsi/aacraid/comminit.c
+++ b/drivers/scsi/aacraid/comminit.c
@@ -43,6 +43,8 @@
#include "aacraid.h"
+static void aac_define_int_mode(struct aac_dev *dev);
+
struct aac_common aac_config = {
.irq_mod = 1
};
@@ -91,7 +93,7 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
init->InitStructRevision = cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION);
if (dev->max_fib_size != sizeof(struct hw_fib))
init->InitStructRevision = cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_4);
- init->MiniPortRevision = cpu_to_le32(Sa_MINIPORT_REVISION);
+ init->NoOfMSIXVectors = cpu_to_le32(Sa_MINIPORT_REVISION);
init->fsrev = cpu_to_le32(dev->fsrev);
/*
@@ -140,7 +142,7 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
INITFLAGS_NEW_COMM_TYPE2_SUPPORTED | INITFLAGS_FAST_JBOD_SUPPORTED);
init->HostRRQ_AddrHigh = cpu_to_le32((u32)((u64)dev->host_rrq_pa >> 32));
init->HostRRQ_AddrLow = cpu_to_le32((u32)(dev->host_rrq_pa & 0xffffffff));
- init->MiniPortRevision = cpu_to_le32(0L); /* number of MSI-X */
+ init->NoOfMSIXVectors = cpu_to_le32(dev->max_msix); /* number of MSI-X */
dprintk((KERN_WARNING"aacraid: New Comm Interface type2 enabled\n"));
}
@@ -228,6 +230,11 @@ int aac_send_shutdown(struct aac_dev * dev)
/* FIB should be freed only after getting the response from the F/W */
if (status != -ERESTARTSYS)
aac_fib_free(fibctx);
+ if ((dev->pdev->device == PMC_DEVICE_S7 ||
+ dev->pdev->device == PMC_DEVICE_S8 ||
+ dev->pdev->device == PMC_DEVICE_S9) &&
+ dev->msi_enabled)
+ aac_src_access_devreg(dev, AAC_ENABLE_INTX);
return status;
}
@@ -388,6 +395,8 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
}
}
}
+ dev->max_msix = 0;
+ dev->msi_enabled = 0;
if ((!aac_adapter_sync_cmd(dev, GET_COMM_PREFERRED_SETTINGS,
0, 0, 0, 0, 0, 0,
status+0, status+1, status+2, status+3, status+4))
@@ -461,6 +470,11 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
if (host->can_queue > AAC_NUM_IO_FIB)
host->can_queue = AAC_NUM_IO_FIB;
+ if (dev->pdev->device == PMC_DEVICE_S6 ||
+ dev->pdev->device == PMC_DEVICE_S7 ||
+ dev->pdev->device == PMC_DEVICE_S8 ||
+ dev->pdev->device == PMC_DEVICE_S9)
+ aac_define_int_mode(dev);
/*
* Ok now init the communication subsystem
*/
@@ -489,4 +503,70 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
return dev;
}
-
+static void aac_define_int_mode(struct aac_dev *dev)
+{
+
+ int i, msi_count;
+
+ /* max. vectors from GET_COMM_PREFERRED_SETTINGS */
+ if (dev->max_msix == 0 ||
+ dev->pdev->device == PMC_DEVICE_S6 ||
+ dev->sync_mode) {
+ dev->max_msix = 1;
+ dev->vector_cap = dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB;
+ return;
+ }
+
+ msi_count = min(dev->max_msix,
+ (unsigned int)num_online_cpus());
+
+ dev->max_msix = msi_count;
+
+ if (msi_count > AAC_MAX_MSIX)
+ msi_count = AAC_MAX_MSIX;
+
+ for (i = 0; i < msi_count; i++)
+ dev->msixentry[i].entry = i;
+
+ if (msi_count > 1 && pci_find_capability(dev->pdev, PCI_CAP_ID_MSIX)) {
+
+ i = pci_enable_msix(dev->pdev, dev->msixentry, msi_count);
+ /* Check how many MSIX vectors are allocated */
+ if (i >= 0) {
+ dev->msi_enabled = 1;
+ if (i) {
+ msi_count = i;
+ if (pci_enable_msix(dev->pdev, dev->msixentry, msi_count)) {
+ dev->msi_enabled = 0;
+ printk(KERN_ERR "%s%d: MSIX not supported!! Will try MSI 0x%x.\n",
+ dev->name, dev->id, i);
+ }
+ }
+ } else {
+ dev->msi_enabled = 0;
+ printk(KERN_ERR "%s%d: MSIX not supported!! Will try MSI 0x%x.\n",
+ dev->name, dev->id, i);
+ }
+ }
+
+ if (!dev->msi_enabled) {
+ msi_count = 1;
+ i = !pci_enable_msi(dev->pdev);
+
+ if (i) {
+ dev->msi_enabled = 1;
+ dev->msi = 1;
+ } else {
+ printk(KERN_ERR "%s%d: MSI not supported!! Will try INTx 0x%x.\n",
+ dev->name, dev->id, i);
+ }
+ }
+
+ if (!dev->msi_enabled)
+ dev->max_msix = msi_count = 1;
+ else {
+ if (dev->max_msix > msi_count)
+ dev->max_msix = msi_count;
+ }
+ dev->vector_cap = (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB) / msi_count;
+}
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index 090ba68..83c5d3f 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -868,7 +868,7 @@ void aac_printf(struct aac_dev *dev, u32 val)
* dispatches it to the appropriate routine for handling.
*/
-#define AIF_SNIFF_TIMEOUT (30*HZ)
+#define AIF_SNIFF_TIMEOUT (500*HZ)
static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
{
struct hw_fib * hw_fib = fibptr->hw_fib_va;
@@ -1251,7 +1251,7 @@ retry_next:
static int _aac_reset_adapter(struct aac_dev *aac, int forced)
{
int index, quirks;
- int retval;
+ int retval, i;
struct Scsi_Host *host;
struct scsi_device *dev;
struct scsi_cmnd *command;
@@ -1319,7 +1319,20 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced)
aac->comm_phys = 0;
kfree(aac->queues);
aac->queues = NULL;
- free_irq(aac->pdev->irq, aac);
+ if (aac->pdev->device == PMC_DEVICE_S6 ||
+ aac->pdev->device == PMC_DEVICE_S7 ||
+ aac->pdev->device == PMC_DEVICE_S8 ||
+ aac->pdev->device == PMC_DEVICE_S9) {
+ if (aac->max_msix > 1) {
+ for (i = 0; i < aac->max_msix; i++)
+ free_irq(aac->msixentry[i].vector, &(aac->aac_msix[i]));
+ pci_disable_msix(aac->pdev);
+ } else {
+ free_irq(aac->pdev->irq, &(aac->aac_msix[0]));
+ }
+ } else {
+ free_irq(aac->pdev->irq, aac);
+ }
if (aac->msi)
pci_disable_msi(aac->pdev);
kfree(aac->fsa_dev);
diff --git a/drivers/scsi/aacraid/dpcsup.c b/drivers/scsi/aacraid/dpcsup.c
index d81b281..2e39466 100644
--- a/drivers/scsi/aacraid/dpcsup.c
+++ b/drivers/scsi/aacraid/dpcsup.c
@@ -389,8 +389,13 @@ 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 &= FIB_CONTEXT_FLAG_FASTRESP;
- fib->callback(fib->callback_data, fib);
+ if (likely(fib->callback && fib->callback_data)) {
+ fib->flags &= FIB_CONTEXT_FLAG_FASTRESP;
+ fib->callback(fib->callback_data, fib);
+ } else {
+ aac_fib_complete(fib);
+ aac_fib_free(fib);
+ }
} else {
unsigned long flagv;
dprintk((KERN_INFO "event_wait up\n"));
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index fdcdf9f..7813a9b 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -1082,6 +1082,8 @@ static struct scsi_host_template aac_driver_template = {
static void __aac_shutdown(struct aac_dev * aac)
{
+ int i;
+
if (aac->aif_thread) {
int i;
/* Clear out events first */
@@ -1095,9 +1097,23 @@ static void __aac_shutdown(struct aac_dev * aac)
}
aac_send_shutdown(aac);
aac_adapter_disable_int(aac);
- free_irq(aac->pdev->irq, aac);
+ if (aac->pdev->device == PMC_DEVICE_S6 ||
+ aac->pdev->device == PMC_DEVICE_S7 ||
+ aac->pdev->device == PMC_DEVICE_S8 ||
+ aac->pdev->device == PMC_DEVICE_S9) {
+ if (aac->max_msix > 1) {
+ for (i = 0; i < aac->max_msix; i++)
+ free_irq(aac->msixentry[i].vector, &(aac->aac_msix[i]));
+ } else {
+ free_irq(aac->pdev->irq, &(aac->aac_msix[0]));
+ }
+ } else {
+ free_irq(aac->pdev->irq, aac);
+ }
if (aac->msi)
pci_disable_msi(aac->pdev);
+ else if (aac->max_msix > 1)
+ pci_disable_msix(aac->pdev);
}
static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c
index 9c65aed..c010248 100644
--- a/drivers/scsi/aacraid/src.c
+++ b/drivers/scsi/aacraid/src.c
@@ -44,98 +44,124 @@
#include "aacraid.h"
-static irqreturn_t aac_src_intr_message(int irq, void *dev_id)
+static int aac_src_get_sync_status(struct aac_dev *dev);
+
+irqreturn_t aac_src_intr_message(int irq, void *dev_id)
{
- struct aac_dev *dev = dev_id;
+ struct aac_msix_ctx *ctx;
+ struct aac_dev *dev;
unsigned long bellbits, bellbits_shifted;
- int our_interrupt = 0;
- int isFastResponse;
+ int vector_no;
+ int isFastResponse, mode;
u32 index, handle;
- bellbits = src_readl(dev, MUnit.ODR_R);
- if (bellbits & PmDoorBellResponseSent) {
- bellbits = PmDoorBellResponseSent;
- /* handle async. status */
- src_writel(dev, MUnit.ODR_C, bellbits);
- src_readl(dev, MUnit.ODR_C);
- our_interrupt = 1;
- index = dev->host_rrq_idx;
- for (;;) {
- isFastResponse = 0;
- /* remove toggle bit (31) */
- handle = le32_to_cpu(dev->host_rrq[index]) & 0x7fffffff;
- /* check fast response bit (30) */
- if (handle & 0x40000000)
- isFastResponse = 1;
- handle &= 0x0000ffff;
- if (handle == 0)
- break;
-
- aac_intr_normal(dev, handle-1, 0, isFastResponse, NULL);
-
- dev->host_rrq[index++] = 0;
- if (index == dev->scsi_host_ptr->can_queue +
- AAC_NUM_MGT_FIB)
- index = 0;
- dev->host_rrq_idx = index;
+ ctx = (struct aac_msix_ctx *)dev_id;
+ dev = ctx->dev;
+ vector_no = ctx->vector_no;
+
+ if (dev->msi_enabled) {
+ mode = AAC_INT_MODE_MSI;
+ if (vector_no == 0) {
+ bellbits = src_readl(dev, MUnit.ODR_MSI);
+ if (bellbits & 0x40000)
+ mode |= AAC_INT_MODE_AIF;
+ if (bellbits & 0x1000)
+ mode |= AAC_INT_MODE_SYNC;
}
} else {
- bellbits_shifted = (bellbits >> SRC_ODR_SHIFT);
- if (bellbits_shifted & DoorBellAifPending) {
+ mode = AAC_INT_MODE_INTX;
+ bellbits = src_readl(dev, MUnit.ODR_R);
+ if (bellbits & PmDoorBellResponseSent) {
+ bellbits = PmDoorBellResponseSent;
+ src_writel(dev, MUnit.ODR_C, bellbits);
+ src_readl(dev, MUnit.ODR_C);
+ } else {
+ bellbits_shifted = (bellbits >> SRC_ODR_SHIFT);
src_writel(dev, MUnit.ODR_C, bellbits);
src_readl(dev, MUnit.ODR_C);
- our_interrupt = 1;
- /* handle AIF */
- aac_intr_normal(dev, 0, 2, 0, NULL);
- } else if (bellbits_shifted & OUTBOUNDDOORBELL_0) {
- unsigned long sflags;
- struct list_head *entry;
- int send_it = 0;
- extern int aac_sync_mode;
+ if (bellbits_shifted & DoorBellAifPending)
+ mode |= AAC_INT_MODE_AIF;
+ else if (bellbits_shifted & OUTBOUNDDOORBELL_0)
+ mode |= AAC_INT_MODE_SYNC;
+ }
+ }
+
+ if (mode & AAC_INT_MODE_SYNC) {
+ unsigned long sflags;
+ struct list_head *entry;
+ int send_it = 0;
+ extern int aac_sync_mode;
+
+ if (!aac_sync_mode && !dev->msi_enabled) {
src_writel(dev, MUnit.ODR_C, bellbits);
src_readl(dev, MUnit.ODR_C);
+ }
- if (!aac_sync_mode) {
- src_writel(dev, MUnit.ODR_C, bellbits);
- src_readl(dev, MUnit.ODR_C);
- our_interrupt = 1;
+ if (dev->sync_fib) {
+ if (dev->sync_fib->callback)
+ dev->sync_fib->callback(dev->sync_fib->callback_data,
+ dev->sync_fib);
+ spin_lock_irqsave(&dev->sync_fib->event_lock, sflags);
+ if (dev->sync_fib->flags & FIB_CONTEXT_FLAG_WAIT) {
+ dev->management_fib_count--;
+ up(&dev->sync_fib->event_wait);
}
-
- if (dev->sync_fib) {
- our_interrupt = 1;
- if (dev->sync_fib->callback)
- dev->sync_fib->callback(dev->sync_fib->callback_data,
- dev->sync_fib);
- spin_lock_irqsave(&dev->sync_fib->event_lock, sflags);
- if (dev->sync_fib->flags & FIB_CONTEXT_FLAG_WAIT) {
- dev->management_fib_count--;
- up(&dev->sync_fib->event_wait);
- }
- spin_unlock_irqrestore(&dev->sync_fib->event_lock, sflags);
- spin_lock_irqsave(&dev->sync_lock, sflags);
- if (!list_empty(&dev->sync_fib_list)) {
- entry = dev->sync_fib_list.next;
- dev->sync_fib = list_entry(entry, struct fib, fiblink);
- list_del(entry);
- send_it = 1;
- } else {
- dev->sync_fib = NULL;
- }
- spin_unlock_irqrestore(&dev->sync_lock, sflags);
- if (send_it) {
- aac_adapter_sync_cmd(dev, SEND_SYNCHRONOUS_FIB,
- (u32)dev->sync_fib->hw_fib_pa, 0, 0, 0, 0, 0,
- NULL, NULL, NULL, NULL, NULL);
- }
+ spin_unlock_irqrestore(&dev->sync_fib->event_lock, sflags);
+ spin_lock_irqsave(&dev->sync_lock, sflags);
+ if (!list_empty(&dev->sync_fib_list)) {
+ entry = dev->sync_fib_list.next;
+ dev->sync_fib = list_entry(entry, struct fib, fiblink);
+ list_del(entry);
+ send_it = 1;
+ } else {
+ dev->sync_fib = NULL;
+ }
+ spin_unlock_irqrestore(&dev->sync_lock, sflags);
+ if (send_it) {
+ aac_adapter_sync_cmd(dev, SEND_SYNCHRONOUS_FIB,
+ (u32)dev->sync_fib->hw_fib_pa, 0, 0, 0, 0, 0,
+ NULL, NULL, NULL, NULL, NULL);
}
}
+ if (!dev->msi_enabled)
+ mode = 0;
+
}
- if (our_interrupt) {
- return IRQ_HANDLED;
+ if (mode & AAC_INT_MODE_AIF) {
+ /* handle AIF */
+ aac_intr_normal(dev, 0, 2, 0, NULL);
+ if (dev->msi_enabled)
+ aac_src_access_devreg(dev, AAC_CLEAR_AIF_BIT);
+ mode = 0;
}
- return IRQ_NONE;
+
+ if (mode) {
+ index = dev->host_rrq_idx[vector_no];
+
+ for (;;) {
+ isFastResponse = 0;
+ /* remove toggle bit (31) */
+ handle = (dev->host_rrq[index] & 0x7fffffff);
+ /* check fast response bit (30) */
+ if (handle & 0x40000000)
+ isFastResponse = 1;
+ handle &= 0x0000ffff;
+ if (handle == 0)
+ break;
+ if (dev->msi_enabled && dev->max_msix > 1)
+ atomic_dec(&dev->rrq_outstanding[vector_no]);
+ aac_intr_normal(dev, handle-1, 0, isFastResponse, NULL);
+ dev->host_rrq[index++] = 0;
+ if (index == (vector_no + 1) * dev->vector_cap)
+ index = vector_no * dev->vector_cap;
+ dev->host_rrq_idx[vector_no] = index;
+ }
+ mode = 0;
+ }
+
+ return IRQ_HANDLED;
}
/**
@@ -155,7 +181,7 @@ static void aac_src_disable_interrupt(struct aac_dev *dev)
static void aac_src_enable_interrupt_message(struct aac_dev *dev)
{
- src_writel(dev, MUnit.OIMR, dev->OIMR = 0xfffffff8);
+ aac_src_access_devreg(dev, AAC_ENABLE_INTERRUPT);
}
/**
@@ -191,7 +217,8 @@ static int src_sync_cmd(struct aac_dev *dev, u32 command,
/*
* Clear the synch command doorbell to start on a clean slate.
*/
- src_writel(dev, MUnit.ODR_C, OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
+ if (!dev->msi_enabled)
+ src_writel(dev, MUnit.ODR_C, OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
/*
* Disable doorbell interrupts
@@ -221,11 +248,14 @@ static int src_sync_cmd(struct aac_dev *dev, u32 command,
/*
* Mon960 will set doorbell0 bit when it has completed the command.
*/
- if ((src_readl(dev, MUnit.ODR_R) >> SRC_ODR_SHIFT) & OUTBOUNDDOORBELL_0) {
+ if (aac_src_get_sync_status(dev) & OUTBOUNDDOORBELL_0) {
/*
* Clear the doorbell.
*/
- src_writel(dev, MUnit.ODR_C, OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
+ if (dev->msi_enabled)
+ aac_src_access_devreg(dev, AAC_CLEAR_SYNC_BIT);
+ else
+ src_writel(dev, MUnit.ODR_C, OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
ok = 1;
break;
}
@@ -254,11 +284,13 @@ static int src_sync_cmd(struct aac_dev *dev, u32 command,
*r3 = readl(&dev->IndexRegs->Mailbox[3]);
if (r4)
*r4 = readl(&dev->IndexRegs->Mailbox[4]);
-
+ if (command == GET_COMM_PREFERRED_SETTINGS)
+ dev->max_msix = readl(&dev->IndexRegs->Mailbox[5]) & 0xFFFF;
/*
* Clear the synch command doorbell.
*/
- src_writel(dev, MUnit.ODR_C, OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
+ if (!dev->msi_enabled)
+ src_writel(dev, MUnit.ODR_C, OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
}
/*
@@ -335,9 +367,14 @@ static void aac_src_notify_adapter(struct aac_dev *dev, u32 event)
static void aac_src_start_adapter(struct aac_dev *dev)
{
struct aac_init *init;
+ int i;
/* reset host_rrq_idx first */
- dev->host_rrq_idx = 0;
+ for (i = 0; i < dev->max_msix; i++) {
+ dev->host_rrq_idx[i] = i * dev->vector_cap;
+ atomic_set(&dev->rrq_outstanding[i], 0);
+ }
+ dev->fibs_pushed_no = 0;
init = dev->init;
init->HostElapsedSeconds = cpu_to_le32(get_seconds());
@@ -400,6 +437,33 @@ static int aac_src_deliver_message(struct fib *fib)
q->numpending++;
spin_unlock_irqrestore(q->lock, qflags);
+ if (dev->msi_enabled && fib->hw_fib_va->header.Command != AifRequest &&
+ dev->max_msix > 1) {
+ u_int16_t vector_no, first_choice = 0xffff;
+
+ vector_no = dev->fibs_pushed_no % dev->max_msix;
+ do {
+ vector_no += 1;
+ if (vector_no == dev->max_msix)
+ vector_no = 1;
+ if (atomic_read(&dev->rrq_outstanding[vector_no]) <
+ dev->vector_cap)
+ break;
+ if (0xffff == first_choice)
+ first_choice = vector_no;
+ else if (vector_no == first_choice)
+ break;
+ } while (1);
+ if (vector_no == first_choice)
+ vector_no = 0;
+ atomic_inc(&dev->rrq_outstanding[vector_no]);
+ if (dev->fibs_pushed_no == 0xffffffff)
+ dev->fibs_pushed_no = 0;
+ else
+ dev->fibs_pushed_no++;
+ fib->hw_fib_va->header.Handle += (vector_no << 16);
+ }
+
if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE2) {
/* Calculate the amount to the fibsize bits */
fibsize = (hdr_size + 127) / 128 - 1;
@@ -502,10 +566,19 @@ static int aac_src_restart_adapter(struct aac_dev *dev, int bled)
0, 0, 0, 0, 0, 0, &var, &reset_mask, NULL, NULL, NULL);
if (bled || (var != 0x00000001))
return -EINVAL;
+
+ if ((dev->pdev->device == PMC_DEVICE_S7 ||
+ dev->pdev->device == PMC_DEVICE_S8 ||
+ dev->pdev->device == PMC_DEVICE_S9) && dev->msi_enabled) {
+ aac_src_access_devreg(dev, AAC_ENABLE_INTX);
+ dev->msi_enabled = 0;
+ msleep(5000); /* Delay 5 seconds */
+ }
+
if (dev->supplement_adapter_info.SupportedOptions2 &
AAC_OPTION_DOORBELL_RESET) {
src_writel(dev, MUnit.IDR, reset_mask);
- msleep(5000); /* Delay 5 seconds */
+ ssleep(45);
}
}
@@ -646,8 +719,11 @@ int aac_src_init(struct aac_dev *dev)
dev->msi = aac_msi && !pci_enable_msi(dev->pdev);
+ dev->aac_msix[0].vector_no = 0;
+ dev->aac_msix[0].dev = dev;
+
if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr,
- IRQF_SHARED, "aacraid", dev) < 0) {
+ IRQF_SHARED, "aacraid", &(dev->aac_msix[0])) < 0) {
if (dev->msi)
pci_disable_msi(dev->pdev);
@@ -688,6 +764,7 @@ int aac_srcv_init(struct aac_dev *dev)
unsigned long status;
int restart = 0;
int instance = dev->id;
+ int i, j;
const char *name = dev->name;
dev->a_ops.adapter_ioremap = aac_srcv_ioremap;
@@ -802,14 +879,36 @@ int aac_srcv_init(struct aac_dev *dev)
goto error_iounmap;
if (dev->comm_interface != AAC_COMM_MESSAGE_TYPE2)
goto error_iounmap;
- dev->msi = aac_msi && !pci_enable_msi(dev->pdev);
- if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr,
- IRQF_SHARED, "aacraid", dev) < 0) {
- if (dev->msi)
- pci_disable_msi(dev->pdev);
- printk(KERN_ERR "%s%d: Interrupt unavailable.\n",
- name, instance);
- goto error_iounmap;
+ if (dev->msi_enabled)
+ aac_src_access_devreg(dev, AAC_ENABLE_MSIX);
+ if (!dev->sync_mode && dev->msi_enabled && dev->max_msix > 1) {
+ for (i = 0; i < dev->max_msix; i++) {
+ dev->aac_msix[i].vector_no = i;
+ dev->aac_msix[i].dev = dev;
+
+ if (request_irq(dev->msixentry[i].vector, dev->a_ops.adapter_intr,
+ 0, "aacraid", &(dev->aac_msix[i]))) {
+ printk(KERN_ERR "%s%d: Failed to register IRQ for vector %d.\n",
+ name, instance, i);
+ for (j = 0 ; j < i ; j++)
+ free_irq(dev->msixentry[j].vector,
+ &(dev->aac_msix[j]));
+ pci_disable_msix(dev->pdev);
+ goto error_iounmap;
+ }
+ }
+ } else {
+ dev->aac_msix[0].vector_no = 0;
+ dev->aac_msix[0].dev = dev;
+
+ if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr,
+ IRQF_SHARED, "aacraid", &(dev->aac_msix[0])) < 0) {
+ if (dev->msi)
+ pci_disable_msi(dev->pdev);
+ printk(KERN_ERR "%s%d: Interrupt unavailable.\n",
+ name, instance);
+ goto error_iounmap;
+ }
}
dev->dbg_base = dev->base_start;
dev->dbg_base_mapped = dev->base;
@@ -831,3 +930,87 @@ error_iounmap:
return -1;
}
+void aac_src_access_devreg(struct aac_dev *dev, int mode)
+{
+ u_int32_t val;
+
+ switch (mode) {
+ case AAC_ENABLE_INTERRUPT:
+ src_writel(dev, MUnit.OIMR, dev->OIMR = (dev->msi_enabled ? AAC_INT_ENABLE_TYPE1_MSIX :
+ AAC_INT_ENABLE_TYPE1_INTX));
+ break;
+
+ case AAC_DISABLE_INTERRUPT:
+ src_writel(dev, MUnit.OIMR, dev->OIMR = AAC_INT_DISABLE_ALL);
+ break;
+
+ case AAC_ENABLE_MSIX:
+ /* set bit 6 */
+ val = src_readl(dev, MUnit.IDR);
+ val |= 0x40;
+ src_writel(dev, MUnit.IDR, val);
+ src_readl(dev, MUnit.IDR);
+ /* unmask int. */
+ val = PMC_ALL_INTERRUPT_BITS;
+ src_writel(dev, MUnit.IOAR, val);
+ val = src_readl(dev, MUnit.OIMR);
+ src_writel(dev, MUnit.OIMR,
+ val & (~(PMC_GLOBAL_INT_BIT2 | PMC_GLOBAL_INT_BIT0)));
+ break;
+
+ case AAC_DISABLE_MSIX:
+ /* reset bit 6 */
+ val = src_readl(dev, MUnit.IDR);
+ val &= ~0x40;
+ src_writel(dev, MUnit.IDR, val);
+ src_readl(dev, MUnit.IDR);
+ break;
+
+ case AAC_CLEAR_AIF_BIT:
+ /* set bit 5 */
+ val = src_readl(dev, MUnit.IDR);
+ val |= 0x20;
+ src_writel(dev, MUnit.IDR, val);
+ src_readl(dev, MUnit.IDR);
+ break;
+
+ case AAC_CLEAR_SYNC_BIT:
+ /* set bit 4 */
+ val = src_readl(dev, MUnit.IDR);
+ val |= 0x10;
+ src_writel(dev, MUnit.IDR, val);
+ src_readl(dev, MUnit.IDR);
+ break;
+
+ case AAC_ENABLE_INTX:
+ /* set bit 7 */
+ val = src_readl(dev, MUnit.IDR);
+ val |= 0x80;
+ src_writel(dev, MUnit.IDR, val);
+ src_readl(dev, MUnit.IDR);
+ /* unmask int. */
+ val = PMC_ALL_INTERRUPT_BITS;
+ src_writel(dev, MUnit.IOAR, val);
+ src_readl(dev, MUnit.IOAR);
+ val = src_readl(dev, MUnit.OIMR);
+ src_writel(dev, MUnit.OIMR,
+ val & (~(PMC_GLOBAL_INT_BIT2)));
+ break;
+
+ default:
+ break;
+ }
+}
+
+static int aac_src_get_sync_status(struct aac_dev *dev)
+{
+
+ int val;
+
+ if (dev->msi_enabled)
+ val = src_readl(dev, MUnit.ODR_MSI) & 0x1000 ? 1 : 0;
+ else
+ val = src_readl(dev, MUnit.ODR_R) >> SRC_ODR_SHIFT;
+
+ return val;
+}
--
1.7.7.3
^ permalink raw reply related [flat|nested] 32+ messages in thread
* RE: [PATCH 5/7] aacraid: vpd page code 0x83 support
2015-03-04 8:38 ` [PATCH 5/7] aacraid: vpd page code 0x83 support Mahesh Rajashekhara
@ 2015-03-17 7:06 ` Murthy Bhat
2015-03-17 15:27 ` Achim Leubner
1 sibling, 0 replies; 32+ messages in thread
From: Murthy Bhat @ 2015-03-17 7:06 UTC (permalink / raw)
To: Mahesh Rajashekhara, JBottomley, linux-scsi
Cc: aacraid, Harry Yang, Achim Leubner, Rajinikanth Pandurangan, Rich Bono
Reviewed-by: Murthy Bhat <Murthy.Bhat@pmcs.com>
-----Original Message-----
From: Mahesh Rajashekhara
Sent: Wednesday, March 04, 2015 2:09 PM
To: JBottomley@Parallels.com; linux-scsi@vger.kernel.org
Cc: aacraid@pmc-sierra.com; Harry Yang; Achim Leubner; Rajinikanth Pandurangan; Rich Bono; Mahesh Rajashekhara
Subject: [PATCH 5/7] aacraid: vpd page code 0x83 support
Add vpd page code 0x83 support
Signed-off-by: Mahesh Rajashekhara <Mahesh.Rajashekhara@pmcs.com>
---
drivers/scsi/aacraid/aachba.c | 154 ++++++++++++++++++++++++++++++++++++---
drivers/scsi/aacraid/aacraid.h | 4 +
drivers/scsi/aacraid/comminit.c | 8 ++-
drivers/scsi/aacraid/commsup.c | 12 +---
drivers/scsi/aacraid/linit.c | 20 +----
drivers/scsi/aacraid/src.c | 34 +++++++--
6 files changed, 185 insertions(+), 47 deletions(-)
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index eb524e6..3e4e0c8 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -163,6 +163,45 @@ struct inquiry_data {
u8 inqd_prl[4]; /* Product Revision Level */
};
+/* Added for VPD 0x83 */
+typedef struct {
+ u8 CodeSet:4; /* VPD_CODE_SET */
+ u8 Reserved:4;
+ u8 IdentifierType:4; /* VPD_IDENTIFIER_TYPE */
+ u8 Reserved2:4;
+ u8 Reserved3;
+ u8 IdentifierLength;
+ u8 VendId[8];
+ u8 ProductId[16];
+ u8 SerialNumber[8]; /* SN in ASCII */
+} TVPD_ID_Descriptor_Type_1;
+
+typedef struct {
+ u8 CodeSet:4; /* VPD_CODE_SET */
+ u8 Reserved:4;
+ u8 IdentifierType:4; /* VPD_IDENTIFIER_TYPE */
+ u8 Reserved2:4;
+ u8 Reserved3;
+ u8 IdentifierLength;
+ struct TEU64Id {
+ u32 Serial;
+ /* The serial number supposed to be 40 bits,
+ * bit we only support 32, so make the last byte zero. */
+ u8 Reserved;
+ u8 VendId[3];
+ } EU64Id;
+} TVPD_ID_Descriptor_Type_2;
+
+typedef struct {
+ u8 DeviceType:5;
+ u8 DeviceTypeQualifier:3;
+ u8 PageCode;
+ u8 Reserved;
+ u8 PageLength;
+ TVPD_ID_Descriptor_Type_1 IdDescriptorType1;
+ TVPD_ID_Descriptor_Type_2 IdDescriptorType2;
+} TVPD_Page83;
+
/*
* M O D U L E G L O B A L S
*/
@@ -420,6 +459,9 @@ int aac_get_containers(struct aac_dev *dev)
if (status >= 0) {
dresp = (struct aac_get_container_count_resp *)fib_data(fibptr);
maximum_num_containers = le32_to_cpu(dresp->ContainerSwitchEntries);
+ if (fibptr->dev->supplement_adapter_info.SupportedOptions2 &
+ AAC_OPTION_SUPPORTED_240_VOLUMES)
+ maximum_num_containers = le32_to_cpu(dresp->MaxSimpleVolumes);
aac_fib_complete(fibptr);
}
/* FIB should be freed only after getting the response from the F/W */
@@ -889,14 +931,81 @@ static void get_container_serial_callback(void *context, struct fib * fibptr)
get_serial_reply = (struct aac_get_serial_resp *) fib_data(fibptr);
/* Failure is irrelevant, using default value instead */
if (le32_to_cpu(get_serial_reply->status) == CT_OK) {
- char sp[13];
- /* EVPD bit set */
- sp[0] = INQD_PDT_DA;
- sp[1] = scsicmd->cmnd[2];
- sp[2] = 0;
- sp[3] = snprintf(sp+4, sizeof(sp)-4, "%08X",
- le32_to_cpu(get_serial_reply->uid));
- scsi_sg_copy_from_buffer(scsicmd, sp, sizeof(sp));
+ /*Check to see if it's for VPD 0x83 or 0x80 */
+ if (scsicmd->cmnd[2] == 0x83) {
+ /* vpd page 0x83 - Device Identification Page */
+ int i;
+ TVPD_Page83 VPDPage83Data;
+
+ memset(((u8 *)&VPDPage83Data), 0,
+ sizeof(VPDPage83Data));
+
+ /* DIRECT_ACCESS_DEVIC */
+ VPDPage83Data.DeviceType = 0;
+ /* DEVICE_CONNECTED */
+ VPDPage83Data.DeviceTypeQualifier = 0;
+ /* VPD_DEVICE_IDENTIFIERS */
+ VPDPage83Data.PageCode = 0x83;
+ VPDPage83Data.Reserved = 0;
+ VPDPage83Data.PageLength = sizeof(VPDPage83Data.IdDescriptorType1) +
+ sizeof(VPDPage83Data.IdDescriptorType2);
+
+ /* T10 Vendor Identifier Field Format */
+ /* VpdCodeSetAscii */
+ VPDPage83Data.IdDescriptorType1.CodeSet = 2;
+ /* VpdIdentifierTypeVendorId */
+ VPDPage83Data.IdDescriptorType1.IdentifierType = 1;
+ VPDPage83Data.IdDescriptorType1.IdentifierLength = sizeof(VPDPage83Data.IdDescriptorType1) - 4;
+
+ /* "ADAPTEC " for adaptec */
+ memcpy(VPDPage83Data.IdDescriptorType1.VendId, "ADAPTEC ",
+ sizeof(VPDPage83Data.IdDescriptorType1.VendId));
+ memcpy(VPDPage83Data.IdDescriptorType1.ProductId, "ARRAY ",
+ sizeof(VPDPage83Data.IdDescriptorType1.ProductId));
+
+ /* Convert to ascii based serial number.
+ * The LSB is the the end.
+ */
+ for (i = 0; i < 8; i++) {
+ u8 temp = (u8)((get_serial_reply->uid >> ((7 - i) * 4)) & 0xF);
+ if (temp > 0x9) {
+ VPDPage83Data.IdDescriptorType1.SerialNumber[i] = 'A' + (temp - 0xA);
+ } else {
+ VPDPage83Data.IdDescriptorType1.SerialNumber[i] = '0' + temp;
+ }
+ }
+
+ /* EUI-64 Vendor Identifier Field Format,
+ * 24 bits for VendId and 40 bits for SN.
+ */
+ /* VpdCodeSetBinary */
+ VPDPage83Data.IdDescriptorType2.CodeSet = 1;
+ /* VpdIdentifierTypeEUI64 */
+ VPDPage83Data.IdDescriptorType2.IdentifierType = 2;
+ VPDPage83Data.IdDescriptorType2.IdentifierLength = sizeof(VPDPage83Data.IdDescriptorType2) - 4;
+
+ /* 0x0000055 for IBM, 0x0000D0 for Adaptec */
+ VPDPage83Data.IdDescriptorType2.EU64Id.VendId[0] = 0xD0;
+ VPDPage83Data.IdDescriptorType2.EU64Id.VendId[1] = 0;
+ VPDPage83Data.IdDescriptorType2.EU64Id.VendId[2] = 0;
+
+ VPDPage83Data.IdDescriptorType2.EU64Id.Serial = get_serial_reply->uid;
+ VPDPage83Data.IdDescriptorType2.EU64Id.Reserved = 0;
+
+ /* Move the inquiry data to the response buffer. */
+ scsi_sg_copy_from_buffer(scsicmd, &VPDPage83Data,
+ sizeof(VPDPage83Data));
+ } else {
+ /* It must be for VPD 0x80 */
+ char sp[13];
+ /* EVPD bit set */
+ sp[0] = INQD_PDT_DA;
+ sp[1] = scsicmd->cmnd[2];
+ sp[2] = 0;
+ sp[3] = snprintf(sp+4, sizeof(sp)-4, "%08X",
+ le32_to_cpu(get_serial_reply->uid));
+ scsi_sg_copy_from_buffer(scsicmd, sp, sizeof(sp));
+ }
}
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
@@ -2302,9 +2411,10 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
INQD_PDT_PROC : INQD_PDT_DA;
if (scsicmd->cmnd[2] == 0) {
/* supported vital product data pages */
- arr[3] = 2;
+ arr[3] = 3;
arr[4] = 0x0;
arr[5] = 0x80;
+ arr[6] = 0x83;
arr[1] = scsicmd->cmnd[2];
scsi_sg_copy_from_buffer(scsicmd, &inq_data,
sizeof(inq_data));
@@ -2323,6 +2433,16 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
/* SLES 10 SP1 special */
scsicmd->result = DID_OK << 16 |
COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
+ } else if (scsicmd->cmnd[2] == 0x83) {
+ /* vpd page 0x83 - Device Identification Page */
+ char *sno = (char *)&inq_data;
+ sno[3] = setinqserial(dev, &sno[4],
+ scmd_id(scsicmd));
+ if (aac_wwn != 2)
+ return aac_get_container_serial(
+ scsicmd);
+ scsicmd->result = DID_OK << 16 |
+ COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
} else {
/* vpd page not implemented */
scsicmd->result = DID_OK << 16 |
@@ -2468,6 +2588,15 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
mpd.bd.block_length[0] = (fsa_dev_ptr[cid].block_size >> 16) & 0xff;
mpd.bd.block_length[1] = (fsa_dev_ptr[cid].block_size >> 8) & 0xff;
mpd.bd.block_length[2] = fsa_dev_ptr[cid].block_size & 0xff;
+
+ mpd.mpc_buf[0] = scsicmd->cmnd[2];
+ if (scsicmd->cmnd[2] == 0x1C) {
+ mpd.mpc_buf[1] = 0xa; /* page length */
+ mpd.hd.data_length = 23; /* Mode data length */
+ } else {
+ mpd.hd.data_length = 15; /* Mode data length */
+ }
+
if (capacity > 0xffffff) {
mpd.bd.block_count[0] = 0xff;
mpd.bd.block_count[1] = 0xff;
@@ -2486,9 +2615,12 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
mpd.mpc_buf[2] = ((aac_cache & 6) == 2)
? 0 : 0x04; /* WCE */
mode_buf_length = sizeof(mpd);
- if (mode_buf_length > scsicmd->cmnd[4])
- mode_buf_length = scsicmd->cmnd[4];
}
+
+ if (mode_buf_length > scsicmd->cmnd[4])
+ mode_buf_length = scsicmd->cmnd[4];
+ else
+ mode_buf_length = sizeof(mpd);
scsi_sg_copy_from_buffer(scsicmd, (char *)&mpd, mode_buf_length);
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
scsicmd->scsi_done(scsicmd);
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index c162a65..a37762e 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -1015,6 +1015,7 @@ struct aac_supplement_adapter_info
#define AAC_OPTION_POWER_MANAGEMENT cpu_to_le32(0x00000004)
#define AAC_OPTION_DOORBELL_RESET cpu_to_le32(0x00004000)
#define AAC_OPTION_VARIABLE_BLOCK_SIZE cpu_to_le32(0x00040000) /* 4KB sector size */
+#define AAC_OPTION_SUPPORTED_240_VOLUMES cpu_to_le32(0x10000000)
#define AAC_SIS_VERSION_V3 3
#define AAC_SIS_SLOT_UNKNOWN 0xFF
@@ -1212,11 +1213,13 @@ struct aac_dev
int sync_mode;
struct fib *sync_fib;
struct list_head sync_fib_list;
+ u32 doorbell_mask; /* from GET_ADAPTER_PROP */
u32 max_msix; /* max. MSI-X vectors */
u32 vector_cap; /* MSI-X vector capab.*/
int msi_enabled; /* MSI/MSI-X enabled */
struct msix_entry msixentry[AAC_MAX_MSIX];
struct aac_msix_ctx aac_msix[AAC_MAX_MSIX]; /* context */
+ u8 adapter_shutdown;
};
#define aac_adapter_interrupt(dev) \
@@ -1749,6 +1752,7 @@ struct aac_get_container_count_resp {
__le32 MaxContainers;
__le32 ContainerSwitchEntries;
__le32 MaxPartitions;
+ __le32 MaxSimpleVolumes;
};
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c
index 29c35c8..c3e13ae 100644
--- a/drivers/scsi/aacraid/comminit.c
+++ b/drivers/scsi/aacraid/comminit.c
@@ -53,7 +53,7 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
{
unsigned char *base;
unsigned long size, align;
- const unsigned long fibsize = 4096;
+ const unsigned long fibsize = dev->max_fib_size;
const unsigned long printfbufsiz = 256;
unsigned long host_rrq_size = 0;
struct aac_init *init;
@@ -230,6 +230,7 @@ int aac_send_shutdown(struct aac_dev * dev)
/* FIB should be freed only after getting the response from the F/W */
if (status != -ERESTARTSYS)
aac_fib_free(fibctx);
+ dev->adapter_shutdown = 1;
if ((dev->pdev->device == PMC_DEVICE_S7 ||
dev->pdev->device == PMC_DEVICE_S8 ||
dev->pdev->device == PMC_DEVICE_S9) &&
@@ -357,8 +358,9 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
dev->raw_io_interface = dev->raw_io_64 = 0;
if ((!aac_adapter_sync_cmd(dev, GET_ADAPTER_PROPERTIES,
- 0, 0, 0, 0, 0, 0, status+0, status+1, status+2, NULL, NULL)) &&
+ 0, 0, 0, 0, 0, 0, status+0, status+1, status+2, status+3, NULL)) &&
(status[0] == 0x00000001)) {
+ dev->doorbell_mask = status[3];
if (status[1] & le32_to_cpu(AAC_OPT_NEW_COMM_64))
dev->raw_io_64 = 1;
dev->sync_mode = aac_sync_mode;
@@ -397,6 +399,7 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
}
dev->max_msix = 0;
dev->msi_enabled = 0;
+ dev->adapter_shutdown = 0;
if ((!aac_adapter_sync_cmd(dev, GET_COMM_PREFERRED_SETTINGS,
0, 0, 0, 0, 0, 0,
status+0, status+1, status+2, status+3, status+4))
@@ -508,6 +511,7 @@ static void aac_define_int_mode(struct aac_dev *dev)
int i, msi_count;
+ msi_count = i = 0;
/* max. vectors from GET_COMM_PREFERRED_SETTINGS */
if (dev->max_msix == 0 ||
dev->pdev->device == PMC_DEVICE_S6 ||
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index 83c5d3f..2bed445 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -208,14 +208,11 @@ struct fib *aac_fib_alloc(struct aac_dev *dev)
void aac_fib_free(struct fib *fibptr)
{
- unsigned long flags, flagsv;
+ unsigned long flags;
- spin_lock_irqsave(&fibptr->event_lock, flagsv);
if (fibptr->done == 2) {
- spin_unlock_irqrestore(&fibptr->event_lock, flagsv);
return;
}
- spin_unlock_irqrestore(&fibptr->event_lock, flagsv);
spin_lock_irqsave(&fibptr->dev->fib_lock, flags);
if (unlikely(fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT))
@@ -775,7 +772,6 @@ int aac_fib_adapter_complete(struct fib *fibptr, unsigned short size)
int aac_fib_complete(struct fib *fibptr)
{
- unsigned long flags;
struct hw_fib * hw_fib = fibptr->hw_fib_va;
/*
@@ -798,12 +794,6 @@ int aac_fib_complete(struct fib *fibptr)
* command is complete that we had sent to the adapter and this
* cdb could be reused.
*/
- spin_lock_irqsave(&fibptr->event_lock, flags);
- if (fibptr->done == 2) {
- spin_unlock_irqrestore(&fibptr->event_lock, flags);
- return 0;
- }
- spin_unlock_irqrestore(&fibptr->event_lock, flags);
if((hw_fib->header.XferState & cpu_to_le32(SentFromHost)) &&
(hw_fib->header.XferState & cpu_to_le32(AdapterProcessed)))
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 7813a9b..4c5ba9e 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -56,7 +56,7 @@
#include "aacraid.h"
-#define AAC_DRIVER_VERSION "1.2-0"
+#define AAC_DRIVER_VERSION "1.2-1"
#ifndef AAC_DRIVER_BRANCH
#define AAC_DRIVER_BRANCH ""
#endif
@@ -65,7 +65,7 @@
#ifdef AAC_DRIVER_BUILD
#define _str(x) #x
#define str(x) _str(x)
-#define AAC_DRIVER_FULL_VERSION AAC_DRIVER_VERSION "[" str(AAC_DRIVER_BUILD) "]" AAC_DRIVER_BRANCH
+#define AAC_DRIVER_FULL_VERSION AAC_DRIVER_VERSION "." str(AAC_DRIVER_BUILD) "" AAC_DRIVER_BRANCH
#else
#define AAC_DRIVER_FULL_VERSION AAC_DRIVER_VERSION AAC_DRIVER_BRANCH
#endif
@@ -253,19 +253,7 @@ static struct aac_driver_ident aac_drivers[] = {
static int aac_queuecommand_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
{
- struct Scsi_Host *host = cmd->device->host;
- struct aac_dev *dev = (struct aac_dev *)host->hostdata;
- u32 count = 0;
cmd->scsi_done = done;
- for (; count < (host->can_queue + AAC_NUM_MGT_FIB); ++count) {
- struct fib * fib = &dev->fibs[count];
- struct scsi_cmnd * command;
- if (fib->hw_fib_va->header.XferState &&
- ((command = fib->callback_data)) &&
- (command == cmd) &&
- (cmd->SCp.phase == AAC_OWNER_FIRMWARE))
- return 0; /* Already owned by Adapter */
- }
cmd->SCp.phase = AAC_OWNER_LOWLEVEL;
return (aac_scsi_cmd(cmd) ? FAILED : 0);
}
@@ -713,7 +701,9 @@ static long aac_cfg_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
{
int ret;
- if (!capable(CAP_SYS_RAWIO))
+ struct aac_dev *aac;
+ aac = (struct aac_dev *)file->private_data;
+ if (!capable(CAP_SYS_RAWIO) || aac->adapter_shutdown)
return -EPERM;
mutex_lock(&aac_mutex);
ret = aac_do_ioctl(file->private_data, cmd, (void __user *)arg);
diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c
index c010248..82ff025 100644
--- a/drivers/scsi/aacraid/src.c
+++ b/drivers/scsi/aacraid/src.c
@@ -200,6 +200,7 @@ static int src_sync_cmd(struct aac_dev *dev, u32 command,
u32 *status, u32 * r1, u32 * r2, u32 * r3, u32 * r4)
{
unsigned long start;
+ unsigned long delay;
int ok;
/*
@@ -240,10 +241,15 @@ static int src_sync_cmd(struct aac_dev *dev, u32 command,
ok = 0;
start = jiffies;
- /*
- * Wait up to 5 minutes
- */
- while (time_before(jiffies, start+300*HZ)) {
+ if (command == IOP_RESET_ALWAYS) {
+ /* Wait up to 10 sec */
+ delay = 10*HZ;
+ } else {
+ /* Wait up to 5 minutes */
+ delay = 300*HZ;
+ }
+ while (time_before(jiffies, start+delay)) {
+
udelay(5); /* Delay 5 microseconds to let Mon960 get info. */
/*
* Mon960 will set doorbell0 bit when it has completed the command.
@@ -562,10 +568,16 @@ static int aac_src_restart_adapter(struct aac_dev *dev, int bled)
if (bled)
printk(KERN_ERR "%s%d: adapter kernel panic'd %x.\n",
dev->name, dev->id, bled);
+ dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
bled = aac_adapter_sync_cmd(dev, IOP_RESET_ALWAYS,
0, 0, 0, 0, 0, 0, &var, &reset_mask, NULL, NULL, NULL);
- if (bled || (var != 0x00000001))
+ if ((bled || (var != 0x00000001)) && !dev->doorbell_mask)
return -EINVAL;
+ else if (dev->doorbell_mask) {
+ reset_mask = dev->doorbell_mask;
+ bled = 0;
+ var = 0x00000001;
+ }
if ((dev->pdev->device == PMC_DEVICE_S7 ||
dev->pdev->device == PMC_DEVICE_S8 ||
@@ -575,10 +587,13 @@ static int aac_src_restart_adapter(struct aac_dev *dev, int bled)
msleep(5000); /* Delay 5 seconds */
}
- if (dev->supplement_adapter_info.SupportedOptions2 &
- AAC_OPTION_DOORBELL_RESET) {
+ if (!bled && (dev->supplement_adapter_info.SupportedOptions2 &
+ AAC_OPTION_DOORBELL_RESET)) {
src_writel(dev, MUnit.IDR, reset_mask);
ssleep(45);
+ } else {
+ src_writel(dev, MUnit.IDR, 0x100);
+ ssleep(45);
}
}
@@ -600,7 +615,6 @@ int aac_src_select_comm(struct aac_dev *dev, int comm)
{
switch (comm) {
case AAC_COMM_MESSAGE:
- dev->a_ops.adapter_enable_int = aac_src_enable_interrupt_message;
dev->a_ops.adapter_intr = aac_src_intr_message;
dev->a_ops.adapter_deliver = aac_src_deliver_message;
break;
@@ -698,6 +712,7 @@ int aac_src_init(struct aac_dev *dev)
*/
dev->a_ops.adapter_interrupt = aac_src_interrupt_adapter;
dev->a_ops.adapter_disable_int = aac_src_disable_interrupt;
+ dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
dev->a_ops.adapter_notify = aac_src_notify_adapter;
dev->a_ops.adapter_sync_cmd = src_sync_cmd;
dev->a_ops.adapter_check_health = aac_src_check_health;
@@ -735,6 +750,7 @@ int aac_src_init(struct aac_dev *dev)
dev->dbg_base = pci_resource_start(dev->pdev, 2);
dev->dbg_base_mapped = dev->regs.src.bar1;
dev->dbg_size = AAC_MIN_SRC_BAR1_SIZE;
+ dev->a_ops.adapter_enable_int = aac_src_enable_interrupt_message;
aac_adapter_enable_int(dev);
@@ -861,6 +877,7 @@ int aac_srcv_init(struct aac_dev *dev)
*/
dev->a_ops.adapter_interrupt = aac_src_interrupt_adapter;
dev->a_ops.adapter_disable_int = aac_src_disable_interrupt;
+ dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
dev->a_ops.adapter_notify = aac_src_notify_adapter;
dev->a_ops.adapter_sync_cmd = src_sync_cmd;
dev->a_ops.adapter_check_health = aac_src_check_health;
@@ -913,6 +930,7 @@ int aac_srcv_init(struct aac_dev *dev)
dev->dbg_base = dev->base_start;
dev->dbg_base_mapped = dev->base;
dev->dbg_size = dev->base_size;
+ dev->a_ops.adapter_enable_int = aac_src_enable_interrupt_message;
aac_adapter_enable_int(dev);
--
1.7.7.3
^ permalink raw reply related [flat|nested] 32+ messages in thread
* RE: [PATCH 6/7] aacraid: performance improvement changes
2015-03-04 8:38 ` [PATCH 6/7] aacraid: performance improvement changes Mahesh Rajashekhara
@ 2015-03-17 7:07 ` Murthy Bhat
2015-03-17 15:27 ` Achim Leubner
1 sibling, 0 replies; 32+ messages in thread
From: Murthy Bhat @ 2015-03-17 7:07 UTC (permalink / raw)
To: Mahesh Rajashekhara, JBottomley, linux-scsi
Cc: aacraid, Harry Yang, Achim Leubner, Rajinikanth Pandurangan, Rich Bono
Reviewed-by: Murthy Bhat <Murthy.Bhat@pmcs.com>
-----Original Message-----
From: Mahesh Rajashekhara
Sent: Wednesday, March 04, 2015 2:09 PM
To: JBottomley@Parallels.com; linux-scsi@vger.kernel.org
Cc: aacraid@pmc-sierra.com; Harry Yang; Achim Leubner; Rajinikanth Pandurangan; Rich Bono; Mahesh Rajashekhara
Subject: [PATCH 6/7] aacraid: performance improvement changes
Add performance improvement changes.
Signed-off-by: Mahesh Rajashekhara <Mahesh.Rajashekhara@pmcs.com>
---
drivers/scsi/aacraid/aacraid.h | 6 +++---
drivers/scsi/aacraid/comminit.c | 12 +++++++++++-
drivers/scsi/aacraid/commsup.c | 7 ++-----
drivers/scsi/aacraid/dpcsup.c | 4 ++--
drivers/scsi/aacraid/linit.c | 10 ++++------
drivers/scsi/aacraid/rx.c | 14 +++-----------
drivers/scsi/aacraid/src.c | 5 +----
7 files changed, 26 insertions(+), 32 deletions(-)
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index a37762e..74a0440 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -12,7 +12,7 @@
* D E F I N E S
*----------------------------------------------------------------------------*/
-#define AAC_MAX_MSIX 32 /* vectors */
+#define AAC_MAX_MSIX 8 /* vectors */
#define AAC_PCI_MSI_ENABLE 0x8000
enum {
@@ -62,7 +62,7 @@ enum {
#define PMC_GLOBAL_INT_BIT0 0x00000001
#ifndef AAC_DRIVER_BUILD
-# define AAC_DRIVER_BUILD 30300
+# define AAC_DRIVER_BUILD 40709
# define AAC_DRIVER_BRANCH "-ms"
#endif
#define MAXIMUM_NUM_CONTAINERS 32
@@ -633,7 +633,7 @@ struct aac_queue {
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. */
- u32 numpending; /* Number of entries on outstanding queue. */
+ atomic_t numpending; /* Number of entries on outstanding queue. */
struct aac_dev * dev; /* Back pointer to adapter structure */
};
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c
index c3e13ae..c16043e 100644
--- a/drivers/scsi/aacraid/comminit.c
+++ b/drivers/scsi/aacraid/comminit.c
@@ -181,7 +181,7 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
static void aac_queue_init(struct aac_dev * dev, struct aac_queue * q, u32 *mem, int qsize)
{
- q->numpending = 0;
+ atomic_set(&q->numpending, 0);
q->dev = dev;
init_waitqueue_head(&q->cmdready);
INIT_LIST_HEAD(&q->cmdq);
@@ -510,6 +510,7 @@ static void aac_define_int_mode(struct aac_dev *dev)
{
int i, msi_count;
+ int cpu;
msi_count = i = 0;
/* max. vectors from GET_COMM_PREFERRED_SETTINGS */
@@ -571,6 +572,15 @@ static void aac_define_int_mode(struct aac_dev *dev)
else {
if (dev->max_msix > msi_count)
dev->max_msix = msi_count;
+
+ /* Added to set IRQ affinity */
+ cpu = cpumask_first(cpu_online_mask);
+ cpu = cpumask_next(cpu, cpu_online_mask);
+
+ for (i = 0; i < dev->max_msix; i++) {
+ irq_set_affinity_hint(dev->msixentry[i].vector, get_cpu_mask(cpu));
+ cpu = cpumask_next(cpu, cpu_online_mask);
+ }
}
dev->vector_cap = (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB) / msi_count;
}
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index 2bed445..0555023 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -318,7 +318,7 @@ static int aac_get_entry (struct aac_dev * dev, u32 qid, struct aac_entry **entr
/* Queue is full */
if ((*index + 1) == le32_to_cpu(*(q->headers.consumer))) {
printk(KERN_WARNING "Queue %d full, %u outstanding.\n",
- qid, q->numpending);
+ qid, atomic_read(&q->numpending));
return 0;
} else {
*entry = q->base + *index;
@@ -411,7 +411,6 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
struct aac_dev * dev = fibptr->dev;
struct hw_fib * hw_fib = fibptr->hw_fib_va;
unsigned long flags = 0;
- unsigned long qflags;
unsigned long mflags = 0;
unsigned long sflags = 0;
@@ -565,9 +564,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
int blink;
if (time_is_before_eq_jiffies(timeout)) {
struct aac_queue * q = &dev->queues->queue[AdapNormCmdQueue];
- spin_lock_irqsave(q->lock, qflags);
- q->numpending--;
- spin_unlock_irqrestore(q->lock, qflags);
+ atomic_dec(&q->numpending);
if (wait == -1) {
printk(KERN_ERR "aacraid: aac_fib_send: first asynchronous command timed out.\n"
"Usually a result of a PCI interrupt routing problem;\n"
diff --git a/drivers/scsi/aacraid/dpcsup.c b/drivers/scsi/aacraid/dpcsup.c
index 2e39466..da9d993 100644
--- a/drivers/scsi/aacraid/dpcsup.c
+++ b/drivers/scsi/aacraid/dpcsup.c
@@ -84,7 +84,7 @@ unsigned int aac_response_normal(struct aac_queue * q)
* continue. The caller has already been notified that
* the fib timed out.
*/
- dev->queues->queue[AdapNormCmdQueue].numpending--;
+ atomic_dec(&dev->queues->queue[AdapNormCmdQueue].numpending);
if (unlikely(fib->flags & FIB_CONTEXT_FLAG_TIMED_OUT)) {
spin_unlock_irqrestore(q->lock, flags);
@@ -354,7 +354,7 @@ unsigned int aac_intr_normal(struct aac_dev *dev, u32 index,
* continue. The caller has already been notified that
* the fib timed out.
*/
- dev->queues->queue[AdapNormCmdQueue].numpending--;
+ atomic_dec(&dev->queues->queue[AdapNormCmdQueue].numpending);
if (unlikely(fib->flags & FIB_CONTEXT_FLAG_TIMED_OUT)) {
aac_fib_complete(fib);
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 4c5ba9e..e0f9f81 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -250,16 +250,14 @@ static struct aac_driver_ident aac_drivers[] = {
*
* TODO: unify with aac_scsi_cmd().
*/
-
-static int aac_queuecommand_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
+static int aac_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
{
- cmd->scsi_done = done;
+ int r = 0;
cmd->SCp.phase = AAC_OWNER_LOWLEVEL;
- return (aac_scsi_cmd(cmd) ? FAILED : 0);
+ r = (aac_scsi_cmd(cmd) ? FAILED : 0);
+ return r;
}
-static DEF_SCSI_QCMD(aac_queuecommand)
-
/**
* aac_info - Returns the host adapter name
* @shost: Scsi host to report on
diff --git a/drivers/scsi/aacraid/rx.c b/drivers/scsi/aacraid/rx.c
index 5c6a870..9570612 100644
--- a/drivers/scsi/aacraid/rx.c
+++ b/drivers/scsi/aacraid/rx.c
@@ -400,16 +400,13 @@ int aac_rx_deliver_producer(struct fib * fib)
{
struct aac_dev *dev = fib->dev;
struct aac_queue *q = &dev->queues->queue[AdapNormCmdQueue];
- unsigned long qflags;
u32 Index;
unsigned long nointr = 0;
- spin_lock_irqsave(q->lock, qflags);
aac_queue_get( dev, &Index, AdapNormCmdQueue, fib->hw_fib_va, 1, fib, &nointr);
- q->numpending++;
+ atomic_inc(&q->numpending);
*(q->headers.producer) = cpu_to_le32(Index + 1);
- spin_unlock_irqrestore(q->lock, qflags);
if (!(nointr & aac_config.irq_mod))
aac_adapter_notify(dev, AdapNormCmdQueue);
@@ -426,15 +423,12 @@ static int aac_rx_deliver_message(struct fib * fib)
{
struct aac_dev *dev = fib->dev;
struct aac_queue *q = &dev->queues->queue[AdapNormCmdQueue];
- unsigned long qflags;
u32 Index;
u64 addr;
volatile void __iomem *device;
unsigned long count = 10000000L; /* 50 seconds */
- spin_lock_irqsave(q->lock, qflags);
- q->numpending++;
- spin_unlock_irqrestore(q->lock, qflags);
+ atomic_inc(&q->numpending);
for(;;) {
Index = rx_readl(dev, MUnit.InboundQueue);
if (unlikely(Index == 0xFFFFFFFFL))
@@ -442,9 +436,7 @@ static int aac_rx_deliver_message(struct fib * fib)
if (likely(Index != 0xFFFFFFFFL))
break;
if (--count == 0) {
- spin_lock_irqsave(q->lock, qflags);
- q->numpending--;
- spin_unlock_irqrestore(q->lock, qflags);
+ atomic_dec(&q->numpending);
return -ETIMEDOUT;
}
udelay(5);
diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c
index 82ff025..bde26a2 100644
--- a/drivers/scsi/aacraid/src.c
+++ b/drivers/scsi/aacraid/src.c
@@ -433,15 +433,12 @@ static int aac_src_deliver_message(struct fib *fib)
{
struct aac_dev *dev = fib->dev;
struct aac_queue *q = &dev->queues->queue[AdapNormCmdQueue];
- unsigned long qflags;
u32 fibsize;
dma_addr_t address;
struct aac_fib_xporthdr *pFibX;
u16 hdr_size = le16_to_cpu(fib->hw_fib_va->header.Size);
- spin_lock_irqsave(q->lock, qflags);
- q->numpending++;
- spin_unlock_irqrestore(q->lock, qflags);
+ atomic_inc(&q->numpending);
if (dev->msi_enabled && fib->hw_fib_va->header.Command != AifRequest &&
dev->max_msix > 1) {
--
1.7.7.3
^ permalink raw reply related [flat|nested] 32+ messages in thread
* RE: [PATCH 7/7] aacraid: AIF raw device remove support
2015-03-04 8:38 ` [PATCH 7/7] aacraid: AIF raw device remove support Mahesh Rajashekhara
@ 2015-03-17 7:07 ` Murthy Bhat
2015-03-17 15:28 ` Achim Leubner
1 sibling, 0 replies; 32+ messages in thread
From: Murthy Bhat @ 2015-03-17 7:07 UTC (permalink / raw)
To: Mahesh Rajashekhara, JBottomley, linux-scsi
Cc: aacraid, Harry Yang, Achim Leubner, Rajinikanth Pandurangan, Rich Bono
Reviewed-by: Murthy Bhat <Murthy.Bhat@pmcs.com>
-----Original Message-----
From: Mahesh Rajashekhara
Sent: Wednesday, March 04, 2015 2:09 PM
To: JBottomley@Parallels.com; linux-scsi@vger.kernel.org
Cc: aacraid@pmc-sierra.com; Harry Yang; Achim Leubner; Rajinikanth Pandurangan; Rich Bono; Mahesh Rajashekhara
Subject: [PATCH 7/7] aacraid: AIF raw device remove support
Add AIF raw device remove support
Signed-off-by: Mahesh Rajashekhara <Mahesh.Rajashekhara@pmcs.com>
---
drivers/scsi/aacraid/aacraid.h | 3 +++
drivers/scsi/aacraid/commsup.c | 32 ++++++++++++++++++++++++++++++++
2 files changed, 35 insertions(+), 0 deletions(-)
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index 74a0440..5aaa9a6 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -2061,6 +2061,9 @@ extern struct aac_common aac_config;
/* PMC NEW COMM: Request the event data */
#define AifReqEvent 200
+/* RAW device deleted */
+#define AifRawDeviceRemove 203
+
/*
* Adapter Initiated FIB command structures. Start with the adapter
* initiated FIBs that really come from the adapter, and get responded
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index 0555023..8bb9ee4 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -884,6 +884,38 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
switch (le32_to_cpu(aifcmd->command)) {
case AifCmdDriverNotify:
switch (le32_to_cpu(((__le32 *)aifcmd->data)[0])) {
+ case AifRawDeviceRemove:
+ container = le32_to_cpu(((__le32 *)aifcmd->data)[1]);
+ if ((container >> 28)) {
+ container = (u32)-1;
+ break;
+ }
+ channel = (container >> 24) & 0xF;
+ if (channel >= dev->maximum_num_channels) {
+ container = (u32)-1;
+ break;
+ }
+ id = container & 0xFFFF;
+ if (id >= dev->maximum_num_physicals) {
+ container = (u32)-1;
+ break;
+ }
+ lun = (container >> 16) & 0xFF;
+ container = (u32)-1;
+ channel = aac_phys_to_logical(channel);
+ device_config_needed =
+ (((__le32 *)aifcmd->data)[0] ==
+ cpu_to_le32(AifRawDeviceRemove)) ? DELETE : ADD;
+
+ if (device_config_needed == ADD) {
+ device = scsi_device_lookup(dev->scsi_host_ptr, channel, id, lun);
+ if (device) {
+ scsi_remove_device(device);
+ scsi_device_put(device);
+ }
+ }
+ break;
+
/*
* Morph or Expand complete
*/
--
1.7.7.3
^ permalink raw reply related [flat|nested] 32+ messages in thread
* RE: [PATCH 1/7] aacraid: AIF support for SES device add/remove
2015-03-04 8:38 ` [PATCH 1/7] aacraid: AIF support for SES device add/remove Mahesh Rajashekhara
2015-03-17 7:05 ` Murthy Bhat
@ 2015-03-17 15:24 ` Achim Leubner
2015-03-18 11:02 ` Hannes Reinecke
1 sibling, 1 reply; 32+ messages in thread
From: Achim Leubner @ 2015-03-17 15:24 UTC (permalink / raw)
To: Mahesh Rajashekhara, JBottomley, linux-scsi
Reviewed-by: Achim Leubner <Achim.Leubner@pmcs.com>
-----Original Message-----
From: Mahesh Rajashekhara
Sent: Wednesday, March 4, 2015 9:38 AM
To: JBottomley@Parallels.com; linux-scsi@vger.kernel.org
Cc: aacraid@pmc-sierra.com; Harry Yang; Achim Leubner; Rajinikanth Pandurangan; Rich Bono; Mahesh Rajashekhara
Subject: [PATCH 1/7] aacraid: AIF support for SES device add/remove
Add new AIF support for SES device add/remove
Signed-off-by: Mahesh Rajashekhara <Mahesh.Rajashekhara@pmcs.com>
---
drivers/scsi/aacraid/aacraid.h | 2 ++
drivers/scsi/aacraid/commsup.c | 8 ++++++--
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index eaaf870..284db39 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -1951,6 +1951,8 @@ extern struct aac_common aac_config;
#define AifEnEnclosureManagement 13 /* EM_DRIVE_* */
#define EM_DRIVE_INSERTION 31
#define EM_DRIVE_REMOVAL 32
+#define EM_SES_DRIVE_INSERTION 33
+#define EM_SES_DRIVE_REMOVAL 26
#define AifEnBatteryEvent 14 /* Change in Battery State */
#define AifEnAddContainer 15 /* A new array was created */
#define AifEnDeleteContainer 16 /* A container was deleted */
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index cab190a..090ba68 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -1044,6 +1044,8 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
switch (le32_to_cpu(((__le32 *)aifcmd->data)[3])) {
case EM_DRIVE_INSERTION:
case EM_DRIVE_REMOVAL:
+ case EM_SES_DRIVE_INSERTION:
+ case EM_SES_DRIVE_REMOVAL:
container = le32_to_cpu(
((__le32 *)aifcmd->data)[2]);
if ((container >> 28)) {
@@ -1069,8 +1071,10 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
}
channel = aac_phys_to_logical(channel);
device_config_needed =
- (((__le32 *)aifcmd->data)[3]
- == cpu_to_le32(EM_DRIVE_INSERTION)) ?
+ ((((__le32 *)aifcmd->data)[3]
+ == cpu_to_le32(EM_DRIVE_INSERTION)) ||
+ (((__le32 *)aifcmd->data)[3]
+ == cpu_to_le32(EM_SES_DRIVE_INSERTION))) ?
ADD : DELETE;
break;
}
--
1.7.7.3
^ permalink raw reply [flat|nested] 32+ messages in thread
* RE: [PATCH 2/7] aacraid: IOCTL pass-through command fix
2015-03-04 8:38 ` [PATCH 2/7] aacraid: IOCTL pass-through command fix Mahesh Rajashekhara
2015-03-17 7:06 ` Murthy Bhat
@ 2015-03-17 15:26 ` Achim Leubner
2015-03-18 11:03 ` Hannes Reinecke
1 sibling, 1 reply; 32+ messages in thread
From: Achim Leubner @ 2015-03-17 15:26 UTC (permalink / raw)
To: Mahesh Rajashekhara, JBottomley, linux-scsi
Reviewed-by: Achim Leubner <Achim.Leubner@pmcs.com>
-----Original Message-----
From: Mahesh Rajashekhara
Sent: Wednesday, March 4, 2015 9:38 AM
To: JBottomley@Parallels.com; linux-scsi@vger.kernel.org
Cc: aacraid@pmc-sierra.com; Harry Yang; Achim Leubner; Rajinikanth Pandurangan; Rich Bono; Mahesh Rajashekhara
Subject: [PATCH 2/7] aacraid: IOCTL pass-through command fix
The Linux aacriad driver fails to detect the case of SG list count=0 on IOCTL pass-through command and cause intermittent fault.
The result is the Linux aacriad driver send down IOCTL pass-through command with one not initialized SG list to firmware when receiving SG list count =0 on pass-through command.
Signed-off-by: Mahesh Rajashekhara <Mahesh.Rajashekhara@pmcs.com>
---
drivers/scsi/aacraid/commctrl.c | 10 ++++++++--
1 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c index fbcd48d..54195a1 100644
--- a/drivers/scsi/aacraid/commctrl.c
+++ b/drivers/scsi/aacraid/commctrl.c
@@ -689,7 +689,10 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
kfree (usg);
}
srbcmd->count = cpu_to_le32(byte_count);
- psg->count = cpu_to_le32(sg_indx+1);
+ if (user_srbcmd->sg.count)
+ psg->count = cpu_to_le32(sg_indx+1);
+ else
+ psg->count = 0;
status = aac_fib_send(ScsiPortCommand64, srbfib, actual_fibsize, FsaNormal, 1, 1,NULL,NULL);
} else {
struct user_sgmap* upsg = &user_srbcmd->sg; @@ -775,7 +778,10 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
}
}
srbcmd->count = cpu_to_le32(byte_count);
- psg->count = cpu_to_le32(sg_indx+1);
+ if (user_srbcmd->sg.count)
+ psg->count = cpu_to_le32(sg_indx+1);
+ else
+ psg->count = 0;
status = aac_fib_send(ScsiPortCommand, srbfib, actual_fibsize, FsaNormal, 1, 1, NULL, NULL);
}
if (status == -ERESTARTSYS) {
--
1.7.7.3
^ permalink raw reply [flat|nested] 32+ messages in thread
* RE: [PATCH 3/7] aacraid: 4KB sector support
2015-03-04 8:38 ` [PATCH 3/7] aacraid: 4KB sector support Mahesh Rajashekhara
2015-03-17 7:06 ` Murthy Bhat
@ 2015-03-17 15:26 ` Achim Leubner
2015-03-18 11:06 ` Hannes Reinecke
1 sibling, 1 reply; 32+ messages in thread
From: Achim Leubner @ 2015-03-17 15:26 UTC (permalink / raw)
To: Mahesh Rajashekhara, JBottomley, linux-scsi
Reviewed-by: Achim Leubner <Achim.Leubner@pmcs.com>
-----Original Message-----
From: Mahesh Rajashekhara
Sent: Wednesday, March 4, 2015 9:38 AM
To: JBottomley@Parallels.com; linux-scsi@vger.kernel.org
Cc: aacraid@pmc-sierra.com; Harry Yang; Achim Leubner; Rajinikanth Pandurangan; Rich Bono; Mahesh Rajashekhara
Subject: [PATCH 3/7] aacraid: 4KB sector support
Add 4KB sector support
Signed-off-by: Mahesh Rajashekhara <Mahesh.Rajashekhara@pmcs.com>
---
drivers/scsi/aacraid/aachba.c | 195 +++++++++++++++++++++++++++++++---------
drivers/scsi/aacraid/aacraid.h | 10 ++-
2 files changed, 160 insertions(+), 45 deletions(-)
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index b32e77d..0819644 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -111,6 +111,41 @@
#define BYTE2(x) (unsigned char)((x) >> 16) #define BYTE3(x) (unsigned char)((x) >> 24)
+/* MODE_SENSE data format */
+typedef struct {
+ struct {
+ u8 data_length;
+ u8 med_type;
+ u8 dev_par;
+ u8 bd_length;
+ } __attribute__((packed)) hd;
+ struct {
+ u8 dens_code;
+ u8 block_count[3];
+ u8 reserved;
+ u8 block_length[3];
+ } __attribute__((packed)) bd;
+ u8 mpc_buf[3];
+} __attribute__((packed)) aac_modep_data;
+
+/* MODE_SENSE_10 data format */
+typedef struct {
+ struct {
+ u8 data_length[2];
+ u8 med_type;
+ u8 dev_par;
+ u8 rsrvd[2];
+ u8 bd_length[2];
+ } __attribute__((packed)) hd;
+ struct {
+ u8 dens_code;
+ u8 block_count[3];
+ u8 reserved;
+ u8 block_length[3];
+ } __attribute__((packed)) bd;
+ u8 mpc_buf[3];
+} __attribute__((packed)) aac_modep10_data;
+
/*------------------------------------------------------------------------------
* S T R U C T S / T Y P E D E F S
*----------------------------------------------------------------------------*/
@@ -539,6 +574,13 @@ static void _aac_probe_container2(void * context, struct fib * fibptr)
if ((le32_to_cpu(dresp->status) == ST_OK) &&
(le32_to_cpu(dresp->mnt[0].vol) != CT_NONE) &&
(le32_to_cpu(dresp->mnt[0].state) != FSCS_HIDDEN)) {
+ if (!(fibptr->dev->supplement_adapter_info.SupportedOptions2 &
+ AAC_OPTION_VARIABLE_BLOCK_SIZE)) {
+ dresp->mnt[0].fileinfo.bdevinfo.block_size = 0x200;
+ fsa_dev_ptr->block_size = 0x200;
+ } else {
+ fsa_dev_ptr->block_size = le32_to_cpu(dresp->mnt[0].fileinfo.bdevinfo.block_size);
+ }
fsa_dev_ptr->valid = 1;
/* sense_key holds the current state of the spin-up */
if (dresp->mnt[0].state & cpu_to_le32(FSCS_NOT_READY)) @@ -586,7 +628,12 @@ static void _aac_probe_container1(void * context, struct fib * fibptr)
dinfo = (struct aac_query_mount *)fib_data(fibptr);
- dinfo->command = cpu_to_le32(VM_NameServe64);
+ if (fibptr->dev->supplement_adapter_info.SupportedOptions2 &
+ AAC_OPTION_VARIABLE_BLOCK_SIZE)
+ dinfo->command = cpu_to_le32(VM_NameServeAllBlk);
+ else
+ dinfo->command = cpu_to_le32(VM_NameServe64);
+
dinfo->count = cpu_to_le32(scmd_id(scsicmd));
dinfo->type = cpu_to_le32(FT_FILESYS);
@@ -621,7 +668,12 @@ static int _aac_probe_container(struct scsi_cmnd * scsicmd, int (*callback)(stru
dinfo = (struct aac_query_mount *)fib_data(fibptr);
- dinfo->command = cpu_to_le32(VM_NameServe);
+ if (fibptr->dev->supplement_adapter_info.SupportedOptions2 &
+ AAC_OPTION_VARIABLE_BLOCK_SIZE)
+ dinfo->command = cpu_to_le32(VM_NameServeAllBlk);
+ else
+ dinfo->command = cpu_to_le32(VM_NameServe);
+
dinfo->count = cpu_to_le32(scmd_id(scsicmd));
dinfo->type = cpu_to_le32(FT_FILESYS);
scsicmd->SCp.ptr = (char *)callback;
@@ -982,7 +1034,7 @@ static int aac_read_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u3
memset(readcmd2, 0, sizeof(struct aac_raw_io2));
readcmd2->blockLow = cpu_to_le32((u32)(lba&0xffffffff));
readcmd2->blockHigh = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32));
- readcmd2->byteCount = cpu_to_le32(count<<9);
+ readcmd2->byteCount = cpu_to_le32(count *
+dev->fsa_dev[scmd_id(cmd)].block_size);
readcmd2->cid = cpu_to_le16(scmd_id(cmd));
readcmd2->flags = cpu_to_le16(RIO2_IO_TYPE_READ);
ret = aac_build_sgraw2(cmd, readcmd2, @@ -997,7 +1049,7 @@ static int aac_read_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u3
readcmd = (struct aac_raw_io *) fib_data(fib);
readcmd->block[0] = cpu_to_le32((u32)(lba&0xffffffff));
readcmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32));
- readcmd->count = cpu_to_le32(count<<9);
+ readcmd->count = cpu_to_le32(count *
+dev->fsa_dev[scmd_id(cmd)].block_size);
readcmd->cid = cpu_to_le16(scmd_id(cmd));
readcmd->flags = cpu_to_le16(RIO_TYPE_READ);
readcmd->bpTotal = 0;
@@ -1062,6 +1114,7 @@ static int aac_read_block(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 {
u16 fibsize;
struct aac_read *readcmd;
+ struct aac_dev *dev = fib->dev;
long ret;
aac_fib_init(fib);
@@ -1069,7 +1122,7 @@ static int aac_read_block(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32
readcmd->command = cpu_to_le32(VM_CtBlockRead);
readcmd->cid = cpu_to_le32(scmd_id(cmd));
readcmd->block = cpu_to_le32((u32)(lba&0xffffffff));
- readcmd->count = cpu_to_le32(count * 512);
+ readcmd->count = cpu_to_le32(count *
+dev->fsa_dev[scmd_id(cmd)].block_size);
ret = aac_build_sg(cmd, &readcmd->sg);
if (ret < 0)
@@ -1104,7 +1157,7 @@ static int aac_write_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u
memset(writecmd2, 0, sizeof(struct aac_raw_io2));
writecmd2->blockLow = cpu_to_le32((u32)(lba&0xffffffff));
writecmd2->blockHigh = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32));
- writecmd2->byteCount = cpu_to_le32(count<<9);
+ writecmd2->byteCount = cpu_to_le32(count *
+dev->fsa_dev[scmd_id(cmd)].block_size);
writecmd2->cid = cpu_to_le16(scmd_id(cmd));
writecmd2->flags = (fua && ((aac_cache & 5) != 1) &&
(((aac_cache & 5) != 5) || !fib->dev->cache_protected)) ?
@@ -1122,7 +1175,7 @@ static int aac_write_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u
writecmd = (struct aac_raw_io *) fib_data(fib);
writecmd->block[0] = cpu_to_le32((u32)(lba&0xffffffff));
writecmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32));
- writecmd->count = cpu_to_le32(count<<9);
+ writecmd->count = cpu_to_le32(count *
+dev->fsa_dev[scmd_id(cmd)].block_size);
writecmd->cid = cpu_to_le16(scmd_id(cmd));
writecmd->flags = (fua && ((aac_cache & 5) != 1) &&
(((aac_cache & 5) != 5) || !fib->dev->cache_protected)) ?
@@ -1190,6 +1243,7 @@ static int aac_write_block(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u3 {
u16 fibsize;
struct aac_write *writecmd;
+ struct aac_dev *dev = fib->dev;
long ret;
aac_fib_init(fib);
@@ -1197,7 +1251,7 @@ static int aac_write_block(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u3
writecmd->command = cpu_to_le32(VM_CtBlockWrite);
writecmd->cid = cpu_to_le32(scmd_id(cmd));
writecmd->block = cpu_to_le32((u32)(lba&0xffffffff));
- writecmd->count = cpu_to_le32(count * 512);
+ writecmd->count = cpu_to_le32(count *
+dev->fsa_dev[scmd_id(cmd)].block_size);
writecmd->sg.count = cpu_to_le32(1);
/* ->stable is not used - it did mean which type of write */
@@ -2329,10 +2383,10 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
cp[5] = (capacity >> 16) & 0xff;
cp[6] = (capacity >> 8) & 0xff;
cp[7] = (capacity >> 0) & 0xff;
- cp[8] = 0;
- cp[9] = 0;
- cp[10] = 2;
- cp[11] = 0;
+ cp[8] = (fsa_dev_ptr[cid].block_size >> 24) & 0xff;
+ cp[9] = (fsa_dev_ptr[cid].block_size >> 16) & 0xff;
+ cp[10] = (fsa_dev_ptr[cid].block_size >> 8) & 0xff;
+ cp[11] = (fsa_dev_ptr[cid].block_size) & 0xff;
cp[12] = 0;
alloc_len = ((scsicmd->cmnd[10] << 24) @@ -2369,10 +2423,10 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
cp[1] = (capacity >> 16) & 0xff;
cp[2] = (capacity >> 8) & 0xff;
cp[3] = (capacity >> 0) & 0xff;
- cp[4] = 0;
- cp[5] = 0;
- cp[6] = 2;
- cp[7] = 0;
+ cp[4] = (fsa_dev_ptr[cid].block_size >> 24) & 0xff;
+ cp[5] = (fsa_dev_ptr[cid].block_size >> 16) & 0xff;
+ cp[6] = (fsa_dev_ptr[cid].block_size >> 8) & 0xff;
+ cp[7] = (fsa_dev_ptr[cid].block_size) & 0xff;
scsi_sg_copy_from_buffer(scsicmd, cp, sizeof(cp));
/* Do not cache partition table for arrays */
scsicmd->device->removable = 1;
@@ -2385,30 +2439,55 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
case MODE_SENSE:
{
- char mode_buf[7];
int mode_buf_length = 4;
+ u32 capacity;
+ aac_modep_data mpd;
+
+ if (fsa_dev_ptr[cid].size <= 0x100000000ULL)
+ capacity = fsa_dev_ptr[cid].size - 1;
+ else
+ capacity = (u32)-1;
dprintk((KERN_DEBUG "MODE SENSE command.\n"));
- mode_buf[0] = 3; /* Mode data length */
- mode_buf[1] = 0; /* Medium type - default */
- mode_buf[2] = 0; /* Device-specific param,
+ memset((char *)&mpd, 0, sizeof(aac_modep_data));
+
+ mpd.hd.data_length = sizeof(mpd.hd) - 1; /* Mode data length */
+ mpd.hd.med_type = 0; /* Medium type - default */
+ mpd.hd.dev_par = 0; /* Device-specific param,
bit 8: 0/1 = write enabled/protected
bit 4: 0/1 = FUA enabled */
if (dev->raw_io_interface && ((aac_cache & 5) != 1))
- mode_buf[2] = 0x10;
- mode_buf[3] = 0; /* Block descriptor length */
+ mpd.hd.dev_par = 0x10;
+ if (scsicmd->cmnd[1] & 0x8) {
+ mpd.hd.bd_length = 0; /* Block descriptor length */
+ } else {
+ mpd.hd.bd_length = sizeof(mpd.bd);
+ mpd.hd.data_length += mpd.hd.bd_length;
+ mpd.bd.block_length[0] = (fsa_dev_ptr[cid].block_size >> 16) & 0xff;
+ mpd.bd.block_length[1] = (fsa_dev_ptr[cid].block_size >> 8) & 0xff;
+ mpd.bd.block_length[2] = fsa_dev_ptr[cid].block_size & 0xff;
+ if (capacity > 0xffffff) {
+ mpd.bd.block_count[0] = 0xff;
+ mpd.bd.block_count[1] = 0xff;
+ mpd.bd.block_count[2] = 0xff;
+ } else {
+ mpd.bd.block_count[0] = (capacity >> 16) & 0xff;
+ mpd.bd.block_count[1] = (capacity >> 8) & 0xff;
+ mpd.bd.block_count[2] = capacity & 0xff;
+ }
+ }
if (((scsicmd->cmnd[2] & 0x3f) == 8) ||
((scsicmd->cmnd[2] & 0x3f) == 0x3f)) {
- mode_buf[0] = 6;
- mode_buf[4] = 8;
- mode_buf[5] = 1;
- mode_buf[6] = ((aac_cache & 6) == 2)
+ mpd.hd.data_length += 3;
+ mpd.mpc_buf[0] = 8;
+ mpd.mpc_buf[1] = 1;
+ mpd.mpc_buf[2] = ((aac_cache & 6) == 2)
? 0 : 0x04; /* WCE */
- mode_buf_length = 7;
+ mode_buf_length = sizeof(mpd);
if (mode_buf_length > scsicmd->cmnd[4])
mode_buf_length = scsicmd->cmnd[4];
}
- scsi_sg_copy_from_buffer(scsicmd, mode_buf, mode_buf_length);
+ scsi_sg_copy_from_buffer(scsicmd, (char *)&mpd, mode_buf_length);
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
scsicmd->scsi_done(scsicmd);
@@ -2416,34 +2495,62 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
}
case MODE_SENSE_10:
{
- char mode_buf[11];
+ u32 capacity;
int mode_buf_length = 8;
+ aac_modep10_data mpd10;
+
+ if (fsa_dev_ptr[cid].size <= 0x100000000ULL)
+ capacity = fsa_dev_ptr[cid].size - 1;
+ else
+ capacity = (u32)-1;
dprintk((KERN_DEBUG "MODE SENSE 10 byte command.\n"));
- mode_buf[0] = 0; /* Mode data length (MSB) */
- mode_buf[1] = 6; /* Mode data length (LSB) */
- mode_buf[2] = 0; /* Medium type - default */
- mode_buf[3] = 0; /* Device-specific param,
+ memset((char *)&mpd10, 0, sizeof(aac_modep10_data));
+ mpd10.hd.data_length[0] = 0; /* Mode data length (MSB) */
+ mpd10.hd.data_length[1] = sizeof(mpd10.hd) - 1; /* Mode data length (LSB) */
+ mpd10.hd.med_type = 0; /* Medium type - default */
+ mpd10.hd.dev_par = 0; /* Device-specific param,
bit 8: 0/1 = write enabled/protected
bit 4: 0/1 = FUA enabled */
if (dev->raw_io_interface && ((aac_cache & 5) != 1))
- mode_buf[3] = 0x10;
- mode_buf[4] = 0; /* reserved */
- mode_buf[5] = 0; /* reserved */
- mode_buf[6] = 0; /* Block descriptor length (MSB) */
- mode_buf[7] = 0; /* Block descriptor length (LSB) */
+ mpd10.hd.dev_par = 0x10;
+ mpd10.hd.rsrvd[0] = 0; /* reserved */
+ mpd10.hd.rsrvd[1] = 0; /* reserved */
+ if (scsicmd->cmnd[1] & 0x8) {
+ mpd10.hd.bd_length[0] = 0; /* Block descriptor length (MSB) */
+ mpd10.hd.bd_length[1] = 0; /* Block descriptor length (LSB) */
+ } else {
+ mpd10.hd.bd_length[0] = 0;
+ mpd10.hd.bd_length[1] = sizeof(mpd10.bd);
+
+ mpd10.hd.data_length[1] += mpd10.hd.bd_length[1];
+
+ mpd10.bd.block_length[0] = (fsa_dev_ptr[cid].block_size >> 16) & 0xff;
+ mpd10.bd.block_length[1] = (fsa_dev_ptr[cid].block_size >> 8) & 0xff;
+ mpd10.bd.block_length[2] = fsa_dev_ptr[cid].block_size & 0xff;
+
+ if (capacity > 0xffffff) {
+ mpd10.bd.block_count[0] = 0xff;
+ mpd10.bd.block_count[1] = 0xff;
+ mpd10.bd.block_count[2] = 0xff;
+ } else {
+ mpd10.bd.block_count[0] = (capacity >> 16) & 0xff;
+ mpd10.bd.block_count[1] = (capacity >> 8) & 0xff;
+ mpd10.bd.block_count[2] = capacity & 0xff;
+ }
+ }
if (((scsicmd->cmnd[2] & 0x3f) == 8) ||
((scsicmd->cmnd[2] & 0x3f) == 0x3f)) {
- mode_buf[1] = 9;
- mode_buf[8] = 8;
- mode_buf[9] = 1;
- mode_buf[10] = ((aac_cache & 6) == 2)
+ mpd10.hd.data_length[1] += 3;
+ mpd10.mpc_buf[0] = 8;
+ mpd10.mpc_buf[1] = 1;
+ mpd10.mpc_buf[2] = ((aac_cache & 6) == 2)
? 0 : 0x04; /* WCE */
- mode_buf_length = 11;
+ mode_buf_length = sizeof(mpd10);
if (mode_buf_length > scsicmd->cmnd[8])
mode_buf_length = scsicmd->cmnd[8];
}
- scsi_sg_copy_from_buffer(scsicmd, mode_buf, mode_buf_length);
+ scsi_sg_copy_from_buffer(scsicmd, (char *)&mpd10, mode_buf_length);
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
scsicmd->scsi_done(scsicmd);
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 284db39..93579f3 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -857,6 +857,7 @@ struct fsa_dev_info {
u8 deleted;
char devname[8];
struct sense_data sense_data;
+ u32 block_size;
};
struct fib {
@@ -960,6 +961,7 @@ struct aac_supplement_adapter_info
#define AAC_OPTION_IGNORE_RESET cpu_to_le32(0x00000002)
#define AAC_OPTION_POWER_MANAGEMENT cpu_to_le32(0x00000004)
#define AAC_OPTION_DOORBELL_RESET cpu_to_le32(0x00004000)
+#define AAC_OPTION_VARIABLE_BLOCK_SIZE cpu_to_le32(0x00040000) /* 4KB sector size */
#define AAC_SIS_VERSION_V3 3
#define AAC_SIS_SLOT_UNKNOWN 0xFF
@@ -1589,6 +1591,7 @@ struct aac_srb_reply
#define VM_CtHostWrite64 20
#define VM_DrvErrTblLog 21
#define VM_NameServe64 22
+#define VM_NameServeAllBlk 30
#define MAX_VMCOMMAND_NUM 23 /* used for sizing stats array - leave last */
@@ -1611,8 +1614,13 @@ struct aac_fsinfo {
__le32 fsInodeDensity;
}; /* valid iff ObjType == FT_FILESYS && !(ContentState & FSCS_NOTCLEAN) */
+struct aac_blockdevinfo {
+ __le32 block_size;
+};
+
union aac_contentinfo {
- struct aac_fsinfo filesys; /* valid iff ObjType == FT_FILESYS && !(ContentState & FSCS_NOTCLEAN) */
+ struct aac_fsinfo filesys; /* valid iff ObjType == FT_FILESYS && !(ContentState & FSCS_NOTCLEAN) */
+ struct aac_blockdevinfo bdevinfo;
};
/*
--
1.7.7.3
^ permalink raw reply [flat|nested] 32+ messages in thread
* RE: [PATCH 4/7] aacraid: MSI-x support
2015-03-04 8:38 ` [PATCH 4/7] aacraid: MSI-x support Mahesh Rajashekhara
2015-03-17 7:06 ` Murthy Bhat
@ 2015-03-17 15:27 ` Achim Leubner
2015-03-18 11:18 ` Hannes Reinecke
1 sibling, 1 reply; 32+ messages in thread
From: Achim Leubner @ 2015-03-17 15:27 UTC (permalink / raw)
To: Mahesh Rajashekhara, JBottomley, linux-scsi
Reviewed-by: Achim Leubner <Achim.Leubner@pmcs.com>
-----Original Message-----
From: Mahesh Rajashekhara
Sent: Wednesday, March 4, 2015 9:39 AM
To: JBottomley@Parallels.com; linux-scsi@vger.kernel.org
Cc: aacraid@pmc-sierra.com; Harry Yang; Achim Leubner; Rajinikanth Pandurangan; Rich Bono; Mahesh Rajashekhara
Subject: [PATCH 4/7] aacraid: MSI-x support
Add MSI-x interrupt mode support.
Signed-off-by: Mahesh Rajashekhara <Mahesh.Rajashekhara@pmcs.com>
---
drivers/scsi/aacraid/aachba.c | 6 +-
drivers/scsi/aacraid/aacraid.h | 79 ++++++++-
drivers/scsi/aacraid/comminit.c | 86 +++++++++-
drivers/scsi/aacraid/commsup.c | 19 ++-
drivers/scsi/aacraid/dpcsup.c | 9 +-
drivers/scsi/aacraid/linit.c | 18 ++-
drivers/scsi/aacraid/src.c | 365 +++++++++++++++++++++++++++++----------
7 files changed, 473 insertions(+), 109 deletions(-)
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 0819644..eb524e6 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -473,7 +473,7 @@ static void get_container_name_callback(void *context, struct fib * fibptr)
if ((le32_to_cpu(get_name_reply->status) == CT_OK)
&& (get_name_reply->data[0] != '\0')) {
char *sp = get_name_reply->data;
- sp[sizeof(((struct aac_get_name_resp *)NULL)->data)-1] = '\0';
+ sp[sizeof(((struct aac_get_name_resp *)NULL)->data)] = '\0';
while (*sp == ' ')
++sp;
if (*sp) {
@@ -613,7 +613,9 @@ static void _aac_probe_container1(void * context, struct fib * fibptr)
int status;
dresp = (struct aac_mount *) fib_data(fibptr);
- dresp->mnt[0].capacityhigh = 0;
+ if (!(fibptr->dev->supplement_adapter_info.SupportedOptions2 &
+ AAC_OPTION_VARIABLE_BLOCK_SIZE))
+ dresp->mnt[0].capacityhigh = 0;
if ((le32_to_cpu(dresp->status) != ST_OK) ||
(le32_to_cpu(dresp->mnt[0].vol) != CT_NONE)) {
_aac_probe_container2(context, fibptr); diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 93579f3..c162a65 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -6,11 +6,61 @@
#define nblank(x) _nblank(x)[0]
#include <linux/interrupt.h>
+#include <linux/pci.h>
/*------------------------------------------------------------------------------
* D E F I N E S
*----------------------------------------------------------------------------*/
+#define AAC_MAX_MSIX 32 /* vectors */
+#define AAC_PCI_MSI_ENABLE 0x8000
+
+enum {
+ AAC_ENABLE_INTERRUPT = 0x0,
+ AAC_DISABLE_INTERRUPT,
+ AAC_ENABLE_MSIX,
+ AAC_DISABLE_MSIX,
+ AAC_CLEAR_AIF_BIT,
+ AAC_CLEAR_SYNC_BIT,
+ AAC_ENABLE_INTX
+};
+
+#define AAC_INT_MODE_INTX (1<<0)
+#define AAC_INT_MODE_MSI (1<<1)
+#define AAC_INT_MODE_AIF (1<<2)
+#define AAC_INT_MODE_SYNC (1<<3)
+
+#define AAC_INT_ENABLE_TYPE1_INTX 0xfffffffb
+#define AAC_INT_ENABLE_TYPE1_MSIX 0xfffffffa
+#define AAC_INT_DISABLE_ALL 0xffffffff
+
+/* Bit definitions in IOA->Host Interrupt Register */
+#define PMC_TRANSITION_TO_OPERATIONAL (0x80000000 >> 0)
+#define PMC_IOARCB_TRANSFER_FAILED (0x80000000 >> 3)
+#define PMC_IOA_UNIT_CHECK (0x80000000 >> 4)
+#define PMC_NO_HOST_RRQ_FOR_CMD_RESPONSE (0x80000000 >> 5)
+#define PMC_CRITICAL_IOA_OP_IN_PROGRESS (0x80000000 >> 6)
+#define PMC_IOARRIN_LOST (0x80000000 >> 27)
+#define PMC_SYSTEM_BUS_MMIO_ERROR (0x80000000 >> 28)
+#define PMC_IOA_PROCESSOR_IN_ERROR_STATE (0x80000000 >> 29)
+#define PMC_HOST_RRQ_VALID (0x80000000 >> 30)
+#define PMC_OPERATIONAL_STATUS (0x80000000 >> 0)
+#define PMC_ALLOW_MSIX_VECTOR0 (0x80000000 >> 31)
+
+#define PMC_IOA_ERROR_INTERRUPTS (PMC_IOARCB_TRANSFER_FAILED | \
+ PMC_IOA_UNIT_CHECK | \
+ PMC_NO_HOST_RRQ_FOR_CMD_RESPONSE | \
+ PMC_IOARRIN_LOST | \
+ PMC_SYSTEM_BUS_MMIO_ERROR | \
+ PMC_IOA_PROCESSOR_IN_ERROR_STATE)
+
+#define PMC_ALL_INTERRUPT_BITS (PMC_IOA_ERROR_INTERRUPTS | \
+ PMC_HOST_RRQ_VALID | \
+ PMC_TRANSITION_TO_OPERATIONAL | \
+ PMC_ALLOW_MSIX_VECTOR0)
+#define PMC_GLOBAL_INT_BIT2 0x00000004
+#define PMC_GLOBAL_INT_BIT0 0x00000001
+
#ifndef AAC_DRIVER_BUILD
# define AAC_DRIVER_BUILD 30300
# define AAC_DRIVER_BRANCH "-ms"
@@ -36,6 +86,7 @@
#define CONTAINER_TO_ID(cont) (cont)
#define CONTAINER_TO_LUN(cont) (0)
+#define PMC_DEVICE_S6 0x28b
#define PMC_DEVICE_S7 0x28c
#define PMC_DEVICE_S8 0x28d
#define PMC_DEVICE_S9 0x28f
@@ -434,7 +485,7 @@ enum fib_xfer_state { struct aac_init {
__le32 InitStructRevision;
- __le32 MiniPortRevision;
+ __le32 NoOfMSIXVectors;
__le32 fsrev;
__le32 CommHeaderAddress;
__le32 FastIoCommAreaAddress;
@@ -755,7 +806,8 @@ struct rkt_registers {
struct src_mu_registers {
/* PCI*| Name */
- __le32 reserved0[8]; /* 00h | Reserved */
+ __le32 reserved0[6]; /* 00h | Reserved */
+ __le32 IOAR[2]; /* 18h | IOA->host interrupt register */
__le32 IDR; /* 20h | Inbound Doorbell Register */
__le32 IISR; /* 24h | Inbound Int. Status Register */
__le32 reserved1[3]; /* 28h | Reserved */
@@ -767,17 +819,18 @@ struct src_mu_registers {
__le32 OMR; /* bch | Outbound Message Register */
__le32 IQ_L; /* c0h | Inbound Queue (Low address) */
__le32 IQ_H; /* c4h | Inbound Queue (High address) */
+ __le32 ODR_MSI; /* c8h | MSI register for sync./AIF */
};
struct src_registers {
- struct src_mu_registers MUnit; /* 00h - c7h */
+ struct src_mu_registers MUnit; /* 00h - cbh */
union {
struct {
- __le32 reserved1[130790]; /* c8h - 7fc5fh */
+ __le32 reserved1[130789]; /* cch - 7fc5fh */
struct src_inbound IndexRegs; /* 7fc60h */
} tupelo;
struct {
- __le32 reserved1[974]; /* c8h - fffh */
+ __le32 reserved1[973]; /* cch - fffh */
struct src_inbound IndexRegs; /* 1000h */
} denali;
} u;
@@ -1028,6 +1081,11 @@ struct aac_bus_info_response {
#define AAC_OPT_NEW_COMM_TYPE3 cpu_to_le32(1<<30)
#define AAC_OPT_NEW_COMM_TYPE4 cpu_to_le32(1<<31)
+/* MSIX context */
+struct aac_msix_ctx {
+ int vector_no;
+ struct aac_dev *dev;
+};
struct aac_dev
{
@@ -1083,8 +1141,9 @@ struct aac_dev
* if AAC_COMM_MESSAGE_TYPE1 */
dma_addr_t host_rrq_pa; /* phys. address */
- u32 host_rrq_idx; /* index into rrq buffer */
-
+ u32 host_rrq_idx[AAC_MAX_MSIX]; /* index into rrq buffer */
+ atomic_t rrq_outstanding[AAC_MAX_MSIX];
+ u32 fibs_pushed_no;
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 */
@@ -1153,6 +1212,11 @@ struct aac_dev
int sync_mode;
struct fib *sync_fib;
struct list_head sync_fib_list;
+ u32 max_msix; /* max. MSI-X vectors */
+ u32 vector_cap; /* MSI-X vector capab.*/
+ int msi_enabled; /* MSI/MSI-X enabled */
+ struct msix_entry msixentry[AAC_MAX_MSIX];
+ struct aac_msix_ctx aac_msix[AAC_MAX_MSIX]; /* context */
};
#define aac_adapter_interrupt(dev) \
@@ -2035,6 +2099,7 @@ void aac_consumer_free(struct aac_dev * dev, struct aac_queue * q, u32 qnum); int aac_fib_complete(struct fib * context); #define fib_data(fibctx) ((void *)(fibctx)->hw_fib_va->data) struct aac_dev *aac_init_adapter(struct aac_dev *dev);
+void aac_src_access_devreg(struct aac_dev *dev, int mode);
int aac_get_config_status(struct aac_dev *dev, int commit_flag); int aac_get_containers(struct aac_dev *dev); int aac_scsi_cmd(struct scsi_cmnd *cmd); diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c index 177b094..29c35c8 100644
--- a/drivers/scsi/aacraid/comminit.c
+++ b/drivers/scsi/aacraid/comminit.c
@@ -43,6 +43,8 @@
#include "aacraid.h"
+static void aac_define_int_mode(struct aac_dev *dev);
+
struct aac_common aac_config = {
.irq_mod = 1
};
@@ -91,7 +93,7 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
init->InitStructRevision = cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION);
if (dev->max_fib_size != sizeof(struct hw_fib))
init->InitStructRevision = cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_4);
- init->MiniPortRevision = cpu_to_le32(Sa_MINIPORT_REVISION);
+ init->NoOfMSIXVectors = cpu_to_le32(Sa_MINIPORT_REVISION);
init->fsrev = cpu_to_le32(dev->fsrev);
/*
@@ -140,7 +142,7 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
INITFLAGS_NEW_COMM_TYPE2_SUPPORTED | INITFLAGS_FAST_JBOD_SUPPORTED);
init->HostRRQ_AddrHigh = cpu_to_le32((u32)((u64)dev->host_rrq_pa >> 32));
init->HostRRQ_AddrLow = cpu_to_le32((u32)(dev->host_rrq_pa & 0xffffffff));
- init->MiniPortRevision = cpu_to_le32(0L); /* number of MSI-X */
+ init->NoOfMSIXVectors = cpu_to_le32(dev->max_msix); /* number of MSI-X */
dprintk((KERN_WARNING"aacraid: New Comm Interface type2 enabled\n"));
}
@@ -228,6 +230,11 @@ int aac_send_shutdown(struct aac_dev * dev)
/* FIB should be freed only after getting the response from the F/W */
if (status != -ERESTARTSYS)
aac_fib_free(fibctx);
+ if ((dev->pdev->device == PMC_DEVICE_S7 ||
+ dev->pdev->device == PMC_DEVICE_S8 ||
+ dev->pdev->device == PMC_DEVICE_S9) &&
+ dev->msi_enabled)
+ aac_src_access_devreg(dev, AAC_ENABLE_INTX);
return status;
}
@@ -388,6 +395,8 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
}
}
}
+ dev->max_msix = 0;
+ dev->msi_enabled = 0;
if ((!aac_adapter_sync_cmd(dev, GET_COMM_PREFERRED_SETTINGS,
0, 0, 0, 0, 0, 0,
status+0, status+1, status+2, status+3, status+4)) @@ -461,6 +470,11 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
if (host->can_queue > AAC_NUM_IO_FIB)
host->can_queue = AAC_NUM_IO_FIB;
+ if (dev->pdev->device == PMC_DEVICE_S6 ||
+ dev->pdev->device == PMC_DEVICE_S7 ||
+ dev->pdev->device == PMC_DEVICE_S8 ||
+ dev->pdev->device == PMC_DEVICE_S9)
+ aac_define_int_mode(dev);
/*
* Ok now init the communication subsystem
*/
@@ -489,4 +503,70 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
return dev;
}
-
+static void aac_define_int_mode(struct aac_dev *dev) {
+
+ int i, msi_count;
+
+ /* max. vectors from GET_COMM_PREFERRED_SETTINGS */
+ if (dev->max_msix == 0 ||
+ dev->pdev->device == PMC_DEVICE_S6 ||
+ dev->sync_mode) {
+ dev->max_msix = 1;
+ dev->vector_cap = dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB;
+ return;
+ }
+
+ msi_count = min(dev->max_msix,
+ (unsigned int)num_online_cpus());
+
+ dev->max_msix = msi_count;
+
+ if (msi_count > AAC_MAX_MSIX)
+ msi_count = AAC_MAX_MSIX;
+
+ for (i = 0; i < msi_count; i++)
+ dev->msixentry[i].entry = i;
+
+ if (msi_count > 1 && pci_find_capability(dev->pdev, PCI_CAP_ID_MSIX))
+{
+
+ i = pci_enable_msix(dev->pdev, dev->msixentry, msi_count);
+ /* Check how many MSIX vectors are allocated */
+ if (i >= 0) {
+ dev->msi_enabled = 1;
+ if (i) {
+ msi_count = i;
+ if (pci_enable_msix(dev->pdev, dev->msixentry, msi_count)) {
+ dev->msi_enabled = 0;
+ printk(KERN_ERR "%s%d: MSIX not supported!! Will try MSI 0x%x.\n",
+ dev->name, dev->id, i);
+ }
+ }
+ } else {
+ dev->msi_enabled = 0;
+ printk(KERN_ERR "%s%d: MSIX not supported!! Will try MSI 0x%x.\n",
+ dev->name, dev->id, i);
+ }
+ }
+
+ if (!dev->msi_enabled) {
+ msi_count = 1;
+ i = !pci_enable_msi(dev->pdev);
+
+ if (i) {
+ dev->msi_enabled = 1;
+ dev->msi = 1;
+ } else {
+ printk(KERN_ERR "%s%d: MSI not supported!! Will try INTx 0x%x.\n",
+ dev->name, dev->id, i);
+ }
+ }
+
+ if (!dev->msi_enabled)
+ dev->max_msix = msi_count = 1;
+ else {
+ if (dev->max_msix > msi_count)
+ dev->max_msix = msi_count;
+ }
+ dev->vector_cap = (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB) /
+msi_count; }
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 090ba68..83c5d3f 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -868,7 +868,7 @@ void aac_printf(struct aac_dev *dev, u32 val)
* dispatches it to the appropriate routine for handling.
*/
-#define AIF_SNIFF_TIMEOUT (30*HZ)
+#define AIF_SNIFF_TIMEOUT (500*HZ)
static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) {
struct hw_fib * hw_fib = fibptr->hw_fib_va; @@ -1251,7 +1251,7 @@ retry_next:
static int _aac_reset_adapter(struct aac_dev *aac, int forced) {
int index, quirks;
- int retval;
+ int retval, i;
struct Scsi_Host *host;
struct scsi_device *dev;
struct scsi_cmnd *command;
@@ -1319,7 +1319,20 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced)
aac->comm_phys = 0;
kfree(aac->queues);
aac->queues = NULL;
- free_irq(aac->pdev->irq, aac);
+ if (aac->pdev->device == PMC_DEVICE_S6 ||
+ aac->pdev->device == PMC_DEVICE_S7 ||
+ aac->pdev->device == PMC_DEVICE_S8 ||
+ aac->pdev->device == PMC_DEVICE_S9) {
+ if (aac->max_msix > 1) {
+ for (i = 0; i < aac->max_msix; i++)
+ free_irq(aac->msixentry[i].vector, &(aac->aac_msix[i]));
+ pci_disable_msix(aac->pdev);
+ } else {
+ free_irq(aac->pdev->irq, &(aac->aac_msix[0]));
+ }
+ } else {
+ free_irq(aac->pdev->irq, aac);
+ }
if (aac->msi)
pci_disable_msi(aac->pdev);
kfree(aac->fsa_dev);
diff --git a/drivers/scsi/aacraid/dpcsup.c b/drivers/scsi/aacraid/dpcsup.c index d81b281..2e39466 100644
--- a/drivers/scsi/aacraid/dpcsup.c
+++ b/drivers/scsi/aacraid/dpcsup.c
@@ -389,8 +389,13 @@ 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 &= FIB_CONTEXT_FLAG_FASTRESP;
- fib->callback(fib->callback_data, fib);
+ if (likely(fib->callback && fib->callback_data)) {
+ fib->flags &= FIB_CONTEXT_FLAG_FASTRESP;
+ fib->callback(fib->callback_data, fib);
+ } else {
+ aac_fib_complete(fib);
+ aac_fib_free(fib);
+ }
} else {
unsigned long flagv;
dprintk((KERN_INFO "event_wait up\n")); diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index fdcdf9f..7813a9b 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -1082,6 +1082,8 @@ static struct scsi_host_template aac_driver_template = {
static void __aac_shutdown(struct aac_dev * aac) {
+ int i;
+
if (aac->aif_thread) {
int i;
/* Clear out events first */
@@ -1095,9 +1097,23 @@ static void __aac_shutdown(struct aac_dev * aac)
}
aac_send_shutdown(aac);
aac_adapter_disable_int(aac);
- free_irq(aac->pdev->irq, aac);
+ if (aac->pdev->device == PMC_DEVICE_S6 ||
+ aac->pdev->device == PMC_DEVICE_S7 ||
+ aac->pdev->device == PMC_DEVICE_S8 ||
+ aac->pdev->device == PMC_DEVICE_S9) {
+ if (aac->max_msix > 1) {
+ for (i = 0; i < aac->max_msix; i++)
+ free_irq(aac->msixentry[i].vector, &(aac->aac_msix[i]));
+ } else {
+ free_irq(aac->pdev->irq, &(aac->aac_msix[0]));
+ }
+ } else {
+ free_irq(aac->pdev->irq, aac);
+ }
if (aac->msi)
pci_disable_msi(aac->pdev);
+ else if (aac->max_msix > 1)
+ pci_disable_msix(aac->pdev);
}
static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c index 9c65aed..c010248 100644
--- a/drivers/scsi/aacraid/src.c
+++ b/drivers/scsi/aacraid/src.c
@@ -44,98 +44,124 @@
#include "aacraid.h"
-static irqreturn_t aac_src_intr_message(int irq, void *dev_id)
+static int aac_src_get_sync_status(struct aac_dev *dev);
+
+irqreturn_t aac_src_intr_message(int irq, void *dev_id)
{
- struct aac_dev *dev = dev_id;
+ struct aac_msix_ctx *ctx;
+ struct aac_dev *dev;
unsigned long bellbits, bellbits_shifted;
- int our_interrupt = 0;
- int isFastResponse;
+ int vector_no;
+ int isFastResponse, mode;
u32 index, handle;
- bellbits = src_readl(dev, MUnit.ODR_R);
- if (bellbits & PmDoorBellResponseSent) {
- bellbits = PmDoorBellResponseSent;
- /* handle async. status */
- src_writel(dev, MUnit.ODR_C, bellbits);
- src_readl(dev, MUnit.ODR_C);
- our_interrupt = 1;
- index = dev->host_rrq_idx;
- for (;;) {
- isFastResponse = 0;
- /* remove toggle bit (31) */
- handle = le32_to_cpu(dev->host_rrq[index]) & 0x7fffffff;
- /* check fast response bit (30) */
- if (handle & 0x40000000)
- isFastResponse = 1;
- handle &= 0x0000ffff;
- if (handle == 0)
- break;
-
- aac_intr_normal(dev, handle-1, 0, isFastResponse, NULL);
-
- dev->host_rrq[index++] = 0;
- if (index == dev->scsi_host_ptr->can_queue +
- AAC_NUM_MGT_FIB)
- index = 0;
- dev->host_rrq_idx = index;
+ ctx = (struct aac_msix_ctx *)dev_id;
+ dev = ctx->dev;
+ vector_no = ctx->vector_no;
+
+ if (dev->msi_enabled) {
+ mode = AAC_INT_MODE_MSI;
+ if (vector_no == 0) {
+ bellbits = src_readl(dev, MUnit.ODR_MSI);
+ if (bellbits & 0x40000)
+ mode |= AAC_INT_MODE_AIF;
+ if (bellbits & 0x1000)
+ mode |= AAC_INT_MODE_SYNC;
}
} else {
- bellbits_shifted = (bellbits >> SRC_ODR_SHIFT);
- if (bellbits_shifted & DoorBellAifPending) {
+ mode = AAC_INT_MODE_INTX;
+ bellbits = src_readl(dev, MUnit.ODR_R);
+ if (bellbits & PmDoorBellResponseSent) {
+ bellbits = PmDoorBellResponseSent;
+ src_writel(dev, MUnit.ODR_C, bellbits);
+ src_readl(dev, MUnit.ODR_C);
+ } else {
+ bellbits_shifted = (bellbits >> SRC_ODR_SHIFT);
src_writel(dev, MUnit.ODR_C, bellbits);
src_readl(dev, MUnit.ODR_C);
- our_interrupt = 1;
- /* handle AIF */
- aac_intr_normal(dev, 0, 2, 0, NULL);
- } else if (bellbits_shifted & OUTBOUNDDOORBELL_0) {
- unsigned long sflags;
- struct list_head *entry;
- int send_it = 0;
- extern int aac_sync_mode;
+ if (bellbits_shifted & DoorBellAifPending)
+ mode |= AAC_INT_MODE_AIF;
+ else if (bellbits_shifted & OUTBOUNDDOORBELL_0)
+ mode |= AAC_INT_MODE_SYNC;
+ }
+ }
+
+ if (mode & AAC_INT_MODE_SYNC) {
+ unsigned long sflags;
+ struct list_head *entry;
+ int send_it = 0;
+ extern int aac_sync_mode;
+
+ if (!aac_sync_mode && !dev->msi_enabled) {
src_writel(dev, MUnit.ODR_C, bellbits);
src_readl(dev, MUnit.ODR_C);
+ }
- if (!aac_sync_mode) {
- src_writel(dev, MUnit.ODR_C, bellbits);
- src_readl(dev, MUnit.ODR_C);
- our_interrupt = 1;
+ if (dev->sync_fib) {
+ if (dev->sync_fib->callback)
+ dev->sync_fib->callback(dev->sync_fib->callback_data,
+ dev->sync_fib);
+ spin_lock_irqsave(&dev->sync_fib->event_lock, sflags);
+ if (dev->sync_fib->flags & FIB_CONTEXT_FLAG_WAIT) {
+ dev->management_fib_count--;
+ up(&dev->sync_fib->event_wait);
}
-
- if (dev->sync_fib) {
- our_interrupt = 1;
- if (dev->sync_fib->callback)
- dev->sync_fib->callback(dev->sync_fib->callback_data,
- dev->sync_fib);
- spin_lock_irqsave(&dev->sync_fib->event_lock, sflags);
- if (dev->sync_fib->flags & FIB_CONTEXT_FLAG_WAIT) {
- dev->management_fib_count--;
- up(&dev->sync_fib->event_wait);
- }
- spin_unlock_irqrestore(&dev->sync_fib->event_lock, sflags);
- spin_lock_irqsave(&dev->sync_lock, sflags);
- if (!list_empty(&dev->sync_fib_list)) {
- entry = dev->sync_fib_list.next;
- dev->sync_fib = list_entry(entry, struct fib, fiblink);
- list_del(entry);
- send_it = 1;
- } else {
- dev->sync_fib = NULL;
- }
- spin_unlock_irqrestore(&dev->sync_lock, sflags);
- if (send_it) {
- aac_adapter_sync_cmd(dev, SEND_SYNCHRONOUS_FIB,
- (u32)dev->sync_fib->hw_fib_pa, 0, 0, 0, 0, 0,
- NULL, NULL, NULL, NULL, NULL);
- }
+ spin_unlock_irqrestore(&dev->sync_fib->event_lock, sflags);
+ spin_lock_irqsave(&dev->sync_lock, sflags);
+ if (!list_empty(&dev->sync_fib_list)) {
+ entry = dev->sync_fib_list.next;
+ dev->sync_fib = list_entry(entry, struct fib, fiblink);
+ list_del(entry);
+ send_it = 1;
+ } else {
+ dev->sync_fib = NULL;
+ }
+ spin_unlock_irqrestore(&dev->sync_lock, sflags);
+ if (send_it) {
+ aac_adapter_sync_cmd(dev, SEND_SYNCHRONOUS_FIB,
+ (u32)dev->sync_fib->hw_fib_pa, 0, 0, 0, 0, 0,
+ NULL, NULL, NULL, NULL, NULL);
}
}
+ if (!dev->msi_enabled)
+ mode = 0;
+
}
- if (our_interrupt) {
- return IRQ_HANDLED;
+ if (mode & AAC_INT_MODE_AIF) {
+ /* handle AIF */
+ aac_intr_normal(dev, 0, 2, 0, NULL);
+ if (dev->msi_enabled)
+ aac_src_access_devreg(dev, AAC_CLEAR_AIF_BIT);
+ mode = 0;
}
- return IRQ_NONE;
+
+ if (mode) {
+ index = dev->host_rrq_idx[vector_no];
+
+ for (;;) {
+ isFastResponse = 0;
+ /* remove toggle bit (31) */
+ handle = (dev->host_rrq[index] & 0x7fffffff);
+ /* check fast response bit (30) */
+ if (handle & 0x40000000)
+ isFastResponse = 1;
+ handle &= 0x0000ffff;
+ if (handle == 0)
+ break;
+ if (dev->msi_enabled && dev->max_msix > 1)
+ atomic_dec(&dev->rrq_outstanding[vector_no]);
+ aac_intr_normal(dev, handle-1, 0, isFastResponse, NULL);
+ dev->host_rrq[index++] = 0;
+ if (index == (vector_no + 1) * dev->vector_cap)
+ index = vector_no * dev->vector_cap;
+ dev->host_rrq_idx[vector_no] = index;
+ }
+ mode = 0;
+ }
+
+ return IRQ_HANDLED;
}
/**
@@ -155,7 +181,7 @@ static void aac_src_disable_interrupt(struct aac_dev *dev)
static void aac_src_enable_interrupt_message(struct aac_dev *dev) {
- src_writel(dev, MUnit.OIMR, dev->OIMR = 0xfffffff8);
+ aac_src_access_devreg(dev, AAC_ENABLE_INTERRUPT);
}
/**
@@ -191,7 +217,8 @@ static int src_sync_cmd(struct aac_dev *dev, u32 command,
/*
* Clear the synch command doorbell to start on a clean slate.
*/
- src_writel(dev, MUnit.ODR_C, OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
+ if (!dev->msi_enabled)
+ src_writel(dev, MUnit.ODR_C, OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
/*
* Disable doorbell interrupts
@@ -221,11 +248,14 @@ static int src_sync_cmd(struct aac_dev *dev, u32 command,
/*
* Mon960 will set doorbell0 bit when it has completed the command.
*/
- if ((src_readl(dev, MUnit.ODR_R) >> SRC_ODR_SHIFT) & OUTBOUNDDOORBELL_0) {
+ if (aac_src_get_sync_status(dev) & OUTBOUNDDOORBELL_0) {
/*
* Clear the doorbell.
*/
- src_writel(dev, MUnit.ODR_C, OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
+ if (dev->msi_enabled)
+ aac_src_access_devreg(dev, AAC_CLEAR_SYNC_BIT);
+ else
+ src_writel(dev, MUnit.ODR_C, OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
ok = 1;
break;
}
@@ -254,11 +284,13 @@ static int src_sync_cmd(struct aac_dev *dev, u32 command,
*r3 = readl(&dev->IndexRegs->Mailbox[3]);
if (r4)
*r4 = readl(&dev->IndexRegs->Mailbox[4]);
-
+ if (command == GET_COMM_PREFERRED_SETTINGS)
+ dev->max_msix = readl(&dev->IndexRegs->Mailbox[5]) & 0xFFFF;
/*
* Clear the synch command doorbell.
*/
- src_writel(dev, MUnit.ODR_C, OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
+ if (!dev->msi_enabled)
+ src_writel(dev, MUnit.ODR_C, OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
}
/*
@@ -335,9 +367,14 @@ static void aac_src_notify_adapter(struct aac_dev *dev, u32 event) static void aac_src_start_adapter(struct aac_dev *dev) {
struct aac_init *init;
+ int i;
/* reset host_rrq_idx first */
- dev->host_rrq_idx = 0;
+ for (i = 0; i < dev->max_msix; i++) {
+ dev->host_rrq_idx[i] = i * dev->vector_cap;
+ atomic_set(&dev->rrq_outstanding[i], 0);
+ }
+ dev->fibs_pushed_no = 0;
init = dev->init;
init->HostElapsedSeconds = cpu_to_le32(get_seconds()); @@ -400,6 +437,33 @@ static int aac_src_deliver_message(struct fib *fib)
q->numpending++;
spin_unlock_irqrestore(q->lock, qflags);
+ if (dev->msi_enabled && fib->hw_fib_va->header.Command != AifRequest &&
+ dev->max_msix > 1) {
+ u_int16_t vector_no, first_choice = 0xffff;
+
+ vector_no = dev->fibs_pushed_no % dev->max_msix;
+ do {
+ vector_no += 1;
+ if (vector_no == dev->max_msix)
+ vector_no = 1;
+ if (atomic_read(&dev->rrq_outstanding[vector_no]) <
+ dev->vector_cap)
+ break;
+ if (0xffff == first_choice)
+ first_choice = vector_no;
+ else if (vector_no == first_choice)
+ break;
+ } while (1);
+ if (vector_no == first_choice)
+ vector_no = 0;
+ atomic_inc(&dev->rrq_outstanding[vector_no]);
+ if (dev->fibs_pushed_no == 0xffffffff)
+ dev->fibs_pushed_no = 0;
+ else
+ dev->fibs_pushed_no++;
+ fib->hw_fib_va->header.Handle += (vector_no << 16);
+ }
+
if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE2) {
/* Calculate the amount to the fibsize bits */
fibsize = (hdr_size + 127) / 128 - 1; @@ -502,10 +566,19 @@ static int aac_src_restart_adapter(struct aac_dev *dev, int bled)
0, 0, 0, 0, 0, 0, &var, &reset_mask, NULL, NULL, NULL);
if (bled || (var != 0x00000001))
return -EINVAL;
+
+ if ((dev->pdev->device == PMC_DEVICE_S7 ||
+ dev->pdev->device == PMC_DEVICE_S8 ||
+ dev->pdev->device == PMC_DEVICE_S9) && dev->msi_enabled) {
+ aac_src_access_devreg(dev, AAC_ENABLE_INTX);
+ dev->msi_enabled = 0;
+ msleep(5000); /* Delay 5 seconds */
+ }
+
if (dev->supplement_adapter_info.SupportedOptions2 &
AAC_OPTION_DOORBELL_RESET) {
src_writel(dev, MUnit.IDR, reset_mask);
- msleep(5000); /* Delay 5 seconds */
+ ssleep(45);
}
}
@@ -646,8 +719,11 @@ int aac_src_init(struct aac_dev *dev)
dev->msi = aac_msi && !pci_enable_msi(dev->pdev);
+ dev->aac_msix[0].vector_no = 0;
+ dev->aac_msix[0].dev = dev;
+
if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr,
- IRQF_SHARED, "aacraid", dev) < 0) {
+ IRQF_SHARED, "aacraid", &(dev->aac_msix[0])) < 0) {
if (dev->msi)
pci_disable_msi(dev->pdev);
@@ -688,6 +764,7 @@ int aac_srcv_init(struct aac_dev *dev)
unsigned long status;
int restart = 0;
int instance = dev->id;
+ int i, j;
const char *name = dev->name;
dev->a_ops.adapter_ioremap = aac_srcv_ioremap; @@ -802,14 +879,36 @@ int aac_srcv_init(struct aac_dev *dev)
goto error_iounmap;
if (dev->comm_interface != AAC_COMM_MESSAGE_TYPE2)
goto error_iounmap;
- dev->msi = aac_msi && !pci_enable_msi(dev->pdev);
- if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr,
- IRQF_SHARED, "aacraid", dev) < 0) {
- if (dev->msi)
- pci_disable_msi(dev->pdev);
- printk(KERN_ERR "%s%d: Interrupt unavailable.\n",
- name, instance);
- goto error_iounmap;
+ if (dev->msi_enabled)
+ aac_src_access_devreg(dev, AAC_ENABLE_MSIX);
+ if (!dev->sync_mode && dev->msi_enabled && dev->max_msix > 1) {
+ for (i = 0; i < dev->max_msix; i++) {
+ dev->aac_msix[i].vector_no = i;
+ dev->aac_msix[i].dev = dev;
+
+ if (request_irq(dev->msixentry[i].vector, dev->a_ops.adapter_intr,
+ 0, "aacraid", &(dev->aac_msix[i]))) {
+ printk(KERN_ERR "%s%d: Failed to register IRQ for vector %d.\n",
+ name, instance, i);
+ for (j = 0 ; j < i ; j++)
+ free_irq(dev->msixentry[j].vector,
+ &(dev->aac_msix[j]));
+ pci_disable_msix(dev->pdev);
+ goto error_iounmap;
+ }
+ }
+ } else {
+ dev->aac_msix[0].vector_no = 0;
+ dev->aac_msix[0].dev = dev;
+
+ if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr,
+ IRQF_SHARED, "aacraid", &(dev->aac_msix[0])) < 0) {
+ if (dev->msi)
+ pci_disable_msi(dev->pdev);
+ printk(KERN_ERR "%s%d: Interrupt unavailable.\n",
+ name, instance);
+ goto error_iounmap;
+ }
}
dev->dbg_base = dev->base_start;
dev->dbg_base_mapped = dev->base;
@@ -831,3 +930,87 @@ error_iounmap:
return -1;
}
+void aac_src_access_devreg(struct aac_dev *dev, int mode) {
+ u_int32_t val;
+
+ switch (mode) {
+ case AAC_ENABLE_INTERRUPT:
+ src_writel(dev, MUnit.OIMR, dev->OIMR = (dev->msi_enabled ? AAC_INT_ENABLE_TYPE1_MSIX :
+ AAC_INT_ENABLE_TYPE1_INTX));
+ break;
+
+ case AAC_DISABLE_INTERRUPT:
+ src_writel(dev, MUnit.OIMR, dev->OIMR = AAC_INT_DISABLE_ALL);
+ break;
+
+ case AAC_ENABLE_MSIX:
+ /* set bit 6 */
+ val = src_readl(dev, MUnit.IDR);
+ val |= 0x40;
+ src_writel(dev, MUnit.IDR, val);
+ src_readl(dev, MUnit.IDR);
+ /* unmask int. */
+ val = PMC_ALL_INTERRUPT_BITS;
+ src_writel(dev, MUnit.IOAR, val);
+ val = src_readl(dev, MUnit.OIMR);
+ src_writel(dev, MUnit.OIMR,
+ val & (~(PMC_GLOBAL_INT_BIT2 | PMC_GLOBAL_INT_BIT0)));
+ break;
+
+ case AAC_DISABLE_MSIX:
+ /* reset bit 6 */
+ val = src_readl(dev, MUnit.IDR);
+ val &= ~0x40;
+ src_writel(dev, MUnit.IDR, val);
+ src_readl(dev, MUnit.IDR);
+ break;
+
+ case AAC_CLEAR_AIF_BIT:
+ /* set bit 5 */
+ val = src_readl(dev, MUnit.IDR);
+ val |= 0x20;
+ src_writel(dev, MUnit.IDR, val);
+ src_readl(dev, MUnit.IDR);
+ break;
+
+ case AAC_CLEAR_SYNC_BIT:
+ /* set bit 4 */
+ val = src_readl(dev, MUnit.IDR);
+ val |= 0x10;
+ src_writel(dev, MUnit.IDR, val);
+ src_readl(dev, MUnit.IDR);
+ break;
+
+ case AAC_ENABLE_INTX:
+ /* set bit 7 */
+ val = src_readl(dev, MUnit.IDR);
+ val |= 0x80;
+ src_writel(dev, MUnit.IDR, val);
+ src_readl(dev, MUnit.IDR);
+ /* unmask int. */
+ val = PMC_ALL_INTERRUPT_BITS;
+ src_writel(dev, MUnit.IOAR, val);
+ src_readl(dev, MUnit.IOAR);
+ val = src_readl(dev, MUnit.OIMR);
+ src_writel(dev, MUnit.OIMR,
+ val & (~(PMC_GLOBAL_INT_BIT2)));
+ break;
+
+ default:
+ break;
+ }
+}
+
+static int aac_src_get_sync_status(struct aac_dev *dev) {
+
+ int val;
+
+ if (dev->msi_enabled)
+ val = src_readl(dev, MUnit.ODR_MSI) & 0x1000 ? 1 : 0;
+ else
+ val = src_readl(dev, MUnit.ODR_R) >> SRC_ODR_SHIFT;
+
+ return val;
+}
--
1.7.7.3
^ permalink raw reply [flat|nested] 32+ messages in thread
* RE: [PATCH 5/7] aacraid: vpd page code 0x83 support
2015-03-04 8:38 ` [PATCH 5/7] aacraid: vpd page code 0x83 support Mahesh Rajashekhara
2015-03-17 7:06 ` Murthy Bhat
@ 2015-03-17 15:27 ` Achim Leubner
2015-03-18 11:26 ` Hannes Reinecke
1 sibling, 1 reply; 32+ messages in thread
From: Achim Leubner @ 2015-03-17 15:27 UTC (permalink / raw)
To: Mahesh Rajashekhara, JBottomley, linux-scsi
Reviewed-by: Achim Leubner <Achim.Leubner@pmcs.com>
-----Original Message-----
From: Mahesh Rajashekhara
Sent: Wednesday, March 4, 2015 9:39 AM
To: JBottomley@Parallels.com; linux-scsi@vger.kernel.org
Cc: aacraid@pmc-sierra.com; Harry Yang; Achim Leubner; Rajinikanth Pandurangan; Rich Bono; Mahesh Rajashekhara
Subject: [PATCH 5/7] aacraid: vpd page code 0x83 support
Add vpd page code 0x83 support
Signed-off-by: Mahesh Rajashekhara <Mahesh.Rajashekhara@pmcs.com>
---
drivers/scsi/aacraid/aachba.c | 154 ++++++++++++++++++++++++++++++++++++---
drivers/scsi/aacraid/aacraid.h | 4 +
drivers/scsi/aacraid/comminit.c | 8 ++-
drivers/scsi/aacraid/commsup.c | 12 +---
drivers/scsi/aacraid/linit.c | 20 +----
drivers/scsi/aacraid/src.c | 34 +++++++--
6 files changed, 185 insertions(+), 47 deletions(-)
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index eb524e6..3e4e0c8 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -163,6 +163,45 @@ struct inquiry_data {
u8 inqd_prl[4]; /* Product Revision Level */
};
+/* Added for VPD 0x83 */
+typedef struct {
+ u8 CodeSet:4; /* VPD_CODE_SET */
+ u8 Reserved:4;
+ u8 IdentifierType:4; /* VPD_IDENTIFIER_TYPE */
+ u8 Reserved2:4;
+ u8 Reserved3;
+ u8 IdentifierLength;
+ u8 VendId[8];
+ u8 ProductId[16];
+ u8 SerialNumber[8]; /* SN in ASCII */
+} TVPD_ID_Descriptor_Type_1;
+
+typedef struct {
+ u8 CodeSet:4; /* VPD_CODE_SET */
+ u8 Reserved:4;
+ u8 IdentifierType:4; /* VPD_IDENTIFIER_TYPE */
+ u8 Reserved2:4;
+ u8 Reserved3;
+ u8 IdentifierLength;
+ struct TEU64Id {
+ u32 Serial;
+ /* The serial number supposed to be 40 bits,
+ * bit we only support 32, so make the last byte zero. */
+ u8 Reserved;
+ u8 VendId[3];
+ } EU64Id;
+} TVPD_ID_Descriptor_Type_2;
+
+typedef struct {
+ u8 DeviceType:5;
+ u8 DeviceTypeQualifier:3;
+ u8 PageCode;
+ u8 Reserved;
+ u8 PageLength;
+ TVPD_ID_Descriptor_Type_1 IdDescriptorType1;
+ TVPD_ID_Descriptor_Type_2 IdDescriptorType2; } TVPD_Page83;
+
/*
* M O D U L E G L O B A L S
*/
@@ -420,6 +459,9 @@ int aac_get_containers(struct aac_dev *dev)
if (status >= 0) {
dresp = (struct aac_get_container_count_resp *)fib_data(fibptr);
maximum_num_containers = le32_to_cpu(dresp->ContainerSwitchEntries);
+ if (fibptr->dev->supplement_adapter_info.SupportedOptions2 &
+ AAC_OPTION_SUPPORTED_240_VOLUMES)
+ maximum_num_containers = le32_to_cpu(dresp->MaxSimpleVolumes);
aac_fib_complete(fibptr);
}
/* FIB should be freed only after getting the response from the F/W */ @@ -889,14 +931,81 @@ static void get_container_serial_callback(void *context, struct fib * fibptr)
get_serial_reply = (struct aac_get_serial_resp *) fib_data(fibptr);
/* Failure is irrelevant, using default value instead */
if (le32_to_cpu(get_serial_reply->status) == CT_OK) {
- char sp[13];
- /* EVPD bit set */
- sp[0] = INQD_PDT_DA;
- sp[1] = scsicmd->cmnd[2];
- sp[2] = 0;
- sp[3] = snprintf(sp+4, sizeof(sp)-4, "%08X",
- le32_to_cpu(get_serial_reply->uid));
- scsi_sg_copy_from_buffer(scsicmd, sp, sizeof(sp));
+ /*Check to see if it's for VPD 0x83 or 0x80 */
+ if (scsicmd->cmnd[2] == 0x83) {
+ /* vpd page 0x83 - Device Identification Page */
+ int i;
+ TVPD_Page83 VPDPage83Data;
+
+ memset(((u8 *)&VPDPage83Data), 0,
+ sizeof(VPDPage83Data));
+
+ /* DIRECT_ACCESS_DEVIC */
+ VPDPage83Data.DeviceType = 0;
+ /* DEVICE_CONNECTED */
+ VPDPage83Data.DeviceTypeQualifier = 0;
+ /* VPD_DEVICE_IDENTIFIERS */
+ VPDPage83Data.PageCode = 0x83;
+ VPDPage83Data.Reserved = 0;
+ VPDPage83Data.PageLength = sizeof(VPDPage83Data.IdDescriptorType1) +
+ sizeof(VPDPage83Data.IdDescriptorType2);
+
+ /* T10 Vendor Identifier Field Format */
+ /* VpdCodeSetAscii */
+ VPDPage83Data.IdDescriptorType1.CodeSet = 2;
+ /* VpdIdentifierTypeVendorId */
+ VPDPage83Data.IdDescriptorType1.IdentifierType = 1;
+ VPDPage83Data.IdDescriptorType1.IdentifierLength =
+sizeof(VPDPage83Data.IdDescriptorType1) - 4;
+
+ /* "ADAPTEC " for adaptec */
+ memcpy(VPDPage83Data.IdDescriptorType1.VendId, "ADAPTEC ",
+ sizeof(VPDPage83Data.IdDescriptorType1.VendId));
+ memcpy(VPDPage83Data.IdDescriptorType1.ProductId, "ARRAY ",
+ sizeof(VPDPage83Data.IdDescriptorType1.ProductId));
+
+ /* Convert to ascii based serial number.
+ * The LSB is the the end.
+ */
+ for (i = 0; i < 8; i++) {
+ u8 temp = (u8)((get_serial_reply->uid >> ((7 - i) * 4)) & 0xF);
+ if (temp > 0x9) {
+ VPDPage83Data.IdDescriptorType1.SerialNumber[i] = 'A' + (temp - 0xA);
+ } else {
+ VPDPage83Data.IdDescriptorType1.SerialNumber[i] = '0' + temp;
+ }
+ }
+
+ /* EUI-64 Vendor Identifier Field Format,
+ * 24 bits for VendId and 40 bits for SN.
+ */
+ /* VpdCodeSetBinary */
+ VPDPage83Data.IdDescriptorType2.CodeSet = 1;
+ /* VpdIdentifierTypeEUI64 */
+ VPDPage83Data.IdDescriptorType2.IdentifierType = 2;
+ VPDPage83Data.IdDescriptorType2.IdentifierLength =
+sizeof(VPDPage83Data.IdDescriptorType2) - 4;
+
+ /* 0x0000055 for IBM, 0x0000D0 for Adaptec */
+ VPDPage83Data.IdDescriptorType2.EU64Id.VendId[0] = 0xD0;
+ VPDPage83Data.IdDescriptorType2.EU64Id.VendId[1] = 0;
+ VPDPage83Data.IdDescriptorType2.EU64Id.VendId[2] = 0;
+
+ VPDPage83Data.IdDescriptorType2.EU64Id.Serial = get_serial_reply->uid;
+ VPDPage83Data.IdDescriptorType2.EU64Id.Reserved = 0;
+
+ /* Move the inquiry data to the response buffer. */
+ scsi_sg_copy_from_buffer(scsicmd, &VPDPage83Data,
+ sizeof(VPDPage83Data));
+ } else {
+ /* It must be for VPD 0x80 */
+ char sp[13];
+ /* EVPD bit set */
+ sp[0] = INQD_PDT_DA;
+ sp[1] = scsicmd->cmnd[2];
+ sp[2] = 0;
+ sp[3] = snprintf(sp+4, sizeof(sp)-4, "%08X",
+ le32_to_cpu(get_serial_reply->uid));
+ scsi_sg_copy_from_buffer(scsicmd, sp, sizeof(sp));
+ }
}
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; @@ -2302,9 +2411,10 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
INQD_PDT_PROC : INQD_PDT_DA;
if (scsicmd->cmnd[2] == 0) {
/* supported vital product data pages */
- arr[3] = 2;
+ arr[3] = 3;
arr[4] = 0x0;
arr[5] = 0x80;
+ arr[6] = 0x83;
arr[1] = scsicmd->cmnd[2];
scsi_sg_copy_from_buffer(scsicmd, &inq_data,
sizeof(inq_data));
@@ -2323,6 +2433,16 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
/* SLES 10 SP1 special */
scsicmd->result = DID_OK << 16 |
COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
+ } else if (scsicmd->cmnd[2] == 0x83) {
+ /* vpd page 0x83 - Device Identification Page */
+ char *sno = (char *)&inq_data;
+ sno[3] = setinqserial(dev, &sno[4],
+ scmd_id(scsicmd));
+ if (aac_wwn != 2)
+ return aac_get_container_serial(
+ scsicmd);
+ scsicmd->result = DID_OK << 16 |
+ COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
} else {
/* vpd page not implemented */
scsicmd->result = DID_OK << 16 |
@@ -2468,6 +2588,15 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
mpd.bd.block_length[0] = (fsa_dev_ptr[cid].block_size >> 16) & 0xff;
mpd.bd.block_length[1] = (fsa_dev_ptr[cid].block_size >> 8) & 0xff;
mpd.bd.block_length[2] = fsa_dev_ptr[cid].block_size & 0xff;
+
+ mpd.mpc_buf[0] = scsicmd->cmnd[2];
+ if (scsicmd->cmnd[2] == 0x1C) {
+ mpd.mpc_buf[1] = 0xa; /* page length */
+ mpd.hd.data_length = 23; /* Mode data length */
+ } else {
+ mpd.hd.data_length = 15; /* Mode data length */
+ }
+
if (capacity > 0xffffff) {
mpd.bd.block_count[0] = 0xff;
mpd.bd.block_count[1] = 0xff;
@@ -2486,9 +2615,12 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
mpd.mpc_buf[2] = ((aac_cache & 6) == 2)
? 0 : 0x04; /* WCE */
mode_buf_length = sizeof(mpd);
- if (mode_buf_length > scsicmd->cmnd[4])
- mode_buf_length = scsicmd->cmnd[4];
}
+
+ if (mode_buf_length > scsicmd->cmnd[4])
+ mode_buf_length = scsicmd->cmnd[4];
+ else
+ mode_buf_length = sizeof(mpd);
scsi_sg_copy_from_buffer(scsicmd, (char *)&mpd, mode_buf_length);
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
scsicmd->scsi_done(scsicmd);
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index c162a65..a37762e 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -1015,6 +1015,7 @@ struct aac_supplement_adapter_info
#define AAC_OPTION_POWER_MANAGEMENT cpu_to_le32(0x00000004)
#define AAC_OPTION_DOORBELL_RESET cpu_to_le32(0x00004000)
#define AAC_OPTION_VARIABLE_BLOCK_SIZE cpu_to_le32(0x00040000) /* 4KB sector size */
+#define AAC_OPTION_SUPPORTED_240_VOLUMES cpu_to_le32(0x10000000)
#define AAC_SIS_VERSION_V3 3
#define AAC_SIS_SLOT_UNKNOWN 0xFF
@@ -1212,11 +1213,13 @@ struct aac_dev
int sync_mode;
struct fib *sync_fib;
struct list_head sync_fib_list;
+ u32 doorbell_mask; /* from GET_ADAPTER_PROP */
u32 max_msix; /* max. MSI-X vectors */
u32 vector_cap; /* MSI-X vector capab.*/
int msi_enabled; /* MSI/MSI-X enabled */
struct msix_entry msixentry[AAC_MAX_MSIX];
struct aac_msix_ctx aac_msix[AAC_MAX_MSIX]; /* context */
+ u8 adapter_shutdown;
};
#define aac_adapter_interrupt(dev) \
@@ -1749,6 +1752,7 @@ struct aac_get_container_count_resp {
__le32 MaxContainers;
__le32 ContainerSwitchEntries;
__le32 MaxPartitions;
+ __le32 MaxSimpleVolumes;
};
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c index 29c35c8..c3e13ae 100644
--- a/drivers/scsi/aacraid/comminit.c
+++ b/drivers/scsi/aacraid/comminit.c
@@ -53,7 +53,7 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co {
unsigned char *base;
unsigned long size, align;
- const unsigned long fibsize = 4096;
+ const unsigned long fibsize = dev->max_fib_size;
const unsigned long printfbufsiz = 256;
unsigned long host_rrq_size = 0;
struct aac_init *init;
@@ -230,6 +230,7 @@ int aac_send_shutdown(struct aac_dev * dev)
/* FIB should be freed only after getting the response from the F/W */
if (status != -ERESTARTSYS)
aac_fib_free(fibctx);
+ dev->adapter_shutdown = 1;
if ((dev->pdev->device == PMC_DEVICE_S7 ||
dev->pdev->device == PMC_DEVICE_S8 ||
dev->pdev->device == PMC_DEVICE_S9) && @@ -357,8 +358,9 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
dev->raw_io_interface = dev->raw_io_64 = 0;
if ((!aac_adapter_sync_cmd(dev, GET_ADAPTER_PROPERTIES,
- 0, 0, 0, 0, 0, 0, status+0, status+1, status+2, NULL, NULL)) &&
+ 0, 0, 0, 0, 0, 0, status+0, status+1, status+2, status+3, NULL)) &&
(status[0] == 0x00000001)) {
+ dev->doorbell_mask = status[3];
if (status[1] & le32_to_cpu(AAC_OPT_NEW_COMM_64))
dev->raw_io_64 = 1;
dev->sync_mode = aac_sync_mode;
@@ -397,6 +399,7 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
}
dev->max_msix = 0;
dev->msi_enabled = 0;
+ dev->adapter_shutdown = 0;
if ((!aac_adapter_sync_cmd(dev, GET_COMM_PREFERRED_SETTINGS,
0, 0, 0, 0, 0, 0,
status+0, status+1, status+2, status+3, status+4)) @@ -508,6 +511,7 @@ static void aac_define_int_mode(struct aac_dev *dev)
int i, msi_count;
+ msi_count = i = 0;
/* max. vectors from GET_COMM_PREFERRED_SETTINGS */
if (dev->max_msix == 0 ||
dev->pdev->device == PMC_DEVICE_S6 || diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 83c5d3f..2bed445 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -208,14 +208,11 @@ struct fib *aac_fib_alloc(struct aac_dev *dev)
void aac_fib_free(struct fib *fibptr)
{
- unsigned long flags, flagsv;
+ unsigned long flags;
- spin_lock_irqsave(&fibptr->event_lock, flagsv);
if (fibptr->done == 2) {
- spin_unlock_irqrestore(&fibptr->event_lock, flagsv);
return;
}
- spin_unlock_irqrestore(&fibptr->event_lock, flagsv);
spin_lock_irqsave(&fibptr->dev->fib_lock, flags);
if (unlikely(fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT)) @@ -775,7 +772,6 @@ int aac_fib_adapter_complete(struct fib *fibptr, unsigned short size)
int aac_fib_complete(struct fib *fibptr) {
- unsigned long flags;
struct hw_fib * hw_fib = fibptr->hw_fib_va;
/*
@@ -798,12 +794,6 @@ int aac_fib_complete(struct fib *fibptr)
* command is complete that we had sent to the adapter and this
* cdb could be reused.
*/
- spin_lock_irqsave(&fibptr->event_lock, flags);
- if (fibptr->done == 2) {
- spin_unlock_irqrestore(&fibptr->event_lock, flags);
- return 0;
- }
- spin_unlock_irqrestore(&fibptr->event_lock, flags);
if((hw_fib->header.XferState & cpu_to_le32(SentFromHost)) &&
(hw_fib->header.XferState & cpu_to_le32(AdapterProcessed))) diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 7813a9b..4c5ba9e 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -56,7 +56,7 @@
#include "aacraid.h"
-#define AAC_DRIVER_VERSION "1.2-0"
+#define AAC_DRIVER_VERSION "1.2-1"
#ifndef AAC_DRIVER_BRANCH
#define AAC_DRIVER_BRANCH ""
#endif
@@ -65,7 +65,7 @@
#ifdef AAC_DRIVER_BUILD
#define _str(x) #x
#define str(x) _str(x)
-#define AAC_DRIVER_FULL_VERSION AAC_DRIVER_VERSION "[" str(AAC_DRIVER_BUILD) "]" AAC_DRIVER_BRANCH
+#define AAC_DRIVER_FULL_VERSION AAC_DRIVER_VERSION "." str(AAC_DRIVER_BUILD) "" AAC_DRIVER_BRANCH
#else
#define AAC_DRIVER_FULL_VERSION AAC_DRIVER_VERSION AAC_DRIVER_BRANCH
#endif
@@ -253,19 +253,7 @@ static struct aac_driver_ident aac_drivers[] = {
static int aac_queuecommand_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) {
- struct Scsi_Host *host = cmd->device->host;
- struct aac_dev *dev = (struct aac_dev *)host->hostdata;
- u32 count = 0;
cmd->scsi_done = done;
- for (; count < (host->can_queue + AAC_NUM_MGT_FIB); ++count) {
- struct fib * fib = &dev->fibs[count];
- struct scsi_cmnd * command;
- if (fib->hw_fib_va->header.XferState &&
- ((command = fib->callback_data)) &&
- (command == cmd) &&
- (cmd->SCp.phase == AAC_OWNER_FIRMWARE))
- return 0; /* Already owned by Adapter */
- }
cmd->SCp.phase = AAC_OWNER_LOWLEVEL;
return (aac_scsi_cmd(cmd) ? FAILED : 0); } @@ -713,7 +701,9 @@ static long aac_cfg_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
{
int ret;
- if (!capable(CAP_SYS_RAWIO))
+ struct aac_dev *aac;
+ aac = (struct aac_dev *)file->private_data;
+ if (!capable(CAP_SYS_RAWIO) || aac->adapter_shutdown)
return -EPERM;
mutex_lock(&aac_mutex);
ret = aac_do_ioctl(file->private_data, cmd, (void __user *)arg); diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c index c010248..82ff025 100644
--- a/drivers/scsi/aacraid/src.c
+++ b/drivers/scsi/aacraid/src.c
@@ -200,6 +200,7 @@ static int src_sync_cmd(struct aac_dev *dev, u32 command,
u32 *status, u32 * r1, u32 * r2, u32 * r3, u32 * r4) {
unsigned long start;
+ unsigned long delay;
int ok;
/*
@@ -240,10 +241,15 @@ static int src_sync_cmd(struct aac_dev *dev, u32 command,
ok = 0;
start = jiffies;
- /*
- * Wait up to 5 minutes
- */
- while (time_before(jiffies, start+300*HZ)) {
+ if (command == IOP_RESET_ALWAYS) {
+ /* Wait up to 10 sec */
+ delay = 10*HZ;
+ } else {
+ /* Wait up to 5 minutes */
+ delay = 300*HZ;
+ }
+ while (time_before(jiffies, start+delay)) {
+
udelay(5); /* Delay 5 microseconds to let Mon960 get info. */
/*
* Mon960 will set doorbell0 bit when it has completed the command.
@@ -562,10 +568,16 @@ static int aac_src_restart_adapter(struct aac_dev *dev, int bled)
if (bled)
printk(KERN_ERR "%s%d: adapter kernel panic'd %x.\n",
dev->name, dev->id, bled);
+ dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
bled = aac_adapter_sync_cmd(dev, IOP_RESET_ALWAYS,
0, 0, 0, 0, 0, 0, &var, &reset_mask, NULL, NULL, NULL);
- if (bled || (var != 0x00000001))
+ if ((bled || (var != 0x00000001)) && !dev->doorbell_mask)
return -EINVAL;
+ else if (dev->doorbell_mask) {
+ reset_mask = dev->doorbell_mask;
+ bled = 0;
+ var = 0x00000001;
+ }
if ((dev->pdev->device == PMC_DEVICE_S7 ||
dev->pdev->device == PMC_DEVICE_S8 || @@ -575,10 +587,13 @@ static int aac_src_restart_adapter(struct aac_dev *dev, int bled)
msleep(5000); /* Delay 5 seconds */
}
- if (dev->supplement_adapter_info.SupportedOptions2 &
- AAC_OPTION_DOORBELL_RESET) {
+ if (!bled && (dev->supplement_adapter_info.SupportedOptions2 &
+ AAC_OPTION_DOORBELL_RESET)) {
src_writel(dev, MUnit.IDR, reset_mask);
ssleep(45);
+ } else {
+ src_writel(dev, MUnit.IDR, 0x100);
+ ssleep(45);
}
}
@@ -600,7 +615,6 @@ int aac_src_select_comm(struct aac_dev *dev, int comm) {
switch (comm) {
case AAC_COMM_MESSAGE:
- dev->a_ops.adapter_enable_int = aac_src_enable_interrupt_message;
dev->a_ops.adapter_intr = aac_src_intr_message;
dev->a_ops.adapter_deliver = aac_src_deliver_message;
break;
@@ -698,6 +712,7 @@ int aac_src_init(struct aac_dev *dev)
*/
dev->a_ops.adapter_interrupt = aac_src_interrupt_adapter;
dev->a_ops.adapter_disable_int = aac_src_disable_interrupt;
+ dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
dev->a_ops.adapter_notify = aac_src_notify_adapter;
dev->a_ops.adapter_sync_cmd = src_sync_cmd;
dev->a_ops.adapter_check_health = aac_src_check_health; @@ -735,6 +750,7 @@ int aac_src_init(struct aac_dev *dev)
dev->dbg_base = pci_resource_start(dev->pdev, 2);
dev->dbg_base_mapped = dev->regs.src.bar1;
dev->dbg_size = AAC_MIN_SRC_BAR1_SIZE;
+ dev->a_ops.adapter_enable_int = aac_src_enable_interrupt_message;
aac_adapter_enable_int(dev);
@@ -861,6 +877,7 @@ int aac_srcv_init(struct aac_dev *dev)
*/
dev->a_ops.adapter_interrupt = aac_src_interrupt_adapter;
dev->a_ops.adapter_disable_int = aac_src_disable_interrupt;
+ dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
dev->a_ops.adapter_notify = aac_src_notify_adapter;
dev->a_ops.adapter_sync_cmd = src_sync_cmd;
dev->a_ops.adapter_check_health = aac_src_check_health; @@ -913,6 +930,7 @@ int aac_srcv_init(struct aac_dev *dev)
dev->dbg_base = dev->base_start;
dev->dbg_base_mapped = dev->base;
dev->dbg_size = dev->base_size;
+ dev->a_ops.adapter_enable_int = aac_src_enable_interrupt_message;
aac_adapter_enable_int(dev);
--
1.7.7.3
^ permalink raw reply [flat|nested] 32+ messages in thread
* RE: [PATCH 6/7] aacraid: performance improvement changes
2015-03-04 8:38 ` [PATCH 6/7] aacraid: performance improvement changes Mahesh Rajashekhara
2015-03-17 7:07 ` Murthy Bhat
@ 2015-03-17 15:27 ` Achim Leubner
2015-03-18 11:27 ` Hannes Reinecke
1 sibling, 1 reply; 32+ messages in thread
From: Achim Leubner @ 2015-03-17 15:27 UTC (permalink / raw)
To: Mahesh Rajashekhara, JBottomley, linux-scsi
Reviewed-by: Achim Leubner <Achim.Leubner@pmcs.com>
-----Original Message-----
From: Mahesh Rajashekhara
Sent: Wednesday, March 4, 2015 9:39 AM
To: JBottomley@Parallels.com; linux-scsi@vger.kernel.org
Cc: aacraid@pmc-sierra.com; Harry Yang; Achim Leubner; Rajinikanth Pandurangan; Rich Bono; Mahesh Rajashekhara
Subject: [PATCH 6/7] aacraid: performance improvement changes
Add performance improvement changes.
Signed-off-by: Mahesh Rajashekhara <Mahesh.Rajashekhara@pmcs.com>
---
drivers/scsi/aacraid/aacraid.h | 6 +++---
drivers/scsi/aacraid/comminit.c | 12 +++++++++++-
drivers/scsi/aacraid/commsup.c | 7 ++-----
drivers/scsi/aacraid/dpcsup.c | 4 ++--
drivers/scsi/aacraid/linit.c | 10 ++++------
drivers/scsi/aacraid/rx.c | 14 +++-----------
drivers/scsi/aacraid/src.c | 5 +----
7 files changed, 26 insertions(+), 32 deletions(-)
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index a37762e..74a0440 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -12,7 +12,7 @@
* D E F I N E S
*----------------------------------------------------------------------------*/
-#define AAC_MAX_MSIX 32 /* vectors */
+#define AAC_MAX_MSIX 8 /* vectors */
#define AAC_PCI_MSI_ENABLE 0x8000
enum {
@@ -62,7 +62,7 @@ enum {
#define PMC_GLOBAL_INT_BIT0 0x00000001
#ifndef AAC_DRIVER_BUILD
-# define AAC_DRIVER_BUILD 30300
+# define AAC_DRIVER_BUILD 40709
# define AAC_DRIVER_BRANCH "-ms"
#endif
#define MAXIMUM_NUM_CONTAINERS 32
@@ -633,7 +633,7 @@ struct aac_queue {
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. */
- u32 numpending; /* Number of entries on outstanding queue. */
+ atomic_t numpending; /* Number of entries on outstanding queue. */
struct aac_dev * dev; /* Back pointer to adapter structure */
};
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c index c3e13ae..c16043e 100644
--- a/drivers/scsi/aacraid/comminit.c
+++ b/drivers/scsi/aacraid/comminit.c
@@ -181,7 +181,7 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
static void aac_queue_init(struct aac_dev * dev, struct aac_queue * q, u32 *mem, int qsize) {
- q->numpending = 0;
+ atomic_set(&q->numpending, 0);
q->dev = dev;
init_waitqueue_head(&q->cmdready);
INIT_LIST_HEAD(&q->cmdq);
@@ -510,6 +510,7 @@ static void aac_define_int_mode(struct aac_dev *dev) {
int i, msi_count;
+ int cpu;
msi_count = i = 0;
/* max. vectors from GET_COMM_PREFERRED_SETTINGS */ @@ -571,6 +572,15 @@ static void aac_define_int_mode(struct aac_dev *dev)
else {
if (dev->max_msix > msi_count)
dev->max_msix = msi_count;
+
+ /* Added to set IRQ affinity */
+ cpu = cpumask_first(cpu_online_mask);
+ cpu = cpumask_next(cpu, cpu_online_mask);
+
+ for (i = 0; i < dev->max_msix; i++) {
+ irq_set_affinity_hint(dev->msixentry[i].vector, get_cpu_mask(cpu));
+ cpu = cpumask_next(cpu, cpu_online_mask);
+ }
}
dev->vector_cap = (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB) / msi_count; } diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 2bed445..0555023 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -318,7 +318,7 @@ static int aac_get_entry (struct aac_dev * dev, u32 qid, struct aac_entry **entr
/* Queue is full */
if ((*index + 1) == le32_to_cpu(*(q->headers.consumer))) {
printk(KERN_WARNING "Queue %d full, %u outstanding.\n",
- qid, q->numpending);
+ qid, atomic_read(&q->numpending));
return 0;
} else {
*entry = q->base + *index;
@@ -411,7 +411,6 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
struct aac_dev * dev = fibptr->dev;
struct hw_fib * hw_fib = fibptr->hw_fib_va;
unsigned long flags = 0;
- unsigned long qflags;
unsigned long mflags = 0;
unsigned long sflags = 0;
@@ -565,9 +564,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
int blink;
if (time_is_before_eq_jiffies(timeout)) {
struct aac_queue * q = &dev->queues->queue[AdapNormCmdQueue];
- spin_lock_irqsave(q->lock, qflags);
- q->numpending--;
- spin_unlock_irqrestore(q->lock, qflags);
+ atomic_dec(&q->numpending);
if (wait == -1) {
printk(KERN_ERR "aacraid: aac_fib_send: first asynchronous command timed out.\n"
"Usually a result of a PCI interrupt routing problem;\n"
diff --git a/drivers/scsi/aacraid/dpcsup.c b/drivers/scsi/aacraid/dpcsup.c index 2e39466..da9d993 100644
--- a/drivers/scsi/aacraid/dpcsup.c
+++ b/drivers/scsi/aacraid/dpcsup.c
@@ -84,7 +84,7 @@ unsigned int aac_response_normal(struct aac_queue * q)
* continue. The caller has already been notified that
* the fib timed out.
*/
- dev->queues->queue[AdapNormCmdQueue].numpending--;
+ atomic_dec(&dev->queues->queue[AdapNormCmdQueue].numpending);
if (unlikely(fib->flags & FIB_CONTEXT_FLAG_TIMED_OUT)) {
spin_unlock_irqrestore(q->lock, flags); @@ -354,7 +354,7 @@ unsigned int aac_intr_normal(struct aac_dev *dev, u32 index,
* continue. The caller has already been notified that
* the fib timed out.
*/
- dev->queues->queue[AdapNormCmdQueue].numpending--;
+ atomic_dec(&dev->queues->queue[AdapNormCmdQueue].numpending);
if (unlikely(fib->flags & FIB_CONTEXT_FLAG_TIMED_OUT)) {
aac_fib_complete(fib);
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 4c5ba9e..e0f9f81 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -250,16 +250,14 @@ static struct aac_driver_ident aac_drivers[] = {
*
* TODO: unify with aac_scsi_cmd().
*/
-
-static int aac_queuecommand_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
+static int aac_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd
+*cmd)
{
- cmd->scsi_done = done;
+ int r = 0;
cmd->SCp.phase = AAC_OWNER_LOWLEVEL;
- return (aac_scsi_cmd(cmd) ? FAILED : 0);
+ r = (aac_scsi_cmd(cmd) ? FAILED : 0);
+ return r;
}
-static DEF_SCSI_QCMD(aac_queuecommand)
-
/**
* aac_info - Returns the host adapter name
* @shost: Scsi host to report on
diff --git a/drivers/scsi/aacraid/rx.c b/drivers/scsi/aacraid/rx.c index 5c6a870..9570612 100644
--- a/drivers/scsi/aacraid/rx.c
+++ b/drivers/scsi/aacraid/rx.c
@@ -400,16 +400,13 @@ int aac_rx_deliver_producer(struct fib * fib) {
struct aac_dev *dev = fib->dev;
struct aac_queue *q = &dev->queues->queue[AdapNormCmdQueue];
- unsigned long qflags;
u32 Index;
unsigned long nointr = 0;
- spin_lock_irqsave(q->lock, qflags);
aac_queue_get( dev, &Index, AdapNormCmdQueue, fib->hw_fib_va, 1, fib, &nointr);
- q->numpending++;
+ atomic_inc(&q->numpending);
*(q->headers.producer) = cpu_to_le32(Index + 1);
- spin_unlock_irqrestore(q->lock, qflags);
if (!(nointr & aac_config.irq_mod))
aac_adapter_notify(dev, AdapNormCmdQueue);
@@ -426,15 +423,12 @@ static int aac_rx_deliver_message(struct fib * fib) {
struct aac_dev *dev = fib->dev;
struct aac_queue *q = &dev->queues->queue[AdapNormCmdQueue];
- unsigned long qflags;
u32 Index;
u64 addr;
volatile void __iomem *device;
unsigned long count = 10000000L; /* 50 seconds */
- spin_lock_irqsave(q->lock, qflags);
- q->numpending++;
- spin_unlock_irqrestore(q->lock, qflags);
+ atomic_inc(&q->numpending);
for(;;) {
Index = rx_readl(dev, MUnit.InboundQueue);
if (unlikely(Index == 0xFFFFFFFFL))
@@ -442,9 +436,7 @@ static int aac_rx_deliver_message(struct fib * fib)
if (likely(Index != 0xFFFFFFFFL))
break;
if (--count == 0) {
- spin_lock_irqsave(q->lock, qflags);
- q->numpending--;
- spin_unlock_irqrestore(q->lock, qflags);
+ atomic_dec(&q->numpending);
return -ETIMEDOUT;
}
udelay(5);
diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c index 82ff025..bde26a2 100644
--- a/drivers/scsi/aacraid/src.c
+++ b/drivers/scsi/aacraid/src.c
@@ -433,15 +433,12 @@ static int aac_src_deliver_message(struct fib *fib) {
struct aac_dev *dev = fib->dev;
struct aac_queue *q = &dev->queues->queue[AdapNormCmdQueue];
- unsigned long qflags;
u32 fibsize;
dma_addr_t address;
struct aac_fib_xporthdr *pFibX;
u16 hdr_size = le16_to_cpu(fib->hw_fib_va->header.Size);
- spin_lock_irqsave(q->lock, qflags);
- q->numpending++;
- spin_unlock_irqrestore(q->lock, qflags);
+ atomic_inc(&q->numpending);
if (dev->msi_enabled && fib->hw_fib_va->header.Command != AifRequest &&
dev->max_msix > 1) {
--
1.7.7.3
^ permalink raw reply [flat|nested] 32+ messages in thread
* RE: [PATCH 7/7] aacraid: AIF raw device remove support
2015-03-04 8:38 ` [PATCH 7/7] aacraid: AIF raw device remove support Mahesh Rajashekhara
2015-03-17 7:07 ` Murthy Bhat
@ 2015-03-17 15:28 ` Achim Leubner
2015-03-18 11:29 ` Hannes Reinecke
1 sibling, 1 reply; 32+ messages in thread
From: Achim Leubner @ 2015-03-17 15:28 UTC (permalink / raw)
To: Mahesh Rajashekhara, JBottomley, linux-scsi
Reviewed-by: Achim Leubner <Achim.Leubner@pmcs.com>
-----Original Message-----
From: Mahesh Rajashekhara
Sent: Wednesday, March 4, 2015 9:39 AM
To: JBottomley@Parallels.com; linux-scsi@vger.kernel.org
Cc: aacraid@pmc-sierra.com; Harry Yang; Achim Leubner; Rajinikanth Pandurangan; Rich Bono; Mahesh Rajashekhara
Subject: [PATCH 7/7] aacraid: AIF raw device remove support
Add AIF raw device remove support
Signed-off-by: Mahesh Rajashekhara <Mahesh.Rajashekhara@pmcs.com>
---
drivers/scsi/aacraid/aacraid.h | 3 +++
drivers/scsi/aacraid/commsup.c | 32 ++++++++++++++++++++++++++++++++
2 files changed, 35 insertions(+), 0 deletions(-)
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 74a0440..5aaa9a6 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -2061,6 +2061,9 @@ extern struct aac_common aac_config;
/* PMC NEW COMM: Request the event data */
#define AifReqEvent 200
+/* RAW device deleted */
+#define AifRawDeviceRemove 203
+
/*
* Adapter Initiated FIB command structures. Start with the adapter
* initiated FIBs that really come from the adapter, and get responded
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 0555023..8bb9ee4 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -884,6 +884,38 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
switch (le32_to_cpu(aifcmd->command)) {
case AifCmdDriverNotify:
switch (le32_to_cpu(((__le32 *)aifcmd->data)[0])) {
+ case AifRawDeviceRemove:
+ container = le32_to_cpu(((__le32 *)aifcmd->data)[1]);
+ if ((container >> 28)) {
+ container = (u32)-1;
+ break;
+ }
+ channel = (container >> 24) & 0xF;
+ if (channel >= dev->maximum_num_channels) {
+ container = (u32)-1;
+ break;
+ }
+ id = container & 0xFFFF;
+ if (id >= dev->maximum_num_physicals) {
+ container = (u32)-1;
+ break;
+ }
+ lun = (container >> 16) & 0xFF;
+ container = (u32)-1;
+ channel = aac_phys_to_logical(channel);
+ device_config_needed =
+ (((__le32 *)aifcmd->data)[0] ==
+ cpu_to_le32(AifRawDeviceRemove)) ? DELETE : ADD;
+
+ if (device_config_needed == ADD) {
+ device = scsi_device_lookup(dev->scsi_host_ptr, channel, id, lun);
+ if (device) {
+ scsi_remove_device(device);
+ scsi_device_put(device);
+ }
+ }
+ break;
+
/*
* Morph or Expand complete
*/
--
1.7.7.3
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 1/7] aacraid: AIF support for SES device add/remove
2015-03-17 15:24 ` Achim Leubner
@ 2015-03-18 11:02 ` Hannes Reinecke
0 siblings, 0 replies; 32+ messages in thread
From: Hannes Reinecke @ 2015-03-18 11:02 UTC (permalink / raw)
To: Achim Leubner, Mahesh Rajashekhara, JBottomley, linux-scsi
On 03/17/2015 04:24 PM, Achim Leubner wrote:
> Reviewed-by: Achim Leubner <Achim.Leubner@pmcs.com>
>
> -----Original Message-----
> From: Mahesh Rajashekhara
> Sent: Wednesday, March 4, 2015 9:38 AM
> To: JBottomley@Parallels.com; linux-scsi@vger.kernel.org
> Cc: aacraid@pmc-sierra.com; Harry Yang; Achim Leubner; Rajinikanth Pandurangan; Rich Bono; Mahesh Rajashekhara
> Subject: [PATCH 1/7] aacraid: AIF support for SES device add/remove
>
> Add new AIF support for SES device add/remove
>
> Signed-off-by: Mahesh Rajashekhara <Mahesh.Rajashekhara@pmcs.com>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Cheers,
Hannes
--
Dr. Hannes Reinecke zSeries & Storage
hare@suse.de +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 2/7] aacraid: IOCTL pass-through command fix
2015-03-17 15:26 ` Achim Leubner
@ 2015-03-18 11:03 ` Hannes Reinecke
0 siblings, 0 replies; 32+ messages in thread
From: Hannes Reinecke @ 2015-03-18 11:03 UTC (permalink / raw)
To: Achim Leubner, Mahesh Rajashekhara, JBottomley, linux-scsi
On 03/17/2015 04:26 PM, Achim Leubner wrote:
> Reviewed-by: Achim Leubner <Achim.Leubner@pmcs.com>
>
> -----Original Message-----
> From: Mahesh Rajashekhara
> Sent: Wednesday, March 4, 2015 9:38 AM
> To: JBottomley@Parallels.com; linux-scsi@vger.kernel.org
> Cc: aacraid@pmc-sierra.com; Harry Yang; Achim Leubner; Rajinikanth Pandurangan; Rich Bono; Mahesh Rajashekhara
> Subject: [PATCH 2/7] aacraid: IOCTL pass-through command fix
>
> The Linux aacriad driver fails to detect the case of SG list count=0 on IOCTL pass-through command and cause intermittent fault.
> The result is the Linux aacriad driver send down IOCTL pass-through command with one not initialized SG list to firmware when receiving SG list count =0 on pass-through command.
>
> Signed-off-by: Mahesh Rajashekhara <Mahesh.Rajashekhara@pmcs.com>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Cheers,
Hannes
--
Dr. Hannes Reinecke zSeries & Storage
hare@suse.de +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 3/7] aacraid: 4KB sector support
2015-03-17 15:26 ` Achim Leubner
@ 2015-03-18 11:06 ` Hannes Reinecke
0 siblings, 0 replies; 32+ messages in thread
From: Hannes Reinecke @ 2015-03-18 11:06 UTC (permalink / raw)
To: Achim Leubner, Mahesh Rajashekhara, JBottomley, linux-scsi
On 03/17/2015 04:26 PM, Achim Leubner wrote:
> Reviewed-by: Achim Leubner <Achim.Leubner@pmcs.com>
>
>
> -----Original Message-----
> From: Mahesh Rajashekhara
> Sent: Wednesday, March 4, 2015 9:38 AM
> To: JBottomley@Parallels.com; linux-scsi@vger.kernel.org
> Cc: aacraid@pmc-sierra.com; Harry Yang; Achim Leubner; Rajinikanth Pandurangan; Rich Bono; Mahesh Rajashekhara
> Subject: [PATCH 3/7] aacraid: 4KB sector support
>
> Add 4KB sector support
>
> Signed-off-by: Mahesh Rajashekhara <Mahesh.Rajashekhara@pmcs.com>
> ---
> drivers/scsi/aacraid/aachba.c | 195 +++++++++++++++++++++++++++++++---------
> drivers/scsi/aacraid/aacraid.h | 10 ++-
> 2 files changed, 160 insertions(+), 45 deletions(-)
>
> diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index b32e77d..0819644 100644
> --- a/drivers/scsi/aacraid/aachba.c
> +++ b/drivers/scsi/aacraid/aachba.c
> @@ -111,6 +111,41 @@
> #define BYTE2(x) (unsigned char)((x) >> 16) #define BYTE3(x) (unsigned char)((x) >> 24)
>
> +/* MODE_SENSE data format */
> +typedef struct {
> + struct {
> + u8 data_length;
> + u8 med_type;
> + u8 dev_par;
> + u8 bd_length;
> + } __attribute__((packed)) hd;
> + struct {
> + u8 dens_code;
> + u8 block_count[3];
> + u8 reserved;
> + u8 block_length[3];
> + } __attribute__((packed)) bd;
> + u8 mpc_buf[3];
> +} __attribute__((packed)) aac_modep_data;
> +
> +/* MODE_SENSE_10 data format */
> +typedef struct {
> + struct {
> + u8 data_length[2];
> + u8 med_type;
> + u8 dev_par;
> + u8 rsrvd[2];
> + u8 bd_length[2];
> + } __attribute__((packed)) hd;
> + struct {
> + u8 dens_code;
> + u8 block_count[3];
> + u8 reserved;
> + u8 block_length[3];
> + } __attribute__((packed)) bd;
> + u8 mpc_buf[3];
> +} __attribute__((packed)) aac_modep10_data;
> +
> /*------------------------------------------------------------------------------
> * S T R U C T S / T Y P E D E F S
> *----------------------------------------------------------------------------*/
> @@ -539,6 +574,13 @@ static void _aac_probe_container2(void * context, struct fib * fibptr)
> if ((le32_to_cpu(dresp->status) == ST_OK) &&
> (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE) &&
> (le32_to_cpu(dresp->mnt[0].state) != FSCS_HIDDEN)) {
> + if (!(fibptr->dev->supplement_adapter_info.SupportedOptions2 &
> + AAC_OPTION_VARIABLE_BLOCK_SIZE)) {
> + dresp->mnt[0].fileinfo.bdevinfo.block_size = 0x200;
> + fsa_dev_ptr->block_size = 0x200;
> + } else {
> + fsa_dev_ptr->block_size = le32_to_cpu(dresp->mnt[0].fileinfo.bdevinfo.block_size);
> + }
> fsa_dev_ptr->valid = 1;
> /* sense_key holds the current state of the spin-up */
> if (dresp->mnt[0].state & cpu_to_le32(FSCS_NOT_READY)) @@ -586,7 +628,12 @@ static void _aac_probe_container1(void * context, struct fib * fibptr)
>
> dinfo = (struct aac_query_mount *)fib_data(fibptr);
>
> - dinfo->command = cpu_to_le32(VM_NameServe64);
> + if (fibptr->dev->supplement_adapter_info.SupportedOptions2 &
> + AAC_OPTION_VARIABLE_BLOCK_SIZE)
> + dinfo->command = cpu_to_le32(VM_NameServeAllBlk);
> + else
> + dinfo->command = cpu_to_le32(VM_NameServe64);
> +
> dinfo->count = cpu_to_le32(scmd_id(scsicmd));
> dinfo->type = cpu_to_le32(FT_FILESYS);
>
> @@ -621,7 +668,12 @@ static int _aac_probe_container(struct scsi_cmnd * scsicmd, int (*callback)(stru
>
> dinfo = (struct aac_query_mount *)fib_data(fibptr);
>
> - dinfo->command = cpu_to_le32(VM_NameServe);
> + if (fibptr->dev->supplement_adapter_info.SupportedOptions2 &
> + AAC_OPTION_VARIABLE_BLOCK_SIZE)
> + dinfo->command = cpu_to_le32(VM_NameServeAllBlk);
> + else
> + dinfo->command = cpu_to_le32(VM_NameServe);
> +
> dinfo->count = cpu_to_le32(scmd_id(scsicmd));
> dinfo->type = cpu_to_le32(FT_FILESYS);
> scsicmd->SCp.ptr = (char *)callback;
> @@ -982,7 +1034,7 @@ static int aac_read_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u3
> memset(readcmd2, 0, sizeof(struct aac_raw_io2));
> readcmd2->blockLow = cpu_to_le32((u32)(lba&0xffffffff));
> readcmd2->blockHigh = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32));
> - readcmd2->byteCount = cpu_to_le32(count<<9);
> + readcmd2->byteCount = cpu_to_le32(count *
> +dev->fsa_dev[scmd_id(cmd)].block_size);
Wrong indentation.
> readcmd2->cid = cpu_to_le16(scmd_id(cmd));
> readcmd2->flags = cpu_to_le16(RIO2_IO_TYPE_READ);
> ret = aac_build_sgraw2(cmd, readcmd2, @@ -997,7 +1049,7 @@ static int aac_read_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u3
> readcmd = (struct aac_raw_io *) fib_data(fib);
> readcmd->block[0] = cpu_to_le32((u32)(lba&0xffffffff));
> readcmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32));
> - readcmd->count = cpu_to_le32(count<<9);
> + readcmd->count = cpu_to_le32(count *
> +dev->fsa_dev[scmd_id(cmd)].block_size);
Same here.
> readcmd->cid = cpu_to_le16(scmd_id(cmd));
> readcmd->flags = cpu_to_le16(RIO_TYPE_READ);
> readcmd->bpTotal = 0;
> @@ -1062,6 +1114,7 @@ static int aac_read_block(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 {
> u16 fibsize;
> struct aac_read *readcmd;
> + struct aac_dev *dev = fib->dev;
> long ret;
>
> aac_fib_init(fib);
> @@ -1069,7 +1122,7 @@ static int aac_read_block(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32
> readcmd->command = cpu_to_le32(VM_CtBlockRead);
> readcmd->cid = cpu_to_le32(scmd_id(cmd));
> readcmd->block = cpu_to_le32((u32)(lba&0xffffffff));
> - readcmd->count = cpu_to_le32(count * 512);
> + readcmd->count = cpu_to_le32(count *
> +dev->fsa_dev[scmd_id(cmd)].block_size);
>
Here.
> ret = aac_build_sg(cmd, &readcmd->sg);
> if (ret < 0)
> @@ -1104,7 +1157,7 @@ static int aac_write_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u
> memset(writecmd2, 0, sizeof(struct aac_raw_io2));
> writecmd2->blockLow = cpu_to_le32((u32)(lba&0xffffffff));
> writecmd2->blockHigh = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32));
> - writecmd2->byteCount = cpu_to_le32(count<<9);
> + writecmd2->byteCount = cpu_to_le32(count *
> +dev->fsa_dev[scmd_id(cmd)].block_size);
Here.
> writecmd2->cid = cpu_to_le16(scmd_id(cmd));
> writecmd2->flags = (fua && ((aac_cache & 5) != 1) &&
> (((aac_cache & 5) != 5) || !fib->dev->cache_protected)) ?
> @@ -1122,7 +1175,7 @@ static int aac_write_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u
> writecmd = (struct aac_raw_io *) fib_data(fib);
> writecmd->block[0] = cpu_to_le32((u32)(lba&0xffffffff));
> writecmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32));
> - writecmd->count = cpu_to_le32(count<<9);
> + writecmd->count = cpu_to_le32(count *
> +dev->fsa_dev[scmd_id(cmd)].block_size);
Here.
> writecmd->cid = cpu_to_le16(scmd_id(cmd));
> writecmd->flags = (fua && ((aac_cache & 5) != 1) &&
> (((aac_cache & 5) != 5) || !fib->dev->cache_protected)) ?
> @@ -1190,6 +1243,7 @@ static int aac_write_block(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u3 {
> u16 fibsize;
> struct aac_write *writecmd;
> + struct aac_dev *dev = fib->dev;
> long ret;
>
> aac_fib_init(fib);
> @@ -1197,7 +1251,7 @@ static int aac_write_block(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u3
> writecmd->command = cpu_to_le32(VM_CtBlockWrite);
> writecmd->cid = cpu_to_le32(scmd_id(cmd));
> writecmd->block = cpu_to_le32((u32)(lba&0xffffffff));
> - writecmd->count = cpu_to_le32(count * 512);
> + writecmd->count = cpu_to_le32(count *
> +dev->fsa_dev[scmd_id(cmd)].block_size);
And here.
> writecmd->sg.count = cpu_to_le32(1);
> /* ->stable is not used - it did mean which type of write */
>
> @@ -2329,10 +2383,10 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
> cp[5] = (capacity >> 16) & 0xff;
> cp[6] = (capacity >> 8) & 0xff;
> cp[7] = (capacity >> 0) & 0xff;
> - cp[8] = 0;
> - cp[9] = 0;
> - cp[10] = 2;
> - cp[11] = 0;
> + cp[8] = (fsa_dev_ptr[cid].block_size >> 24) & 0xff;
> + cp[9] = (fsa_dev_ptr[cid].block_size >> 16) & 0xff;
> + cp[10] = (fsa_dev_ptr[cid].block_size >> 8) & 0xff;
> + cp[11] = (fsa_dev_ptr[cid].block_size) & 0xff;
> cp[12] = 0;
>
> alloc_len = ((scsicmd->cmnd[10] << 24) @@ -2369,10 +2423,10 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
> cp[1] = (capacity >> 16) & 0xff;
> cp[2] = (capacity >> 8) & 0xff;
> cp[3] = (capacity >> 0) & 0xff;
> - cp[4] = 0;
> - cp[5] = 0;
> - cp[6] = 2;
> - cp[7] = 0;
> + cp[4] = (fsa_dev_ptr[cid].block_size >> 24) & 0xff;
> + cp[5] = (fsa_dev_ptr[cid].block_size >> 16) & 0xff;
> + cp[6] = (fsa_dev_ptr[cid].block_size >> 8) & 0xff;
> + cp[7] = (fsa_dev_ptr[cid].block_size) & 0xff;
> scsi_sg_copy_from_buffer(scsicmd, cp, sizeof(cp));
> /* Do not cache partition table for arrays */
> scsicmd->device->removable = 1;
> @@ -2385,30 +2439,55 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
>
> case MODE_SENSE:
> {
> - char mode_buf[7];
> int mode_buf_length = 4;
> + u32 capacity;
> + aac_modep_data mpd;
> +
> + if (fsa_dev_ptr[cid].size <= 0x100000000ULL)
> + capacity = fsa_dev_ptr[cid].size - 1;
> + else
> + capacity = (u32)-1;
>
> dprintk((KERN_DEBUG "MODE SENSE command.\n"));
> - mode_buf[0] = 3; /* Mode data length */
> - mode_buf[1] = 0; /* Medium type - default */
> - mode_buf[2] = 0; /* Device-specific param,
> + memset((char *)&mpd, 0, sizeof(aac_modep_data));
> +
> + mpd.hd.data_length = sizeof(mpd.hd) - 1; /* Mode data length */
> + mpd.hd.med_type = 0; /* Medium type - default */
> + mpd.hd.dev_par = 0; /* Device-specific param,
> bit 8: 0/1 = write enabled/protected
> bit 4: 0/1 = FUA enabled */
> if (dev->raw_io_interface && ((aac_cache & 5) != 1))
> - mode_buf[2] = 0x10;
> - mode_buf[3] = 0; /* Block descriptor length */
> + mpd.hd.dev_par = 0x10;
> + if (scsicmd->cmnd[1] & 0x8) {
> + mpd.hd.bd_length = 0; /* Block descriptor length */
> + } else {
No braces around conditions in a single line.
Remember to run './scripts/checkpatch.pl' before submission.
Cheers,
Hannes
--
Dr. Hannes Reinecke zSeries & Storage
hare@suse.de +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 4/7] aacraid: MSI-x support
2015-03-17 15:27 ` Achim Leubner
@ 2015-03-18 11:18 ` Hannes Reinecke
0 siblings, 0 replies; 32+ messages in thread
From: Hannes Reinecke @ 2015-03-18 11:18 UTC (permalink / raw)
To: Achim Leubner, Mahesh Rajashekhara, JBottomley, linux-scsi
On 03/17/2015 04:27 PM, Achim Leubner wrote:
> Reviewed-by: Achim Leubner <Achim.Leubner@pmcs.com>
>
>
> -----Original Message-----
> From: Mahesh Rajashekhara
> Sent: Wednesday, March 4, 2015 9:39 AM
> To: JBottomley@Parallels.com; linux-scsi@vger.kernel.org
> Cc: aacraid@pmc-sierra.com; Harry Yang; Achim Leubner; Rajinikanth Pandurangan; Rich Bono; Mahesh Rajashekhara
> Subject: [PATCH 4/7] aacraid: MSI-x support
>
> Add MSI-x interrupt mode support.
>
> Signed-off-by: Mahesh Rajashekhara <Mahesh.Rajashekhara@pmcs.com>
> ---
> drivers/scsi/aacraid/aachba.c | 6 +-
> drivers/scsi/aacraid/aacraid.h | 79 ++++++++-
> drivers/scsi/aacraid/comminit.c | 86 +++++++++-
> drivers/scsi/aacraid/commsup.c | 19 ++-
> drivers/scsi/aacraid/dpcsup.c | 9 +-
> drivers/scsi/aacraid/linit.c | 18 ++-
> drivers/scsi/aacraid/src.c | 365 +++++++++++++++++++++++++++++----------
> 7 files changed, 473 insertions(+), 109 deletions(-)
>
> diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 0819644..eb524e6 100644
> --- a/drivers/scsi/aacraid/aachba.c
> +++ b/drivers/scsi/aacraid/aachba.c
> @@ -473,7 +473,7 @@ static void get_container_name_callback(void *context, struct fib * fibptr)
> if ((le32_to_cpu(get_name_reply->status) == CT_OK)
> && (get_name_reply->data[0] != '\0')) {
> char *sp = get_name_reply->data;
> - sp[sizeof(((struct aac_get_name_resp *)NULL)->data)-1] = '\0';
> + sp[sizeof(((struct aac_get_name_resp *)NULL)->data)] = '\0';
> while (*sp == ' ')
> ++sp;
> if (*sp) {
> @@ -613,7 +613,9 @@ static void _aac_probe_container1(void * context, struct fib * fibptr)
> int status;
>
> dresp = (struct aac_mount *) fib_data(fibptr);
> - dresp->mnt[0].capacityhigh = 0;
> + if (!(fibptr->dev->supplement_adapter_info.SupportedOptions2 &
> + AAC_OPTION_VARIABLE_BLOCK_SIZE))
> + dresp->mnt[0].capacityhigh = 0;
> if ((le32_to_cpu(dresp->status) != ST_OK) ||
> (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE)) {
> _aac_probe_container2(context, fibptr); diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 93579f3..c162a65 100644
> --- a/drivers/scsi/aacraid/aacraid.h
> +++ b/drivers/scsi/aacraid/aacraid.h
> @@ -6,11 +6,61 @@
> #define nblank(x) _nblank(x)[0]
>
> #include <linux/interrupt.h>
> +#include <linux/pci.h>
>
> /*------------------------------------------------------------------------------
> * D E F I N E S
> *----------------------------------------------------------------------------*/
>
> +#define AAC_MAX_MSIX 32 /* vectors */
> +#define AAC_PCI_MSI_ENABLE 0x8000
> +
> +enum {
> + AAC_ENABLE_INTERRUPT = 0x0,
> + AAC_DISABLE_INTERRUPT,
> + AAC_ENABLE_MSIX,
> + AAC_DISABLE_MSIX,
> + AAC_CLEAR_AIF_BIT,
> + AAC_CLEAR_SYNC_BIT,
> + AAC_ENABLE_INTX
> +};
> +
> +#define AAC_INT_MODE_INTX (1<<0)
> +#define AAC_INT_MODE_MSI (1<<1)
> +#define AAC_INT_MODE_AIF (1<<2)
> +#define AAC_INT_MODE_SYNC (1<<3)
> +
> +#define AAC_INT_ENABLE_TYPE1_INTX 0xfffffffb
> +#define AAC_INT_ENABLE_TYPE1_MSIX 0xfffffffa
> +#define AAC_INT_DISABLE_ALL 0xffffffff
> +
> +/* Bit definitions in IOA->Host Interrupt Register */
> +#define PMC_TRANSITION_TO_OPERATIONAL (0x80000000 >> 0)
> +#define PMC_IOARCB_TRANSFER_FAILED (0x80000000 >> 3)
> +#define PMC_IOA_UNIT_CHECK (0x80000000 >> 4)
> +#define PMC_NO_HOST_RRQ_FOR_CMD_RESPONSE (0x80000000 >> 5)
> +#define PMC_CRITICAL_IOA_OP_IN_PROGRESS (0x80000000 >> 6)
> +#define PMC_IOARRIN_LOST (0x80000000 >> 27)
> +#define PMC_SYSTEM_BUS_MMIO_ERROR (0x80000000 >> 28)
> +#define PMC_IOA_PROCESSOR_IN_ERROR_STATE (0x80000000 >> 29)
> +#define PMC_HOST_RRQ_VALID (0x80000000 >> 30)
> +#define PMC_OPERATIONAL_STATUS (0x80000000 >> 0)
> +#define PMC_ALLOW_MSIX_VECTOR0 (0x80000000 >> 31)
> +
How positively curious.
Typically you define a git mask by shifting _left_, not right.
> +#define PMC_IOA_ERROR_INTERRUPTS (PMC_IOARCB_TRANSFER_FAILED | \
> + PMC_IOA_UNIT_CHECK | \
> + PMC_NO_HOST_RRQ_FOR_CMD_RESPONSE | \
> + PMC_IOARRIN_LOST | \
> + PMC_SYSTEM_BUS_MMIO_ERROR | \
> + PMC_IOA_PROCESSOR_IN_ERROR_STATE)
> +
> +#define PMC_ALL_INTERRUPT_BITS (PMC_IOA_ERROR_INTERRUPTS | \
> + PMC_HOST_RRQ_VALID | \
> + PMC_TRANSITION_TO_OPERATIONAL | \
> + PMC_ALLOW_MSIX_VECTOR0)
> +#define PMC_GLOBAL_INT_BIT2 0x00000004
> +#define PMC_GLOBAL_INT_BIT0 0x00000001
> +
> #ifndef AAC_DRIVER_BUILD
> # define AAC_DRIVER_BUILD 30300
> # define AAC_DRIVER_BRANCH "-ms"
> @@ -36,6 +86,7 @@
> #define CONTAINER_TO_ID(cont) (cont)
> #define CONTAINER_TO_LUN(cont) (0)
>
> +#define PMC_DEVICE_S6 0x28b
> #define PMC_DEVICE_S7 0x28c
> #define PMC_DEVICE_S8 0x28d
> #define PMC_DEVICE_S9 0x28f
> @@ -434,7 +485,7 @@ enum fib_xfer_state { struct aac_init {
> __le32 InitStructRevision;
> - __le32 MiniPortRevision;
> + __le32 NoOfMSIXVectors;
> __le32 fsrev;
> __le32 CommHeaderAddress;
> __le32 FastIoCommAreaAddress;
> @@ -755,7 +806,8 @@ struct rkt_registers {
>
> struct src_mu_registers {
> /* PCI*| Name */
> - __le32 reserved0[8]; /* 00h | Reserved */
> + __le32 reserved0[6]; /* 00h | Reserved */
> + __le32 IOAR[2]; /* 18h | IOA->host interrupt register */
> __le32 IDR; /* 20h | Inbound Doorbell Register */
> __le32 IISR; /* 24h | Inbound Int. Status Register */
> __le32 reserved1[3]; /* 28h | Reserved */
> @@ -767,17 +819,18 @@ struct src_mu_registers {
> __le32 OMR; /* bch | Outbound Message Register */
> __le32 IQ_L; /* c0h | Inbound Queue (Low address) */
> __le32 IQ_H; /* c4h | Inbound Queue (High address) */
> + __le32 ODR_MSI; /* c8h | MSI register for sync./AIF */
> };
>
> struct src_registers {
> - struct src_mu_registers MUnit; /* 00h - c7h */
> + struct src_mu_registers MUnit; /* 00h - cbh */
> union {
> struct {
> - __le32 reserved1[130790]; /* c8h - 7fc5fh */
> + __le32 reserved1[130789]; /* cch - 7fc5fh */
> struct src_inbound IndexRegs; /* 7fc60h */
> } tupelo;
> struct {
> - __le32 reserved1[974]; /* c8h - fffh */
> + __le32 reserved1[973]; /* cch - fffh */
> struct src_inbound IndexRegs; /* 1000h */
> } denali;
> } u;
> @@ -1028,6 +1081,11 @@ struct aac_bus_info_response {
> #define AAC_OPT_NEW_COMM_TYPE3 cpu_to_le32(1<<30)
> #define AAC_OPT_NEW_COMM_TYPE4 cpu_to_le32(1<<31)
>
> +/* MSIX context */
> +struct aac_msix_ctx {
> + int vector_no;
> + struct aac_dev *dev;
> +};
>
> struct aac_dev
> {
> @@ -1083,8 +1141,9 @@ struct aac_dev
> * if AAC_COMM_MESSAGE_TYPE1 */
>
> dma_addr_t host_rrq_pa; /* phys. address */
> - u32 host_rrq_idx; /* index into rrq buffer */
> -
> + u32 host_rrq_idx[AAC_MAX_MSIX]; /* index into rrq buffer */
> + atomic_t rrq_outstanding[AAC_MAX_MSIX];
> + u32 fibs_pushed_no;
> 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 */
> @@ -1153,6 +1212,11 @@ struct aac_dev
> int sync_mode;
> struct fib *sync_fib;
> struct list_head sync_fib_list;
> + u32 max_msix; /* max. MSI-X vectors */
> + u32 vector_cap; /* MSI-X vector capab.*/
> + int msi_enabled; /* MSI/MSI-X enabled */
> + struct msix_entry msixentry[AAC_MAX_MSIX];
> + struct aac_msix_ctx aac_msix[AAC_MAX_MSIX]; /* context */
> };
>
> #define aac_adapter_interrupt(dev) \
> @@ -2035,6 +2099,7 @@ void aac_consumer_free(struct aac_dev * dev, struct aac_queue * q, u32 qnum); int aac_fib_complete(struct fib * context); #define fib_data(fibctx) ((void *)(fibctx)->hw_fib_va->data) struct aac_dev *aac_init_adapter(struct aac_dev *dev);
> +void aac_src_access_devreg(struct aac_dev *dev, int mode);
> int aac_get_config_status(struct aac_dev *dev, int commit_flag); int aac_get_containers(struct aac_dev *dev); int aac_scsi_cmd(struct scsi_cmnd *cmd); diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c index 177b094..29c35c8 100644
> --- a/drivers/scsi/aacraid/comminit.c
> +++ b/drivers/scsi/aacraid/comminit.c
> @@ -43,6 +43,8 @@
>
> #include "aacraid.h"
>
> +static void aac_define_int_mode(struct aac_dev *dev);
> +
> struct aac_common aac_config = {
> .irq_mod = 1
> };
> @@ -91,7 +93,7 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
> init->InitStructRevision = cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION);
> if (dev->max_fib_size != sizeof(struct hw_fib))
> init->InitStructRevision = cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_4);
> - init->MiniPortRevision = cpu_to_le32(Sa_MINIPORT_REVISION);
> + init->NoOfMSIXVectors = cpu_to_le32(Sa_MINIPORT_REVISION);
> init->fsrev = cpu_to_le32(dev->fsrev);
>
> /*
Now that you switched the field definition from 'MiniPortRevision'
to 'NoOfMSIXVectors', shouldn't you rather introduce a
'Sa_MSIXVECTORS' here instead of using the old definitions?
> @@ -140,7 +142,7 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
> INITFLAGS_NEW_COMM_TYPE2_SUPPORTED | INITFLAGS_FAST_JBOD_SUPPORTED);
> init->HostRRQ_AddrHigh = cpu_to_le32((u32)((u64)dev->host_rrq_pa >> 32));
> init->HostRRQ_AddrLow = cpu_to_le32((u32)(dev->host_rrq_pa & 0xffffffff));
> - init->MiniPortRevision = cpu_to_le32(0L); /* number of MSI-X */
> + init->NoOfMSIXVectors = cpu_to_le32(dev->max_msix); /* number of MSI-X */
> dprintk((KERN_WARNING"aacraid: New Comm Interface type2 enabled\n"));
> }
>
> @@ -228,6 +230,11 @@ int aac_send_shutdown(struct aac_dev * dev)
> /* FIB should be freed only after getting the response from the F/W */
> if (status != -ERESTARTSYS)
> aac_fib_free(fibctx);
> + if ((dev->pdev->device == PMC_DEVICE_S7 ||
> + dev->pdev->device == PMC_DEVICE_S8 ||
> + dev->pdev->device == PMC_DEVICE_S9) &&
> + dev->msi_enabled)
> + aac_src_access_devreg(dev, AAC_ENABLE_INTX);
> return status;
> }
>
> @@ -388,6 +395,8 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
> }
> }
> }
> + dev->max_msix = 0;
> + dev->msi_enabled = 0;
> if ((!aac_adapter_sync_cmd(dev, GET_COMM_PREFERRED_SETTINGS,
> 0, 0, 0, 0, 0, 0,
> status+0, status+1, status+2, status+3, status+4)) @@ -461,6 +470,11 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
> if (host->can_queue > AAC_NUM_IO_FIB)
> host->can_queue = AAC_NUM_IO_FIB;
>
> + if (dev->pdev->device == PMC_DEVICE_S6 ||
> + dev->pdev->device == PMC_DEVICE_S7 ||
> + dev->pdev->device == PMC_DEVICE_S8 ||
> + dev->pdev->device == PMC_DEVICE_S9)
> + aac_define_int_mode(dev);
> /*
> * Ok now init the communication subsystem
> */
> @@ -489,4 +503,70 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
> return dev;
> }
>
> -
> +static void aac_define_int_mode(struct aac_dev *dev) {
> +
> + int i, msi_count;
> +
> + /* max. vectors from GET_COMM_PREFERRED_SETTINGS */
> + if (dev->max_msix == 0 ||
> + dev->pdev->device == PMC_DEVICE_S6 ||
> + dev->sync_mode) {
> + dev->max_msix = 1;
> + dev->vector_cap = dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB;
> + return;
> + }
> +
> + msi_count = min(dev->max_msix,
> + (unsigned int)num_online_cpus());
> +
> + dev->max_msix = msi_count;
> +
> + if (msi_count > AAC_MAX_MSIX)
> + msi_count = AAC_MAX_MSIX;
> +
> + for (i = 0; i < msi_count; i++)
> + dev->msixentry[i].entry = i;
> +
> + if (msi_count > 1 && pci_find_capability(dev->pdev, PCI_CAP_ID_MSIX))
> +{
> +
Braces should be at the same line as the condition.
> + i = pci_enable_msix(dev->pdev, dev->msixentry, msi_count);
> + /* Check how many MSIX vectors are allocated */
> + if (i >= 0) {
> + dev->msi_enabled = 1;
> + if (i) {
> + msi_count = i;
> + if (pci_enable_msix(dev->pdev, dev->msixentry, msi_count)) {
> + dev->msi_enabled = 0;
> + printk(KERN_ERR "%s%d: MSIX not supported!! Will try MSI 0x%x.\n",
> + dev->name, dev->id, i);
> + }
> + }
> + } else {
> + dev->msi_enabled = 0;
> + printk(KERN_ERR "%s%d: MSIX not supported!! Will try MSI 0x%x.\n",
> + dev->name, dev->id, i);
> + }
> + }
> +
> + if (!dev->msi_enabled) {
> + msi_count = 1;
> + i = !pci_enable_msi(dev->pdev);
> +
Yikes. Please don't do that; use (!i) in the condition instead.
> + if (i) {
> + dev->msi_enabled = 1;
> + dev->msi = 1;
> + } else {
> + printk(KERN_ERR "%s%d: MSI not supported!! Will try INTx 0x%x.\n",
> + dev->name, dev->id, i);
> + }
> + }
> +
> + if (!dev->msi_enabled)
> + dev->max_msix = msi_count = 1;
> + else {
> + if (dev->max_msix > msi_count)
> + dev->max_msix = msi_count;
> + }
> + dev->vector_cap = (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB) /
> +msi_count; }
Closing braces should be on an individual line.
Also here: please remember to run checkpatch before submitting.
Cheers,
Hannes
--
Dr. Hannes Reinecke zSeries & Storage
hare@suse.de +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 5/7] aacraid: vpd page code 0x83 support
2015-03-17 15:27 ` Achim Leubner
@ 2015-03-18 11:26 ` Hannes Reinecke
0 siblings, 0 replies; 32+ messages in thread
From: Hannes Reinecke @ 2015-03-18 11:26 UTC (permalink / raw)
To: Achim Leubner, Mahesh Rajashekhara, JBottomley, linux-scsi
On 03/17/2015 04:27 PM, Achim Leubner wrote:
> Reviewed-by: Achim Leubner <Achim.Leubner@pmcs.com>
>
>
> -----Original Message-----
> From: Mahesh Rajashekhara
> Sent: Wednesday, March 4, 2015 9:39 AM
> To: JBottomley@Parallels.com; linux-scsi@vger.kernel.org
> Cc: aacraid@pmc-sierra.com; Harry Yang; Achim Leubner; Rajinikanth Pandurangan; Rich Bono; Mahesh Rajashekhara
> Subject: [PATCH 5/7] aacraid: vpd page code 0x83 support
>
> Add vpd page code 0x83 support
>
> Signed-off-by: Mahesh Rajashekhara <Mahesh.Rajashekhara@pmcs.com>
> ---
> drivers/scsi/aacraid/aachba.c | 154 ++++++++++++++++++++++++++++++++++++---
> drivers/scsi/aacraid/aacraid.h | 4 +
> drivers/scsi/aacraid/comminit.c | 8 ++-
> drivers/scsi/aacraid/commsup.c | 12 +---
> drivers/scsi/aacraid/linit.c | 20 +----
> drivers/scsi/aacraid/src.c | 34 +++++++--
> 6 files changed, 185 insertions(+), 47 deletions(-)
>
> diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index eb524e6..3e4e0c8 100644
> --- a/drivers/scsi/aacraid/aachba.c
> +++ b/drivers/scsi/aacraid/aachba.c
> @@ -163,6 +163,45 @@ struct inquiry_data {
> u8 inqd_prl[4]; /* Product Revision Level */
> };
>
> +/* Added for VPD 0x83 */
> +typedef struct {
> + u8 CodeSet:4; /* VPD_CODE_SET */
> + u8 Reserved:4;
> + u8 IdentifierType:4; /* VPD_IDENTIFIER_TYPE */
> + u8 Reserved2:4;
> + u8 Reserved3;
> + u8 IdentifierLength;
> + u8 VendId[8];
> + u8 ProductId[16];
> + u8 SerialNumber[8]; /* SN in ASCII */
> +} TVPD_ID_Descriptor_Type_1;
> +
> +typedef struct {
> + u8 CodeSet:4; /* VPD_CODE_SET */
> + u8 Reserved:4;
> + u8 IdentifierType:4; /* VPD_IDENTIFIER_TYPE */
> + u8 Reserved2:4;
> + u8 Reserved3;
> + u8 IdentifierLength;
> + struct TEU64Id {
> + u32 Serial;
> + /* The serial number supposed to be 40 bits,
> + * bit we only support 32, so make the last byte zero. */
> + u8 Reserved;
> + u8 VendId[3];
> + } EU64Id;
> +} TVPD_ID_Descriptor_Type_2;
> +
> +typedef struct {
> + u8 DeviceType:5;
> + u8 DeviceTypeQualifier:3;
> + u8 PageCode;
> + u8 Reserved;
> + u8 PageLength;
> + TVPD_ID_Descriptor_Type_1 IdDescriptorType1;
> + TVPD_ID_Descriptor_Type_2 IdDescriptorType2; } TVPD_Page83;
> +
> /*
> * M O D U L E G L O B A L S
> */
> @@ -420,6 +459,9 @@ int aac_get_containers(struct aac_dev *dev)
> if (status >= 0) {
> dresp = (struct aac_get_container_count_resp *)fib_data(fibptr);
> maximum_num_containers = le32_to_cpu(dresp->ContainerSwitchEntries);
> + if (fibptr->dev->supplement_adapter_info.SupportedOptions2 &
> + AAC_OPTION_SUPPORTED_240_VOLUMES)
> + maximum_num_containers = le32_to_cpu(dresp->MaxSimpleVolumes);
> aac_fib_complete(fibptr);
> }
> /* FIB should be freed only after getting the response from the F/W */ @@ -889,14 +931,81 @@ static void get_container_serial_callback(void *context, struct fib * fibptr)
Garbled patch?
> get_serial_reply = (struct aac_get_serial_resp *) fib_data(fibptr);
> /* Failure is irrelevant, using default value instead */
> if (le32_to_cpu(get_serial_reply->status) == CT_OK) {
> - char sp[13];
> - /* EVPD bit set */
> - sp[0] = INQD_PDT_DA;
> - sp[1] = scsicmd->cmnd[2];
> - sp[2] = 0;
> - sp[3] = snprintf(sp+4, sizeof(sp)-4, "%08X",
> - le32_to_cpu(get_serial_reply->uid));
> - scsi_sg_copy_from_buffer(scsicmd, sp, sizeof(sp));
> + /*Check to see if it's for VPD 0x83 or 0x80 */
> + if (scsicmd->cmnd[2] == 0x83) {
> + /* vpd page 0x83 - Device Identification Page */
> + int i;
> + TVPD_Page83 VPDPage83Data;
> +
> + memset(((u8 *)&VPDPage83Data), 0,
> + sizeof(VPDPage83Data));
> +
> + /* DIRECT_ACCESS_DEVIC */
> + VPDPage83Data.DeviceType = 0;
> + /* DEVICE_CONNECTED */
> + VPDPage83Data.DeviceTypeQualifier = 0;
> + /* VPD_DEVICE_IDENTIFIERS */
> + VPDPage83Data.PageCode = 0x83;
> + VPDPage83Data.Reserved = 0;
> + VPDPage83Data.PageLength = sizeof(VPDPage83Data.IdDescriptorType1) +
> + sizeof(VPDPage83Data.IdDescriptorType2);
> +
> + /* T10 Vendor Identifier Field Format */
> + /* VpdCodeSetAscii */
> + VPDPage83Data.IdDescriptorType1.CodeSet = 2;
> + /* VpdIdentifierTypeVendorId */
> + VPDPage83Data.IdDescriptorType1.IdentifierType = 1;
> + VPDPage83Data.IdDescriptorType1.IdentifierLength =
> +sizeof(VPDPage83Data.IdDescriptorType1) - 4;
> +
Wrong indentation.
> + /* "ADAPTEC " for adaptec */
> + memcpy(VPDPage83Data.IdDescriptorType1.VendId, "ADAPTEC ",
> + sizeof(VPDPage83Data.IdDescriptorType1.VendId));
> + memcpy(VPDPage83Data.IdDescriptorType1.ProductId, "ARRAY ",
> + sizeof(VPDPage83Data.IdDescriptorType1.ProductId));
> +
> + /* Convert to ascii based serial number.
> + * The LSB is the the end.
> + */
> + for (i = 0; i < 8; i++) {
> + u8 temp = (u8)((get_serial_reply->uid >> ((7 - i) * 4)) & 0xF);
> + if (temp > 0x9) {
> + VPDPage83Data.IdDescriptorType1.SerialNumber[i] = 'A' + (temp - 0xA);
> + } else {
> + VPDPage83Data.IdDescriptorType1.SerialNumber[i] = '0' + temp;
> + }
> + }
> +
> + /* EUI-64 Vendor Identifier Field Format,
> + * 24 bits for VendId and 40 bits for SN.
> + */
> + /* VpdCodeSetBinary */
> + VPDPage83Data.IdDescriptorType2.CodeSet = 1;
> + /* VpdIdentifierTypeEUI64 */
> + VPDPage83Data.IdDescriptorType2.IdentifierType = 2;
> + VPDPage83Data.IdDescriptorType2.IdentifierLength =
> +sizeof(VPDPage83Data.IdDescriptorType2) - 4;
> +
Same here.
> + /* 0x0000055 for IBM, 0x0000D0 for Adaptec */
Do you ever use the IBM Vendor ID?
If not, why do you mention it here?
> + VPDPage83Data.IdDescriptorType2.EU64Id.VendId[0] = 0xD0;
> + VPDPage83Data.IdDescriptorType2.EU64Id.VendId[1] = 0;
> + VPDPage83Data.IdDescriptorType2.EU64Id.VendId[2] = 0;
> +
> + VPDPage83Data.IdDescriptorType2.EU64Id.Serial = get_serial_reply->uid;
> + VPDPage83Data.IdDescriptorType2.EU64Id.Reserved = 0;
> +
> + /* Move the inquiry data to the response buffer. */
> + scsi_sg_copy_from_buffer(scsicmd, &VPDPage83Data,
> + sizeof(VPDPage83Data));
> + } else {
> + /* It must be for VPD 0x80 */
> + char sp[13];
> + /* EVPD bit set */
> + sp[0] = INQD_PDT_DA;
> + sp[1] = scsicmd->cmnd[2];
> + sp[2] = 0;
> + sp[3] = snprintf(sp+4, sizeof(sp)-4, "%08X",
> + le32_to_cpu(get_serial_reply->uid));
> + scsi_sg_copy_from_buffer(scsicmd, sp, sizeof(sp));
> + }
> }
>
> scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; @@ -2302,9 +2411,10 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
> INQD_PDT_PROC : INQD_PDT_DA;
> if (scsicmd->cmnd[2] == 0) {
> /* supported vital product data pages */
> - arr[3] = 2;
> + arr[3] = 3;
> arr[4] = 0x0;
> arr[5] = 0x80;
> + arr[6] = 0x83;
> arr[1] = scsicmd->cmnd[2];
> scsi_sg_copy_from_buffer(scsicmd, &inq_data,
> sizeof(inq_data));
> @@ -2323,6 +2433,16 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
> /* SLES 10 SP1 special */
Gods. Are we still in there?
I guess it's time to remove that, at least the comment ...
> scsicmd->result = DID_OK << 16 |
> COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
> + } else if (scsicmd->cmnd[2] == 0x83) {
> + /* vpd page 0x83 - Device Identification Page */
> + char *sno = (char *)&inq_data;
> + sno[3] = setinqserial(dev, &sno[4],
> + scmd_id(scsicmd));
> + if (aac_wwn != 2)
> + return aac_get_container_serial(
> + scsicmd);
> + scsicmd->result = DID_OK << 16 |
> + COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
> } else {
> /* vpd page not implemented */
> scsicmd->result = DID_OK << 16 |
> @@ -2468,6 +2588,15 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
> mpd.bd.block_length[0] = (fsa_dev_ptr[cid].block_size >> 16) & 0xff;
> mpd.bd.block_length[1] = (fsa_dev_ptr[cid].block_size >> 8) & 0xff;
> mpd.bd.block_length[2] = fsa_dev_ptr[cid].block_size & 0xff;
> +
> + mpd.mpc_buf[0] = scsicmd->cmnd[2];
> + if (scsicmd->cmnd[2] == 0x1C) {
> + mpd.mpc_buf[1] = 0xa; /* page length */
> + mpd.hd.data_length = 23; /* Mode data length */
> + } else {
> + mpd.hd.data_length = 15; /* Mode data length */
> + }
> +
> if (capacity > 0xffffff) {
> mpd.bd.block_count[0] = 0xff;
> mpd.bd.block_count[1] = 0xff;
> @@ -2486,9 +2615,12 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
> mpd.mpc_buf[2] = ((aac_cache & 6) == 2)
> ? 0 : 0x04; /* WCE */
> mode_buf_length = sizeof(mpd);
> - if (mode_buf_length > scsicmd->cmnd[4])
> - mode_buf_length = scsicmd->cmnd[4];
> }
> +
> + if (mode_buf_length > scsicmd->cmnd[4])
> + mode_buf_length = scsicmd->cmnd[4];
> + else
> + mode_buf_length = sizeof(mpd);
> scsi_sg_copy_from_buffer(scsicmd, (char *)&mpd, mode_buf_length);
> scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
> scsicmd->scsi_done(scsicmd);
> diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index c162a65..a37762e 100644
> --- a/drivers/scsi/aacraid/aacraid.h
> +++ b/drivers/scsi/aacraid/aacraid.h
> @@ -1015,6 +1015,7 @@ struct aac_supplement_adapter_info
> #define AAC_OPTION_POWER_MANAGEMENT cpu_to_le32(0x00000004)
> #define AAC_OPTION_DOORBELL_RESET cpu_to_le32(0x00004000)
> #define AAC_OPTION_VARIABLE_BLOCK_SIZE cpu_to_le32(0x00040000) /* 4KB sector size */
> +#define AAC_OPTION_SUPPORTED_240_VOLUMES cpu_to_le32(0x10000000)
> #define AAC_SIS_VERSION_V3 3
> #define AAC_SIS_SLOT_UNKNOWN 0xFF
>
> @@ -1212,11 +1213,13 @@ struct aac_dev
> int sync_mode;
> struct fib *sync_fib;
> struct list_head sync_fib_list;
> + u32 doorbell_mask; /* from GET_ADAPTER_PROP */
> u32 max_msix; /* max. MSI-X vectors */
> u32 vector_cap; /* MSI-X vector capab.*/
> int msi_enabled; /* MSI/MSI-X enabled */
> struct msix_entry msixentry[AAC_MAX_MSIX];
> struct aac_msix_ctx aac_msix[AAC_MAX_MSIX]; /* context */
> + u8 adapter_shutdown;
> };
>
> #define aac_adapter_interrupt(dev) \
> @@ -1749,6 +1752,7 @@ struct aac_get_container_count_resp {
> __le32 MaxContainers;
> __le32 ContainerSwitchEntries;
> __le32 MaxPartitions;
> + __le32 MaxSimpleVolumes;
> };
>
>
What exactly has this to do with VPD page support?
Please split if off into a separate patch.
> diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c index 29c35c8..c3e13ae 100644
> --- a/drivers/scsi/aacraid/comminit.c
> +++ b/drivers/scsi/aacraid/comminit.c
> @@ -53,7 +53,7 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co {
> unsigned char *base;
> unsigned long size, align;
> - const unsigned long fibsize = 4096;
> + const unsigned long fibsize = dev->max_fib_size;
> const unsigned long printfbufsiz = 256;
> unsigned long host_rrq_size = 0;
> struct aac_init *init;
> @@ -230,6 +230,7 @@ int aac_send_shutdown(struct aac_dev * dev)
> /* FIB should be freed only after getting the response from the F/W */
> if (status != -ERESTARTSYS)
> aac_fib_free(fibctx);
> + dev->adapter_shutdown = 1;
> if ((dev->pdev->device == PMC_DEVICE_S7 ||
> dev->pdev->device == PMC_DEVICE_S8 ||
> dev->pdev->device == PMC_DEVICE_S9) && @@ -357,8 +358,9 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
> dev->raw_io_interface = dev->raw_io_64 = 0;
>
> if ((!aac_adapter_sync_cmd(dev, GET_ADAPTER_PROPERTIES,
> - 0, 0, 0, 0, 0, 0, status+0, status+1, status+2, NULL, NULL)) &&
> + 0, 0, 0, 0, 0, 0, status+0, status+1, status+2, status+3, NULL)) &&
> (status[0] == 0x00000001)) {
> + dev->doorbell_mask = status[3];
> if (status[1] & le32_to_cpu(AAC_OPT_NEW_COMM_64))
> dev->raw_io_64 = 1;
> dev->sync_mode = aac_sync_mode;
> @@ -397,6 +399,7 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
> }
> dev->max_msix = 0;
> dev->msi_enabled = 0;
> + dev->adapter_shutdown = 0;
> if ((!aac_adapter_sync_cmd(dev, GET_COMM_PREFERRED_SETTINGS,
> 0, 0, 0, 0, 0, 0,
> status+0, status+1, status+2, status+3, status+4)) @@ -508,6 +511,7 @@ static void aac_define_int_mode(struct aac_dev *dev)
>
> int i, msi_count;
>
> + msi_count = i = 0;
> /* max. vectors from GET_COMM_PREFERRED_SETTINGS */
> if (dev->max_msix == 0 ||
> dev->pdev->device == PMC_DEVICE_S6 || diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 83c5d3f..2bed445 100644
> --- a/drivers/scsi/aacraid/commsup.c
> +++ b/drivers/scsi/aacraid/commsup.c
> @@ -208,14 +208,11 @@ struct fib *aac_fib_alloc(struct aac_dev *dev)
>
> void aac_fib_free(struct fib *fibptr)
> {
> - unsigned long flags, flagsv;
> + unsigned long flags;
>
> - spin_lock_irqsave(&fibptr->event_lock, flagsv);
> if (fibptr->done == 2) {
> - spin_unlock_irqrestore(&fibptr->event_lock, flagsv);
> return;
> }
> - spin_unlock_irqrestore(&fibptr->event_lock, flagsv);
>
> spin_lock_irqsave(&fibptr->dev->fib_lock, flags);
> if (unlikely(fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT)) @@ -775,7 +772,6 @@ int aac_fib_adapter_complete(struct fib *fibptr, unsigned short size)
>
> int aac_fib_complete(struct fib *fibptr) {
> - unsigned long flags;
> struct hw_fib * hw_fib = fibptr->hw_fib_va;
>
> /*
> @@ -798,12 +794,6 @@ int aac_fib_complete(struct fib *fibptr)
> * command is complete that we had sent to the adapter and this
> * cdb could be reused.
> */
> - spin_lock_irqsave(&fibptr->event_lock, flags);
> - if (fibptr->done == 2) {
> - spin_unlock_irqrestore(&fibptr->event_lock, flags);
> - return 0;
> - }
> - spin_unlock_irqrestore(&fibptr->event_lock, flags);
>
> if((hw_fib->header.XferState & cpu_to_le32(SentFromHost)) &&
> (hw_fib->header.XferState & cpu_to_le32(AdapterProcessed))) diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 7813a9b..4c5ba9e 100644
> --- a/drivers/scsi/aacraid/linit.c
> +++ b/drivers/scsi/aacraid/linit.c
> @@ -56,7 +56,7 @@
>
> #include "aacraid.h"
>
> -#define AAC_DRIVER_VERSION "1.2-0"
> +#define AAC_DRIVER_VERSION "1.2-1"
> #ifndef AAC_DRIVER_BRANCH
> #define AAC_DRIVER_BRANCH ""
> #endif
> @@ -65,7 +65,7 @@
> #ifdef AAC_DRIVER_BUILD
> #define _str(x) #x
> #define str(x) _str(x)
> -#define AAC_DRIVER_FULL_VERSION AAC_DRIVER_VERSION "[" str(AAC_DRIVER_BUILD) "]" AAC_DRIVER_BRANCH
> +#define AAC_DRIVER_FULL_VERSION AAC_DRIVER_VERSION "." str(AAC_DRIVER_BUILD) "" AAC_DRIVER_BRANCH
> #else
> #define AAC_DRIVER_FULL_VERSION AAC_DRIVER_VERSION AAC_DRIVER_BRANCH
> #endif
> @@ -253,19 +253,7 @@ static struct aac_driver_ident aac_drivers[] = {
>
> static int aac_queuecommand_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) {
> - struct Scsi_Host *host = cmd->device->host;
> - struct aac_dev *dev = (struct aac_dev *)host->hostdata;
> - u32 count = 0;
> cmd->scsi_done = done;
> - for (; count < (host->can_queue + AAC_NUM_MGT_FIB); ++count) {
> - struct fib * fib = &dev->fibs[count];
> - struct scsi_cmnd * command;
> - if (fib->hw_fib_va->header.XferState &&
> - ((command = fib->callback_data)) &&
> - (command == cmd) &&
> - (cmd->SCp.phase == AAC_OWNER_FIRMWARE))
> - return 0; /* Already owned by Adapter */
> - }
> cmd->SCp.phase = AAC_OWNER_LOWLEVEL;
> return (aac_scsi_cmd(cmd) ? FAILED : 0); } @@ -713,7 +701,9 @@ static long aac_cfg_ioctl(struct file *file,
> unsigned int cmd, unsigned long arg)
> {
> int ret;
> - if (!capable(CAP_SYS_RAWIO))
> + struct aac_dev *aac;
> + aac = (struct aac_dev *)file->private_data;
> + if (!capable(CAP_SYS_RAWIO) || aac->adapter_shutdown)
> return -EPERM;
> mutex_lock(&aac_mutex);
> ret = aac_do_ioctl(file->private_data, cmd, (void __user *)arg); diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c index c010248..82ff025 100644
> --- a/drivers/scsi/aacraid/src.c
> +++ b/drivers/scsi/aacraid/src.c
> @@ -200,6 +200,7 @@ static int src_sync_cmd(struct aac_dev *dev, u32 command,
> u32 *status, u32 * r1, u32 * r2, u32 * r3, u32 * r4) {
> unsigned long start;
> + unsigned long delay;
> int ok;
>
> /*
> @@ -240,10 +241,15 @@ static int src_sync_cmd(struct aac_dev *dev, u32 command,
> ok = 0;
> start = jiffies;
>
> - /*
> - * Wait up to 5 minutes
> - */
> - while (time_before(jiffies, start+300*HZ)) {
> + if (command == IOP_RESET_ALWAYS) {
> + /* Wait up to 10 sec */
> + delay = 10*HZ;
> + } else {
> + /* Wait up to 5 minutes */
> + delay = 300*HZ;
> + }
> + while (time_before(jiffies, start+delay)) {
> +
> udelay(5); /* Delay 5 microseconds to let Mon960 get info. */
> /*
> * Mon960 will set doorbell0 bit when it has completed the command.
> @@ -562,10 +568,16 @@ static int aac_src_restart_adapter(struct aac_dev *dev, int bled)
> if (bled)
> printk(KERN_ERR "%s%d: adapter kernel panic'd %x.\n",
> dev->name, dev->id, bled);
> + dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
> bled = aac_adapter_sync_cmd(dev, IOP_RESET_ALWAYS,
> 0, 0, 0, 0, 0, 0, &var, &reset_mask, NULL, NULL, NULL);
> - if (bled || (var != 0x00000001))
> + if ((bled || (var != 0x00000001)) && !dev->doorbell_mask)
> return -EINVAL;
> + else if (dev->doorbell_mask) {
> + reset_mask = dev->doorbell_mask;
> + bled = 0;
> + var = 0x00000001;
> + }
>
> if ((dev->pdev->device == PMC_DEVICE_S7 ||
> dev->pdev->device == PMC_DEVICE_S8 || @@ -575,10 +587,13 @@ static int aac_src_restart_adapter(struct aac_dev *dev, int bled)
> msleep(5000); /* Delay 5 seconds */
> }
>
> - if (dev->supplement_adapter_info.SupportedOptions2 &
> - AAC_OPTION_DOORBELL_RESET) {
> + if (!bled && (dev->supplement_adapter_info.SupportedOptions2 &
> + AAC_OPTION_DOORBELL_RESET)) {
> src_writel(dev, MUnit.IDR, reset_mask);
> ssleep(45);
> + } else {
> + src_writel(dev, MUnit.IDR, 0x100);
> + ssleep(45);
> }
> }
>
> @@ -600,7 +615,6 @@ int aac_src_select_comm(struct aac_dev *dev, int comm) {
> switch (comm) {
> case AAC_COMM_MESSAGE:
> - dev->a_ops.adapter_enable_int = aac_src_enable_interrupt_message;
> dev->a_ops.adapter_intr = aac_src_intr_message;
> dev->a_ops.adapter_deliver = aac_src_deliver_message;
> break;
> @@ -698,6 +712,7 @@ int aac_src_init(struct aac_dev *dev)
> */
> dev->a_ops.adapter_interrupt = aac_src_interrupt_adapter;
> dev->a_ops.adapter_disable_int = aac_src_disable_interrupt;
> + dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
> dev->a_ops.adapter_notify = aac_src_notify_adapter;
> dev->a_ops.adapter_sync_cmd = src_sync_cmd;
> dev->a_ops.adapter_check_health = aac_src_check_health; @@ -735,6 +750,7 @@ int aac_src_init(struct aac_dev *dev)
> dev->dbg_base = pci_resource_start(dev->pdev, 2);
> dev->dbg_base_mapped = dev->regs.src.bar1;
> dev->dbg_size = AAC_MIN_SRC_BAR1_SIZE;
> + dev->a_ops.adapter_enable_int = aac_src_enable_interrupt_message;
>
> aac_adapter_enable_int(dev);
>
> @@ -861,6 +877,7 @@ int aac_srcv_init(struct aac_dev *dev)
> */
> dev->a_ops.adapter_interrupt = aac_src_interrupt_adapter;
> dev->a_ops.adapter_disable_int = aac_src_disable_interrupt;
> + dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
> dev->a_ops.adapter_notify = aac_src_notify_adapter;
> dev->a_ops.adapter_sync_cmd = src_sync_cmd;
> dev->a_ops.adapter_check_health = aac_src_check_health; @@ -913,6 +930,7 @@ int aac_srcv_init(struct aac_dev *dev)
> dev->dbg_base = dev->base_start;
> dev->dbg_base_mapped = dev->base;
> dev->dbg_size = dev->base_size;
> + dev->a_ops.adapter_enable_int = aac_src_enable_interrupt_message;
>
> aac_adapter_enable_int(dev);
>
> --
> 1.7.7.3
>
Please split off the unrelated bits into a separate patch. Otherwise
tracking and regression testing becomes really hard.
Cheers,
Hannes
--
Dr. Hannes Reinecke zSeries & Storage
hare@suse.de +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 6/7] aacraid: performance improvement changes
2015-03-17 15:27 ` Achim Leubner
@ 2015-03-18 11:27 ` Hannes Reinecke
0 siblings, 0 replies; 32+ messages in thread
From: Hannes Reinecke @ 2015-03-18 11:27 UTC (permalink / raw)
To: Achim Leubner, Mahesh Rajashekhara, JBottomley, linux-scsi
On 03/17/2015 04:27 PM, Achim Leubner wrote:
> Reviewed-by: Achim Leubner <Achim.Leubner@pmcs.com>
>
>
> -----Original Message-----
> From: Mahesh Rajashekhara
> Sent: Wednesday, March 4, 2015 9:39 AM
> To: JBottomley@Parallels.com; linux-scsi@vger.kernel.org
> Cc: aacraid@pmc-sierra.com; Harry Yang; Achim Leubner; Rajinikanth Pandurangan; Rich Bono; Mahesh Rajashekhara
> Subject: [PATCH 6/7] aacraid: performance improvement changes
>
> Add performance improvement changes.
>
> Signed-off-by: Mahesh Rajashekhara <Mahesh.Rajashekhara@pmcs.com>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Cheers,
Hannes
--
Dr. Hannes Reinecke zSeries & Storage
hare@suse.de +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 7/7] aacraid: AIF raw device remove support
2015-03-17 15:28 ` Achim Leubner
@ 2015-03-18 11:29 ` Hannes Reinecke
2015-03-26 14:43 ` Mahesh Rajashekhara
0 siblings, 1 reply; 32+ messages in thread
From: Hannes Reinecke @ 2015-03-18 11:29 UTC (permalink / raw)
To: Achim Leubner, Mahesh Rajashekhara, JBottomley, linux-scsi
On 03/17/2015 04:28 PM, Achim Leubner wrote:
> Reviewed-by: Achim Leubner <Achim.Leubner@pmcs.com>
>
>
> -----Original Message-----
> From: Mahesh Rajashekhara
> Sent: Wednesday, March 4, 2015 9:39 AM
> To: JBottomley@Parallels.com; linux-scsi@vger.kernel.org
> Cc: aacraid@pmc-sierra.com; Harry Yang; Achim Leubner; Rajinikanth Pandurangan; Rich Bono; Mahesh Rajashekhara
> Subject: [PATCH 7/7] aacraid: AIF raw device remove support
>
> Add AIF raw device remove support
>
> Signed-off-by: Mahesh Rajashekhara <Mahesh.Rajashekhara@pmcs.com>
Reviewed-by: Hannes Reinecke <hare@suse.de>
But please split off the unrelated patches from the VPD support one.
And I would recommend to split off the version increase into a
separate one, too, to be applied at the end.
Otherwise it'll be hard to track which patches belong to which version.
Cheers,
Hannes
--
Dr. Hannes Reinecke zSeries & Storage
hare@suse.de +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 32+ messages in thread
* RE: [PATCH 7/7] aacraid: AIF raw device remove support
2015-03-18 11:29 ` Hannes Reinecke
@ 2015-03-26 14:43 ` Mahesh Rajashekhara
0 siblings, 0 replies; 32+ messages in thread
From: Mahesh Rajashekhara @ 2015-03-26 14:43 UTC (permalink / raw)
To: Hannes Reinecke, Achim Leubner, JBottomley, linux-scsi
Thanks for your review comments. I have prepared V2 patch set and in which I have taken care all your review comments.
Regards,
Mahesh
-----Original Message-----
From: Hannes Reinecke [mailto:hare@suse.de]
Sent: Wednesday, March 18, 2015 4:59 PM
To: Achim Leubner; Mahesh Rajashekhara; JBottomley@Parallels.com; linux-scsi@vger.kernel.org
Subject: Re: [PATCH 7/7] aacraid: AIF raw device remove support
On 03/17/2015 04:28 PM, Achim Leubner wrote:
> Reviewed-by: Achim Leubner <Achim.Leubner@pmcs.com>
>
>
> -----Original Message-----
> From: Mahesh Rajashekhara
> Sent: Wednesday, March 4, 2015 9:39 AM
> To: JBottomley@Parallels.com; linux-scsi@vger.kernel.org
> Cc: aacraid@pmc-sierra.com; Harry Yang; Achim Leubner; Rajinikanth
> Pandurangan; Rich Bono; Mahesh Rajashekhara
> Subject: [PATCH 7/7] aacraid: AIF raw device remove support
>
> Add AIF raw device remove support
>
> Signed-off-by: Mahesh Rajashekhara <Mahesh.Rajashekhara@pmcs.com>
Reviewed-by: Hannes Reinecke <hare@suse.de>
But please split off the unrelated patches from the VPD support one.
And I would recommend to split off the version increase into a separate one, too, to be applied at the end.
Otherwise it'll be hard to track which patches belong to which version.
Cheers,
Hannes
--
Dr. Hannes Reinecke zSeries & Storage
hare@suse.de +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton HRB 21284 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 32+ messages in thread
end of thread, other threads:[~2015-03-26 14:43 UTC | newest]
Thread overview: 32+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-04 8:38 [PATCH 0/7] aacraid driver updates Mahesh Rajashekhara
2015-03-04 8:38 ` [PATCH 1/7] aacraid: AIF support for SES device add/remove Mahesh Rajashekhara
2015-03-17 7:05 ` Murthy Bhat
2015-03-17 15:24 ` Achim Leubner
2015-03-18 11:02 ` Hannes Reinecke
2015-03-04 8:38 ` [PATCH 2/7] aacraid: IOCTL pass-through command fix Mahesh Rajashekhara
2015-03-17 7:06 ` Murthy Bhat
2015-03-17 15:26 ` Achim Leubner
2015-03-18 11:03 ` Hannes Reinecke
2015-03-04 8:38 ` [PATCH 3/7] aacraid: 4KB sector support Mahesh Rajashekhara
2015-03-17 7:06 ` Murthy Bhat
2015-03-17 15:26 ` Achim Leubner
2015-03-18 11:06 ` Hannes Reinecke
2015-03-04 8:38 ` [PATCH 4/7] aacraid: MSI-x support Mahesh Rajashekhara
2015-03-17 7:06 ` Murthy Bhat
2015-03-17 15:27 ` Achim Leubner
2015-03-18 11:18 ` Hannes Reinecke
2015-03-04 8:38 ` [PATCH 5/7] aacraid: vpd page code 0x83 support Mahesh Rajashekhara
2015-03-17 7:06 ` Murthy Bhat
2015-03-17 15:27 ` Achim Leubner
2015-03-18 11:26 ` Hannes Reinecke
2015-03-04 8:38 ` [PATCH 6/7] aacraid: performance improvement changes Mahesh Rajashekhara
2015-03-17 7:07 ` Murthy Bhat
2015-03-17 15:27 ` Achim Leubner
2015-03-18 11:27 ` Hannes Reinecke
2015-03-04 8:38 ` [PATCH 7/7] aacraid: AIF raw device remove support Mahesh Rajashekhara
2015-03-17 7:07 ` Murthy Bhat
2015-03-17 15:28 ` Achim Leubner
2015-03-18 11:29 ` Hannes Reinecke
2015-03-26 14:43 ` Mahesh Rajashekhara
2015-03-16 11:24 ` [PATCH 0/7] aacraid driver updates Mahesh Rajashekhara
2015-03-16 12:49 ` James Bottomley
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.