RE: [PATCH 1/7] aacraid: AIF support for SES device add/remove

2015-03-17 Thread Murthy Bhat
Reviewed-by: Murthy Bhat 

-Original Message-
From: Mahesh Rajashekhara 
Sent: Wednesday, March 04, 2015 2:08 PM
To: jbottom...@parallels.com; linux-scsi@vger.kernel.org
Cc: aacr...@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 
---
 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;
 #defineAifEnEnclosureManagement 13 /* EM_DRIVE_* */
 #defineEM_DRIVE_INSERTION  31
 #defineEM_DRIVE_REMOVAL32
+#defineEM_SES_DRIVE_INSERTION  33
+#defineEM_SES_DRIVE_REMOVAL26
 #defineAifEnBatteryEvent   14  /* Change in 
Battery State */
 #defineAifEnAddContainer   15  /* A new array 
was created */
 #defineAifEnDeleteContainer16  /* 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

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH 3/7] aacraid: 4KB sector support

2015-03-17 Thread Murthy Bhat
Reviewed-by: Murthy Bhat 

-Original Message-
From: Mahesh Rajashekhara 
Sent: Wednesday, March 04, 2015 2:08 PM
To: jbottom...@parallels.com; linux-scsi@vger.kernel.org
Cc: aacr...@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 
---
 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&0x));
readcmd2->blockHigh = 
cpu_to_le32((u32)((lba&0xLL)>>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));

RE: [PATCH 7/7] aacraid: AIF raw device remove support

2015-03-17 Thread Murthy Bhat
Reviewed-by: Murthy Bhat 

-Original Message-
From: Mahesh Rajashekhara 
Sent: Wednesday, March 04, 2015 2:09 PM
To: jbottom...@parallels.com; linux-scsi@vger.kernel.org
Cc: aacr...@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 
---
 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 */
 #defineAifReqEvent 200
 
+/* RAW device deleted */
+#defineAifRawDeviceRemove  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 & 0x;
+   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

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH 2/7] aacraid: IOCTL pass-through command fix

2015-03-17 Thread Murthy Bhat
Reviewed-by: Murthy Bhat 

-Original Message-
From: Mahesh Rajashekhara 
Sent: Wednesday, March 04, 2015 2:08 PM
To: jbottom...@parallels.com; linux-scsi@vger.kernel.org
Cc: aacr...@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 
---
 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

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH 5/7] aacraid: vpd page code 0x83 support

2015-03-17 Thread Murthy Bhat
Reviewed-by: Murthy Bhat 

-Original Message-
From: Mahesh Rajashekhara 
Sent: Wednesday, March 04, 2015 2:09 PM
To: jbottom...@parallels.com; linux-scsi@vger.kernel.org
Cc: aacr...@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 
---
 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.IdDesc

RE: [PATCH 4/7] aacraid: MSI-x support

2015-03-17 Thread Murthy Bhat
Reviewed-by: Murthy Bhat 

-Original Message-
From: Mahesh Rajashekhara 
Sent: Wednesday, March 04, 2015 2:09 PM
To: jbottom...@parallels.com; linux-scsi@vger.kernel.org
Cc: aacr...@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 
---
 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 
+#include 
 
 
/*--
  *  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  0xfffb
+#define AAC_INT_ENABLE_TYPE1_MSIX  0xfffa
+#define AAC_INT_DISABLE_ALL0x
+
+/* Bit definitions in IOA->Host Interrupt Register */
+#define PMC_TRANSITION_TO_OPERATIONAL  (0x8000 >> 0)
+#define PMC_IOARCB_TRANSFER_FAILED (0x8000 >> 3)
+#define PMC_IOA_UNIT_CHECK (0x8000 >> 4)
+#define PMC_NO_HOST_RRQ_FOR_CMD_RESPONSE (0x8000 >> 5)
+#define PMC_CRITICAL_IOA_OP_IN_PROGRESS(0x8000 >> 6)
+#define PMC_IOARRIN_LOST   (0x8000 >> 27)
+#define PMC_SYSTEM_BUS_MMIO_ERROR  (0x8000 >> 28)
+#define PMC_IOA_PROCESSOR_IN_ERROR_STATE (0x8000 >> 29)
+#define PMC_HOST_RRQ_VALID (0x8000 >> 30)
+#define PMC_OPERATIONAL_STATUS (0x8000 >> 0)
+#define PMC_ALLOW_MSIX_VECTOR0 (0x8000 >> 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)
+#definePMC_GLOBAL_INT_BIT2 0x0004
+#definePMC_GLOBAL_INT_BIT0 0x0001
+
 #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  

RE: [PATCH 6/7] aacraid: performance improvement changes

2015-03-17 Thread Murthy Bhat
Reviewed-by: Murthy Bhat 

-Original Message-
From: Mahesh Rajashekhara 
Sent: Wednesday, March 04, 2015 2:09 PM
To: jbottom...@parallels.com; linux-scsi@vger.kernel.org
Cc: aacr...@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 
---
 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 {
 #definePMC_GLOBAL_INT_BIT0 0x0001
 
 #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_headcmdq;   /* 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_tnumpending; /* 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];
-  

RE: [PATCH 3/7] aacraid: 4KB sector support

2015-03-17 Thread Achim Leubner
Reviewed-by: Achim Leubner 


-Original Message-
From: Mahesh Rajashekhara 
Sent: Wednesday, March 4, 2015 9:38 AM
To: jbottom...@parallels.com; linux-scsi@vger.kernel.org
Cc: aacr...@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 
---
 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&0x));
readcmd2->blockHigh = 
cpu_to_le32((u32)((lba&0xLL)>>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));
  

RE: [PATCH 6/7] aacraid: performance improvement changes

2015-03-17 Thread Achim Leubner
Reviewed-by: Achim Leubner 


-Original Message-
From: Mahesh Rajashekhara 
Sent: Wednesday, March 4, 2015 9:39 AM
To: jbottom...@parallels.com; linux-scsi@vger.kernel.org
Cc: aacr...@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 
---
 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 {
 #definePMC_GLOBAL_INT_BIT0 0x0001
 
 #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_headcmdq;   /* 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_tnumpending; /* 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];
-

RE: [PATCH 7/7] aacraid: AIF raw device remove support

2015-03-17 Thread Achim Leubner
Reviewed-by: Achim Leubner 


-Original Message-
From: Mahesh Rajashekhara 
Sent: Wednesday, March 4, 2015 9:39 AM
To: jbottom...@parallels.com; linux-scsi@vger.kernel.org
Cc: aacr...@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 
---
 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 */
 #defineAifReqEvent 200
 
+/* RAW device deleted */
+#defineAifRawDeviceRemove  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 & 0x;
+   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

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH 1/7] aacraid: AIF support for SES device add/remove

2015-03-17 Thread Achim Leubner
Reviewed-by: Achim Leubner 

-Original Message-
From: Mahesh Rajashekhara 
Sent: Wednesday, March 4, 2015 9:38 AM
To: jbottom...@parallels.com; linux-scsi@vger.kernel.org
Cc: aacr...@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 
---
 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;
 #defineAifEnEnclosureManagement 13 /* EM_DRIVE_* */
 #defineEM_DRIVE_INSERTION  31
 #defineEM_DRIVE_REMOVAL32
+#defineEM_SES_DRIVE_INSERTION  33
+#defineEM_SES_DRIVE_REMOVAL26
 #defineAifEnBatteryEvent   14  /* Change in 
Battery State */
 #defineAifEnAddContainer   15  /* A new array 
was created */
 #defineAifEnDeleteContainer16  /* 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

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH 2/7] aacraid: IOCTL pass-through command fix

2015-03-17 Thread Achim Leubner
Reviewed-by: Achim Leubner 

-Original Message-
From: Mahesh Rajashekhara 
Sent: Wednesday, March 4, 2015 9:38 AM
To: jbottom...@parallels.com; linux-scsi@vger.kernel.org
Cc: aacr...@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 
---
 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

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH 5/7] aacraid: vpd page code 0x83 support

2015-03-17 Thread Achim Leubner
Reviewed-by: Achim Leubner 


-Original Message-
From: Mahesh Rajashekhara 
Sent: Wednesday, March 4, 2015 9:39 AM
To: jbottom...@parallels.com; linux-scsi@vger.kernel.org
Cc: aacr...@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 
---
 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.Id

RE: [PATCH 4/7] aacraid: MSI-x support

2015-03-17 Thread Achim Leubner
Reviewed-by: Achim Leubner 


-Original Message-
From: Mahesh Rajashekhara 
Sent: Wednesday, March 4, 2015 9:39 AM
To: jbottom...@parallels.com; linux-scsi@vger.kernel.org
Cc: aacr...@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 
---
 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 
+#include 
 
 
/*--
  *  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  0xfffb
+#define AAC_INT_ENABLE_TYPE1_MSIX  0xfffa
+#define AAC_INT_DISABLE_ALL0x
+
+/* Bit definitions in IOA->Host Interrupt Register */
+#define PMC_TRANSITION_TO_OPERATIONAL  (0x8000 >> 0)
+#define PMC_IOARCB_TRANSFER_FAILED (0x8000 >> 3)
+#define PMC_IOA_UNIT_CHECK (0x8000 >> 4)
+#define PMC_NO_HOST_RRQ_FOR_CMD_RESPONSE (0x8000 >> 5)
+#define PMC_CRITICAL_IOA_OP_IN_PROGRESS(0x8000 >> 6)
+#define PMC_IOARRIN_LOST   (0x8000 >> 27)
+#define PMC_SYSTEM_BUS_MMIO_ERROR  (0x8000 >> 28)
+#define PMC_IOA_PROCESSOR_IN_ERROR_STATE (0x8000 >> 29)
+#define PMC_HOST_RRQ_VALID (0x8000 >> 30)
+#define PMC_OPERATIONAL_STATUS (0x8000 >> 0)
+#define PMC_ALLOW_MSIX_VECTOR0 (0x8000 >> 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)
+#definePMC_GLOBAL_INT_BIT2 0x0004
+#definePMC_GLOBAL_INT_BIT0 0x0001
+
 #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

[PATCH] scsi: sd: add a capacity_override attribute

2015-03-17 Thread Alan Stern
This patch provides a sysfs interface allowing users to override the
capacity of a SCSI disk.  This will help in situations where a buggy
USB-SATA adapter fails to support READ CAPACITY(16) and reports only
the low 32 bits of the capacity in its READ CAPACITY(10) reply.  For
an example, see this thread:

http://marc.info/?l=linux-scsi&m=140908235510961&w=2

The interface is awkward because it requires the user to tell the
system to re-read the disk's partition table afterward, but at least
it provides a way to handle deficient hardware.

Signed-off-by: Alan Stern 
CC: Dale R. Worley 

---


[as1777]


 Documentation/ABI/testing/sysfs-class-scsi_disk |   19 
 drivers/scsi/sd.c   |   37 
 drivers/scsi/sd.h   |1 
 3 files changed, 57 insertions(+)

Index: usb-4.0/Documentation/ABI/testing/sysfs-class-scsi_disk
===
--- /dev/null
+++ usb-4.0/Documentation/ABI/testing/sysfs-class-scsi_disk
@@ -0,0 +1,19 @@
+What:  /sys/class/scsi_disk/HOST:CHANNEL:TARGET:LUN/capacity_override
+Date:  March 2015
+KernelVersion: 4.1
+Contact:   Alan Stern 
+Description:
+   This file provides a way for users to override the
+   automatically determined disk capacity.  For example, some
+   buggy USB-SATA adapters report only the low 32 bits of a
+   drive's block count, resulting in a calculated capacity
+   value that is the actual capacity modulo 2 TB.
+
+   After the correct capacity (in native-size blocks -- often
+   512 bytes per block but sometimes 4096) is written to this
+   file, the user must tell the system to re-read the disk's
+   partition table by running the command:
+
+   /usr/sbin/blockdev --rereadpt /dev/sdX
+
+   where X is the disk's drive letter.
Index: usb-4.0/drivers/scsi/sd.h
===
--- usb-4.0.orig/drivers/scsi/sd.h
+++ usb-4.0/drivers/scsi/sd.h
@@ -66,6 +66,7 @@ struct scsi_disk {
struct gendisk  *disk;
atomic_topeners;
sector_tcapacity;   /* size in 512-byte sectors */
+   sector_tcapacity_override;  /* in native-size blocks */
u32 max_xfer_blocks;
u32 max_ws_blocks;
u32 max_unmap_blocks;
Index: usb-4.0/drivers/scsi/sd.c
===
--- usb-4.0.orig/drivers/scsi/sd.c
+++ usb-4.0/drivers/scsi/sd.c
@@ -477,6 +477,35 @@ max_write_same_blocks_store(struct devic
 }
 static DEVICE_ATTR_RW(max_write_same_blocks);
 
+static ssize_t
+capacity_override_show(struct device *dev, struct device_attribute *attr,
+   char *buf)
+{
+   struct scsi_disk *sdkp = to_scsi_disk(dev);
+
+   return sprintf(buf, "%llu\n",
+   (unsigned long long) sdkp->capacity_override);
+}
+
+static ssize_t
+capacity_override_store(struct device *dev, struct device_attribute *attr,
+   const char *buf, size_t count)
+{
+   struct scsi_disk *sdkp = to_scsi_disk(dev);
+   unsigned long long cap;
+   int err;
+
+   if (!capable(CAP_SYS_ADMIN))
+   return -EACCES;
+
+   err = kstrtoull(buf, 10, &cap);
+   if (err)
+   return err;
+   sdkp->capacity_override = cap;
+   return count;
+}
+static DEVICE_ATTR_RW(capacity_override);
+
 static struct attribute *sd_disk_attrs[] = {
&dev_attr_cache_type.attr,
&dev_attr_FUA.attr,
@@ -489,6 +518,7 @@ static struct attribute *sd_disk_attrs[]
&dev_attr_provisioning_mode.attr,
&dev_attr_max_write_same_blocks.attr,
&dev_attr_max_medium_access_timeouts.attr,
+   &dev_attr_capacity_override.attr,
NULL,
 };
 ATTRIBUTE_GROUPS(sd_disk);
@@ -2152,6 +2182,13 @@ sd_read_capacity(struct scsi_disk *sdkp,
struct scsi_device *sdp = sdkp->device;
sector_t old_capacity = sdkp->capacity;
 
+   /* Did the user override the reported capacity? */
+   if (!sdkp->first_scan && sdkp->capacity_override) {
+   sector_size = sdkp->device->sector_size;
+   sdkp->capacity = sdkp->capacity_override;
+   goto got_data;
+   }
+
if (sd_try_rc16_first(sdp)) {
sector_size = read_capacity_16(sdkp, sdp, buffer);
if (sector_size == -EOVERFLOW)

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


hyvää päivää

2015-03-17 Thread Loan
hyvää päivää

Hanki laina tänään Loan Engine, jonka korko on 3%. täyttää
Lomake jos kiinnostaa:

Sukupuoli:
Maa:
Tarvittava määrä:
Kesto:
Mission:

On monia syitä, miksi lainan voi auttaa

terveiset

Ana Paula
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 00/42] hpsa updates

2015-03-17 Thread Don Brace
These patches are based on Linus's tree

The changes are:
 - make function names consistent
 - refactor functions
 - cleanup driver messages
 - cleanup error handling
 - clean up abort management
 - enhance sense data reporting
 - enhance ioaccel command support
 - add in block layer tag support
 - clean up resets
 - update copyright

---

Don Brace (2):
  hpsa: change driver version
  hpsa: add PMC to copyright

Joe Handzik (3):
  hpsa: use ioaccel2 path to submit IOs to physical drives in HBA mode.
  hpsa: Get queue depth from identify physical bmic for physical disks.
  hpsa: add more ioaccel2 error handling, including underrun statuses.

Robert Elliott (18):
  hpsa: make function names consistent
  hpsa: print accurate SSD Smart Path Enabled status
  hpsa: break hpsa_free_irqs_and_disable_msix into two functions
  hpsa: clean up error handling
  hpsa: refactor freeing of resources into more logical functions
  hpsa: do not check cmd_alloc return value - it cannnot return NULL
  hpsa: correct return values from driver functions.
  hpsa: clean up driver init
  hpsa: clean up some error reporting output in abort handler
  hpsa: do not print ioaccel2 warning messages about unusual completions.
  hpsa: call pci_release_regions after pci_disable_device
  hpsa: skip free_irq calls if irqs are not allocated
  hpsa: cleanup for init_one step 2 in kdump
  hpsa: fix try_soft_reset error handling
  hpsa: create workqueue after the driver is ready for use
  hpsa: add interrupt number to /proc/interrupts interrupt name
  hpsa: use scsi host_no as hpsa controller number
  hpsa: propagate the error code in hpsa_kdump_soft_reset

Stephen Cameron (9):
  hpsa: add masked physical devices into h->dev[] array
  hpsa: clean up aborts
  hpsa: decrement h->commands_outstanding in fail_all_outstanding_cmds
  hpsa: hpsa decode sense data for io and tmf
  hpsa: allow lockup detected to be viewed via sysfs
  hpsa: factor out hpsa_init_cmd function
  hpsa: do not ignore return value of hpsa_register_scsi
  hpsa: try resubmitting down raid path on task set full
  hpsa: add support sending aborts to physical devices via the ioaccel2 path

Webb Scales (10):
  hpsa: clean up host, channel, target, lun prints
  hpsa: rework controller command submission
  hpsa: factor out hpsa_ioaccel_submit function
  hpsa: add ioaccel sg chaining for the ioaccel2 path
  hpsa: use helper routines for finishing commands
  hpsa: don't return abort request until target is complete
  hpsa: refactor and rework support for sending TEST_UNIT_READY
  hpsa: performance tweak for hpsa_scatter_gather()
  hpsa: use block layer tag for command allocation
  hpsa: cleanup reset


 drivers/scsi/hpsa.c | 2801 ++-
 drivers/scsi/hpsa.h |   22 
 drivers/scsi/hpsa_cmd.h |   37 +
 3 files changed, 2052 insertions(+), 808 deletions(-)

--
Signature
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 04/42] hpsa: clean up aborts

2015-03-17 Thread Don Brace
From: Stephen Cameron 

Do not send aborts to logical devices that do not support aborts

Instead of relying on what the Smart Array claims for supporting logical
drives, simply try an abort and see how it responds at device discovery
time.  This way devices that do support aborts (e.g. MSA2000) can work
and we do not waste time trying to send aborts to logical drives that do
not support them (important for high IOPS devices.)

While rescanning devices only test whether devices support aborts
the first time we encounter a device rather than every time.

Some Smart Arrays required aborts to be sent with tags in
the wrong endian byte order.  To avoid having to know about
this, we would send two aborts with tags with each endian order.
On high IOPS devices, this turns out to be not such a hot idea.
So we now have a list of the devices that got the tag backwards,
and we only send it one way.

If all available commands are outstanding and the abort handler
is invoked, the abort handler may not be able to allocate a command
and may busy-wait excessivly.  Reserve a small number of commands
for the abort handler and limit the number of concurrent abort
requests to the number of reserved commands.

Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |  176 +--
 drivers/scsi/hpsa.h |4 +
 2 files changed, 147 insertions(+), 33 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 488f81b..fe860a6 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -428,7 +428,7 @@ static ssize_t host_show_hp_ssd_smart_path_status(struct 
device *dev,
 /* List of controllers which cannot be hard reset on kexec with reset_devices 
*/
 static u32 unresettable_controller[] = {
0x324a103C, /* Smart Array P712m */
-   0x324b103C, /* SmartArray P711m */
+   0x324b103C, /* Smart Array P711m */
0x3223103C, /* Smart Array P800 */
0x3234103C, /* Smart Array P400 */
0x3235103C, /* Smart Array P400i */
@@ -470,24 +470,32 @@ static u32 soft_unresettable_controller[] = {
0x409D0E11, /* Smart Array 6400 EM */
 };
 
-static int ctlr_is_hard_resettable(u32 board_id)
+static u32 needs_abort_tags_swizzled[] = {
+   0x323D103C, /* Smart Array P700m */
+   0x324a103C, /* Smart Array P712m */
+   0x324b103C, /* SmartArray P711m */
+};
+
+static int board_id_in_array(u32 a[], int nelems, u32 board_id)
 {
int i;
 
-   for (i = 0; i < ARRAY_SIZE(unresettable_controller); i++)
-   if (unresettable_controller[i] == board_id)
-   return 0;
-   return 1;
+   for (i = 0; i < nelems; i++)
+   if (a[i] == board_id)
+   return 1;
+   return 0;
 }
 
-static int ctlr_is_soft_resettable(u32 board_id)
+static int ctlr_is_hard_resettable(u32 board_id)
 {
-   int i;
+   return !board_id_in_array(unresettable_controller,
+   ARRAY_SIZE(unresettable_controller), board_id);
+}
 
-   for (i = 0; i < ARRAY_SIZE(soft_unresettable_controller); i++)
-   if (soft_unresettable_controller[i] == board_id)
-   return 0;
-   return 1;
+static int ctlr_is_soft_resettable(u32 board_id)
+{
+   return !board_id_in_array(soft_unresettable_controller,
+   ARRAY_SIZE(soft_unresettable_controller), board_id);
 }
 
 static int ctlr_is_resettable(u32 board_id)
@@ -496,6 +504,12 @@ static int ctlr_is_resettable(u32 board_id)
ctlr_is_soft_resettable(board_id);
 }
 
+static int ctlr_needs_abort_tags_swizzled(u32 board_id)
+{
+   return board_id_in_array(needs_abort_tags_swizzled,
+   ARRAY_SIZE(needs_abort_tags_swizzled), board_id);
+}
+
 static ssize_t host_show_resettable(struct device *dev,
struct device_attribute *attr, char *buf)
 {
@@ -2838,6 +2852,50 @@ static int hpsa_volume_offline(struct ctlr_info *h,
return 0;
 }
 
+/*
+ * Find out if a logical device supports aborts by simply trying one.
+ * Smart Array may claim not to support aborts on logical drives, but
+ * if a MSA2000 * is connected, the drives on that will be presented
+ * by the Smart Array as logical drives, and aborts may be sent to
+ * those devices successfully.  So the simplest way to find out is
+ * to simply try an abort and see how the device responds.
+ */
+static int hpsa_device_supports_aborts(struct ctlr_info *h,
+   unsigned char *scsi3addr)
+{
+   struct CommandList *c;
+   struct ErrorInfo *ei;
+   int rc = 0;
+
+   u64 tag = (u64) -1; /* bogus tag */
+
+   /* Assume that physical devices support aborts */
+   if (!is_logical_dev_addr_mode(scsi3addr))
+   return 1;
+
+   c = cmd_alloc(h);
+   if (!c)
+   return -ENOMEM;
+   (void) fill_cmd(c, HPSA_ABORT_MSG, h, &tag, 0, 0, scsi3addr, TYPE_MSG);
+  

[PATCH v3 06/42] hpsa: hpsa decode sense data for io and tmf

2015-03-17 Thread Don Brace
From: Stephen Cameron 

In hba mode, we could get sense data in descriptor format so
we need to handle that.

It's possible for CommandStatus to have value 0x0D
"TMF Function Status", which we should handle.  We will get
this from a P1224 when aborting a non-existent tag, for
example.  The "ScsiStatus" field of the errinfo field
will contain the TMF function status value.

Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |  143 +++
 drivers/scsi/hpsa_cmd.h |9 +++
 2 files changed, 117 insertions(+), 35 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 3a06812..415ec4d 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -43,6 +43,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -268,16 +269,49 @@ static inline struct ctlr_info *shost_to_hba(struct 
Scsi_Host *sh)
return (struct ctlr_info *) *priv;
 }
 
+/* extract sense key, asc, and ascq from sense data.  -1 means invalid. */
+static void decode_sense_data(const u8 *sense_data, int sense_data_len,
+   int *sense_key, int *asc, int *ascq)
+{
+   struct scsi_sense_hdr sshdr;
+   bool rc;
+
+   *sense_key = -1;
+   *asc = -1;
+   *ascq = -1;
+
+   if (sense_data_len < 1)
+   return;
+
+   rc = scsi_normalize_sense(sense_data, sense_data_len, &sshdr);
+   if (rc) {
+   *sense_key = sshdr.sense_key;
+   *asc = sshdr.asc;
+   *ascq = sshdr.ascq;
+   }
+}
+
 static int check_for_unit_attention(struct ctlr_info *h,
struct CommandList *c)
 {
-   if (c->err_info->SenseInfo[2] != UNIT_ATTENTION)
+   int sense_key, asc, ascq;
+   int sense_len;
+
+   if (c->err_info->SenseLen > sizeof(c->err_info->SenseInfo))
+   sense_len = sizeof(c->err_info->SenseInfo);
+   else
+   sense_len = c->err_info->SenseLen;
+
+   decode_sense_data(c->err_info->SenseInfo, sense_len,
+   &sense_key, &asc, &ascq);
+   if (sense_key != UNIT_ATTENTION || asc == -1)
return 0;
 
-   switch (c->err_info->SenseInfo[12]) {
+   switch (asc) {
case STATE_CHANGED:
-   dev_warn(&h->pdev->dev, HPSA "%d: a state change "
-   "detected, command retried\n", h->ctlr);
+   dev_warn(&h->pdev->dev,
+   HPSA "%d: a state change detected, command retried\n",
+   h->ctlr);
break;
case LUN_FAILED:
dev_warn(&h->pdev->dev,
@@ -1890,6 +1924,34 @@ retry_cmd:
queue_work_on(raw_smp_processor_id(), h->resubmit_wq, &c->work);
 }
 
+/* Returns 0 on success, < 0 otherwise. */
+static int hpsa_evaluate_tmf_status(struct ctlr_info *h,
+   struct CommandList *cp)
+{
+   u8 tmf_status = cp->err_info->ScsiStatus;
+
+   switch (tmf_status) {
+   case CISS_TMF_COMPLETE:
+   /*
+* CISS_TMF_COMPLETE never happens, instead,
+* ei->CommandStatus == 0 for this case.
+*/
+   case CISS_TMF_SUCCESS:
+   return 0;
+   case CISS_TMF_INVALID_FRAME:
+   case CISS_TMF_NOT_SUPPORTED:
+   case CISS_TMF_FAILED:
+   case CISS_TMF_WRONG_LUN:
+   case CISS_TMF_OVERLAPPED_TAG:
+   break;
+   default:
+   dev_warn(&h->pdev->dev, "Unknown TMF status: 0x%02x\n",
+   tmf_status);
+   break;
+   }
+   return -tmf_status;
+}
+
 static void complete_scsi_command(struct CommandList *cp)
 {
struct scsi_cmnd *cmd;
@@ -1897,9 +1959,9 @@ static void complete_scsi_command(struct CommandList *cp)
struct ErrorInfo *ei;
struct hpsa_scsi_dev_t *dev;
 
-   unsigned char sense_key;
-   unsigned char asc;  /* additional sense code */
-   unsigned char ascq; /* additional sense code qualifier */
+   int sense_key;
+   int asc;  /* additional sense code */
+   int ascq; /* additional sense code qualifier */
unsigned long sense_data_size;
 
ei = cp->err_info;
@@ -1934,8 +1996,6 @@ static void complete_scsi_command(struct CommandList *cp)
if (cp->cmd_type == CMD_IOACCEL2)
return process_ioaccel2_completion(h, cp, cmd, dev);
 
-   cmd->result |= ei->ScsiStatus;
-
scsi_set_resid(cmd, ei->ResidualCnt);
if (ei->CommandStatus == 0) {
if (cp->cmd_type == CMD_IOACCEL1)
@@ -1945,16 +2005,6 @@ static void complete_scsi_command(struct CommandList *cp)
return;
}
 
-   /* copy the sense data */
-   if (SCSI_SENSE_BUFFERSIZE < sizeof(ei->SenseInfo))
-   sense_data_size = SCSI_SENSE_BUFFERSIZE;
-   else
-   sense_data_size = sizeof(ei->SenseInf

[PATCH v3 03/42] hpsa: rework controller command submission

2015-03-17 Thread Don Brace
From: Webb Scales 

Allow driver initiated commands to have a timeout.  It does not
yet try to do anything with timeouts on such commands.

We are sending a reset in order to get rid of a command we want to abort.
If we make it return on the same reply queue as the command we want to abort,
the completion of the aborted command will not race with the completion of
the reset command.

Rename hpsa_scsi_do_simple_cmd_core() to hpsa_scsi_do_simple_cmd(), since
this function is the interface for issuing commands to the controller and
not the "core" of that implementation.  Add a parameter to it which allows
the caller to specify the reply queue to be used.  Modify existing callers
to specify the default reply queue.

Rename __hpsa_scsi_do_simple_cmd_core() to hpsa_scsi_do_simple_cmd_core(),
since this routine is the "core" implementation of the "do simple command"
function and there is no longer any other function with a similar name.
Modify the existing callers of this routine (other than
hpsa_scsi_do_simple_cmd()) to instead call hpsa_scsi_do_simple_cmd(), since
it will now accept the reply_queue paramenter, and it provides a controller
lock-up check.  (Also, tweak two related message strings to make them
distinct from each other.)

Submitting a command to a locked up controller always results in a timeout,
so check for controller lock-up before submitting.

This is to enable fixing a race between command completions and
abort completions on different reply queues in a subsequent patch.
We want to be able to specify which reply queue an abort completion
should occur on so that it cannot race the completion of the command
it is trying to abort.

The following race was possible in theory:

  1. Abort command is sent to hardware.
  2. Command to be aborted simultaneously completes on another
 reply queue.
  3. Hardware receives abort command, decides command has already
 completed and indicates this to the driver via another different
 reply queue.
  4. driver processes abort completion finds that the hardware does not know
 about the command, concludes that therefore the command cannot complete,
 returns SUCCESS indicating to the mid-layer that the scsi_cmnd may be
 re-used.
  5. Command from step 2 is processed and completed back to scsi mid
 layer (after we already promised that would never happen.)

Fix by forcing aborts to complete on the same reply queue as the command
they are aborting.

Piggybacking device rescanning functionality onto the lockup
detection thread is not a good idea because if the controller
locks up during device rescanning, then the thread could get
stuck, then the lockup isn't detected.  Use separate work
queues for device rescanning and lockup detection.

Detect controller lockup in abort handler.

After a lockup is detected, return DO_NO_CONNECT which results in immediate
termination of commands rather than DID_ERR which results in retries.

Modify detect_controller_lockup() to return the result, to remove the need for 
a separate check.

Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Webb Scales 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |  326 ---
 drivers/scsi/hpsa_cmd.h |5 +
 2 files changed, 254 insertions(+), 77 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 9b88726..488f81b 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -253,6 +253,8 @@ static int hpsa_scsi_ioaccel_queue_command(struct ctlr_info 
*h,
struct CommandList *c, u32 ioaccel_handle, u8 *cdb, int cdb_len,
u8 *scsi3addr, struct hpsa_scsi_dev_t *phys_disk);
 static void hpsa_command_resubmit_worker(struct work_struct *work);
+static u32 lockup_detected(struct ctlr_info *h);
+static int detect_controller_lockup(struct ctlr_info *h);
 
 static inline struct ctlr_info *sdev_to_hba(struct scsi_device *sdev)
 {
@@ -748,30 +750,43 @@ static inline u32 next_command(struct ctlr_info *h, u8 q)
  * a separate special register for submitting commands.
  */
 
-/* set_performant_mode: Modify the tag for cciss performant
+/*
+ * set_performant_mode: Modify the tag for cciss performant
  * set bit 0 for pull model, bits 3-1 for block fetch
  * register number
  */
-static void set_performant_mode(struct ctlr_info *h, struct CommandList *c)
+#define DEFAULT_REPLY_QUEUE (-1)
+static void set_performant_mode(struct ctlr_info *h, struct CommandList *c,
+   int reply_queue)
 {
if (likely(h->transMethod & CFGTBL_Trans_Performant)) {
c->busaddr |= 1 | (h->blockFetchTable[c->Header.SGList] << 1);
-   if (likely(h->msix_vector > 0))
+   if (unlikely(!h->msix_vector))
+   return;
+   if (likely(reply_queue == DEFAULT_REPLY_QUEUE))
c->Header.ReplyQueue =
raw_smp_processor_id() % h->nreply_queues;
+ 

[PATCH v3 01/42] hpsa: add masked physical devices into h->dev[] array

2015-03-17 Thread Don Brace
From: Stephen Cameron 

Cache the ioaccel handle so that when we need to abort commands sent
down the ioaccel2 path, we can look up the LUN ID in h->dev[] instead of
having to do I/O to the controller.

Add a field to elements in h->dev[] to keep track of how the device is exposed
to the SCSI mid layer: Not at all, without an upper level driver
(no_uld_attach) or normally exposed.

Since masked physical devices are now present in h->dev[] array
it would be perfectly possible to do

echo scsi add-single-device 2 2 0 0 > /proc/scsi/scsi

and bring them online.  This was previously not allowed for masked
physical devices.

Ensure that the mapping of physical disks to logical drives gets updated in a
consistent way when a RAID migration occurs and is not touched until updates
to it are complete.

now instead of doing CISS_REPORT_PHYSICAL to get the LUNID for
the physical disk in hpsa_get_pdisk_of_ioaccel2(), just get
it out of h->dev[] where we already have it cached.

do not touch phys_disk[] for ioaccel enabled logical drives during rescan

Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |  253 +--
 drivers/scsi/hpsa.h |6 +
 drivers/scsi/hpsa_cmd.h |3 +
 3 files changed, 141 insertions(+), 121 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index a1cfbd3..3417b8b 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -222,6 +222,7 @@ static int hpsa_change_queue_depth(struct scsi_device 
*sdev, int qdepth);
 static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd);
 static int hpsa_eh_abort_handler(struct scsi_cmnd *scsicmd);
 static int hpsa_slave_alloc(struct scsi_device *sdev);
+static int hpsa_slave_configure(struct scsi_device *sdev);
 static void hpsa_slave_destroy(struct scsi_device *sdev);
 
 static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno);
@@ -667,6 +668,9 @@ static struct device_attribute *hpsa_shost_attrs[] = {
NULL,
 };
 
+#define HPSA_NRESERVED_CMDS(HPSA_CMDS_RESERVED_FOR_ABORTS + \
+   HPSA_CMDS_RESERVED_FOR_DRIVER + HPSA_MAX_CONCURRENT_PASSTHRUS)
+
 static struct scsi_host_template hpsa_driver_template = {
.module = THIS_MODULE,
.name   = HPSA,
@@ -681,6 +685,7 @@ static struct scsi_host_template hpsa_driver_template = {
.eh_device_reset_handler = hpsa_eh_device_reset_handler,
.ioctl  = hpsa_ioctl,
.slave_alloc= hpsa_slave_alloc,
+   .slave_configure= hpsa_slave_configure,
.slave_destroy  = hpsa_slave_destroy,
 #ifdef CONFIG_COMPAT
.compat_ioctl   = hpsa_compat_ioctl,
@@ -946,6 +951,8 @@ lun_assigned:
 
h->dev[n] = device;
h->ndevices++;
+   device->offload_to_be_enabled = device->offload_enabled;
+   device->offload_enabled = 0;
added[*nadded] = device;
(*nadded)++;
 
@@ -982,16 +989,20 @@ static void hpsa_scsi_update_entry(struct ctlr_info *h, 
int hostno,
 */
h->dev[entry]->raid_map = new_entry->raid_map;
h->dev[entry]->ioaccel_handle = new_entry->ioaccel_handle;
-   wmb(); /* ensure raid map updated prior to ->offload_enabled */
}
h->dev[entry]->offload_config = new_entry->offload_config;
h->dev[entry]->offload_to_mirror = new_entry->offload_to_mirror;
-   h->dev[entry]->offload_enabled = new_entry->offload_enabled;
h->dev[entry]->queue_depth = new_entry->queue_depth;
 
-   dev_info(&h->pdev->dev, "%s device c%db%dt%dl%d updated.\n",
-   scsi_device_type(new_entry->devtype), hostno, new_entry->bus,
-   new_entry->target, new_entry->lun);
+   /*
+* We can turn off ioaccel offload now, but need to delay turning
+* it on until we can update h->dev[entry]->phys_disk[], but we
+* can't do that until all the devices are updated.
+*/
+   h->dev[entry]->offload_to_be_enabled = new_entry->offload_enabled;
+   if (!new_entry->offload_enabled)
+   h->dev[entry]->offload_enabled = 0;
+
 }
 
 /* Replace an entry from h->dev[] array. */
@@ -1014,6 +1025,8 @@ static void hpsa_scsi_replace_entry(struct ctlr_info *h, 
int hostno,
new_entry->lun = h->dev[entry]->lun;
}
 
+   new_entry->offload_to_be_enabled = new_entry->offload_enabled;
+   new_entry->offload_enabled = 0;
h->dev[entry] = new_entry;
added[*nadded] = new_entry;
(*nadded)++;
@@ -1312,7 +1325,8 @@ static void hpsa_figure_phys_disk_ptrs(struct ctlr_info 
*h,
 */
if (!logical_drive->phys_disk[i]) {
logical_drive->offload_enabled = 0;
-   logical_drive->queue_depth = h->nr_cmds;
+   logical_drive->offload_to_be_enabled = 0;
+

[PATCH v3 05/42] hpsa: decrement h->commands_outstanding in fail_all_outstanding_cmds

2015-03-17 Thread Don Brace
From: Stephen Cameron 

make tracking of outstanding commands more robust

Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index fe860a6..3a06812 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -6945,7 +6945,7 @@ static void fail_all_outstanding_cmds(struct ctlr_info *h)
if (refcount > 1) {
c->err_info->CommandStatus = CMD_CTLR_LOCKUP;
finish_cmd(c);
-   failcount++;
+   atomic_dec(&h->commands_outstanding);
}
cmd_free(h, c);
}

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 02/42] hpsa: clean up host, channel, target, lun prints

2015-03-17 Thread Don Brace
From: Webb Scales 

We had a mix of formats used for specifying controller, bus, target,
and lun address of devices.

change to the format used by the scsi midlayer and upper layer (2:3:0:0)
so you can easily follow the information from hpsa to scsi midlayer
to sd upper layer.

Also add this information:
- product ID
- vendor ID
- RAID level
- SSD Smath Path capable and enabled
- exposure level (sg-only)

Example:
hpsa :04:00.0: added scsi 2:0:0:0: Direct-Access HP LOGICAL VOLUME   
RAID-0 SSDSmartPathCap+ En+ Exp=4
scsi 2:0:0:0: Direct-Access HP   LOGICAL VOLUME   10.0 PQ: 0 ANSI: 5
sd 2:0:0:0: [sdr] 12501713072 512-byte logical blocks: (6.40 TB/5.82 TiB)
sd 2:0:0:0: [sdr] 4096-byte physical blocks
sd 2:0:0:0: [sdr] Attached SCSI disk
sd 2:0:0:0: Attached scsi generic sg20 type 0

Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Robert Elliott 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |  103 +++
 1 file changed, 71 insertions(+), 32 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 3417b8b..9b88726 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -886,6 +886,53 @@ static int hpsa_find_target_lun(struct ctlr_info *h,
return !found;
 }
 
+static inline void hpsa_show_dev_msg(int type, struct ctlr_info *h,
+   struct hpsa_scsi_dev_t *dev, char *description)
+{
+#define HPSA_INFO 0
+#define HPSA_WARN 1
+#define HPSA_ERR 2
+   if (type == HPSA_INFO)
+   dev_info(&h->pdev->dev,
+   "scsi %d:%d:%d:%d: %s %s %.8s %.16s RAID-%s 
SSDSmartPathCap%c En%c Exp=%d\n",
+   h->scsi_host->host_no, dev->bus, dev->target, dev->lun,
+   description,
+   scsi_device_type(dev->devtype),
+   dev->vendor,
+   dev->model,
+   dev->raid_level > RAID_UNKNOWN ?
+   "RAID-?" : raid_label[dev->raid_level],
+   dev->offload_config ? '+' : '-',
+   dev->offload_enabled ? '+' : '-',
+   dev->expose_state);
+   else if (type == HPSA_WARN)
+   dev_warn(&h->pdev->dev,
+   "scsi %d:%d:%d:%d: %s %s %.8s %.16s RAID-%s 
SSDSmartPathCap%c En%c Exp=%d\n",
+   h->scsi_host->host_no, dev->bus, dev->target, dev->lun,
+   description,
+   scsi_device_type(dev->devtype),
+   dev->vendor,
+   dev->model,
+   dev->raid_level > RAID_UNKNOWN ?
+   "RAID-?" : raid_label[dev->raid_level],
+   dev->offload_config ? '+' : '-',
+   dev->offload_enabled ? '+' : '-',
+   dev->expose_state);
+   else if (type == HPSA_ERR)
+   dev_err(&h->pdev->dev,
+   "scsi %d:%d:%d:%d: %s %s %.8s %.16s RAID-%s 
SSDSmartPathCap%c En%c Exp=%d\n",
+   h->scsi_host->host_no, dev->bus, dev->target, dev->lun,
+   description,
+   scsi_device_type(dev->devtype),
+   dev->vendor,
+   dev->model,
+   dev->raid_level > RAID_UNKNOWN ?
+   "RAID-?" : raid_label[dev->raid_level],
+   dev->offload_config ? '+' : '-',
+   dev->offload_enabled ? '+' : '-',
+   dev->expose_state);
+}
+
 /* Add an entry into h->dev[] array. */
 static int hpsa_scsi_add_entry(struct ctlr_info *h, int hostno,
struct hpsa_scsi_dev_t *device,
@@ -955,15 +1002,8 @@ lun_assigned:
device->offload_enabled = 0;
added[*nadded] = device;
(*nadded)++;
-
-   /* initially, (before registering with scsi layer) we don't
-* know our hostno and we don't want to print anything first
-* time anyway (the scsi layer's inquiries will show that info)
-*/
-   /* if (hostno != -1) */
-   dev_info(&h->pdev->dev, "%s device c%db%dt%dl%d added.\n",
-   scsi_device_type(device->devtype), hostno,
-   device->bus, device->target, device->lun);
+   hpsa_show_dev_msg(HPSA_INFO, h, device,
+   device->expose_state & HPSA_SCSI_ADD ? "added" : "masked");
return 0;
 }
 
@@ -1003,6 +1043,7 @@ static void hpsa_scsi_update_entry(struct ctlr_info *h, 
int hostno,
if (!new_entry->offload_enabled)
h->dev[entry]->offload_enabled = 0;
 
+   hpsa_show_dev_msg(HPSA_INFO, h, h->dev[entry], "updated");
 }
 
 /* Replace an entry from h->dev[] array. */
@@ -1030,9 +1071,7 @@ static void hpsa_scsi_replace_entry(struct ctlr_info *h, 
int hostno,
h->dev[entry] = new_entry;
added[*nadded] = new_entry;
(*nadded)++;

[PATCH v3 10/42] hpsa: do not ignore return value of hpsa_register_scsi

2015-03-17 Thread Don Brace
From: Stephen Cameron 

add error handling for failure when registering with SCSI subsystem.

Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index d57fa4b..15bf3bcb 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -7453,7 +7453,9 @@ reinit_after_soft_reset:
h->access.set_intr_mask(h, HPSA_INTR_ON);
 
hpsa_hba_inquiry(h);
-   hpsa_register_scsi(h);  /* hook ourselves into SCSI subsystem */
+   rc = hpsa_register_scsi(h); /* hook ourselves into SCSI subsystem */
+   if (rc)
+   goto clean4;
 
/* Monitor the controller for firmware lockups */
h->heartbeat_sample_interval = HEARTBEAT_SAMPLE_INTERVAL;

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 09/42] hpsa: factor out hpsa_init_cmd function

2015-03-17 Thread Don Brace
From: Stephen Cameron 

Factor out hpsa_cmd_init from cmd_alloc().  We also need
this for resubmitting commands down the default RAID path
when they have returned from the ioaccel paths with errors.

In particular, reinitialize the cmd_type and busaddr fields as these
will not be correct for submitting down the RAID stack path
after ioaccel command completion.

This saves time when submitting commands.

Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |   77 ---
 drivers/scsi/hpsa_cmd.h |2 +
 2 files changed, 53 insertions(+), 26 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 9a13525..d57fa4b 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -4317,7 +4317,6 @@ static int hpsa_ciss_submit(struct ctlr_info *h,
/* Fill in the request block... */
 
c->Request.Timeout = 0;
-   memset(c->Request.CDB, 0, sizeof(c->Request.CDB));
BUG_ON(cmd->cmd_len > sizeof(c->Request.CDB));
c->Request.CDBLen = cmd->cmd_len;
memcpy(c->Request.CDB, cmd->cmnd, cmd->cmd_len);
@@ -4368,6 +4367,48 @@ static int hpsa_ciss_submit(struct ctlr_info *h,
return 0;
 }
 
+static void hpsa_cmd_init(struct ctlr_info *h, int index,
+   struct CommandList *c)
+{
+   dma_addr_t cmd_dma_handle, err_dma_handle;
+
+   /* Zero out all of commandlist except the last field, refcount */
+   memset(c, 0, offsetof(struct CommandList, refcount));
+   c->Header.tag = cpu_to_le64((u64) (index << DIRECT_LOOKUP_SHIFT));
+   cmd_dma_handle = h->cmd_pool_dhandle + index * sizeof(*c);
+   c->err_info = h->errinfo_pool + index;
+   memset(c->err_info, 0, sizeof(*c->err_info));
+   err_dma_handle = h->errinfo_pool_dhandle
+   + index * sizeof(*c->err_info);
+   c->cmdindex = index;
+   c->busaddr = (u32) cmd_dma_handle;
+   c->ErrDesc.Addr = cpu_to_le64((u64) err_dma_handle);
+   c->ErrDesc.Len = cpu_to_le32((u32) sizeof(*c->err_info));
+   c->h = h;
+}
+
+static void hpsa_preinitialize_commands(struct ctlr_info *h)
+{
+   int i;
+
+   for (i = 0; i < h->nr_cmds; i++) {
+   struct CommandList *c = h->cmd_pool + i;
+
+   hpsa_cmd_init(h, i, c);
+   atomic_set(&c->refcount, 0);
+   }
+}
+
+static inline void hpsa_cmd_partial_init(struct ctlr_info *h, int index,
+   struct CommandList *c)
+{
+   dma_addr_t cmd_dma_handle = h->cmd_pool_dhandle + index * sizeof(*c);
+
+   memset(c->Request.CDB, 0, sizeof(c->Request.CDB));
+   memset(c->err_info, 0, sizeof(*c->err_info));
+   c->busaddr = (u32) cmd_dma_handle;
+}
+
 static void hpsa_command_resubmit_worker(struct work_struct *work)
 {
struct scsi_cmnd *cmd;
@@ -4382,6 +4423,7 @@ static void hpsa_command_resubmit_worker(struct 
work_struct *work)
cmd->scsi_done(cmd);
return;
}
+   hpsa_cmd_partial_init(c->h, c->cmdindex, c);
if (hpsa_ciss_submit(c->h, c, cmd, dev->scsi3addr)) {
/*
 * If we get here, it means dma mapping failed. Try
@@ -4438,10 +4480,11 @@ static int hpsa_scsi_queue_command(struct Scsi_Host 
*sh, struct scsi_cmnd *cmd)
h->acciopath_status)) {
 
cmd->host_scribble = (unsigned char *) c;
-   c->cmd_type = CMD_SCSI;
-   c->scsi_cmd = cmd;
 
if (dev->offload_enabled) {
+   hpsa_cmd_init(h, c->cmdindex, c);
+   c->cmd_type = CMD_SCSI;
+   c->scsi_cmd = cmd;
rc = hpsa_scsi_ioaccel_raid_map(h, c);
if (rc == 0)
return 0; /* Sent on ioaccel path */
@@ -4450,6 +4493,9 @@ static int hpsa_scsi_queue_command(struct Scsi_Host *sh, 
struct scsi_cmnd *cmd)
return SCSI_MLQUEUE_HOST_BUSY;
}
} else if (dev->ioaccel_handle) {
+   hpsa_cmd_init(h, c->cmdindex, c);
+   c->cmd_type = CMD_SCSI;
+   c->scsi_cmd = cmd;
rc = hpsa_scsi_ioaccel_direct_map(h, c);
if (rc == 0)
return 0; /* Sent on direct map path */
@@ -5061,10 +5107,7 @@ static int hpsa_eh_abort_handler(struct scsi_cmnd *sc)
 static struct CommandList *cmd_alloc(struct ctlr_info *h)
 {
struct CommandList *c;
-   int i;
-   union u64bit temp64;
-   dma_addr_t cmd_dma_handle, err_dma_handle;
-   int refcount;
+   int refcount, i;
unsigned long offset;
 
/*
@@ -5098,24 +5141,7 @@ static struct CommandList *cmd_alloc(struct ctlr_info *h)
break; /* it's ours now. */
}
h->last_allocation = i; /* benignly racy */
-
-   /

[PATCH v3 08/42] hpsa: make function names consistent

2015-03-17 Thread Don Brace
From: Robert Elliott 

make function names more consistent and meaningful

Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Robert Elliott 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |   14 --
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index f84d63f..9a13525 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -6817,7 +6817,7 @@ out_disable:
return rc;
 }
 
-static int hpsa_allocate_cmd_pool(struct ctlr_info *h)
+static int hpsa_alloc_cmd_pool(struct ctlr_info *h)
 {
h->cmd_pool_bits = kzalloc(
DIV_ROUND_UP(h->nr_cmds, BITS_PER_LONG) *
@@ -7347,7 +7347,7 @@ reinit_after_soft_reset:
dev_info(&pdev->dev, "%s: <0x%x> at IRQ %d%s using DAC\n",
   h->devname, pdev->device,
   h->intr[h->intr_mode], dac ? "" : " not");
-   rc = hpsa_allocate_cmd_pool(h);
+   rc = hpsa_alloc_cmd_pool(h);
if (rc)
goto clean2_and_free_irqs;
if (hpsa_allocate_sg_chain_blocks(h))
@@ -7794,7 +7794,8 @@ static int hpsa_enter_performant_mode(struct ctlr_info 
*h, u32 trans_support)
return 0;
 }
 
-static int hpsa_alloc_ioaccel_cmd_and_bft(struct ctlr_info *h)
+/* Allocate ioaccel1 mode command blocks and block fetch table */
+static int hpsa_alloc_ioaccel1_cmd_and_bft(struct ctlr_info *h)
 {
h->ioaccel_maxsg =
readl(&(h->cfgtable->io_accel_max_embedded_sg_count));
@@ -7833,7 +7834,8 @@ clean_up:
return 1;
 }
 
-static int ioaccel2_alloc_cmds_and_bft(struct ctlr_info *h)
+/* Allocate ioaccel2 mode command blocks and block fetch table */
+static int hpsa_alloc_ioaccel2_cmd_and_bft(struct ctlr_info *h)
 {
/* Allocate ioaccel2 mode command blocks and block fetch table */
 
@@ -7888,13 +7890,13 @@ static void hpsa_put_ctlr_into_performant_mode(struct 
ctlr_info *h)
if (trans_support & CFGTBL_Trans_io_accel1) {
transMethod |= CFGTBL_Trans_io_accel1 |
CFGTBL_Trans_enable_directed_msix;
-   if (hpsa_alloc_ioaccel_cmd_and_bft(h))
+   if (hpsa_alloc_ioaccel1_cmd_and_bft(h))
goto clean_up;
} else {
if (trans_support & CFGTBL_Trans_io_accel2) {
transMethod |= CFGTBL_Trans_io_accel2 |
CFGTBL_Trans_enable_directed_msix;
-   if (ioaccel2_alloc_cmds_and_bft(h))
+   if (hpsa_alloc_ioaccel2_cmd_and_bft(h))
goto clean_up;
}
}

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 07/42] hpsa: allow lockup detected to be viewed via sysfs

2015-03-17 Thread Don Brace
From: Stephen Cameron 

expose a detected lockup via sysfs

Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |   17 +
 1 file changed, 17 insertions(+)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 415ec4d..f84d63f 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -351,6 +351,20 @@ static int check_for_busy(struct ctlr_info *h, struct 
CommandList *c)
return 1;
 }
 
+static u32 lockup_detected(struct ctlr_info *h);
+static ssize_t host_show_lockup_detected(struct device *dev,
+   struct device_attribute *attr, char *buf)
+{
+   int ld;
+   struct ctlr_info *h;
+   struct Scsi_Host *shost = class_to_shost(dev);
+
+   h = shost_to_hba(shost);
+   ld = lockup_detected(h);
+
+   return sprintf(buf, "ld=%d\n", ld);
+}
+
 static ssize_t host_store_hp_ssd_smart_path_status(struct device *dev,
 struct device_attribute *attr,
 const char *buf, size_t count)
@@ -698,12 +712,15 @@ static DEVICE_ATTR(transport_mode, S_IRUGO,
host_show_transport_mode, NULL);
 static DEVICE_ATTR(resettable, S_IRUGO,
host_show_resettable, NULL);
+static DEVICE_ATTR(lockup_detected, S_IRUGO,
+   host_show_lockup_detected, NULL);
 
 static struct device_attribute *hpsa_sdev_attrs[] = {
&dev_attr_raid_level,
&dev_attr_lunid,
&dev_attr_unique_id,
&dev_attr_hp_ssd_smart_path_enabled,
+   &dev_attr_lockup_detected,
NULL,
 };
 

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 14/42] hpsa: use ioaccel2 path to submit IOs to physical drives in HBA mode.

2015-03-17 Thread Don Brace
From: Joe Handzik 

use ioaccel2 path to submit I/O to physical drives in HBA mode

Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Joe Handzik 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |   10 +-
 drivers/scsi/hpsa.h |1 +
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index e9d3d71..76f9042 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -1123,6 +1123,11 @@ static void hpsa_scsi_update_entry(struct ctlr_info *h, 
int hostno,
h->dev[entry]->raid_map = new_entry->raid_map;
h->dev[entry]->ioaccel_handle = new_entry->ioaccel_handle;
}
+   if (new_entry->hba_ioaccel_enabled) {
+   h->dev[entry]->ioaccel_handle = new_entry->ioaccel_handle;
+   wmb(); /* set ioaccel_handle *before* hba_ioaccel_enabled */
+   }
+   h->dev[entry]->hba_ioaccel_enabled = new_entry->hba_ioaccel_enabled;
h->dev[entry]->offload_config = new_entry->offload_config;
h->dev[entry]->offload_to_mirror = new_entry->offload_to_mirror;
h->dev[entry]->queue_depth = new_entry->queue_depth;
@@ -3039,6 +3044,7 @@ static int hpsa_update_device_info(struct ctlr_info *h,
this_device->offload_config = 0;
this_device->offload_enabled = 0;
this_device->offload_to_be_enabled = 0;
+   this_device->hba_ioaccel_enabled = 0;
this_device->volume_offline = 0;
this_device->queue_depth = h->nr_cmds;
}
@@ -3327,6 +,8 @@ static void hpsa_get_ioaccel_drive_info(struct ctlr_info 
*h,
(struct ext_report_lun_entry *) lunaddrbytes;
 
dev->ioaccel_handle = rle->ioaccel_handle;
+   if (PHYS_IOACCEL(lunaddrbytes) && dev->ioaccel_handle)
+   dev->hba_ioaccel_enabled = 1;
memset(id_phys, 0, sizeof(*id_phys));
rc = hpsa_bmic_id_physical_device(h, lunaddrbytes,
GET_BMIC_DRIVE_NUMBER(lunaddrbytes), id_phys,
@@ -4428,7 +4436,7 @@ static int hpsa_ioaccel_submit(struct ctlr_info *h,
rc = hpsa_scsi_ioaccel_raid_map(h, c);
if (rc < 0) /* scsi_dma_map failed. */
rc = SCSI_MLQUEUE_HOST_BUSY;
-   } else if (dev->ioaccel_handle) {
+   } else if (dev->hba_ioaccel_enabled) {
hpsa_cmd_init(h, c->cmdindex, c);
c->cmd_type = CMD_SCSI;
c->scsi_cmd = cmd;
diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
index df2468c..87a70b5 100644
--- a/drivers/scsi/hpsa.h
+++ b/drivers/scsi/hpsa.h
@@ -55,6 +55,7 @@ struct hpsa_scsi_dev_t {
int offload_config; /* I/O accel RAID offload configured */
int offload_enabled;/* I/O accel RAID offload enabled */
int offload_to_be_enabled;
+   int hba_ioaccel_enabled;
int offload_to_mirror;  /* Send next I/O accelerator RAID
 * offload request to mirror drive
 */

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 22/42] hpsa: correct return values from driver functions.

2015-03-17 Thread Don Brace
From: Robert Elliott 

correct return codes for error conditions

Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Robert Elliott 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |   10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 886e928..2cb4db7 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -2691,9 +2691,9 @@ static int hpsa_get_raid_map(struct ctlr_info *h,
if (fill_cmd(c, HPSA_GET_RAID_MAP, h, &this_device->raid_map,
sizeof(this_device->raid_map), 0,
scsi3addr, TYPE_CMD)) {
-   dev_warn(&h->pdev->dev, "Out of memory in 
hpsa_get_raid_map()\n");
-   rc = -ENOMEM;
-   goto out;
+   dev_warn(&h->pdev->dev, "hpsa_get_raid_map fill_cmd failed\n");
+   cmd_free(h, c);
+   return -1;
}
rc = hpsa_scsi_do_simple_cmd_with_retry(h, c,
PCI_DMA_FROMDEVICE, NO_TIMEOUT);
@@ -5455,7 +5455,7 @@ static int hpsa_passthru_ioctl(struct ctlr_info *h, void 
__user *argp)
if (iocommand.buf_size > 0) {
buff = kmalloc(iocommand.buf_size, GFP_KERNEL);
if (buff == NULL)
-   return -EFAULT;
+   return -ENOMEM;
if (iocommand.Request.Type.Direction & XFER_WRITE) {
/* Copy the data into the buffer we created */
if (copy_from_user(buff, iocommand.buf,
@@ -8002,7 +8002,7 @@ static int hpsa_alloc_ioaccel1_cmd_and_bft(struct 
ctlr_info *h)
 
 clean_up:
hpsa_free_ioaccel1_cmd_and_bft(h);
-   return 1;
+   return -ENOMEM;
 }
 
 /* Free ioaccel2 mode command blocks and block fetch table */

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 21/42] hpsa: do not check cmd_alloc return value - it cannnot return NULL

2015-03-17 Thread Don Brace
From: Robert Elliott 

cmd_alloc can no longer return NULL, so don't check for NULL any more
(which is unreachable code).

Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Robert Elliott 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |   77 ++-
 1 file changed, 15 insertions(+), 62 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index ba89375a..886e928 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -2504,11 +2504,6 @@ static int hpsa_scsi_do_inquiry(struct ctlr_info *h, 
unsigned char *scsi3addr,
 
c = cmd_alloc(h);
 
-   if (c == NULL) {
-   dev_warn(&h->pdev->dev, "cmd_alloc returned NULL!\n");
-   return -ENOMEM;
-   }
-
if (fill_cmd(c, HPSA_INQUIRY, h, buf, bufsize,
page, scsi3addr, TYPE_CMD)) {
rc = -1;
@@ -2537,11 +2532,6 @@ static int hpsa_bmic_ctrl_mode_sense(struct ctlr_info *h,
struct ErrorInfo *ei;
 
c = cmd_alloc(h);
-   if (c == NULL) {/* trouble... */
-   dev_warn(&h->pdev->dev, "cmd_alloc returned NULL!\n");
-   return -ENOMEM;
-   }
-
if (fill_cmd(c, BMIC_SENSE_CONTROLLER_PARAMETERS, h, buf, bufsize,
page, scsi3addr, TYPE_CMD)) {
rc = -1;
@@ -2559,7 +2549,7 @@ static int hpsa_bmic_ctrl_mode_sense(struct ctlr_info *h,
 out:
cmd_free(h, c);
return rc;
-   }
+}
 
 static int hpsa_send_reset(struct ctlr_info *h, unsigned char *scsi3addr,
u8 reset_type, int reply_queue)
@@ -2570,10 +2560,6 @@ static int hpsa_send_reset(struct ctlr_info *h, unsigned 
char *scsi3addr,
 
c = cmd_alloc(h);
 
-   if (c == NULL) {/* trouble... */
-   dev_warn(&h->pdev->dev, "cmd_alloc returned NULL!\n");
-   return -ENOMEM;
-   }
 
/* fill_cmd can't fail here, no data buffer to map. */
(void) fill_cmd(c, HPSA_DEVICE_RESET_MSG, h, NULL, 0, 0,
@@ -2701,10 +2687,7 @@ static int hpsa_get_raid_map(struct ctlr_info *h,
struct ErrorInfo *ei;
 
c = cmd_alloc(h);
-   if (c == NULL) {
-   dev_warn(&h->pdev->dev, "cmd_alloc returned NULL!\n");
-   return -ENOMEM;
-   }
+
if (fill_cmd(c, HPSA_GET_RAID_MAP, h, &this_device->raid_map,
sizeof(this_device->raid_map), 0,
scsi3addr, TYPE_CMD)) {
@@ -2877,10 +2860,7 @@ static int hpsa_scsi_do_report_luns(struct ctlr_info *h, 
int logical,
struct ErrorInfo *ei;
 
c = cmd_alloc(h);
-   if (c == NULL) {/* trouble... */
-   dev_err(&h->pdev->dev, "cmd_alloc returned NULL!\n");
-   return -1;
-   }
+
/* address the controller */
memset(scsi3addr, 0, sizeof(scsi3addr));
if (fill_cmd(c, logical ? HPSA_REPORT_LOG : HPSA_REPORT_PHYS, h,
@@ -2995,8 +2975,7 @@ static int hpsa_volume_offline(struct ctlr_info *h,
 #define ASCQ_LUN_NOT_READY_INITIALIZING_CMD_REQ 0x02
 
c = cmd_alloc(h);
-   if (!c)
-   return 0;
+
(void) fill_cmd(c, TEST_UNIT_READY, h, NULL, 0, 0, scsi3addr, TYPE_CMD);
rc = hpsa_scsi_do_simple_cmd(h, c, DEFAULT_REPLY_QUEUE, NO_TIMEOUT);
if (rc) {
@@ -3070,8 +3049,7 @@ static int hpsa_device_supports_aborts(struct ctlr_info 
*h,
return 1;
 
c = cmd_alloc(h);
-   if (!c)
-   return -ENOMEM;
+
(void) fill_cmd(c, HPSA_ABORT_MSG, h, &tag, 0, 0, scsi3addr, TYPE_MSG);
(void) hpsa_scsi_do_simple_cmd(h, c, DEFAULT_REPLY_QUEUE, NO_TIMEOUT);
/* no unmap needed here because no data xfer. */
@@ -4642,10 +4620,7 @@ static int hpsa_scsi_queue_command(struct Scsi_Host *sh, 
struct scsi_cmnd *cmd)
return 0;
}
c = cmd_alloc(h);
-   if (c == NULL) {/* trouble... */
-   dev_err(&h->pdev->dev, "cmd_alloc returned NULL!\n");
-   return SCSI_MLQUEUE_HOST_BUSY;
-   }
+
if (unlikely(lockup_detected(h))) {
cmd->result = DID_NO_CONNECT << 16;
cmd_free(h, c);
@@ -4806,11 +4781,6 @@ static int wait_for_device_to_become_ready(struct 
ctlr_info *h,
struct CommandList *c;
 
c = cmd_alloc(h);
-   if (!c) {
-   dev_warn(&h->pdev->dev, "out of memory in "
-   "wait_for_device_to_become_ready.\n");
-   return IO_ERROR;
-   }
 
/* Send test unit ready until device ready, or give up. */
while (count < HPSA_TUR_RETRY_LIMIT) {
@@ -4973,10 +4943,6 @@ static int hpsa_send_abort(struct ctlr_info *h, unsigned 
char *scsi3addr,
__le32 tagupper, taglower;
 
c = cmd_alloc(h);
-   if (c == NULL) {/* trouble... */
-   dev_warn(&h->pdev->dev, "cmd_alloc returned N

[PATCH v3 13/42] hpsa: print accurate SSD Smart Path Enabled status

2015-03-17 Thread Don Brace
From: Robert Elliott 

offload_enabled changes are deferred until after the
added/updated prints occur, so the values are incorrect.

defer printing SSD Smart Path Enabled status information until the
information is correct

Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Robert Elliott 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |   12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 813f3c8..e9d3d71 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -1090,12 +1090,12 @@ lun_assigned:
 
h->dev[n] = device;
h->ndevices++;
-   device->offload_to_be_enabled = device->offload_enabled;
-   device->offload_enabled = 0;
added[*nadded] = device;
(*nadded)++;
hpsa_show_dev_msg(HPSA_INFO, h, device,
device->expose_state & HPSA_SCSI_ADD ? "added" : "masked");
+   device->offload_to_be_enabled = device->offload_enabled;
+   device->offload_enabled = 0;
return 0;
 }
 
@@ -1103,6 +1103,7 @@ lun_assigned:
 static void hpsa_scsi_update_entry(struct ctlr_info *h, int hostno,
int entry, struct hpsa_scsi_dev_t *new_entry)
 {
+   int offload_enabled;
/* assumes h->devlock is held */
BUG_ON(entry < 0 || entry >= HPSA_MAX_DEVICES);
 
@@ -1135,7 +1136,10 @@ static void hpsa_scsi_update_entry(struct ctlr_info *h, 
int hostno,
if (!new_entry->offload_enabled)
h->dev[entry]->offload_enabled = 0;
 
+   offload_enabled = h->dev[entry]->offload_enabled;
+   h->dev[entry]->offload_enabled = h->dev[entry]->offload_to_be_enabled;
hpsa_show_dev_msg(HPSA_INFO, h, h->dev[entry], "updated");
+   h->dev[entry]->offload_enabled = offload_enabled;
 }
 
 /* Replace an entry from h->dev[] array. */
@@ -1158,12 +1162,12 @@ static void hpsa_scsi_replace_entry(struct ctlr_info 
*h, int hostno,
new_entry->lun = h->dev[entry]->lun;
}
 
-   new_entry->offload_to_be_enabled = new_entry->offload_enabled;
-   new_entry->offload_enabled = 0;
h->dev[entry] = new_entry;
added[*nadded] = new_entry;
(*nadded)++;
hpsa_show_dev_msg(HPSA_INFO, h, new_entry, "replaced");
+   new_entry->offload_to_be_enabled = new_entry->offload_enabled;
+   new_entry->offload_enabled = 0;
 }
 
 /* Remove an entry from h->dev[] array. */

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 24/42] hpsa: clean up some error reporting output in abort handler

2015-03-17 Thread Don Brace
From: Robert Elliott 

report more useful information on aborts

Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Robert Elliott 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |   29 ++---
 1 file changed, 14 insertions(+), 15 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index f980b89..7ab34f8 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -5140,10 +5140,10 @@ static int hpsa_eh_abort_handler(struct scsi_cmnd *sc)
return FAILED;
 
memset(msg, 0, sizeof(msg));
-   ml += sprintf(msg+ml, "scsi %d:%d:%d:%llu %s",
+   ml += sprintf(msg+ml, "scsi %d:%d:%d:%llu %s %p",
h->scsi_host->host_no, sc->device->channel,
sc->device->id, sc->device->lun,
-   "Aborting command");
+   "Aborting command", sc);
 
/* Find the device of the command to be aborted */
dev = sc->device->hostdata;
@@ -5177,12 +5177,12 @@ static int hpsa_eh_abort_handler(struct scsi_cmnd *sc)
ml += sprintf(msg+ml, "Tag:0x%08x:%08x ", tagupper, taglower);
as  = abort->scsi_cmd;
if (as != NULL)
-   ml += sprintf(msg+ml, "Command:0x%x SN:0x%lx ",
-   as->cmnd[0], as->serial_number);
-   dev_dbg(&h->pdev->dev, "%s\n", msg);
-   dev_warn(&h->pdev->dev, "scsi %d:%d:%d:%d %s\n",
-   h->scsi_host->host_no, dev->bus, dev->target, dev->lun,
-   "Aborting command");
+   ml += sprintf(msg+ml,
+   "CDBLen: %d CDB: 0x%02x%02x... SN: 0x%lx ",
+   as->cmd_len, as->cmnd[0], as->cmnd[1],
+   as->serial_number);
+   dev_warn(&h->pdev->dev, "%s BEING SENT\n", msg);
+
/*
 * Command is in flight, or possibly already completed
 * by the firmware (but not to the scsi mid layer) but we can't
@@ -5190,7 +5190,8 @@ static int hpsa_eh_abort_handler(struct scsi_cmnd *sc)
 */
if (wait_for_available_abort_cmd(h)) {
dev_warn(&h->pdev->dev,
-   "Timed out waiting for an abort command to become 
available.\n");
+   "%s FAILED, timeout waiting for an abort command to 
become available.\n",
+   msg);
cmd_free(h, abort);
return FAILED;
}
@@ -5198,16 +5199,14 @@ static int hpsa_eh_abort_handler(struct scsi_cmnd *sc)
atomic_inc(&h->abort_cmds_available);
wake_up_all(&h->abort_cmd_wait_queue);
if (rc != 0) {
-   dev_warn(&h->pdev->dev, "scsi %d:%d:%d:%d %s\n",
-   h->scsi_host->host_no,
-   dev->bus, dev->target, dev->lun,
-   "FAILED to abort command");
+   dev_warn(&h->pdev->dev, "%s SENT, FAILED\n", msg);
cmd_free(h, abort);
return FAILED;
}
-   dev_info(&h->pdev->dev, "%s REQUEST SUCCEEDED.\n", msg);
+   dev_info(&h->pdev->dev, "%s SENT, SUCCESS\n", msg);
 
-   /* If the abort(s) above completed and actually aborted the
+   /*
+* If the abort(s) above completed and actually aborted the
 * command, then the command to be aborted should already be
 * completed.  If not, wait around a bit more to see if they
 * manage to complete normally.

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 15/42] hpsa: Get queue depth from identify physical bmic for physical disks.

2015-03-17 Thread Don Brace
From: Joe Handzik 

get drive queue depth to help avoid task set full conditions.

Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Joe Handzik 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |   33 +
 1 file changed, 13 insertions(+), 20 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 76f9042..3fa72a1 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -3497,29 +3497,22 @@ static void hpsa_update_scsi_devices(struct ctlr_info 
*h, int hostno)
ncurrent++;
break;
case TYPE_DISK:
-   if (h->hba_mode_enabled) {
-   /* never use raid mapper in HBA mode */
-   this_device->offload_enabled = 0;
-   ncurrent++;
-   break;
-   } else if (h->acciopath_status) {
-   if (i >= nphysicals) {
-   ncurrent++;
-   break;
-   }
-   } else {
-   if (i < nphysicals)
-   break;
+   if (i >= nphysicals) {
ncurrent++;
break;
}
-   if (h->transMethod & CFGTBL_Trans_io_accel1 ||
-   h->transMethod & CFGTBL_Trans_io_accel2) {
-   hpsa_get_ioaccel_drive_info(h, this_device,
-   lunaddrbytes, id_phys);
-   atomic_set(&this_device->ioaccel_cmds_out, 0);
-   ncurrent++;
-   }
+
+   if (h->hba_mode_enabled)
+   /* never use raid mapper in HBA mode */
+   this_device->offload_enabled = 0;
+   else if (!(h->transMethod & CFGTBL_Trans_io_accel1 ||
+   h->transMethod & CFGTBL_Trans_io_accel2))
+   break;
+
+   hpsa_get_ioaccel_drive_info(h, this_device,
+   lunaddrbytes, id_phys);
+   atomic_set(&this_device->ioaccel_cmds_out, 0);
+   ncurrent++;
break;
case TYPE_TAPE:
case TYPE_MEDIUM_CHANGER:

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 32/42] hpsa: skip free_irq calls if irqs are not allocated

2015-03-17 Thread Don Brace
From: Robert Elliott 

If try_soft_reset fails to re-allocate irqs, the error exit
starts with free_irq calls, which generate kernel WARN
messages since they were already freed a few lines earlier.

Jump to the next exit label to skip the free_irq calls.

Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Robert Elliott 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 33aca38..f26e6bc 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -7799,7 +7799,12 @@ reinit_after_soft_reset:
if (rc) {
dev_warn(&h->pdev->dev,
"Failed to request_irq after soft reset.\n");
-   goto clean4;
+   /*
+* clean4 starts with free_irqs, but that was just
+* done. Then, request_irqs_failed, so there is
+* nothing to free. So, goto the next label.
+*/
+   goto clean3;
}
 
rc = hpsa_kdump_soft_reset(h);

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 18/42] hpsa: refactor freeing of resources into more logical functions

2015-03-17 Thread Don Brace
From: Robert Elliott 

refactor freeing of resources into more logical functions

Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Robert Elliott 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |  104 +++
 1 file changed, 56 insertions(+), 48 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 3559425a4..9ca86be 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -235,6 +235,8 @@ static void check_ioctl_unit_attention(struct ctlr_info *h,
 static void calc_bucket_map(int *bucket, int num_buckets,
int nsgs, int min_blocks, u32 *bucket_map);
 static void hpsa_put_ctlr_into_performant_mode(struct ctlr_info *h);
+static void hpsa_free_ioaccel1_cmd_and_bft(struct ctlr_info *h);
+static void hpsa_free_ioaccel2_cmd_and_bft(struct ctlr_info *h);
 static inline u32 next_command(struct ctlr_info *h, u8 q);
 static int hpsa_find_cfg_addrs(struct pci_dev *pdev, void __iomem *vaddr,
   u32 *cfg_base_addr, u64 *cfg_base_addr_index,
@@ -6924,6 +6926,21 @@ out_disable:
return rc;
 }
 
+static void hpsa_free_cmd_pool(struct ctlr_info *h)
+{
+   kfree(h->cmd_pool_bits);
+   if (h->cmd_pool)
+   pci_free_consistent(h->pdev,
+   h->nr_cmds * sizeof(struct CommandList),
+   h->cmd_pool,
+   h->cmd_pool_dhandle);
+   if (h->errinfo_pool)
+   pci_free_consistent(h->pdev,
+   h->nr_cmds * sizeof(struct ErrorInfo),
+   h->errinfo_pool,
+   h->errinfo_pool_dhandle);
+}
+
 static int hpsa_alloc_cmd_pool(struct ctlr_info *h)
 {
h->cmd_pool_bits = kzalloc(
@@ -6948,28 +6965,6 @@ clean_up:
return -ENOMEM;
 }
 
-static void hpsa_free_cmd_pool(struct ctlr_info *h)
-{
-   kfree(h->cmd_pool_bits);
-   if (h->cmd_pool)
-   pci_free_consistent(h->pdev,
-   h->nr_cmds * sizeof(struct CommandList),
-   h->cmd_pool, h->cmd_pool_dhandle);
-   if (h->ioaccel2_cmd_pool)
-   pci_free_consistent(h->pdev,
-   h->nr_cmds * sizeof(*h->ioaccel2_cmd_pool),
-   h->ioaccel2_cmd_pool, h->ioaccel2_cmd_pool_dhandle);
-   if (h->errinfo_pool)
-   pci_free_consistent(h->pdev,
-   h->nr_cmds * sizeof(struct ErrorInfo),
-   h->errinfo_pool,
-   h->errinfo_pool_dhandle);
-   if (h->ioaccel_cmd_pool)
-   pci_free_consistent(h->pdev,
-   h->nr_cmds * sizeof(struct io_accel1_cmd),
-   h->ioaccel_cmd_pool, h->ioaccel_cmd_pool_dhandle);
-}
-
 static void hpsa_irq_affinity_hints(struct ctlr_info *h)
 {
int i, cpu;
@@ -7090,8 +7085,10 @@ static void hpsa_free_reply_queues(struct ctlr_info *h)
for (i = 0; i < h->nreply_queues; i++) {
if (!h->reply_queue[i].head)
continue;
-   pci_free_consistent(h->pdev, h->reply_queue_size,
-   h->reply_queue[i].head, h->reply_queue[i].busaddr);
+   pci_free_consistent(h->pdev,
+   h->reply_queue_size,
+   h->reply_queue[i].head,
+   h->reply_queue[i].busaddr);
h->reply_queue[i].head = NULL;
h->reply_queue[i].busaddr = 0;
}
@@ -7102,9 +7099,10 @@ static void 
hpsa_undo_allocations_after_kdump_soft_reset(struct ctlr_info *h)
hpsa_free_irqs(h);
hpsa_free_sg_chain_blocks(h);
hpsa_free_cmd_pool(h);
-   kfree(h->ioaccel1_blockFetchTable);
-   kfree(h->blockFetchTable);
-   hpsa_free_reply_queues(h);
+   kfree(h->blockFetchTable);  /* perf 2 */
+   hpsa_free_reply_queues(h);  /* perf 1 */
+   hpsa_free_ioaccel1_cmd_and_bft(h);  /* perf 1 */
+   hpsa_free_ioaccel2_cmd_and_bft(h);  /* perf 1 */
hpsa_free_cfgtables(h); /* pci_init 4 */
iounmap(h->vaddr);  /* pci_init 3 */
hpsa_disable_interrupt_mode(h); /* pci_init 2 */
@@ -7535,6 +7533,8 @@ reinit_after_soft_reset:
 clean4:
hpsa_free_sg_chain_blocks(h);
hpsa_free_cmd_pool(h);
+   hpsa_free_ioaccel1_cmd_and_bft(h);
+   hpsa_free_ioaccel2_cmd_and_bft(h);
 clean2_and_free_irqs:
hpsa_free_irqs(h);
 clean2:
@@ -7636,17 +7636,11 @@ static void hpsa_remove_one(struct pci_dev *pdev)
 
hpsa_free_device_info(h);
hpsa_free_sg_chain_blocks(h);
-   pci_free_consistent(h->pdev,
-   h->nr_cmds * sizeof(struct CommandList),
-   h->cmd_pool, h->cmd_pool_dhandle);
-   pci_free_consistent(h->pdev,
-   h->nr_

[PATCH v3 31/42] hpsa: call pci_release_regions after pci_disable_device

2015-03-17 Thread Don Brace
From: Robert Elliott 

Despite the fact that PCI devices are enabled in this order:
1. pci_enable_device
2. pci_request_regions

Documentation/PCI/pci.txt specifies that they be undone
in this order
1. pci_disable_device
2. pci_release_regions

Tested by injecting error in the call to pci_enable_device
in hpsa_init_one -> hpsa_pci_init:
[9.095001] hpsa :04:00.0: failed to enable PCI device
[9.095005] hpsa: probe of :04:00.0 failed with error -22
(-22 is -EINVAL)
and then in the call pci_request_regions:
[9.178623] hpsa :04:00.0: failed to obtain PCI resources
[9.178671] hpsa: probe of :04:00.0 failed with error -16
(-16 is -EBUSY)

and then by adding
reset_devices
to the kernel command line and inject errors into the two
calls to pci_enable_device and the call to pci_request_regions
in hpsa_init_one -> hpsa_init_reset_devices.

(inject on 6th call, 1st to hpsa2)
[   62.413750] hpsa :04:00.0: Failed to enable PCI device

(inject on 7th call, 2nd to hpsa2)
[   62.807571] hpsa :04:00.0: failed to enable device.

(inject on 8th call, 3rd to hpsa2)
[   62.697198] hpsa :04:00.0: failed to obtain PCI resources
[   62.697234] hpsa: probe of :04:00.0 failed with error -16

The reset_devices path calls return -ENODEV on failure
rather than passing the result, which apparently doesn't
cause the pci driver to print anything.

Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Robert Elliott 
Signed-off-by: Don Brace < don.br...@pmcs.com>
---
 drivers/scsi/hpsa.c |   17 +
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index b533b8e..33aca38 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -7075,8 +7075,12 @@ static void hpsa_free_pci_init(struct ctlr_info *h)
iounmap(h->vaddr);  /* pci_init 3 */
h->vaddr = NULL;
hpsa_disable_interrupt_mode(h); /* pci_init 2 */
-   pci_release_regions(h->pdev);   /* pci_init 2 */
+   /*
+* call pci_disable_device before pci_release_regions per
+* Documentation/PCI/pci.txt
+*/
pci_disable_device(h->pdev);/* pci_init 1 */
+   pci_release_regions(h->pdev);   /* pci_init 2 */
 }
 
 /* several items must be freed later */
@@ -7099,6 +7103,7 @@ static int hpsa_pci_init(struct ctlr_info *h)
err = pci_enable_device(h->pdev);
if (err) {
dev_err(&h->pdev->dev, "failed to enable PCI device\n");
+   pci_disable_device(h->pdev);
return err;
}
 
@@ -7106,7 +7111,8 @@ static int hpsa_pci_init(struct ctlr_info *h)
if (err) {
dev_err(&h->pdev->dev,
"failed to obtain PCI resources\n");
-   goto clean1;/* pci */
+   pci_disable_device(h->pdev);
+   return err;
}
 
pci_set_master(h->pdev);
@@ -7147,9 +7153,12 @@ clean3:  /* vaddr, intmode+region, pci */
h->vaddr = NULL;
 clean2:/* intmode+region, pci */
hpsa_disable_interrupt_mode(h);
-   pci_release_regions(h->pdev);
-clean1:/* pci */
+   /*
+* call pci_disable_device before pci_release_regions per
+* Documentation/PCI/pci.txt
+*/
pci_disable_device(h->pdev);
+   pci_release_regions(h->pdev);
return err;
 }
 

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 16/42] hpsa: break hpsa_free_irqs_and_disable_msix into two functions

2015-03-17 Thread Don Brace
From: Robert Elliott 

replace calls to hpsa_free_irqs_and_disable_msix with
hpsa_free_irqs and hpsa_disable_interrupt_mode

Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Robert Elliott 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |   35 ++-
 1 file changed, 18 insertions(+), 17 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 3fa72a1..c98c591 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -6402,10 +6402,20 @@ static int find_PCI_BAR_index(struct pci_dev *pdev, 
unsigned long pci_bar_addr)
return -1;
 }
 
+static void hpsa_disable_interrupt_mode(struct ctlr_info *h)
+{
+   if (h->msix_vector) {
+   if (h->pdev->msix_enabled)
+   pci_disable_msix(h->pdev);
+   } else if (h->msi_vector) {
+   if (h->pdev->msi_enabled)
+   pci_disable_msi(h->pdev);
+   }
+}
+
 /* If MSI/MSI-X is supported by the kernel we will try to enable it on
  * controllers that are capable. If not, we use legacy INTx mode.
  */
-
 static void hpsa_interrupt_mode(struct ctlr_info *h)
 {
 #ifdef CONFIG_PCI_MSI
@@ -7046,20 +7056,6 @@ static int hpsa_kdump_soft_reset(struct ctlr_info *h)
return 0;
 }
 
-static void hpsa_free_irqs_and_disable_msix(struct ctlr_info *h)
-{
-   hpsa_free_irqs(h);
-#ifdef CONFIG_PCI_MSI
-   if (h->msix_vector) {
-   if (h->pdev->msix_enabled)
-   pci_disable_msix(h->pdev);
-   } else if (h->msi_vector) {
-   if (h->pdev->msi_enabled)
-   pci_disable_msi(h->pdev);
-   }
-#endif /* CONFIG_PCI_MSI */
-}
-
 static void hpsa_free_reply_queues(struct ctlr_info *h)
 {
int i;
@@ -7076,7 +7072,7 @@ static void hpsa_free_reply_queues(struct ctlr_info *h)
 
 static void hpsa_undo_allocations_after_kdump_soft_reset(struct ctlr_info *h)
 {
-   hpsa_free_irqs_and_disable_msix(h);
+   hpsa_free_irqs(h);
hpsa_free_sg_chain_blocks(h);
hpsa_free_cmd_pool(h);
kfree(h->ioaccel1_blockFetchTable);
@@ -7088,6 +7084,7 @@ static void 
hpsa_undo_allocations_after_kdump_soft_reset(struct ctlr_info *h)
iounmap(h->transtable);
if (h->cfgtable)
iounmap(h->cfgtable);
+   hpsa_disable_interrupt_mode(h);
pci_disable_device(h->pdev);
pci_release_regions(h->pdev);
kfree(h);
@@ -7576,7 +7573,8 @@ static void hpsa_shutdown(struct pci_dev *pdev)
 */
hpsa_flush_cache(h);
h->access.set_intr_mask(h, HPSA_INTR_OFF);
-   hpsa_free_irqs_and_disable_msix(h);
+   hpsa_free_irqs(h);
+   hpsa_disable_interrupt_mode(h); /* pci_init 2 */
 }
 
 static void hpsa_free_device_info(struct ctlr_info *h)
@@ -7607,7 +7605,10 @@ static void hpsa_remove_one(struct pci_dev *pdev)
destroy_workqueue(h->rescan_ctlr_wq);
destroy_workqueue(h->resubmit_wq);
hpsa_unregister_scsi(h);/* unhook from SCSI subsystem */
+
+   /* includes hpsa_free_irqs and hpsa_disable_interrupt_mode */
hpsa_shutdown(pdev);
+
iounmap(h->vaddr);
iounmap(h->transtable);
iounmap(h->cfgtable);

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 25/42] hpsa: do not print ioaccel2 warning messages about unusual completions.

2015-03-17 Thread Don Brace
From: Robert Elliott 

The SCSI midlayer already prints more detail about completions,
and has logging level options to filter them if not wanted.
These just slow down the system if a lot of errors occur,
stressing error handling even more.

Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Robert Elliott 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |   24 
 1 file changed, 24 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 7ab34f8..7d0e226 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -1906,9 +1906,6 @@ static int handle_ioaccel_mode2_error(struct ctlr_info *h,
case IOACCEL2_STATUS_SR_TASK_COMP_GOOD:
break;
case IOACCEL2_STATUS_SR_TASK_COMP_CHK_COND:
-   dev_warn(&h->pdev->dev,
-   "%s: task complete with check condition.\n",
-   "HP SSD Smart Path");
cmd->result |= SAM_STAT_CHECK_CONDITION;
if (c2->error_data.data_present !=
IOACCEL2_SENSE_DATA_PRESENT) {
@@ -1928,30 +1925,18 @@ static int handle_ioaccel_mode2_error(struct ctlr_info 
*h,
retry = 1;
break;
case IOACCEL2_STATUS_SR_TASK_COMP_BUSY:
-   dev_warn(&h->pdev->dev,
-   "%s: task complete with BUSY status.\n",
-   "HP SSD Smart Path");
retry = 1;
break;
case IOACCEL2_STATUS_SR_TASK_COMP_RES_CON:
-   dev_warn(&h->pdev->dev,
-   "%s: task complete with reservation 
conflict.\n",
-   "HP SSD Smart Path");
retry = 1;
break;
case IOACCEL2_STATUS_SR_TASK_COMP_SET_FULL:
retry = 1;
break;
case IOACCEL2_STATUS_SR_TASK_COMP_ABORTED:
-   dev_warn(&h->pdev->dev,
-   "%s: task complete with aborted status.\n",
-   "HP SSD Smart Path");
retry = 1;
break;
default:
-   dev_warn(&h->pdev->dev,
-   "%s: task complete with unrecognized status: 
0x%02x\n",
-   "HP SSD Smart Path", c2->error_data.status);
retry = 1;
break;
}
@@ -1980,9 +1965,6 @@ static int handle_ioaccel_mode2_error(struct ctlr_info *h,
break;
default:
retry = 1;
-   dev_warn(&h->pdev->dev,
-   "unexpected delivery or target failure, status 
= 0x%02x\n",
-   c2->error_data.status);
}
break;
case IOACCEL2_SERV_RESPONSE_TMF_COMPLETE:
@@ -1990,17 +1972,11 @@ static int handle_ioaccel_mode2_error(struct ctlr_info 
*h,
case IOACCEL2_SERV_RESPONSE_TMF_SUCCESS:
break;
case IOACCEL2_SERV_RESPONSE_TMF_REJECTED:
-   dev_warn(&h->pdev->dev, "task management function rejected.\n");
retry = 1;
break;
case IOACCEL2_SERV_RESPONSE_TMF_WRONG_LUN:
-   dev_warn(&h->pdev->dev, "task management function invalid 
LUN\n");
break;
default:
-   dev_warn(&h->pdev->dev,
-   "%s: Unrecognized server response: 0x%02x\n",
-   "HP SSD Smart Path",
-   c2->error_data.serv_response);
retry = 1;
break;
}

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 11/42] hpsa: try resubmitting down raid path on task set full

2015-03-17 Thread Don Brace
From: Stephen Cameron 

allow the controller firmware to queue up commands when the ioaccel device
queue is full.

Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 15bf3bcb..76865df 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -1855,8 +1855,7 @@ static int handle_ioaccel_mode2_error(struct ctlr_info *h,
retry = 1;
break;
case IOACCEL2_STATUS_SR_TASK_COMP_SET_FULL:
-   /* Make scsi midlayer do unlimited retries */
-   cmd->result = DID_IMM_RETRY << 16;
+   retry = 1;
break;
case IOACCEL2_STATUS_SR_TASK_COMP_ABORTED:
dev_warn(&h->pdev->dev,

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 12/42] hpsa: factor out hpsa_ioaccel_submit function

2015-03-17 Thread Don Brace
From: Webb Scales 

clean up command submission

Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Webb Scales 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |   91 +--
 1 file changed, 66 insertions(+), 25 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 76865df..813f3c8 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -4408,6 +4408,33 @@ static inline void hpsa_cmd_partial_init(struct 
ctlr_info *h, int index,
c->busaddr = (u32) cmd_dma_handle;
 }
 
+static int hpsa_ioaccel_submit(struct ctlr_info *h,
+   struct CommandList *c, struct scsi_cmnd *cmd,
+   unsigned char *scsi3addr)
+{
+   struct hpsa_scsi_dev_t *dev = cmd->device->hostdata;
+   int rc = IO_ACCEL_INELIGIBLE;
+
+   cmd->host_scribble = (unsigned char *) c;
+
+   if (dev->offload_enabled) {
+   hpsa_cmd_init(h, c->cmdindex, c);
+   c->cmd_type = CMD_SCSI;
+   c->scsi_cmd = cmd;
+   rc = hpsa_scsi_ioaccel_raid_map(h, c);
+   if (rc < 0) /* scsi_dma_map failed. */
+   rc = SCSI_MLQUEUE_HOST_BUSY;
+   } else if (dev->ioaccel_handle) {
+   hpsa_cmd_init(h, c->cmdindex, c);
+   c->cmd_type = CMD_SCSI;
+   c->scsi_cmd = cmd;
+   rc = hpsa_scsi_ioaccel_direct_map(h, c);
+   if (rc < 0) /* scsi_dma_map failed. */
+   rc = SCSI_MLQUEUE_HOST_BUSY;
+   }
+   return rc;
+}
+
 static void hpsa_command_resubmit_worker(struct work_struct *work)
 {
struct scsi_cmnd *cmd;
@@ -4419,15 +4446,46 @@ static void hpsa_command_resubmit_worker(struct 
work_struct *work)
dev = cmd->device->hostdata;
if (!dev) {
cmd->result = DID_NO_CONNECT << 16;
+   cmd_free(c->h, c);
cmd->scsi_done(cmd);
return;
}
+   if (c->cmd_type == CMD_IOACCEL2) {
+   struct ctlr_info *h = c->h;
+   struct io_accel2_cmd *c2 = &h->ioaccel2_cmd_pool[c->cmdindex];
+   int rc;
+
+   if (c2->error_data.serv_response ==
+   IOACCEL2_STATUS_SR_TASK_COMP_SET_FULL) {
+   rc = hpsa_ioaccel_submit(h, c, cmd, dev->scsi3addr);
+   if (rc == 0)
+   return;
+   if (rc == SCSI_MLQUEUE_HOST_BUSY) {
+   /*
+* If we get here, it means dma mapping failed.
+* Try again via scsi mid layer, which will
+* then get SCSI_MLQUEUE_HOST_BUSY.
+*/
+   cmd->result = DID_IMM_RETRY << 16;
+   cmd->scsi_done(cmd);
+   cmd_free(h, c); /* FIX-ME:  on merge, change
+* to cmd_tagged_free() and
+* ultimately to
+* hpsa_cmd_free_and_done(). */
+   return;
+   }
+   /* else, fall thru and resubmit down CISS path */
+   }
+   }
hpsa_cmd_partial_init(c->h, c->cmdindex, c);
if (hpsa_ciss_submit(c->h, c, cmd, dev->scsi3addr)) {
/*
 * If we get here, it means dma mapping failed. Try
 * again via scsi mid layer, which will then get
 * SCSI_MLQUEUE_HOST_BUSY.
+*
+* hpsa_ciss_submit will have already freed c
+* if it encountered a dma mapping failure.
 */
cmd->result = DID_IMM_RETRY << 16;
cmd->scsi_done(cmd);
@@ -4477,31 +4535,14 @@ static int hpsa_scsi_queue_command(struct Scsi_Host 
*sh, struct scsi_cmnd *cmd)
if (likely(cmd->retries == 0 &&
cmd->request->cmd_type == REQ_TYPE_FS &&
h->acciopath_status)) {
-
-   cmd->host_scribble = (unsigned char *) c;
-
-   if (dev->offload_enabled) {
-   hpsa_cmd_init(h, c->cmdindex, c);
-   c->cmd_type = CMD_SCSI;
-   c->scsi_cmd = cmd;
-   rc = hpsa_scsi_ioaccel_raid_map(h, c);
-   if (rc == 0)
-   return 0; /* Sent on ioaccel path */
-   if (rc < 0) {   /* scsi_dma_map failed. */
-   cmd_free(h, c);
-   return SCSI_MLQUEUE_HOST_BUSY;
-   }
-   } else if (dev->ioaccel_handle) {
-   hpsa_cmd_init(h, c->cmdindex, c);
-   c->cmd_type = CMD_SCSI;
-   

[PATCH v3 19/42] hpsa: add ioaccel sg chaining for the ioaccel2 path

2015-03-17 Thread Don Brace
From: Webb Scales 

Increase the request size for ioaccel2 path.

The error, if any, returned by hpsa_allocate_ioaccel2_sg_chain_blocks
to hpsa_alloc_ioaccel2_cmd_and_bft should be returned upstream rather
than assumed to be -ENOMEM.

This differs slightly from hpsa_alloc_ioaccel1_cmd_and_bft,
which does not call another hpsa_allocate function and only
has -ENOMEM to return from some kmalloc calls.

Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Robert Elliott 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |  125 +++
 drivers/scsi/hpsa.h |1 
 2 files changed, 116 insertions(+), 10 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 9ca86be..0a3ea37 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -1734,6 +1734,46 @@ static void hpsa_slave_destroy(struct scsi_device *sdev)
/* nothing to do. */
 }
 
+static void hpsa_free_ioaccel2_sg_chain_blocks(struct ctlr_info *h)
+{
+   int i;
+
+   if (!h->ioaccel2_cmd_sg_list)
+   return;
+   for (i = 0; i < h->nr_cmds; i++) {
+   kfree(h->ioaccel2_cmd_sg_list[i]);
+   h->ioaccel2_cmd_sg_list[i] = NULL;
+   }
+   kfree(h->ioaccel2_cmd_sg_list);
+   h->ioaccel2_cmd_sg_list = NULL;
+}
+
+static int hpsa_allocate_ioaccel2_sg_chain_blocks(struct ctlr_info *h)
+{
+   int i;
+
+   if (h->chainsize <= 0)
+   return 0;
+
+   h->ioaccel2_cmd_sg_list =
+   kzalloc(sizeof(*h->ioaccel2_cmd_sg_list) * h->nr_cmds,
+   GFP_KERNEL);
+   if (!h->ioaccel2_cmd_sg_list)
+   return -ENOMEM;
+   for (i = 0; i < h->nr_cmds; i++) {
+   h->ioaccel2_cmd_sg_list[i] =
+   kmalloc(sizeof(*h->ioaccel2_cmd_sg_list[i]) *
+   h->maxsgentries, GFP_KERNEL);
+   if (!h->ioaccel2_cmd_sg_list[i])
+   goto clean;
+   }
+   return 0;
+
+clean:
+   hpsa_free_ioaccel2_sg_chain_blocks(h);
+   return -ENOMEM;
+}
+
 static void hpsa_free_sg_chain_blocks(struct ctlr_info *h)
 {
int i;
@@ -1776,6 +1816,39 @@ clean:
return -ENOMEM;
 }
 
+static int hpsa_map_ioaccel2_sg_chain_block(struct ctlr_info *h,
+   struct io_accel2_cmd *cp, struct CommandList *c)
+{
+   struct ioaccel2_sg_element *chain_block;
+   u64 temp64;
+   u32 chain_size;
+
+   chain_block = h->ioaccel2_cmd_sg_list[c->cmdindex];
+   chain_size = le32_to_cpu(cp->data_len);
+   temp64 = pci_map_single(h->pdev, chain_block, chain_size,
+   PCI_DMA_TODEVICE);
+   if (dma_mapping_error(&h->pdev->dev, temp64)) {
+   /* prevent subsequent unmapping */
+   cp->sg->address = 0;
+   return -1;
+   }
+   cp->sg->address = cpu_to_le64(temp64);
+   return 0;
+}
+
+static void hpsa_unmap_ioaccel2_sg_chain_block(struct ctlr_info *h,
+   struct io_accel2_cmd *cp)
+{
+   struct ioaccel2_sg_element *chain_sg;
+   u64 temp64;
+   u32 chain_size;
+
+   chain_sg = cp->sg;
+   temp64 = le64_to_cpu(chain_sg->address);
+   chain_size = le32_to_cpu(cp->data_len);
+   pci_unmap_single(h->pdev, temp64, chain_size, PCI_DMA_TODEVICE);
+}
+
 static int hpsa_map_sg_chain_block(struct ctlr_info *h,
struct CommandList *c)
 {
@@ -1985,6 +2058,7 @@ static void complete_scsi_command(struct CommandList *cp)
struct ctlr_info *h;
struct ErrorInfo *ei;
struct hpsa_scsi_dev_t *dev;
+   struct io_accel2_cmd *c2;
 
int sense_key;
int asc;  /* additional sense code */
@@ -1995,12 +2069,17 @@ static void complete_scsi_command(struct CommandList 
*cp)
cmd = cp->scsi_cmd;
h = cp->h;
dev = cmd->device->hostdata;
+   c2 = &h->ioaccel2_cmd_pool[cp->cmdindex];
 
scsi_dma_unmap(cmd); /* undo the DMA mappings */
if ((cp->cmd_type == CMD_SCSI) &&
(le16_to_cpu(cp->Header.SGTotal) > h->max_cmd_sg_entries))
hpsa_unmap_sg_chain_block(h, cp);
 
+   if ((cp->cmd_type == CMD_IOACCEL2) &&
+   (c2->sg[0].chain_indicator == IOACCEL2_CHAIN))
+   hpsa_unmap_ioaccel2_sg_chain_block(h, c2);
+
cmd->result = (DID_OK << 16);   /* host byte */
cmd->result |= (COMMAND_COMPLETE << 8); /* msg byte */
 
@@ -3842,10 +3921,7 @@ static int hpsa_scsi_ioaccel2_queue_command(struct 
ctlr_info *h,
u32 len;
u32 total_len = 0;
 
-   if (scsi_sg_count(cmd) > h->ioaccel_maxsg) {
-   atomic_dec(&phys_disk->ioaccel_cmds_out);
-   return IO_ACCEL_INELIGIBLE;
-   }
+   BUG_ON(scsi_sg_count(cmd) > h->maxsgentries);
 
if (fixup_ioaccel_cdb(cdb, &cdb_len)) {
atomic_dec(&phys_disk->ioaccel_cmds_out);
@@ -3868,8 +3944,19 @@ static int hpsa_scsi_ioaccel2_qu

[PATCH v3 30/42] hpsa: performance tweak for hpsa_scatter_gather()

2015-03-17 Thread Don Brace
From: Webb Scales 

Divide the loop in hpsa_scatter_gather() into two, one for the initial SG list
and a second one for the chained list, if any.  This allows the conditional
check which resets the indicies for the chained list to be performed outside
the loop instead of being done on every iteration inside the loop.

Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Webb Scales 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |   39 ---
 1 file changed, 28 insertions(+), 11 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 3751df3..b533b8e 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -3709,7 +3709,7 @@ static int hpsa_scatter_gather(struct ctlr_info *h,
struct scsi_cmnd *cmd)
 {
struct scatterlist *sg;
-   int use_sg, i, sg_index, chained;
+   int use_sg, i, sg_limit, chained, last_sg;
struct SGDescriptor *curr_sg;
 
BUG_ON(scsi_sg_count(cmd) > h->maxsgentries);
@@ -3721,22 +3721,39 @@ static int hpsa_scatter_gather(struct ctlr_info *h,
if (!use_sg)
goto sglist_finished;
 
+   /*
+* If the number of entries is greater than the max for a single list,
+* then we have a chained list; we will set up all but one entry in the
+* first list (the last entry is saved for link information);
+* otherwise, we don't have a chained list and we'll set up at each of
+* the entries in the one list.
+*/
curr_sg = cp->SG;
-   chained = 0;
-   sg_index = 0;
-   scsi_for_each_sg(cmd, sg, use_sg, i) {
-   if (i == h->max_cmd_sg_entries - 1 &&
-   use_sg > h->max_cmd_sg_entries) {
-   chained = 1;
-   curr_sg = h->cmd_sg_list[cp->cmdindex];
-   sg_index = 0;
-   }
+   chained = use_sg > h->max_cmd_sg_entries;
+   sg_limit = chained ? h->max_cmd_sg_entries - 1 : use_sg;
+   last_sg = scsi_sg_count(cmd) - 1;
+   scsi_for_each_sg(cmd, sg, sg_limit, i) {
hpsa_set_sg_descriptor(curr_sg, sg);
curr_sg++;
}
 
+   if (chained) {
+   /*
+* Continue with the chained list.  Set curr_sg to the chained
+* list.  Modify the limit to the total count less the entries
+* we've already set up.  Resume the scan at the list entry
+* where the previous loop left off.
+*/
+   curr_sg = h->cmd_sg_list[cp->cmdindex];
+   sg_limit = use_sg - sg_limit;
+   for_each_sg(sg, sg, sg_limit, i) {
+   hpsa_set_sg_descriptor(curr_sg, sg);
+   curr_sg++;
+   }
+   }
+
/* Back the pointer up to the last entry and mark it as "last". */
-   (--curr_sg)->Ext = cpu_to_le32(HPSA_SG_LAST);
+   (curr_sg - 1)->Ext = cpu_to_le32(HPSA_SG_LAST);
 
if (use_sg + chained > h->maxSG)
h->maxSG = use_sg + chained;

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 23/42] hpsa: clean up driver init

2015-03-17 Thread Don Brace
From: Robert Elliott 

Improve initialization error handling in hpsa_init_one
Clean up style and indent issues
Rename functions for consistency
Improve error messaging on allocations
Fix return status from hpsa_put_ctlr_into_performant_mode
Correct free order in hpsa_init_one using new function
   hpsa_free_performant_mode
Prevent inadvertent use of null pointers by nulling out the parent structures
   and zeroing out associated size variables.

Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Robert Elliott 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |  243 +--
 1 file changed, 157 insertions(+), 86 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 2cb4db7..f980b89 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -234,9 +234,8 @@ static void check_ioctl_unit_attention(struct ctlr_info *h,
 /* performant mode helper functions */
 static void calc_bucket_map(int *bucket, int num_buckets,
int nsgs, int min_blocks, u32 *bucket_map);
-static void hpsa_put_ctlr_into_performant_mode(struct ctlr_info *h);
-static void hpsa_free_ioaccel1_cmd_and_bft(struct ctlr_info *h);
-static void hpsa_free_ioaccel2_cmd_and_bft(struct ctlr_info *h);
+static void hpsa_free_performant_mode(struct ctlr_info *h);
+static int hpsa_put_ctlr_into_performant_mode(struct ctlr_info *h);
 static inline u32 next_command(struct ctlr_info *h, u8 q);
 static int hpsa_find_cfg_addrs(struct pci_dev *pdev, void __iomem *vaddr,
   u32 *cfg_base_addr, u64 *cfg_base_addr_index,
@@ -1665,6 +1664,7 @@ static void adjust_hpsa_scsi_table(struct ctlr_info *h, 
int hostno,
 * since it didn't get added to scsi mid layer
 */
fixup_botched_add(h, added[i]);
+   added[i] = NULL;
}
 
 free_and_out:
@@ -1788,7 +1788,7 @@ static void hpsa_free_sg_chain_blocks(struct ctlr_info *h)
h->cmd_sg_list = NULL;
 }
 
-static int hpsa_allocate_sg_chain_blocks(struct ctlr_info *h)
+static int hpsa_alloc_sg_chain_blocks(struct ctlr_info *h)
 {
int i;
 
@@ -6488,9 +6488,11 @@ static void hpsa_disable_interrupt_mode(struct ctlr_info 
*h)
if (h->msix_vector) {
if (h->pdev->msix_enabled)
pci_disable_msix(h->pdev);
+   h->msix_vector = 0;
} else if (h->msi_vector) {
if (h->pdev->msi_enabled)
pci_disable_msi(h->pdev);
+   h->msi_vector = 0;
}
 }
 
@@ -6629,10 +6631,14 @@ static int hpsa_find_cfg_addrs(struct pci_dev *pdev, 
void __iomem *vaddr,
 
 static void hpsa_free_cfgtables(struct ctlr_info *h)
 {
-   if (h->transtable)
+   if (h->transtable) {
iounmap(h->transtable);
-   if (h->cfgtable)
+   h->transtable = NULL;
+   }
+   if (h->cfgtable) {
iounmap(h->cfgtable);
+   h->cfgtable = NULL;
+   }
 }
 
 /* Find and map CISS config table and transfer table
@@ -6849,6 +6855,7 @@ static void hpsa_free_pci_init(struct ctlr_info *h)
 {
hpsa_free_cfgtables(h); /* pci_init 4 */
iounmap(h->vaddr);  /* pci_init 3 */
+   h->vaddr = NULL;
hpsa_disable_interrupt_mode(h); /* pci_init 2 */
pci_release_regions(h->pdev);   /* pci_init 2 */
pci_disable_device(h->pdev);/* pci_init 1 */
@@ -6919,6 +6926,7 @@ clean4:   /* cfgtables, vaddr, intmode+region, pci */
hpsa_free_cfgtables(h);
 clean3:/* vaddr, intmode+region, pci */
iounmap(h->vaddr);
+   h->vaddr = NULL;
 clean2:/* intmode+region, pci */
hpsa_disable_interrupt_mode(h);
pci_release_regions(h->pdev);
@@ -7008,16 +7016,23 @@ out_disable:
 static void hpsa_free_cmd_pool(struct ctlr_info *h)
 {
kfree(h->cmd_pool_bits);
-   if (h->cmd_pool)
+   h->cmd_pool_bits = NULL;
+   if (h->cmd_pool) {
pci_free_consistent(h->pdev,
h->nr_cmds * sizeof(struct CommandList),
h->cmd_pool,
h->cmd_pool_dhandle);
-   if (h->errinfo_pool)
+   h->cmd_pool = NULL;
+   h->cmd_pool_dhandle = 0;
+   }
+   if (h->errinfo_pool) {
pci_free_consistent(h->pdev,
h->nr_cmds * sizeof(struct ErrorInfo),
h->errinfo_pool,
h->errinfo_pool_dhandle);
+   h->errinfo_pool = NULL;
+   h->errinfo_pool_dhandle = 0;
+   }
 }
 
 static int hpsa_alloc_cmd_pool(struct ctlr_info *h)
@@ -7065,12 +7080,14 @@ static void hpsa_free_irqs(struct ctlr_info *h)
i = h->intr_mode;
irq_set_affinity_hint(h->intr[i], NULL);
free_irq(h->intr[i], &h->q[i]);
+ 

[PATCH v3 17/42] hpsa: clean up error handling

2015-03-17 Thread Don Brace
From: Robert Elliott 

refactor error cleanup and shutdown
disable interrupts and pci_disable_device on critical failures
add hpsa_free_cfgtables function

Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Robert Elliott 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |   92 ---
 1 file changed, 58 insertions(+), 34 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index c98c591..3559425a4 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -6546,6 +6546,17 @@ static int hpsa_find_cfg_addrs(struct pci_dev *pdev, 
void __iomem *vaddr,
return 0;
 }
 
+static void hpsa_free_cfgtables(struct ctlr_info *h)
+{
+   if (h->transtable)
+   iounmap(h->transtable);
+   if (h->cfgtable)
+   iounmap(h->cfgtable);
+}
+
+/* Find and map CISS config table and transfer table
++ * several items must be unmapped (freed) later
++ * */
 static int hpsa_find_cfgtables(struct ctlr_info *h)
 {
u64 cfg_offset;
@@ -6572,8 +6583,11 @@ static int hpsa_find_cfgtables(struct ctlr_info *h)
h->transtable = remap_pci_mem(pci_resource_start(h->pdev,
cfg_base_addr_index)+cfg_offset+trans_offset,
sizeof(*h->transtable));
-   if (!h->transtable)
+   if (!h->transtable) {
+   dev_err(&h->pdev->dev, "Failed mapping transfer table\n");
+   hpsa_free_cfgtables(h);
return -ENOMEM;
+   }
return 0;
 }
 
@@ -6749,6 +6763,17 @@ error:
return -ENODEV;
 }
 
+/* free items allocated or mapped by hpsa_pci_init */
+static void hpsa_free_pci_init(struct ctlr_info *h)
+{
+   hpsa_free_cfgtables(h); /* pci_init 4 */
+   iounmap(h->vaddr);  /* pci_init 3 */
+   hpsa_disable_interrupt_mode(h); /* pci_init 2 */
+   pci_release_regions(h->pdev);   /* pci_init 2 */
+   pci_disable_device(h->pdev);/* pci_init 1 */
+}
+
+/* several items must be freed later */
 static int hpsa_pci_init(struct ctlr_info *h)
 {
int prod_index, err;
@@ -6767,15 +6792,15 @@ static int hpsa_pci_init(struct ctlr_info *h)
 
err = pci_enable_device(h->pdev);
if (err) {
-   dev_warn(&h->pdev->dev, "unable to enable PCI device\n");
+   dev_err(&h->pdev->dev, "failed to enable PCI device\n");
return err;
}
 
err = pci_request_regions(h->pdev, HPSA);
if (err) {
dev_err(&h->pdev->dev,
-   "cannot obtain PCI resources, aborting\n");
-   return err;
+   "failed to obtain PCI resources\n");
+   goto clean1;/* pci */
}
 
pci_set_master(h->pdev);
@@ -6783,40 +6808,41 @@ static int hpsa_pci_init(struct ctlr_info *h)
hpsa_interrupt_mode(h);
err = hpsa_pci_find_memory_BAR(h->pdev, &h->paddr);
if (err)
-   goto err_out_free_res;
+   goto clean2;/* intmode+region, pci */
h->vaddr = remap_pci_mem(h->paddr, 0x250);
if (!h->vaddr) {
+   dev_err(&h->pdev->dev, "failed to remap PCI mem\n");
err = -ENOMEM;
-   goto err_out_free_res;
+   goto clean2;/* intmode+region, pci */
}
err = hpsa_wait_for_board_state(h->pdev, h->vaddr, BOARD_READY);
if (err)
-   goto err_out_free_res;
+   goto clean3;/* vaddr, intmode+region, pci */
err = hpsa_find_cfgtables(h);
if (err)
-   goto err_out_free_res;
+   goto clean3;/* vaddr, intmode+region, pci */
hpsa_find_board_params(h);
 
if (!hpsa_CISS_signature_present(h)) {
err = -ENODEV;
-   goto err_out_free_res;
+   goto clean4;/* cfgtables, vaddr, intmode+region, pci */
}
hpsa_set_driver_support_bits(h);
hpsa_p600_dma_prefetch_quirk(h);
err = hpsa_enter_simple_mode(h);
if (err)
-   goto err_out_free_res;
+   goto clean4;/* cfgtables, vaddr, intmode+region, pci */
return 0;
 
-err_out_free_res:
-   if (h->transtable)
-   iounmap(h->transtable);
-   if (h->cfgtable)
-   iounmap(h->cfgtable);
-   if (h->vaddr)
-   iounmap(h->vaddr);
-   pci_disable_device(h->pdev);
+clean4:/* cfgtables, vaddr, intmode+region, pci */
+   hpsa_free_cfgtables(h);
+clean3:/* vaddr, intmode+region, pci */
+   iounmap(h->vaddr);
+clean2:/* intmode+region, pci */
+   hpsa_disable_interrupt_mode(h);
pci_release_regions(h->pdev);
+clean1:/* pci */
+   pci_disable_device(h->pdev);
return err;
 }
 
@@ -7025,8 +7051,9 @@ static int hpsa_request_irqs(struct ctlr_info *h,
}
}
 

[PATCH v3 20/42] hpsa: add more ioaccel2 error handling, including underrun statuses.

2015-03-17 Thread Don Brace
From: Joe Handzik 

improve ioaccel2 error handling, including better handling of
underrun statuses

Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Joe Handzik 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |   33 -
 drivers/scsi/hpsa_cmd.h |6 ++
 2 files changed, 34 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 0a3ea37..ba89375a 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -1898,6 +1898,7 @@ static int handle_ioaccel_mode2_error(struct ctlr_info *h,
 {
int data_len;
int retry = 0;
+   u32 ioaccel2_resid = 0;
 
switch (c2->error_data.serv_response) {
case IOACCEL2_SERV_RESPONSE_COMPLETE:
@@ -1956,11 +1957,33 @@ static int handle_ioaccel_mode2_error(struct ctlr_info 
*h,
}
break;
case IOACCEL2_SERV_RESPONSE_FAILURE:
-   /* don't expect to get here. */
-   dev_warn(&h->pdev->dev,
-   "unexpected delivery or target failure, status = 
0x%02x\n",
-   c2->error_data.status);
-   retry = 1;
+   switch (c2->error_data.status) {
+   case IOACCEL2_STATUS_SR_IO_ERROR:
+   case IOACCEL2_STATUS_SR_IO_ABORTED:
+   case IOACCEL2_STATUS_SR_OVERRUN:
+   retry = 1;
+   break;
+   case IOACCEL2_STATUS_SR_UNDERRUN:
+   cmd->result = (DID_OK << 16);   /* host byte */
+   cmd->result |= (COMMAND_COMPLETE << 8); /* msg byte */
+   ioaccel2_resid = c2->error_data.resid_cnt[3] << 24;
+   ioaccel2_resid |= c2->error_data.resid_cnt[2] << 16;
+   ioaccel2_resid |= c2->error_data.resid_cnt[1] << 8;
+   ioaccel2_resid |= c2->error_data.resid_cnt[0];
+   scsi_set_resid(cmd, ioaccel2_resid);
+   break;
+   case IOACCEL2_STATUS_SR_NO_PATH_TO_DEVICE:
+   case IOACCEL2_STATUS_SR_INVALID_DEVICE:
+   case IOACCEL2_STATUS_SR_IOACCEL_DISABLED:
+   /* We will get an event from ctlr to trigger rescan */
+   retry = 1;
+   break;
+   default:
+   retry = 1;
+   dev_warn(&h->pdev->dev,
+   "unexpected delivery or target failure, status 
= 0x%02x\n",
+   c2->error_data.status);
+   }
break;
case IOACCEL2_SERV_RESPONSE_TMF_COMPLETE:
break;
diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h
index 0efb6f2b..cecb62b 100644
--- a/drivers/scsi/hpsa_cmd.h
+++ b/drivers/scsi/hpsa_cmd.h
@@ -532,6 +532,12 @@ struct io_accel2_scsi_response {
 #define IOACCEL2_STATUS_SR_TASK_COMP_SET_FULL  0x28
 #define IOACCEL2_STATUS_SR_TASK_COMP_ABORTED   0x40
 #define IOACCEL2_STATUS_SR_IOACCEL_DISABLED0x0E
+#define IOACCEL2_STATUS_SR_IO_ERROR0x01
+#define IOACCEL2_STATUS_SR_IO_ABORTED  0x02
+#define IOACCEL2_STATUS_SR_NO_PATH_TO_DEVICE   0x03
+#define IOACCEL2_STATUS_SR_INVALID_DEVICE  0x04
+#define IOACCEL2_STATUS_SR_UNDERRUN0x51
+#define IOACCEL2_STATUS_SR_OVERRUN 0x75
u8 data_present;/* low 2 bits */
 #define IOACCEL2_NO_DATAPRESENT0x000
 #define IOACCEL2_RESPONSE_DATAPRESENT  0x001

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 27/42] hpsa: use helper routines for finishing commands

2015-03-17 Thread Don Brace
From: Webb Scales 

cleanup command completions

Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Webb Scales 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |   78 ---
 1 file changed, 31 insertions(+), 47 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index e9642dd..b0949f7 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -2010,6 +2010,19 @@ static int handle_ioaccel_mode2_error(struct ctlr_info 
*h,
return retry;   /* retry on raid path? */
 }
 
+static void hpsa_cmd_free_and_done(struct ctlr_info *h,
+   struct CommandList *c, struct scsi_cmnd *cmd)
+{
+   cmd_free(h, c);
+   cmd->scsi_done(cmd);
+}
+
+static void hpsa_retry_cmd(struct ctlr_info *h, struct CommandList *c)
+{
+   INIT_WORK(&c->work, hpsa_command_resubmit_worker);
+   queue_work_on(raw_smp_processor_id(), h->resubmit_wq, &c->work);
+}
+
 static void process_ioaccel2_completion(struct ctlr_info *h,
struct CommandList *c, struct scsi_cmnd *cmd,
struct hpsa_scsi_dev_t *dev)
@@ -2018,13 +2031,11 @@ static void process_ioaccel2_completion(struct 
ctlr_info *h,
 
/* check for good status */
if (likely(c2->error_data.serv_response == 0 &&
-   c2->error_data.status == 0)) {
-   cmd_free(h, c);
-   cmd->scsi_done(cmd);
-   return;
-   }
+   c2->error_data.status == 0))
+   return hpsa_cmd_free_and_done(h, c, cmd);
 
-   /* Any RAID offload error results in retry which will use
+   /*
+* Any RAID offload error results in retry which will use
 * the normal I/O path so the controller can handle whatever's
 * wrong.
 */
@@ -2034,19 +2045,14 @@ static void process_ioaccel2_completion(struct 
ctlr_info *h,
if (c2->error_data.status ==
IOACCEL2_STATUS_SR_IOACCEL_DISABLED)
dev->offload_enabled = 0;
-   goto retry_cmd;
+
+   return hpsa_retry_cmd(h, c);
}
 
if (handle_ioaccel_mode2_error(h, c, cmd, c2))
-   goto retry_cmd;
-
-   cmd_free(h, c);
-   cmd->scsi_done(cmd);
-   return;
+   return hpsa_retry_cmd(h, c);
 
-retry_cmd:
-   INIT_WORK(&c->work, hpsa_command_resubmit_worker);
-   queue_work_on(raw_smp_processor_id(), h->resubmit_wq, &c->work);
+   return hpsa_cmd_free_and_done(h, c, cmd);
 }
 
 /* Returns 0 on success, < 0 otherwise. */
@@ -2119,22 +2125,15 @@ static void complete_scsi_command(struct CommandList 
*cp)
if (unlikely(ei->CommandStatus == CMD_CTLR_LOCKUP)) {
/* DID_NO_CONNECT will prevent a retry */
cmd->result = DID_NO_CONNECT << 16;
-   cmd_free(h, cp);
-   cmd->scsi_done(cmd);
-   return;
+   return hpsa_cmd_free_and_done(h, cp, cmd);
}
 
if (cp->cmd_type == CMD_IOACCEL2)
return process_ioaccel2_completion(h, cp, cmd, dev);
 
scsi_set_resid(cmd, ei->ResidualCnt);
-   if (ei->CommandStatus == 0) {
-   if (cp->cmd_type == CMD_IOACCEL1)
-   atomic_dec(&cp->phys_disk->ioaccel_cmds_out);
-   cmd_free(h, cp);
-   cmd->scsi_done(cmd);
-   return;
-   }
+   if (ei->CommandStatus == 0)
+   return hpsa_cmd_free_and_done(h, cp, cmd);
 
/* For I/O accelerator commands, copy over some fields to the normal
 * CISS header used below for error handling.
@@ -2156,10 +2155,7 @@ static void complete_scsi_command(struct CommandList *cp)
if (is_logical_dev_addr_mode(dev->scsi3addr)) {
if (ei->CommandStatus == CMD_IOACCEL_DISABLED)
dev->offload_enabled = 0;
-   INIT_WORK(&cp->work, hpsa_command_resubmit_worker);
-   queue_work_on(raw_smp_processor_id(),
-   h->resubmit_wq, &cp->work);
-   return;
+   return hpsa_retry_cmd(h, cp);
}
}
 
@@ -2290,8 +2286,8 @@ static void complete_scsi_command(struct CommandList *cp)
dev_warn(&h->pdev->dev, "cp %p returned unknown status %x\n",
cp, ei->CommandStatus);
}
-   cmd_free(h, cp);
-   cmd->scsi_done(cmd);
+
+   return hpsa_cmd_free_and_done(h, cp, cmd);
 }
 
 static void hpsa_pci_unmap(struct pci_dev *pdev,
@@ -4544,16 +4540,13 @@ static void hpsa_command_resubmit_worker(struct 
work_struct *work)
 {
struct scsi_cmnd *cmd;
struct hpsa_scsi_dev_t *dev;
-   struct CommandList *c =
-   container_of(work, struct CommandList, work);
+   struct CommandList *c = container_of(work, struct CommandList, work);
 

[PATCH v3 29/42] hpsa: refactor and rework support for sending TEST_UNIT_READY

2015-03-17 Thread Don Brace
From: Webb Scales 

Factor out the code which sends the TEST_UNIT_READY from
wait_for_device_to_become_ready() into its own function.

Move the code which waits for the TEST_UNIT_READY from
wait_for_device_to_become_ready() into its own function.

If a logical drive has failed, resetting it will ensure
outstanding commands are completed, but polling it with
TURs after the reset will not work because the TURs will
never report good status.  So successful TUR should not
be a condition of success for the device reset error
handler.

Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Webb Scales 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |  117 ++-
 1 file changed, 87 insertions(+), 30 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 1cae336..3751df3 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -4822,51 +4822,108 @@ static int hpsa_register_scsi(struct ctlr_info *h)
return -ENOMEM;
 }
 
-static int wait_for_device_to_become_ready(struct ctlr_info *h,
-   unsigned char lunaddr[])
+/*
+ * Send a TEST_UNIT_READY command to the specified LUN using the specified
+ * reply queue; returns zero if the unit is ready, and non-zero otherwise.
+ */
+static int hpsa_send_test_unit_ready(struct ctlr_info *h,
+   struct CommandList *c, unsigned char lunaddr[],
+   int reply_queue)
+{
+   int rc;
+
+   /* Send the Test Unit Ready, fill_cmd can't fail, no mapping */
+   (void) fill_cmd(c, TEST_UNIT_READY, h,
+   NULL, 0, 0, lunaddr, TYPE_CMD);
+   rc = hpsa_scsi_do_simple_cmd(h, c, reply_queue, NO_TIMEOUT);
+   if (rc)
+   return rc;
+   /* no unmap needed here because no data xfer. */
+
+   /* Check if the unit is already ready. */
+   if (c->err_info->CommandStatus == CMD_SUCCESS)
+   return 0;
+
+   /*
+* The first command sent after reset will receive "unit attention" to
+* indicate that the LUN has been reset...this is actually what we're
+* looking for (but, success is good too).
+*/
+   if (c->err_info->CommandStatus == CMD_TARGET_STATUS &&
+   c->err_info->ScsiStatus == SAM_STAT_CHECK_CONDITION &&
+   (c->err_info->SenseInfo[2] == NO_SENSE ||
+c->err_info->SenseInfo[2] == UNIT_ATTENTION))
+   return 0;
+
+   return 1;
+}
+
+/*
+ * Wait for a TEST_UNIT_READY command to complete, retrying as necessary;
+ * returns zero when the unit is ready, and non-zero when giving up.
+ */
+static int hpsa_wait_for_test_unit_ready(struct ctlr_info *h,
+   struct CommandList *c,
+   unsigned char lunaddr[], int reply_queue)
 {
int rc;
int count = 0;
int waittime = 1; /* seconds */
-   struct CommandList *c;
-
-   c = cmd_alloc(h);
 
/* Send test unit ready until device ready, or give up. */
-   while (count < HPSA_TUR_RETRY_LIMIT) {
+   for (count = 0; count < HPSA_TUR_RETRY_LIMIT; count++) {
 
-   /* Wait for a bit.  do this first, because if we send
+   /*
+* Wait for a bit.  do this first, because if we send
 * the TUR right away, the reset will just abort it.
 */
msleep(1000 * waittime);
-   count++;
-   rc = 0; /* Device ready. */
+
+   rc = hpsa_send_test_unit_ready(h, c, lunaddr, reply_queue);
+   if (!rc)
+   break;
 
/* Increase wait time with each try, up to a point. */
if (waittime < HPSA_MAX_WAIT_INTERVAL_SECS)
-   waittime = waittime * 2;
+   waittime *= 2;
 
-   /* Send the Test Unit Ready, fill_cmd can't fail, no mapping */
-   (void) fill_cmd(c, TEST_UNIT_READY, h,
-   NULL, 0, 0, lunaddr, TYPE_CMD);
-   rc = hpsa_scsi_do_simple_cmd(h, c, DEFAULT_REPLY_QUEUE,
-   NO_TIMEOUT);
-   if (rc)
-   goto do_it_again;
-   /* no unmap needed here because no data xfer. */
+   dev_warn(&h->pdev->dev,
+"waiting %d secs for device to become ready.\n",
+waittime);
+   }
 
-   if (c->err_info->CommandStatus == CMD_SUCCESS)
-   break;
+   return rc;
+}
 
-   if (c->err_info->CommandStatus == CMD_TARGET_STATUS &&
-   c->err_info->ScsiStatus == SAM_STAT_CHECK_CONDITION &&
-   (c->err_info->SenseInfo[2] == NO_SENSE ||
-   c->err_info->SenseInfo[2] == UNIT_ATTENTION))
+static int wait_for_device_to_become_ready(struct ctlr_info *h,

[PATCH v3 26/42] hpsa: add support sending aborts to physical devices via the ioaccel2 path

2015-03-17 Thread Don Brace
From: Stephen Cameron 

add support for tmf when in ioaccel2 mode

Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Joe Handzik 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |  136 +--
 drivers/scsi/hpsa.h |1 
 drivers/scsi/hpsa_cmd.h |6 +-
 3 files changed, 135 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 7d0e226..e9642dd 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -861,6 +861,28 @@ static void set_ioaccel1_performant_mode(struct ctlr_info 
*h,
IOACCEL1_BUSADDR_CMDTYPE;
 }
 
+static void set_ioaccel2_tmf_performant_mode(struct ctlr_info *h,
+   struct CommandList *c,
+   int reply_queue)
+{
+   struct hpsa_tmf_struct *cp = (struct hpsa_tmf_struct *)
+   &h->ioaccel2_cmd_pool[c->cmdindex];
+
+   /* Tell the controller to post the reply to the queue for this
+* processor.  This seems to give the best I/O throughput.
+*/
+   if (likely(reply_queue == DEFAULT_REPLY_QUEUE))
+   cp->reply_queue = smp_processor_id() % h->nreply_queues;
+   else
+   cp->reply_queue = reply_queue % h->nreply_queues;
+   /* Set the bits in the address sent down to include:
+*  - performant mode bit not used in ioaccel mode 2
+*  - pull count (bits 0-3)
+*  - command type isn't needed for ioaccel2
+*/
+   c->busaddr |= h->ioaccel2_blockFetchTable[0];
+}
+
 static void set_ioaccel2_performant_mode(struct ctlr_info *h,
struct CommandList *c,
int reply_queue)
@@ -927,6 +949,10 @@ static void __enqueue_cmd_and_start_io(struct ctlr_info *h,
set_ioaccel2_performant_mode(h, c, reply_queue);
writel(c->busaddr, h->vaddr + IOACCEL2_INBOUND_POSTQ_32);
break;
+   case IOACCEL2_TMF:
+   set_ioaccel2_tmf_performant_mode(h, c, reply_queue);
+   writel(c->busaddr, h->vaddr + IOACCEL2_INBOUND_POSTQ_32);
+   break;
default:
set_performant_mode(h, c, reply_queue);
h->access.submit_command(h, c);
@@ -4954,6 +4980,47 @@ static int hpsa_send_abort(struct ctlr_info *h, unsigned 
char *scsi3addr,
return rc;
 }
 
+static void setup_ioaccel2_abort_cmd(struct CommandList *c, struct ctlr_info 
*h,
+   struct CommandList *command_to_abort, int reply_queue)
+{
+   struct io_accel2_cmd *c2 = &h->ioaccel2_cmd_pool[c->cmdindex];
+   struct hpsa_tmf_struct *ac = (struct hpsa_tmf_struct *) c2;
+   struct io_accel2_cmd *c2a =
+   &h->ioaccel2_cmd_pool[command_to_abort->cmdindex];
+   struct scsi_cmnd *scmd =
+   (struct scsi_cmnd *) command_to_abort->scsi_cmd;
+   struct hpsa_scsi_dev_t *dev = scmd->device->hostdata;
+
+   /*
+* We're overlaying struct hpsa_tmf_struct on top of something which
+* was allocated as a struct io_accel2_cmd, so we better be sure it
+* actually fits, and doesn't overrun the error info space.
+*/
+   BUILD_BUG_ON(sizeof(struct hpsa_tmf_struct) >
+   sizeof(struct io_accel2_cmd));
+   BUG_ON(offsetof(struct io_accel2_cmd, error_data) <
+   offsetof(struct hpsa_tmf_struct, error_len) +
+   sizeof(ac->error_len));
+
+   c->cmd_type = IOACCEL2_TMF;
+   /* Adjust the DMA address to point to the accelerated command buffer */
+   c->busaddr = (u32) h->ioaccel2_cmd_pool_dhandle +
+   (c->cmdindex * sizeof(struct io_accel2_cmd));
+   BUG_ON(c->busaddr & 0x007F);
+
+   memset(ac, 0, sizeof(*c2)); /* yes this is correct */
+   ac->iu_type = IOACCEL2_IU_TMF_TYPE;
+   ac->reply_queue = reply_queue;
+   ac->tmf = IOACCEL2_TMF_ABORT;
+   ac->it_nexus = cpu_to_le32(dev->ioaccel_handle);
+   memset(ac->lun_id, 0, sizeof(ac->lun_id));
+   ac->tag = cpu_to_le64(c->cmdindex << DIRECT_LOOKUP_SHIFT);
+   ac->abort_tag = cpu_to_le64(le32_to_cpu(c2a->Tag));
+   ac->error_ptr = cpu_to_le64(c->busaddr +
+   offsetof(struct io_accel2_cmd, error_data));
+   ac->error_len = cpu_to_le32(sizeof(c2->error_data));
+}
+
 /* ioaccel2 path firmware cannot handle abort task requests.
  * Change abort requests to physical target reset, and send to the
  * address of the physical disk used for the ioaccel 2 command.
@@ -5032,17 +5099,72 @@ static int hpsa_send_reset_as_abort_ioaccel2(struct 
ctlr_info *h,
return rc; /* success */
 }
 
+static int hpsa_send_abort_ioaccel2(struct ctlr_info *h,
+   struct CommandList *abort, int reply_queue)
+{
+   int rc = IO_OK;
+   struct CommandList *c;
+  

[PATCH v3 34/42] hpsa: fix try_soft_reset error handling

2015-03-17 Thread Don Brace
From: Robert Elliott 

If registering the special interrupt handlers in hpsa_init_one
before a soft reset fails, the error exit needs to deallocate
everything that was allocated before.

Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Robert Elliott 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |   16 +++-
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 0afc48b..fdf36a7 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -7810,9 +7810,15 @@ reinit_after_soft_reset:
dev_warn(&h->pdev->dev,
"Failed to request_irq after soft reset.\n");
/*
-* clean4 starts with free_irqs, but that was just
-* done. Then, request_irqs_failed, so there is
-* nothing to free. So, goto the next label.
+* cannot goto clean7 or free_irqs will be called
+* again. Instead, do its work
+*/
+   hpsa_free_performant_mode(h);   /* clean7 */
+   hpsa_free_sg_chain_blocks(h);   /* clean6 */
+   hpsa_free_cmd_pool(h);  /* clean5 */
+   /*
+* skip hpsa_free_irqs(h) clean4 since that
+* was just called before request_irqs failed
 */
goto clean3;
}
@@ -7820,7 +7826,7 @@ reinit_after_soft_reset:
rc = hpsa_kdump_soft_reset(h);
if (rc)
/* Neither hard nor soft reset worked, we're hosed. */
-   goto clean4;
+   goto clean7;
 
dev_info(&h->pdev->dev, "Board READY.\n");
dev_info(&h->pdev->dev,
@@ -7841,7 +7847,7 @@ reinit_after_soft_reset:
hpsa_undo_allocations_after_kdump_soft_reset(h);
try_soft_reset = 0;
if (rc)
-   /* don't go to clean4, we already unallocated */
+   /* don't goto clean, we already unallocated */
return -ENODEV;
 
goto reinit_after_soft_reset;

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 28/42] hpsa: don't return abort request until target is complete

2015-03-17 Thread Don Brace
From: Webb Scales 

Don't return from the abort request until the target command is complete.
Mark outstanding commands which have a pending abort, and do not send them
to the host if we can avoid it.

If the current command has been aborted, do not call the SCSI command
completion routine from the I/O path: when the abort returns successfully,
the SCSI mid-layer will handle the completion implicitly.

The following race was possible in theory.

1. LLD is requested to abort a scsi command
2. scsi command completes
3. The struct CommandList associated with 2 is made available.
4. new io request to LLD to another LUN re-uses struct CommandList
5. abort handler follows scsi_cmnd->host_scribble and
   finds struct CommandList and tries to aborts it.

Now we have aborted the wrong command.

Fix by resetting the scsi_cmd field of struct CommandList
upon completion and making the abort handler check that
the scsi_cmd pointer in the CommadList struct matches the
scsi_cmnd that it has been asked to abort.

Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Webb Scales 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |  120 +++
 drivers/scsi/hpsa.h |1 
 drivers/scsi/hpsa_cmd.h |2 +
 3 files changed, 93 insertions(+), 30 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index b0949f7..1cae336 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -195,6 +195,10 @@ static struct board_type products[] = {
{0x103C, "Unknown Smart Array", &SA5_access},
 };
 
+#define SCSI_CMD_BUSY ((struct scsi_cmnd *)&hpsa_cmd_busy)
+static const struct scsi_cmnd hpsa_cmd_busy;
+#define SCSI_CMD_IDLE ((struct scsi_cmnd *)&hpsa_cmd_idle)
+static const struct scsi_cmnd hpsa_cmd_idle;
 static int number_of_controllers;
 
 static irqreturn_t do_hpsa_intr_intx(int irq, void *dev_id);
@@ -270,6 +274,11 @@ static inline struct ctlr_info *shost_to_hba(struct 
Scsi_Host *sh)
return (struct ctlr_info *) *priv;
 }
 
+static inline bool hpsa_is_cmd_idle(struct CommandList *c)
+{
+   return c->scsi_cmd == SCSI_CMD_IDLE;
+}
+
 /* extract sense key, asc, and ascq from sense data.  -1 means invalid. */
 static void decode_sense_data(const u8 *sense_data, int sense_data_len,
int *sense_key, int *asc, int *ascq)
@@ -959,9 +968,11 @@ static void __enqueue_cmd_and_start_io(struct ctlr_info *h,
}
 }
 
-static void enqueue_cmd_and_start_io(struct ctlr_info *h,
-   struct CommandList *c)
+static void enqueue_cmd_and_start_io(struct ctlr_info *h, struct CommandList 
*c)
 {
+   if (unlikely(c->abort_pending))
+   return finish_cmd(c);
+
__enqueue_cmd_and_start_io(h, c, DEFAULT_REPLY_QUEUE);
 }
 
@@ -2010,9 +2021,36 @@ static int handle_ioaccel_mode2_error(struct ctlr_info 
*h,
return retry;   /* retry on raid path? */
 }
 
+static void hpsa_cmd_resolve_events(struct ctlr_info *h,
+   struct CommandList *c)
+{
+   /*
+* Prevent the following race in the abort handler:
+*
+* 1. LLD is requested to abort a SCSI command
+* 2. The SCSI command completes
+* 3. The struct CommandList associated with step 2 is made available
+* 4. New I/O request to LLD to another LUN re-uses struct CommandList
+* 5. Abort handler follows scsi_cmnd->host_scribble and
+*finds struct CommandList and tries to aborts it
+* Now we have aborted the wrong command.
+*
+* Clear c->scsi_cmd here so that the abort handler will know this
+* command has completed.  Then, check to see if the abort handler is
+* waiting for this command, and, if so, wake it.
+*/
+   c->scsi_cmd = SCSI_CMD_IDLE;
+   mb(); /* Ensure c->scsi_cmd is set to SCSI_CMD_IDLE */
+   if (c->abort_pending) {
+   c->abort_pending = false;
+   wake_up_all(&h->abort_sync_wait_queue);
+   }
+}
+
 static void hpsa_cmd_free_and_done(struct ctlr_info *h,
struct CommandList *c, struct scsi_cmnd *cmd)
 {
+   hpsa_cmd_resolve_events(h, c);
cmd_free(h, c);
cmd->scsi_done(cmd);
 }
@@ -2023,6 +2061,21 @@ static void hpsa_retry_cmd(struct ctlr_info *h, struct 
CommandList *c)
queue_work_on(raw_smp_processor_id(), h->resubmit_wq, &c->work);
 }
 
+static void hpsa_set_scsi_cmd_aborted(struct scsi_cmnd *cmd)
+{
+   cmd->result = DID_ABORT << 16;
+}
+
+static void hpsa_cmd_abort_and_free(struct ctlr_info *h, struct CommandList *c,
+   struct scsi_cmnd *cmd)
+{
+   hpsa_set_scsi_cmd_aborted(cmd);
+   dev_warn(&h->pdev->dev, "CDB %16phN was aborted with status 0x%x\n",
+c->Request.CDB, c->err_info->ScsiStatus);
+   hpsa_cmd_resolve_events(h, c);
+   cmd_free(h, c); /* FIX-ME:  change to cmd_tagged_free(h, c) */
+}
+
 static void

[PATCH v3 33/42] hpsa: cleanup for init_one step 2 in kdump

2015-03-17 Thread Don Brace
From: Robert Elliott 

In hpsa_undo_allocations_after_kdump_soft_reset,
the things allocated in hpsa_init_one step 2 -
h->resubmit_wq and h->lockup_detected  need to
be freed, in the right order.

Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Robert Elliott 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |   10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index f26e6bc..0afc48b 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -7422,6 +7422,16 @@ static void 
hpsa_undo_allocations_after_kdump_soft_reset(struct ctlr_info *h)
hpsa_free_cmd_pool(h);  /* init_one 5 */
hpsa_free_irqs(h);  /* init_one 4 */
hpsa_free_pci_init(h);  /* init_one 3 */
+   free_percpu(h->lockup_detected);/* init_one 2 */
+   h->lockup_detected = NULL;  /* init_one 2 */
+   if (h->resubmit_wq) {
+   destroy_workqueue(h->resubmit_wq);  /* init_one 1 */
+   h->resubmit_wq = NULL;
+   }
+   if (h->rescan_ctlr_wq) {
+   destroy_workqueue(h->rescan_ctlr_wq);
+   h->rescan_ctlr_wq = NULL;
+   }
kfree(h);   /* init_one 1 */
 }
 

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 35/42] hpsa: create workqueue after the driver is ready for use

2015-03-17 Thread Don Brace
From: Robert Elliott 

Don't create the resubmit workqueue in hpsa_init_one until everything else
is ready to use, so everything can be freed in reverse order of when they
were allocated without risking freeing things while workqueue items are
still active.

Destroy the workqueue in the right order in
hpsa_undo_allocations_after_kdump_soft_reset too.

Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Robert Elliott 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |   60 ++-
 1 file changed, 31 insertions(+), 29 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index fdf36a7..0057236 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -7714,30 +7714,18 @@ reinit_after_soft_reset:
atomic_set(&h->passthru_cmds_avail, HPSA_MAX_CONCURRENT_PASSTHRUS);
atomic_set(&h->abort_cmds_available, HPSA_CMDS_RESERVED_FOR_ABORTS);
 
-   h->rescan_ctlr_wq = hpsa_create_controller_wq(h, "rescan");
-   if (!h->rescan_ctlr_wq) {
-   rc = -ENOMEM;
-   goto clean1;
-   }
-
-   h->resubmit_wq = hpsa_create_controller_wq(h, "resubmit");
-   if (!h->resubmit_wq) {
-   rc = -ENOMEM;
-   goto clean1;/* aer/h */
-   }
-
/* Allocate and clear per-cpu variable lockup_detected */
h->lockup_detected = alloc_percpu(u32);
if (!h->lockup_detected) {
dev_err(&h->pdev->dev, "Failed to allocate lockup detector\n");
rc = -ENOMEM;
-   goto clean1;/* wq/aer/h */
+   goto clean1;/* aer/h */
}
set_lockup_detected_for_all_cpus(h, 0);
 
rc = hpsa_pci_init(h);
if (rc)
-   goto clean2;/* lockup, wq/aer/h */
+   goto clean2;/* lockup, aer/h */
 
sprintf(h->devname, HPSA "%d", number_of_controllers);
h->ctlr = number_of_controllers;
@@ -7753,7 +7741,7 @@ reinit_after_soft_reset:
dac = 0;
} else {
dev_err(&pdev->dev, "no suitable DMA available\n");
-   goto clean3;/* pci, lockup, wq/aer/h */
+   goto clean3;/* pci, lockup, aer/h */
}
}
 
@@ -7762,16 +7750,16 @@ reinit_after_soft_reset:
 
rc = hpsa_request_irqs(h, do_hpsa_intr_msi, do_hpsa_intr_intx);
if (rc)
-   goto clean3;/* pci, lockup, wq/aer/h */
+   goto clean3;/* pci, lockup, aer/h */
dev_info(&pdev->dev, "%s: <0x%x> at IRQ %d%s using DAC\n",
   h->devname, pdev->device,
   h->intr[h->intr_mode], dac ? "" : " not");
rc = hpsa_alloc_cmd_pool(h);
if (rc)
-   goto clean4;/* irq, pci, lockup, wq/aer/h */
+   goto clean4;/* irq, pci, lockup, aer/h */
rc = hpsa_alloc_sg_chain_blocks(h);
if (rc)
-   goto clean5;/* cmd, irq, pci, lockup, wq/aer/h */
+   goto clean5;/* cmd, irq, pci, lockup, aer/h */
init_waitqueue_head(&h->scan_wait_queue);
init_waitqueue_head(&h->abort_cmd_wait_queue);
init_waitqueue_head(&h->abort_sync_wait_queue);
@@ -7784,7 +7772,20 @@ reinit_after_soft_reset:
spin_lock_init(&h->devlock);
rc = hpsa_put_ctlr_into_performant_mode(h);
if (rc)
-   goto clean6;/* sg, cmd, irq, pci, lockup, wq/aer/h */
+   goto clean6;/* sg, cmd, irq, pci, lockup, aer/h */
+
+   /* create the resubmit workqueue */
+   h->rescan_ctlr_wq = hpsa_create_controller_wq(h, "rescan");
+   if (!h->rescan_ctlr_wq) {
+   rc = -ENOMEM;
+   goto clean7;
+   }
+
+   h->resubmit_wq = hpsa_create_controller_wq(h, "resubmit");
+   if (!h->resubmit_wq) {
+   rc = -ENOMEM;
+   goto clean7;/* aer/h */
+   }
 
/*
 * At this point, the controller is ready to take commands.
@@ -7826,7 +7827,7 @@ reinit_after_soft_reset:
rc = hpsa_kdump_soft_reset(h);
if (rc)
/* Neither hard nor soft reset worked, we're hosed. */
-   goto clean7;
+   goto clean8;
 
dev_info(&h->pdev->dev, "Board READY.\n");
dev_info(&h->pdev->dev,
@@ -7863,7 +7864,7 @@ reinit_after_soft_reset:
hpsa_hba_inquiry(h);
rc = hpsa_register_scsi(h); /* hook ourselves into SCSI subsystem */
if (rc)
-   goto clean7;
+   goto clean8; /* wq, perf, sg, cmd, irq, pci, lockup, aer/h */
 
/* Monitor the controller for firmware lockups */
h->heartbeat_sample_interval = HEARTBEAT_SAMPLE_INTERVAL;
@@ -7875,19 +7876,20 @@ reinit_after_soft_reset:
h->heartbeat_sample_interval);
return 0;
 
-clean7: /* perf, sg, cmd, irq, pci, 

[PATCH v3 36/42] hpsa: add interrupt number to /proc/interrupts interrupt name

2015-03-17 Thread Don Brace
From: Robert Elliott 

Add the interrupt number to the interrupt names that
appear in /proc/interrupts, so they are unique

Also, delete the IRQ and DAC prints.  Other parts of the kernel
already print the IRQ assignments, and dual-address-cycle support
has not been interesting since the parallel PCI bus went from
32 to 64 bits wide.

Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Robert Elliott 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |   20 ++--
 drivers/scsi/hpsa.h |1 +
 2 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 0057236..34c178c 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -7337,8 +7337,9 @@ static int hpsa_request_irqs(struct ctlr_info *h,
if (h->intr_mode == PERF_MODE_INT && h->msix_vector > 0) {
/* If performant mode and MSI-X, use multiple reply queues */
for (i = 0; i < h->msix_vector; i++) {
+   sprintf(h->intrname[i], "%s-msix%d", h->devname, i);
rc = request_irq(h->intr[i], msixhandler,
-   0, h->devname,
+   0, h->intrname[i],
&h->q[i]);
if (rc) {
int j;
@@ -7359,12 +7360,22 @@ static int hpsa_request_irqs(struct ctlr_info *h,
} else {
/* Use single reply pool */
if (h->msix_vector > 0 || h->msi_vector) {
+   if (h->msix_vector)
+   sprintf(h->intrname[h->intr_mode],
+   "%s-msix", h->devname);
+   else
+   sprintf(h->intrname[h->intr_mode],
+   "%s-msi", h->devname);
rc = request_irq(h->intr[h->intr_mode],
-   msixhandler, 0, h->devname,
+   msixhandler, 0,
+   h->intrname[h->intr_mode],
&h->q[h->intr_mode]);
} else {
+   sprintf(h->intrname[h->intr_mode],
+   "%s-intx", h->devname);
rc = request_irq(h->intr[h->intr_mode],
-   intxhandler, IRQF_SHARED, h->devname,
+   intxhandler, IRQF_SHARED,
+   h->intrname[h->intr_mode],
&h->q[h->intr_mode]);
}
irq_set_affinity_hint(h->intr[h->intr_mode], NULL);
@@ -7751,9 +7762,6 @@ reinit_after_soft_reset:
rc = hpsa_request_irqs(h, do_hpsa_intr_msi, do_hpsa_intr_intx);
if (rc)
goto clean3;/* pci, lockup, aer/h */
-   dev_info(&pdev->dev, "%s: <0x%x> at IRQ %d%s using DAC\n",
-  h->devname, pdev->device,
-  h->intr[h->intr_mode], dac ? "" : " not");
rc = hpsa_alloc_cmd_pool(h);
if (rc)
goto clean4;/* irq, pci, lockup, aer/h */
diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
index 7cb8586..3ec8934 100644
--- a/drivers/scsi/hpsa.h
+++ b/drivers/scsi/hpsa.h
@@ -220,6 +220,7 @@ struct ctlr_info {
int remove_in_progress;
/* Address of h->q[x] is passed to intr handler to know which queue */
u8 q[MAX_REPLY_QUEUES];
+   char intrname[MAX_REPLY_QUEUES][16];/* "hpsa0-msix00" names */
u32 TMFSupportFlags; /* cache what task mgmt funcs are supported. */
 #define HPSATMF_BITS_SUPPORTED  (1 << 0)
 #define HPSATMF_PHYS_LUN_RESET  (1 << 1)

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 39/42] hpsa: propagate the error code in hpsa_kdump_soft_reset

2015-03-17 Thread Don Brace
From: Robert Elliott 

If hpsa_wait_for_board_state fails, hpsa_kdump_soft_reset
should propagate its return value (e.g., -ENODEV) rather
than just returning -1.

Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Robert Elliott 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |   11 +++
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 511b7ab..3987400 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -7480,19 +7480,22 @@ static int hpsa_request_irqs(struct ctlr_info *h,
 
 static int hpsa_kdump_soft_reset(struct ctlr_info *h)
 {
+   int rc;
hpsa_send_host_reset(h, RAID_CTLR_LUNID, HPSA_RESET_TYPE_CONTROLLER);
 
dev_info(&h->pdev->dev, "Waiting for board to soft reset.\n");
-   if (hpsa_wait_for_board_state(h->pdev, h->vaddr, BOARD_NOT_READY)) {
+   rc = hpsa_wait_for_board_state(h->pdev, h->vaddr, BOARD_NOT_READY);
+   if (rc) {
dev_warn(&h->pdev->dev, "Soft reset had no effect.\n");
-   return -1;
+   return rc;
}
 
dev_info(&h->pdev->dev, "Board reset, awaiting READY status.\n");
-   if (hpsa_wait_for_board_state(h->pdev, h->vaddr, BOARD_READY)) {
+   rc = hpsa_wait_for_board_state(h->pdev, h->vaddr, BOARD_READY);
+   if (rc) {
dev_warn(&h->pdev->dev, "Board failed to become ready "
"after soft reset.\n");
-   return -1;
+   return rc;
}
 
return 0;

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 40/42] hpsa: cleanup reset

2015-03-17 Thread Don Brace
From: Webb Scales 

Synchronize completion the reset with completion of outstanding commands

Extending the newly-added synchronous abort functionality,
now also synchronize resets with the completion of outstanding commands.
Rename the wait queue to reflect the fact that it's being used for both
types of waits.  Also, don't complete commands which are terminated
due to a reset operation.

fix for controller lockup during reset

Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Webb Scales 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |  200 +--
 drivers/scsi/hpsa.h |5 +
 drivers/scsi/hpsa_cmd.h |1 
 3 files changed, 178 insertions(+), 28 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 3987400..96e1d02 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -283,6 +283,11 @@ static inline bool hpsa_is_cmd_idle(struct CommandList *c)
return c->scsi_cmd == SCSI_CMD_IDLE;
 }
 
+static inline bool hpsa_is_pending_event(struct CommandList *c)
+{
+   return c->abort_pending || c->reset_pending;
+}
+
 /* extract sense key, asc, and ascq from sense data.  -1 means invalid. */
 static void decode_sense_data(const u8 *sense_data, int sense_data_len,
int *sense_key, int *asc, int *ascq)
@@ -977,7 +982,7 @@ static void __enqueue_cmd_and_start_io(struct ctlr_info *h,
 
 static void enqueue_cmd_and_start_io(struct ctlr_info *h, struct CommandList 
*c)
 {
-   if (unlikely(c->abort_pending))
+   if (unlikely(hpsa_is_pending_event(c)))
return finish_cmd(c);
 
__enqueue_cmd_and_start_io(h, c, DEFAULT_REPLY_QUEUE);
@@ -1479,6 +1484,8 @@ static void hpsa_figure_phys_disk_ptrs(struct ctlr_info 
*h,
if (nraid_map_entries > RAID_MAP_MAX_ENTRIES)
nraid_map_entries = RAID_MAP_MAX_ENTRIES;
 
+   logical_drive->nphysical_disks = nraid_map_entries;
+
qdepth = 0;
for (i = 0; i < nraid_map_entries; i++) {
logical_drive->phys_disk[i] = NULL;
@@ -2031,6 +2038,8 @@ static int handle_ioaccel_mode2_error(struct ctlr_info *h,
 static void hpsa_cmd_resolve_events(struct ctlr_info *h,
struct CommandList *c)
 {
+   bool do_wake = false;
+
/*
 * Prevent the following race in the abort handler:
 *
@@ -2042,16 +2051,35 @@ static void hpsa_cmd_resolve_events(struct ctlr_info *h,
 *finds struct CommandList and tries to aborts it
 * Now we have aborted the wrong command.
 *
-* Clear c->scsi_cmd here so that the abort handler will know this
-* command has completed.  Then, check to see if the abort handler is
+* Reset c->scsi_cmd here so that the abort or reset handler will know
+* this command has completed.  Then, check to see if the handler is
 * waiting for this command, and, if so, wake it.
 */
c->scsi_cmd = SCSI_CMD_IDLE;
-   mb(); /* Ensure c->scsi_cmd is set to SCSI_CMD_IDLE */
+   mb();   /* Declare command idle before checking for pending events. */
if (c->abort_pending) {
+   do_wake = true;
c->abort_pending = false;
-   wake_up_all(&h->abort_sync_wait_queue);
}
+   if (c->reset_pending) {
+   unsigned long flags;
+   struct hpsa_scsi_dev_t *dev;
+
+   /*
+* There appears to be a reset pending; lock the lock and
+* reconfirm.  If so, then decrement the count of outstanding
+* commands and wake the reset command if this is the last one.
+*/
+   spin_lock_irqsave(&h->lock, flags);
+   dev = c->reset_pending; /* Re-fetch under the lock. */
+   if (dev && atomic_dec_and_test(&dev->reset_cmds_out))
+   do_wake = true;
+   c->reset_pending = NULL;
+   spin_unlock_irqrestore(&h->lock, flags);
+   }
+
+   if (do_wake)
+   wake_up_all(&h->event_sync_wait_queue);
 }
 
 static void hpsa_cmd_resolve_and_free(struct ctlr_info *h,
@@ -2099,10 +2127,6 @@ static void process_ioaccel2_completion(struct ctlr_info 
*h,
c2->error_data.status == 0))
return hpsa_cmd_free_and_done(h, c, cmd);
 
-   /* don't requeue a command which is being aborted */
-   if (unlikely(c->abort_pending))
-   return hpsa_cmd_abort_and_free(h, c, cmd);
-
/*
 * Any RAID offload error results in retry which will use
 * the normal I/O path so the controller can handle whatever's
@@ -2197,6 +2221,13 @@ static void complete_scsi_command(struct CommandList *cp)
return hpsa_cmd_free_and_done(h, cp, cmd);
}
 
+   if ((unlikely(hpsa_is_pending_event(cp {
+   if (cp->reset_pending)
+   return hpsa_cmd_resolve_an

[PATCH v3 37/42] hpsa: use block layer tag for command allocation

2015-03-17 Thread Don Brace
From: Webb Scales 

Rework slave allocation:
  - separate the tagging support setup from the hostdata setup
  - make the hostdata setup act consistently when the lookup fails
  - make the hostdata setup act consistently when the device is not added
  - set up the queue depth consistently across these scenarios
  - if the block layer mq support is not available, explicitly enable and
activate the SCSI layer tcq support (and do this at allocation-time so
that the tags will be available for INQUIRY commands)

Tweak slave configuration so that devices which are masked are also
not attached.

Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Webb Scales 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |  153 +--
 drivers/scsi/hpsa.h |1 
 2 files changed, 123 insertions(+), 31 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 34c178c..4e34a62 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -44,6 +44,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -212,6 +213,9 @@ static int hpsa_compat_ioctl(struct scsi_device *dev, int 
cmd,
 
 static void cmd_free(struct ctlr_info *h, struct CommandList *c);
 static struct CommandList *cmd_alloc(struct ctlr_info *h);
+static void cmd_tagged_free(struct ctlr_info *h, struct CommandList *c);
+static struct CommandList *cmd_tagged_alloc(struct ctlr_info *h,
+   struct scsi_cmnd *scmd);
 static int fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h,
void *buff, size_t size, u16 page_code, unsigned char *scsi3addr,
int cmd_type);
@@ -2047,11 +2051,17 @@ static void hpsa_cmd_resolve_events(struct ctlr_info *h,
}
 }
 
+static void hpsa_cmd_resolve_and_free(struct ctlr_info *h,
+ struct CommandList *c)
+{
+   hpsa_cmd_resolve_events(h, c);
+   cmd_tagged_free(h, c);
+}
+
 static void hpsa_cmd_free_and_done(struct ctlr_info *h,
struct CommandList *c, struct scsi_cmnd *cmd)
 {
-   hpsa_cmd_resolve_events(h, c);
-   cmd_free(h, c);
+   hpsa_cmd_resolve_and_free(h, c);
cmd->scsi_done(cmd);
 }
 
@@ -2072,8 +2082,7 @@ static void hpsa_cmd_abort_and_free(struct ctlr_info *h, 
struct CommandList *c,
hpsa_set_scsi_cmd_aborted(cmd);
dev_warn(&h->pdev->dev, "CDB %16phN was aborted with status 0x%x\n",
 c->Request.CDB, c->err_info->ScsiStatus);
-   hpsa_cmd_resolve_events(h, c);
-   cmd_free(h, c); /* FIX-ME:  change to cmd_tagged_free(h, c) */
+   hpsa_cmd_resolve_and_free(h, c);
 }
 
 static void process_ioaccel2_completion(struct ctlr_info *h,
@@ -4535,7 +4544,7 @@ static int hpsa_ciss_submit(struct ctlr_info *h,
}
 
if (hpsa_scatter_gather(h, c, cmd) < 0) { /* Fill SG list */
-   cmd_free(h, c);
+   hpsa_cmd_resolve_and_free(h, c);
return SCSI_MLQUEUE_HOST_BUSY;
}
enqueue_cmd_and_start_io(h, c);
@@ -4581,6 +4590,8 @@ static inline void hpsa_cmd_partial_init(struct ctlr_info 
*h, int index,
 {
dma_addr_t cmd_dma_handle = h->cmd_pool_dhandle + index * sizeof(*c);
 
+   BUG_ON(c->cmdindex != index);
+
memset(c->Request.CDB, 0, sizeof(c->Request.CDB));
memset(c->err_info, 0, sizeof(*c->err_info));
c->busaddr = (u32) cmd_dma_handle;
@@ -4675,27 +4686,24 @@ static int hpsa_scsi_queue_command(struct Scsi_Host 
*sh, struct scsi_cmnd *cmd)
 
/* Get the ptr to our adapter structure out of cmd->host. */
h = sdev_to_hba(cmd->device);
+
+   BUG_ON(cmd->request->tag < 0);
+
dev = cmd->device->hostdata;
if (!dev) {
cmd->result = DID_NO_CONNECT << 16;
cmd->scsi_done(cmd);
return 0;
}
-   memcpy(scsi3addr, dev->scsi3addr, sizeof(scsi3addr));
 
-   if (unlikely(lockup_detected(h))) {
-   cmd->result = DID_NO_CONNECT << 16;
-   cmd->scsi_done(cmd);
-   return 0;
-   }
-   c = cmd_alloc(h);
+   memcpy(scsi3addr, dev->scsi3addr, sizeof(scsi3addr));
 
if (unlikely(lockup_detected(h))) {
cmd->result = DID_NO_CONNECT << 16;
-   cmd_free(h, c);
cmd->scsi_done(cmd);
return 0;
}
+   c = cmd_tagged_alloc(h, cmd);
 
/*
 * Call alternate submit routine for I/O accelerated commands.
@@ -4708,7 +4716,7 @@ static int hpsa_scsi_queue_command(struct Scsi_Host *sh, 
struct scsi_cmnd *cmd)
if (rc == 0)
return 0;
if (rc == SCSI_MLQUEUE_HOST_BUSY) {
-   cmd_free(h, c);
+   hpsa_cmd_resolve_and_free(h, c);
return SCSI_MLQUEUE_HOST_BUSY;
}
}
@@ -4822,15 +4830,23 @@ static int hpsa_re

[PATCH v3 41/42] hpsa: change driver version

2015-03-17 Thread Don Brace
update driver version

Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 96e1d02..893bb50 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -58,7 +58,7 @@
 #include "hpsa.h"
 
 /* HPSA_DRIVER_VERSION must be 3 byte values (0-255) separated by '.' */
-#define HPSA_DRIVER_VERSION "3.4.4-1"
+#define HPSA_DRIVER_VERSION "3.4.10-0"
 #define DRIVER_NAME "HP HPSA Driver (v " HPSA_DRIVER_VERSION ")"
 #define HPSA "hpsa"
 

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 42/42] hpsa: add PMC to copyright

2015-03-17 Thread Don Brace
need to add PMC to copyright notice and update the Hewlett-Packard
copyright notification.

Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Reviewed-by: Justin Lindley 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |3 ++-
 drivers/scsi/hpsa.h |3 ++-
 drivers/scsi/hpsa_cmd.h |3 ++-
 3 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 893bb50..33ad6eb 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -1,6 +1,7 @@
 /*
  *Disk Array driver for HP Smart Array SAS controllers
- *Copyright 2000, 2014 Hewlett-Packard Development Company, L.P.
+ *Copyright 2014-2015 PMC-Sierra, Inc.
+ *Portions Copyright 2008-2014 Hewlett-Packard Development Company, L.P.
  *
  *This program is free software; you can redistribute it and/or modify
  *it under the terms of the GNU General Public License as published by
diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
index 6ee4da6..80cfc79 100644
--- a/drivers/scsi/hpsa.h
+++ b/drivers/scsi/hpsa.h
@@ -1,6 +1,7 @@
 /*
  *Disk Array driver for HP Smart Array SAS controllers
- *Copyright 2000, 2014 Hewlett-Packard Development Company, L.P.
+ *Copyright 2014-2015 PMC-Sierra, Inc.
+ *Portions Copyright 2008-2014 Hewlett-Packard Development Company, L.P.
  *
  *This program is free software; you can redistribute it and/or modify
  *it under the terms of the GNU General Public License as published by
diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h
index c601622..23a8f0d 100644
--- a/drivers/scsi/hpsa_cmd.h
+++ b/drivers/scsi/hpsa_cmd.h
@@ -1,6 +1,7 @@
 /*
  *Disk Array driver for HP Smart Array SAS controllers
- *Copyright 2000, 2014 Hewlett-Packard Development Company, L.P.
+ *Copyright 2014-2015 PMC-Sierra, Inc.
+ *Portions Copyright 2008-2014 Hewlett-Packard Development Company, L.P.
  *
  *This program is free software; you can redistribute it and/or modify
  *it under the terms of the GNU General Public License as published by

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 38/42] hpsa: use scsi host_no as hpsa controller number

2015-03-17 Thread Don Brace
From: Robert Elliott 

Rather than numbering the hpsa controllers with an
incrementing 0..n value (e.g., that shows up in
/proc/interrupts), use the scsi midlayer
host_no (e.g. matching /sys/class/scsi_host/hostNN).

Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Robert Elliott 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |  134 ---
 1 file changed, 74 insertions(+), 60 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 4e34a62..511b7ab 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -324,32 +324,35 @@ static int check_for_unit_attention(struct ctlr_info *h,
switch (asc) {
case STATE_CHANGED:
dev_warn(&h->pdev->dev,
-   HPSA "%d: a state change detected, command retried\n",
-   h->ctlr);
+   "%s: a state change detected, command retried\n",
+   h->devname);
break;
case LUN_FAILED:
dev_warn(&h->pdev->dev,
-   HPSA "%d: LUN failure detected\n", h->ctlr);
+   "%s: LUN failure detected\n", h->devname);
break;
case REPORT_LUNS_CHANGED:
dev_warn(&h->pdev->dev,
-   HPSA "%d: report LUN data changed\n", h->ctlr);
+   "%s: report LUN data changed\n", h->devname);
/*
 * Note: this REPORT_LUNS_CHANGED condition only occurs on the external
 * target (array) devices.
 */
break;
case POWER_OR_RESET:
-   dev_warn(&h->pdev->dev, HPSA "%d: a power on "
-   "or device reset detected\n", h->ctlr);
+   dev_warn(&h->pdev->dev,
+   "%s: a power on or device reset detected\n",
+   h->devname);
break;
case UNIT_ATTENTION_CLEARED:
-   dev_warn(&h->pdev->dev, HPSA "%d: unit attention "
-   "cleared by another initiator\n", h->ctlr);
+   dev_warn(&h->pdev->dev,
+   "%s: unit attention cleared by another initiator\n",
+   h->devname);
break;
default:
-   dev_warn(&h->pdev->dev, HPSA "%d: unknown "
-   "unit attention detected\n", h->ctlr);
+   dev_warn(&h->pdev->dev,
+   "%s: unknown unit attention detected\n",
+   h->devname);
break;
}
return 1;
@@ -4799,22 +4802,16 @@ static int hpsa_scan_finished(struct Scsi_Host *sh,
return finished;
 }
 
-static void hpsa_unregister_scsi(struct ctlr_info *h)
-{
-   /* we are being forcibly unloaded, and may not refuse. */
-   scsi_remove_host(h->scsi_host);
-   scsi_host_put(h->scsi_host);
-   h->scsi_host = NULL;
-}
-
-static int hpsa_register_scsi(struct ctlr_info *h)
+static int hpsa_scsi_host_alloc(struct ctlr_info *h)
 {
struct Scsi_Host *sh;
int error;
 
sh = scsi_host_alloc(&hpsa_driver_template, sizeof(h));
-   if (sh == NULL)
-   goto fail;
+   if (sh == NULL) {
+   dev_err(&h->pdev->dev, "scsi_host_alloc failed\n");
+   return -ENOMEM;
+   }
 
sh->io_port = 0;
sh->n_io_port = 0;
@@ -4826,7 +4823,6 @@ static int hpsa_register_scsi(struct ctlr_info *h)
sh->can_queue = h->nr_cmds - HPSA_NRESERVED_CMDS;
sh->cmd_per_lun = sh->can_queue;
sh->sg_tablesize = h->maxsgentries;
-   h->scsi_host = sh;
sh->hostdata[0] = (unsigned long) h;
sh->irq = h->intr[h->intr_mode];
sh->unique_id = sh->irq;
@@ -4835,24 +4831,24 @@ static int hpsa_register_scsi(struct ctlr_info *h)
dev_err(&h->pdev->dev,
"%s: scsi_init_shared_tag_map failed for controller 
%d\n",
__func__, h->ctlr);
-   goto fail_host_put;
-   }
-   error = scsi_add_host(sh, &h->pdev->dev);
-   if (error) {
-   dev_err(&h->pdev->dev, "%s: scsi_add_host failed for controller 
%d\n",
-   __func__, h->ctlr);
-   goto fail_host_put;
+   scsi_host_put(sh);
+   return error;
}
-   scsi_scan_host(sh);
+   h->scsi_host = sh;
return 0;
+}
 
- fail_host_put:
-   scsi_host_put(sh);
-   return error;
- fail:
-   dev_err(&h->pdev->dev, "%s: scsi_host_alloc"
-   " failed for controller %d\n", __func__, h->ctlr);
-   return -ENOMEM;
+static int hpsa_scsi_add_host(struct ctlr_info *h)
+{
+   int rv;
+
+   rv = scsi_add_host(h->scsi_host, &h->pdev->dev);
+   if (rv) {
+   dev_err(&h->pdev->dev, "scsi_add_host failed\n");
+   return rv;
+   }
+   scsi_scan_host(h->scsi_host);
+  

[PATCH] libfc: abort an exchange in case of underrun error

2015-03-17 Thread Vasu Dev
Currently exchange is not aborted in case underrun, so this patch
fixes this by issuing exchange abort along FC_DATA_UNDRUN error since
such error-ed exchange must be aborted first before same can be re-used.

Tested-By: Jack Morgan
Signed-off-by: Vasu Dev 
---

 drivers/scsi/libfc/fc_fcp.c |4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
index c679594..9ad1248 100644
--- a/drivers/scsi/libfc/fc_fcp.c
+++ b/drivers/scsi/libfc/fc_fcp.c
@@ -959,8 +959,10 @@ static void fc_fcp_complete_locked(struct fc_fcp_pkt *fsp)
if (fsp->cdb_status == SAM_STAT_GOOD &&
fsp->xfer_len < fsp->data_len && !fsp->io_status &&
(!(fsp->scsi_comp_flags & FCP_RESID_UNDER) ||
-fsp->xfer_len < fsp->data_len - fsp->scsi_resid))
+fsp->xfer_len < fsp->data_len - fsp->scsi_resid)) {
fsp->status_code = FC_DATA_UNDRUN;
+   fc_fcp_send_abort(fsp);
+   }
}
 
seq = fsp->seq_ptr;

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: OOPS: unplugging western digital passport drive

2015-03-17 Thread Joe Lawrence
On 03/11/2015 12:25 AM, Stanisław Pitucha wrote:
> Hi linux-scsi,
> I've got another case of reproducible crash when unplugging western
> digital passport drives. This was mentioned before in
> http://www.spinics.net/lists/linux-scsi/msg82603.html
> 
> Is there any way I can get a more correct stacktrace of the original
> bug without changing/recompiling the kernel? (or with?)
> 
> My last log from oops is:
> 
> [ 3343.469871]: usb 4-1: USB disconnect, device number 3
> [ 3343.521948]: BUG: unable to handle kernel NULL pointer dereference
> at 01a0
> [ 3343.522052]: IP: [] blk_post_runtime_resume+0x65/0x80
> [ 3343.522131]: PGD 0
> [ 3343.522159]: Oops: 0002 [#1] PREEMPT SMP
> [ 3343.522215]: Modules linked in: nls_utf8 hfsplus ses enclosure uas
> usb_storage rfcomm fuse ctr ccm bnep ecb btusb bluetooth uvcvideo
> videobuf2_vmalloc videobuf2_memops videobuf2_core v4l2_common videodev
> joydev media mousedev iTCO_wdt iTCO_vendor_support arc4 coretemp
> intel_rapl x86_pkg_temp_thermal intel_powerclamp iwldvm kvm_intel
> mac80211 kvm evdev mac_hid psmouse serio_raw pcspkr snd_hda_codec_hdmi
> iwlwifi snd_hda_codec_realtek i2c_i801 snd_hda_codec_generic
> rtsx_pci_ms i915 snd_hda_intel memstick snd_hda_controller cfg80211
> snd_hda_codec r8169 snd_hwdep mii snd_pcm drm_kms_helper snd_timer
> lpc_ich shpchp drm thinkpad_acpi intel_gtt i2c_algo_bit nvram mei_me
> i2c_core snd mei soundcore led_class rfkill hwmon tpm_tis tpm battery
> wmi thermal video button processor ac sch_fq_codel usbhid
> hid_logitech_dj
> [ 3343.523406]:  hid_generic hid nfs lockd grace sunrpc fscache ext4
> crc16 mbcache jbd2 sha256_ssse3 sha256_generic algif_skcipher af_alg
> dm_crypt dm_mod sr_mod cdrom sd_mod rtsx_pci_sdmmc atkbd mmc_core
> libps2 crct10dif_pclmul crc32_pclmul crc32c_intel ghash_clmulni_intel
> ahci libahci aesni_intel aes_x86_64 lrw gf128mul glue_helper
> ablk_helper cryptd libata xhci_pci ehci_pci scsi_mod xhci_hcd ehci_hcd
> rtsx_pci usbcore usb_common i8042 serio
> [ 3343.523825]: CPU: 1 PID: 22490 Comm: kworker/1:0 Not tainted 3.18.6-1-ARCH 
> #1
> [ 3343.523882]: Hardware name: LENOVO 2481CTO/2481CTO, BIOS
> G3ET36WW(1.10) 06/20/2012
> [ 3343.523953]: Workqueue: usb_hub_wq hub_event [usbcore]
> [ 3343.523997]: task: 880211fd5080 ti: 8801971bc000 task.ti:
> 8801971bc000
> [ 3343.524054]: RIP: 0010:[]  []
> blk_post_runtime_resume+0x65/0x80
> [ 3343.524131]: RSP: 0018:8801971bf8c8  EFLAGS: 00010092
> [ 3343.524173]: RAX:  RBX: 880211ca1698 RCX:
> 
> [ 3343.524228]: RDX: 0001000dea0f RSI: 0009 RDI:
> 880211ca1698
> [ 3343.524283]: RBP: 8801971bf8d8 R08:  R09:
> 880216c3f000
> [ 3343.524338]: R10: 88021f256db0 R11: ea0002987d40 R12:
> 
> [ 3343.524392]: R13:  R14: 88020df7b428 R15:
> 0004
> [ 3343.524448]: FS:  () GS:88021f24()
> knlGS:
> [ 3343.524509]: CS:  0010 DS:  ES:  CR0: 80050033
> [ 3343.524554]: CR2: 01a0 CR3: 01811000 CR4:
> 001407e0
> [ 3343.524609]: Stack:
> [ 3343.524628]:  8802123fe968  8801971bf908
> a0119564
> [ 3343.524695]:  8801971bf910 8802123fe968 8802123fea16
> a01194e0
> [ 3343.524762]:  8801971bf938 813c4636 8800a61f5780
> 8802123fe968
> [ 3343.524828]: Call Trace:
> [ 3343.524866]:  [] scsi_runtime_resume+0x84/0xd0 [scsi_mod]
> [ 3343.524930]:  [] ?
> scsi_autopm_put_device+0x20/0x20 [scsi_mod]
> [ 3343.524990]:  [] __rpm_callback+0x36/0x90
> [ 3343.525035]:  [] rpm_callback+0x26/0xa0
> [ 3343.525079]:  [] rpm_resume+0x4b1/0x690
> [ 3343.525124]:  [] __pm_runtime_resume+0x40/0x60
> [ 3343.525177]:  [] __device_release_driver+0x29/0xf0
> [ 3343.525228]:  [] device_release_driver+0x23/0x30
> [ 3343.525277]:  [] bus_remove_device+0x108/0x180
> [ 3343.525325]:  [] device_del+0x129/0x1f0
> [ 3343.525378]:  [] __scsi_remove_device+0xcd/0xe0 
> [scsi_mod]
> [ 3343.525442]:  [] scsi_forget_host+0x64/0x70 [scsi_mod]
> [ 3343.525502]:  [] scsi_remove_host+0x7b/0x130 [scsi_mod]
> [ 3343.525558]:  [] usb_stor_disconnect+0x59/0xd0
> [usb_storage]
> [ 3343.525625]:  [] usb_unbind_interface+0x1f8/0x2c0 
> [usbcore]
> [ 3343.525682]:  [] ? rpm_idle+0x23/0x340
> [ 3343.525729]:  [] __device_release_driver+0x7f/0xf0
> [ 3343.525779]:  [] device_release_driver+0x23/0x30
> [ 3343.525828]:  [] bus_remove_device+0x108/0x180
> [ 3343.525876]:  [] device_del+0x129/0x1f0
> [ 3343.528574]:  [] usb_disable_device+0x91/0x290 [usbcore]
> [ 3343.531302]:  [] usb_disconnect+0x94/0x2d0 [usbcore]
> [ 3343.533981]:  [] hub_event+0x66a/0x1640 [usbcore]
> [ 3343.536657]:  [] ? __schedule+0x3e8/0xa50
> [ 3343.539275]:  [] process_one_work+0x145/0x400
> [ 3343.541919]:  [] worker_thread+0x6b/0x480
> [ 3343.544524]:  [] ? init_pwq.part.22+0x10/0x10
> [ 3343.547108]:  [] kthread+0xea/0x100
> [ 3343.549708]:  [

Re: iSCSI bug

2015-03-17 Thread Govindarajan
I see the same problem. Would this help?

Mar 17 21:13:00 storage1 kernel: [119260.960821] TARGET_CORE[iSCSI]: 
Detected NON_EXISTENT_LUN Access for 0x0090
Mar 17 21:13:00 storage1 kernel: [119260.963752] ABORT_TASK: Sending 
TMR_TASK_DOES_NOT_EXIST for ref_tag: 18170949
Mar 17 21:13:00 storage1 kernel: [119260.963759] ABORT_TASK: Sending 
TMR_TASK_DOES_NOT_EXIST for ref_tag: 18170948
Mar 17 21:13:00 storage1 kernel: [119260.963761] ABORT_TASK: Sending 
TMR_TASK_DOES_NOT_EXIST for ref_tag: 18170950
Mar 17 21:13:04 storage1 kernel: [119265.171082] Unexpected ret: -32 send 
data 48
Mar 17 21:13:06 storage1 kernel: [119267.172218] TARGET_CORE[iSCSI]: 
Detected NON_EXISTENT_LUN Access for 0x000a
Mar 17 21:13:06 storage1 kernel: [119267.175296] ABORT_TASK: Sending 
TMR_TASK_DOES_NOT_EXIST for ref_tag: 182076996
Mar 17 21:13:06 storage1 kernel: [119267.175303] ABORT_TASK: Sending 
TMR_TASK_DOES_NOT_EXIST for ref_tag: 182076994
Mar 17 21:13:06 storage1 kernel: [119267.175306] ABORT_TASK: Sending 
TMR_TASK_DOES_NOT_EXIST for ref_tag: 182076997
Mar 17 21:13:07 storage1 kernel: [119267.796469] iSCSI Login timeout on 
Network Portal 10.12.9.249:3260
Mar 17 21:13:17 storage1 kernel: [119278.498259] NMI watchdog: BUG: soft 
lockup - CPU#1 stuck for 22s! [iscsi_trx:5637]
Mar 17 21:13:17 storage1 kernel: [119278.501397] Modules linked in: 
ib_srpt(E) tcm_qla2xxx(E) tcm_loop(E) tcm_fc(E) iscsi_target_mod(E) 
target_core_user(E) uio(E) target_core_pscsi(E) target_core_file(E) 
target_core_iblock(E) target_core_mod(E) ib_cm(E) ib_sa(E) ib_mad(E) 
ib_core(E) ib_addr(E) qla2xxx(E) libfc(E) scsi_transport_fc(E) configfs(E) 
nfsd(E) auth_rpcgss(E) nfs_acl(E) nfs(E) lockd(E) grace(E) sunrpc(E) 
fscache(E) gpio_ich(E) amdkfd(E) amd_iommu_v2(E) coretemp(E) kvm_intel(E) 
kvm(E) radeon(E) serio_raw(E) 8021q(E) joydev(E) garp(E) ttm(E) mrp(E) 
stp(E) llc(E) drm_kms_helper(E) drm(E) lpc_ich(E) i7core_edac(E) 
edac_core(E) i5500_temp(E) ioatdma(E) 8250_fintek(E) mac_hid(E) shpchp(E) 
bonding(E) btrfs(E) raid456(E) async_raid6_recov(E) async_memcpy(E) 
bcache(E) async_pq(E) async_xor(E) raid10(E) async_tx(E) xor(E) raid6_pq(E) 
raid1(E) hid_generic(E) raid0(E) multipath(E) igb(E) mpt2sas(E) ixgbe(E) 
linear(E) raid_class(E) pata_acpi(E) i2c_algo_bit(E) dca(E) usbhid(E) 
scsi_transport_sas(E) hid(E) ahci(E) pata_jmicron(E) psmouse(E) mdio(E) 
ptp(E) libahci(E) pps_core(E) [last unloaded: target_core_mod]
Mar 17 21:13:17 storage1 kernel: [119278.501476] CPU: 1 PID: 5637 Comm: 
iscsi_trx Tainted: GE  3.19.0-031900-generic #201502091451
Mar 17 21:13:17 storage1 kernel: [119278.501479] Hardware name: Supermicro 
X8DTN/X8DTN, BIOS 2.1c   10/28/2011
Mar 17 21:13:17 storage1 kernel: [119278.501481] task: 8808f86c2740 ti: 
8808e7234000 task.ti: 8808e7234000
Mar 17 21:13:17 storage1 kernel: [119278.501484] RIP: 0010:
[]  [] 
iscsit_remove_cmd_from_immediate_queue+0x25/0x120 [iscsi_target_mod]
Mar 17 21:13:17 storage1 kernel: [119278.501501] RSP: 0018:8808e7237ce8  
EFLAGS: 0246
Mar 17 21:13:17 storage1 kernel: [119278.501503] RAX: 96da96da RBX: 
0001 RCX: f9a9b4a6
Mar 17 21:13:17 storage1 kernel: [119278.501505] RDX: 96da RSI: 
881081bbc800 RDI: 881081bbcbe8
Mar 17 21:13:17 storage1 kernel: [119278.501507] RBP: 8808e7237d08 R08: 
880f45d68410 R09: 0101
Mar 17 21:13:17 storage1 kernel: [119278.501509] R10: 0001 R11: 
001d R12: ff10
Mar 17 21:13:17 storage1 kernel: [119278.501511] R13: 8808e7237cd8 R14: 
880f45d68350 R15: f9ac4872
Mar 17 21:13:17 storage1 kernel: [119278.501513] FS:  () 
GS:88091bc2() knlGS:
Mar 17 21:13:17 storage1 kernel: [119278.501516] CS:  0010 DS:  ES:  
CR0: 8005003b
Mar 17 21:13:17 storage1 kernel: [119278.501518] CR2: 012bb100 CR3: 
01c15000 CR4: 07e0
Mar 17 21:13:17 storage1 kernel: [119278.501520] Stack:
Mar 17 21:13:17 storage1 kernel: [119278.501521]  880f45d68140 
881081bbc800 0001 880f45d68350
Mar 17 21:13:17 storage1 kernel: [119278.501525]  8808e7237d38 
c0984230 c098d30b 880f45d68140
Mar 17 21:13:17 storage1 kernel: [119278.501528]  0001 
0001 8808e7237d78 c098433e
Mar 17 21:13:17 storage1 kernel: [119278.501531] Call Trace:
Mar 17 21:13:17 storage1 kernel: [119278.501545]  [] 
__iscsit_free_cmd+0x50/0xa0 [iscsi_target_mod]
Mar 17 21:13:17 storage1 kernel: [119278.501557]  [] ? 
iscsit_close_connection+0x3ab/0x640 [iscsi_target_mod]
Mar 17 21:13:17 storage1 kernel: [119278.501568]  [] 
iscsit_free_cmd+0xbe/0x160 [iscsi_target_mod]
Mar 17 21:13:17 storage1 kernel: [119278.501580]  [] 
iscsit_close_connection+0x3c4/0x640 [iscsi_target_mod]
Mar 17 21:13:17 storage1 kernel: [119278.501590]  [] 
iscsit_take_action_for_connection_exit+0x83/0x110 [iscsi_target_mod]
Mar 17 21:13:17 storag