Re: [PATCH 25/27] block: remove the discard_zeroes_data flag

2017-05-04 Thread Nicholas A. Bellinger
On Wed, 2017-05-03 at 10:33 -0400, Mike Snitzer wrote:
> On Tue, May 02 2017 at 11:33pm -0400,
> Nicholas A. Bellinger  wrote:
> 
> > On Tue, 2017-05-02 at 09:23 +0200, h...@lst.de wrote:
> > > On Tue, May 02, 2017 at 12:16:13AM -0700, Nicholas A. Bellinger wrote:
> > > > Or, another options is use bdev_write_zeroes_sectors() to determine when
> > > > dev_attrib->unmap_zeroes_data should be set.
> > > 
> > > Yes, that in combination with your patch to use bdev_write_zeroes_sectors
> > > for zeroing from write same seems like the right fix.
> > 
> > The larger target/iblock conversion patch looks like post v4.12 material
> > at this point, so to avoid breakage wrt to existing LBPRZ behavior, I'll
> > plan to push the following patch post -rc1.
> > 
> > diff --git a/drivers/target/target_core_device.c 
> > b/drivers/target/target_core_device.c
> > index d2f089c..e7caf78 100644
> > --- a/drivers/target/target_core_device.c
> > +++ b/drivers/target/target_core_device.c
> > @@ -851,7 +851,7 @@ bool target_configure_unmap_from_queue(struct 
> > se_dev_attrib *attrib,
> > attrib->unmap_granularity = q->limits.discard_granularity / 
> > block_size;
> > attrib->unmap_granularity_alignment = q->limits.discard_alignment /
> > block_size;
> > -   attrib->unmap_zeroes_data = 0;
> > +   attrib->unmap_zeroes_data = (q->limits.max_write_zeroes_sectors);
> > return true;
> >  }
> >  EXPORT_SYMBOL(target_configure_unmap_from_queue);
> > 
> 
> Completely a nit but: why the extra parenthesis?

dev_attrib->unmap_zeros_data is only compared as a bool.



Re: [PATCH v2] ibmvscsis: Do not send aborted task response

2017-05-04 Thread Nicholas A. Bellinger
On Thu, 2017-05-04 at 18:13 -0500, Bryant G. Ly wrote:
> 
>
> Sorry Nick, but can you hold off on this patch. We are still getting extra 
> responses but in a small timing window.
> 
> The majority of the aborts work but if we get an abort between LIO calling 
> queue_state and LIO calling release_cmd, we get an extra response.
> 
> 
> Working on a solution, and will still have to do the tests where we basically 
> send aborts over and over on the client btwn random timing widows.
> 

Sure, dropping this patch for now.



[PATCH] tcmu: Add fifo type waiter list support to avoid starvation

2017-05-04 Thread lixiubo
From: Xiubo Li 

The fifo type waiter list will hold the udevs who are waiting for the
blocks from the data global pool. The unmap thread will try to feed the
first udevs in waiter list, if the global free blocks available are
not enough, it will stop traversing the list and abort waking up the
others.

Signed-off-by: Xiubo Li 
---
 drivers/target/target_core_user.c | 82 +++
 1 file changed, 66 insertions(+), 16 deletions(-)

diff --git a/drivers/target/target_core_user.c 
b/drivers/target/target_core_user.c
index 9045837..10c99e7 100644
--- a/drivers/target/target_core_user.c
+++ b/drivers/target/target_core_user.c
@@ -97,6 +97,7 @@ struct tcmu_hba {
 
 struct tcmu_dev {
struct list_head node;
+   struct list_head waiter;
 
struct se_device se_dev;
 
@@ -123,7 +124,7 @@ struct tcmu_dev {
wait_queue_head_t wait_cmdr;
struct mutex cmdr_lock;
 
-   bool waiting_global;
+   uint32_t waiting_blocks;
uint32_t dbi_max;
uint32_t dbi_thresh;
DECLARE_BITMAP(data_bitmap, DATA_BLOCK_BITS);
@@ -165,6 +166,10 @@ struct tcmu_cmd {
 static DEFINE_MUTEX(root_udev_mutex);
 static LIST_HEAD(root_udev);
 
+/* The data blocks global pool waiter list */
+static DEFINE_MUTEX(root_udev_waiter_mutex);
+static LIST_HEAD(root_udev_waiter);
+
 static atomic_t global_db_count = ATOMIC_INIT(0);
 
 static struct kmem_cache *tcmu_cmd_cache;
@@ -195,6 +200,11 @@ enum tcmu_multicast_groups {
 #define tcmu_cmd_set_dbi(cmd, index) ((cmd)->dbi[(cmd)->dbi_cur++] = (index))
 #define tcmu_cmd_get_dbi(cmd) ((cmd)->dbi[(cmd)->dbi_cur++])
 
+static inline bool is_in_waiter_list(struct tcmu_dev *udev)
+{
+   return !!udev->waiting_blocks;
+}
+
 static void tcmu_cmd_free_data(struct tcmu_cmd *tcmu_cmd, uint32_t len)
 {
struct tcmu_dev *udev = tcmu_cmd->tcmu_dev;
@@ -250,8 +260,6 @@ static bool tcmu_get_empty_blocks(struct tcmu_dev *udev,
 {
int i;
 
-   udev->waiting_global = false;
-
for (i = tcmu_cmd->dbi_cur; i < tcmu_cmd->dbi_cnt; i++) {
if (!tcmu_get_empty_block(udev, tcmu_cmd))
goto err;
@@ -259,9 +267,7 @@ static bool tcmu_get_empty_blocks(struct tcmu_dev *udev,
return true;
 
 err:
-   udev->waiting_global = true;
-   /* Try to wake up the unmap thread */
-   wake_up(_wait);
+   udev->waiting_blocks += tcmu_cmd->dbi_cnt - i;
return false;
 }
 
@@ -671,6 +677,7 @@ static inline size_t tcmu_cmd_get_cmd_size(struct tcmu_cmd 
*tcmu_cmd,
 
while (!is_ring_space_avail(udev, tcmu_cmd, command_size, data_length)) 
{
int ret;
+   bool is_waiting_blocks = !!udev->waiting_blocks;
DEFINE_WAIT(__wait);
 
prepare_to_wait(>wait_cmdr, &__wait, TASK_INTERRUPTIBLE);
@@ -688,6 +695,18 @@ static inline size_t tcmu_cmd_get_cmd_size(struct tcmu_cmd 
*tcmu_cmd,
return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
}
 
+   /*
+* Try to insert the current udev to waiter list and
+* then wake up the unmap thread
+*/
+   if (is_waiting_blocks) {
+   mutex_lock(_udev_waiter_mutex);
+   list_add_tail(>waiter, _udev_waiter);
+   mutex_unlock(_udev_waiter_mutex);
+
+   wake_up(_wait);
+   }
+
mutex_lock(>cmdr_lock);
 
/* We dropped cmdr_lock, cmd_head is stale */
@@ -902,8 +921,6 @@ static unsigned int tcmu_handle_completions(struct tcmu_dev 
*udev)
if (mb->cmd_tail == mb->cmd_head)
del_timer(>timeout); /* no more pending cmds */
 
-   wake_up(>wait_cmdr);
-
return handled;
 }
 
@@ -996,7 +1013,17 @@ static int tcmu_irqcontrol(struct uio_info *info, s32 
irq_on)
struct tcmu_dev *tcmu_dev = container_of(info, struct tcmu_dev, 
uio_info);
 
mutex_lock(_dev->cmdr_lock);
-   tcmu_handle_completions(tcmu_dev);
+   /*
+* If the current udev is also in waiter list, this will
+* make sure that the other waiters in list be feeded ahead
+* of it.
+*/
+   if (is_in_waiter_list(tcmu_dev)) {
+   wake_up(_wait);
+   } else {
+   tcmu_handle_completions(tcmu_dev);
+   wake_up(_dev->wait_cmdr);
+   }
mutex_unlock(_dev->cmdr_lock);
 
return 0;
@@ -1231,7 +1258,7 @@ static int tcmu_configure_device(struct se_device *dev)
udev->data_off = CMDR_SIZE;
udev->data_size = DATA_SIZE;
udev->dbi_thresh = 0; /* Default in Idle state */
-   udev->waiting_global = false;
+   udev->waiting_blocks = 0;
 
/* Initialise the mailbox of the ring buffer */
mb = udev->mb_addr;
@@ -1345,6 +1372,13 @@ static void tcmu_free_device(struct se_device *dev)

Re: [PATCH v2] ibmvscsis: Do not send aborted task response

2017-05-04 Thread Bryant G. Ly



On 5/3/17 1:55 PM, Bryant G. Ly wrote:

On 5/3/17 11:38 AM, Bryant G. Ly wrote:


Hi Nick,

On 5/2/17 10:43 PM, Nicholas A. Bellinger wrote:


On Tue, 2017-05-02 at 13:54 -0500, Bryant G. Ly wrote:

The driver is sending a response to the actual scsi op that was
aborted by an abort task TM, while LIO is sending a response to
the abort task TM.

ibmvscsis_tgt does not send the response to the client until
release_cmd time. The reason for this was because if we did it
at queue_status time, then the client would be free to reuse the
tag for that command, but we're still using the tag until the
command is released at release_cmd time, so we chose to delay
sending the response until then. That then caused this issue, because
release_cmd is always called, even if queue_status is not.

SCSI spec says that the initiator that sends the abort task
TM NEVER gets a response to the aborted op and with the current
code it will send a response. Thus this fix will remove that response
if the TAS bit is set.

Cc:  # v4.8+
Signed-off-by: Bryant G. Ly 
Reviewed-by: Tyrel Datwyler 
---
  drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c | 66 
++--

  1 file changed, 45 insertions(+), 21 deletions(-)

Applied, with a small update to the last sentence of the commit log wrt
to 'if ABORTED && !TAS bit is set'.

Thanks Bryant + Tyrel.

So I have been running tests on this patch extensively and it seems 
like after running 2 hrs of consecutive aborts it fails again with 
the same problem of driver sending a response to the actual scsi op.


It looks like when LIO processes the abort and if 
(!__target_check_io_state(se_cmd, se_sess, 0)) then rsp gets set as 
TMR_TASK_DOES_NOT_EXIST.


With that response the CMD_T_ABORTED state is not set, so then the 
ibmvscsis driver still sends that duplicate response.


I think the best solution would be in driver when queue_tm_rsp gets 
called and when the driver builds the response to check for the 
TMR_TASK_DOES_NOT_EXIST and set our own flag.

Then we would also check for that flag, so it would be:

if ((cmd->se_cmd.transport_state & CMD_T_ABORTED && 
!(cmd->se_cmd.transport_state & CMD_T_TAS)) || cmd->flags & 
CMD_ABORTED) {


This will ensure in the CMD_T_ABORTED w/o CMD_T_TAS scenarios are 
handled and the ABORT_TASK: Sending TMR_TASK_DOES_NOT_EXIST case.


-Bryant



Hi Nick,

You can ignore the email about the patch being broken. The script that 
was used for testing isn't right.


So the patch is working as intended now, where on an abort the client 
does not receive an extra response to the actual scsi op.


Thanks,

Bryant Ly


Sorry Nick, but can you hold off on this patch. We are still getting extra 
responses but in a small timing window.

The majority of the aborts work but if we get an abort between LIO calling 
queue_state and LIO calling release_cmd, we get an extra response.


Working on a solution, and will still have to do the tests where we basically 
send aborts over and over on the client btwn random timing widows.

-Bryant



[PATCH V4 12/12] hpsa: bump driver version

2017-05-04 Thread Don Brace
Reviewed-by: Scott Benesh 
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 9a631e3..9934947 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -60,7 +60,7 @@
  * HPSA_DRIVER_VERSION must be 3 byte values (0-255) separated by '.'
  * with an optional trailing '-' followed by a byte value (0-255).
  */
-#define HPSA_DRIVER_VERSION "3.4.18-0"
+#define HPSA_DRIVER_VERSION "3.4.20-0"
 #define DRIVER_NAME "HP HPSA Driver (v " HPSA_DRIVER_VERSION ")"
 #define HPSA "hpsa"
 



[PATCH V4 10/12] hpsa: send ioaccel requests with 0 length down raid path

2017-05-04 Thread Don Brace
 - Block I/O requests with 0 length transfers which go down
   the ioaccel path. This causes lockup issues down in the basecode.
   - These issues have been fixed, but there are customers who are
 experiencing the issues when running older firmware.

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

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 2ec9079..ea778cc 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -4591,7 +4591,55 @@ static int hpsa_scatter_gather(struct ctlr_info *h,
return 0;
 }
 
-#define IO_ACCEL_INELIGIBLE (1)
+#define BUFLEN 128
+static inline void warn_zero_length_transfer(struct ctlr_info *h,
+   u8 *cdb, int cdb_len,
+   const char *func)
+{
+   char buf[BUFLEN];
+   int outlen;
+   int i;
+
+   outlen = scnprintf(buf, BUFLEN,
+   "%s: Blocking zero-length request: CDB:", func);
+   for (i = 0; i < cdb_len; i++)
+   outlen += scnprintf(buf+outlen, BUFLEN - outlen,
+   "%02hhx", cdb[i]);
+   dev_warn(>pdev->dev, "%s\n", buf);
+}
+
+#define IO_ACCEL_INELIGIBLE 1
+/* zero-length transfers trigger hardware errors. */
+static bool is_zero_length_transfer(u8 *cdb)
+{
+   u32 block_cnt;
+
+   /* Block zero-length transfer sizes on certain commands. */
+   switch (cdb[0]) {
+   case READ_10:
+   case WRITE_10:
+   case VERIFY:/* 0x2F */
+   case WRITE_VERIFY:  /* 0x2E */
+   block_cnt = get_unaligned_be16([7]);
+   break;
+   case READ_12:
+   case WRITE_12:
+   case VERIFY_12: /* 0xAF */
+   case WRITE_VERIFY_12:   /* 0xAE */
+   block_cnt = get_unaligned_be32([6]);
+   break;
+   case READ_16:
+   case WRITE_16:
+   case VERIFY_16: /* 0x8F */
+   block_cnt = get_unaligned_be32([10]);
+   break;
+   default:
+   return false;
+   }
+
+   return block_cnt == 0;
+}
+
 static int fixup_ioaccel_cdb(u8 *cdb, int *cdb_len)
 {
int is_write = 0;
@@ -4658,6 +4706,12 @@ static int hpsa_scsi_ioaccel1_queue_command(struct 
ctlr_info *h,
 
BUG_ON(cmd->cmd_len > IOACCEL1_IOFLAGS_CDBLEN_MAX);
 
+   if (is_zero_length_transfer(cdb)) {
+   warn_zero_length_transfer(h, cdb, cdb_len, __func__);
+   atomic_dec(_disk->ioaccel_cmds_out);
+   return IO_ACCEL_INELIGIBLE;
+   }
+
if (fixup_ioaccel_cdb(cdb, _len)) {
atomic_dec(_disk->ioaccel_cmds_out);
return IO_ACCEL_INELIGIBLE;
@@ -4822,6 +4876,12 @@ static int hpsa_scsi_ioaccel2_queue_command(struct 
ctlr_info *h,
 
BUG_ON(scsi_sg_count(cmd) > h->maxsgentries);
 
+   if (is_zero_length_transfer(cdb)) {
+   warn_zero_length_transfer(h, cdb, cdb_len, __func__);
+   atomic_dec(_disk->ioaccel_cmds_out);
+   return IO_ACCEL_INELIGIBLE;
+   }
+
if (fixup_ioaccel_cdb(cdb, _len)) {
atomic_dec(_disk->ioaccel_cmds_out);
return IO_ACCEL_INELIGIBLE;



[PATCH V4 06/12] hpsa: correct resets on retried commands

2017-05-04 Thread Don Brace
 - call scsi_done when the command completes.

Reviewed-by: Scott Benesh 
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 53a4f34..a2852da 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -5465,7 +5465,7 @@ static void hpsa_command_resubmit_worker(struct 
work_struct *work)
return hpsa_cmd_free_and_done(c->h, c, cmd);
}
if (c->reset_pending)
-   return hpsa_cmd_resolve_and_free(c->h, c);
+   return hpsa_cmd_free_and_done(c->h, c, cmd);
if (c->abort_pending)
return hpsa_cmd_abort_and_free(c->h, c, cmd);
if (c->cmd_type == CMD_IOACCEL2) {



[PATCH V4 11/12] hpsa: remove abort handler

2017-05-04 Thread Don Brace
 - simplify the driver
 - there are a lot of quirky racy conditions not handled
 - causes more aborts/resets when the number of commands to
   be aborted is large, such as in multi-path fail-overs.
 - has been turned off in our internal driver since 8/31/2015

Reviewed-by: Scott Benesh 
Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |  621 +--
 drivers/scsi/hpsa.h |1 
 2 files changed, 8 insertions(+), 614 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index ea778cc..9a631e3 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -258,7 +258,6 @@ static int hpsa_scan_finished(struct Scsi_Host *sh,
 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);
@@ -326,7 +325,7 @@ static inline bool hpsa_is_cmd_idle(struct CommandList *c)
 
 static inline bool hpsa_is_pending_event(struct CommandList *c)
 {
-   return c->abort_pending || c->reset_pending;
+   return c->reset_pending;
 }
 
 /* extract sense key, asc, and ascq from sense data.  -1 means invalid. */
@@ -581,12 +580,6 @@ static u32 soft_unresettable_controller[] = {
0x409D0E11, /* Smart Array 6400 EM */
 };
 
-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;
@@ -615,12 +608,6 @@ 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)
 {
@@ -928,8 +915,8 @@ 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)
+#define HPSA_NRESERVED_CMDS(HPSA_CMDS_RESERVED_FOR_DRIVER +\
+HPSA_MAX_CONCURRENT_PASSTHRUS)
 
 static struct scsi_host_template hpsa_driver_template = {
.module = THIS_MODULE,
@@ -941,7 +928,6 @@ static struct scsi_host_template hpsa_driver_template = {
.change_queue_depth = hpsa_change_queue_depth,
.this_id= -1,
.use_clustering = ENABLE_CLUSTERING,
-   .eh_abort_handler   = hpsa_eh_abort_handler,
.eh_device_reset_handler = hpsa_eh_device_reset_handler,
.ioctl  = hpsa_ioctl,
.slave_alloc= hpsa_slave_alloc,
@@ -2361,26 +2347,12 @@ static void hpsa_cmd_resolve_events(struct ctlr_info *h,
bool do_wake = false;
 
/*
-* 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.
-*
-* Reset c->scsi_cmd here so that the abort or reset handler will know
+* Reset c->scsi_cmd here so that the 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();   /* Declare command idle before checking for pending events. */
-   if (c->abort_pending) {
-   do_wake = true;
-   c->abort_pending = false;
-   }
if (c->reset_pending) {
unsigned long flags;
struct hpsa_scsi_dev_t *dev;
@@ -2423,20 +2395,6 @@ static void hpsa_retry_cmd(struct ctlr_info *h, struct 
CommandList *c)
queue_work_on(raw_smp_processor_id(), h->resubmit_wq, >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)
-{
-   

[PATCH V4 08/12] hpsa: correct queue depth for externals

2017-05-04 Thread Don Brace
 - queue depth assignment not in correct place, had no effect.

Reviewed-by: Scott Benesh 
Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |   22 ++
 drivers/scsi/hpsa.h |1 +
 2 files changed, 11 insertions(+), 12 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 20b4e83..5b0cc0e 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -2069,10 +2069,13 @@ static int hpsa_slave_configure(struct scsi_device 
*sdev)
sd = sdev->hostdata;
sdev->no_uld_attach = !sd || !sd->expose_device;
 
-   if (sd)
-   queue_depth = sd->queue_depth != 0 ?
-   sd->queue_depth : sdev->host->can_queue;
-   else
+   if (sd) {
+   if (sd->external)
+   queue_depth = EXTERNAL_QD;
+   else
+   queue_depth = sd->queue_depth != 0 ?
+   sd->queue_depth : sdev->host->can_queue;
+   } else
queue_depth = sdev->host->can_queue;
 
scsi_change_queue_depth(sdev, queue_depth);
@@ -3915,6 +3918,9 @@ static int hpsa_update_device_info(struct ctlr_info *h,
this_device->queue_depth = h->nr_cmds;
}
 
+   if (this_device->external)
+   this_device->queue_depth = EXTERNAL_QD;
+
if (is_OBDR_device) {
/* See if this is a One-Button-Disaster-Recovery device
 * by looking for "$DR-10" at offset 43 in inquiry data.
@@ -4123,14 +4129,6 @@ static void hpsa_get_ioaccel_drive_info(struct ctlr_info 
*h,
int rc;
struct ext_report_lun_entry *rle;
 
-   /*
-* external targets don't support BMIC
-*/
-   if (dev->external) {
-   dev->queue_depth = 7;
-   return;
-   }
-
rle = >LUN[rle_index];
 
dev->ioaccel_handle = rle->ioaccel_handle;
diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
index 5352664..61dd54a 100644
--- a/drivers/scsi/hpsa.h
+++ b/drivers/scsi/hpsa.h
@@ -57,6 +57,7 @@ struct hpsa_sas_phy {
bool added_to_port;
 };
 
+#define EXTERNAL_QD 7
 struct hpsa_scsi_dev_t {
unsigned int devtype;
int bus, target, lun;   /* as presented to the OS */



[PATCH V4 09/12] hpsa: separate monitor events from rescan worker

2017-05-04 Thread Don Brace
From: Scott Teel 

create new worker thread to monitor controller events
 - both the rescan and event monitor workers can cause a
   rescan to occur however for multipath we have found
   that we need to respond faster than the normal scheduled
   rescan interval for path fail-overs.
 - getting controller events only involves reading a register, but
   the rescan worker can obtain an updated LUN list when there
   is a PTRAID device present.
 - move common code to a separate function.
advantages:
 - detect controller events more frequently.
 - leave rescan thread interval at 30 seconds.

Reviewed-by: Scott Benesh 
Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |   76 +++
 drivers/scsi/hpsa.h |1 +
 2 files changed, 59 insertions(+), 18 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 5b0cc0e..2ec9079 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -1110,6 +1110,7 @@ static int is_firmware_flash_cmd(u8 *cdb)
  */
 #define HEARTBEAT_SAMPLE_INTERVAL_DURING_FLASH (240 * HZ)
 #define HEARTBEAT_SAMPLE_INTERVAL (30 * HZ)
+#define HPSA_EVENT_MONITOR_INTERVAL (15 * HZ)
 static void dial_down_lockup_detection_during_fw_flash(struct ctlr_info *h,
struct CommandList *c)
 {
@@ -8661,15 +8662,10 @@ static int hpsa_luns_changed(struct ctlr_info *h)
return rc;
 }
 
-static void hpsa_rescan_ctlr_worker(struct work_struct *work)
+static void hpsa_perform_rescan(struct ctlr_info *h)
 {
+   struct Scsi_Host *sh = NULL;
unsigned long flags;
-   struct ctlr_info *h = container_of(to_delayed_work(work),
-   struct ctlr_info, rescan_ctlr_work);
-
-
-   if (h->remove_in_progress)
-   return;
 
/*
 * Do the scan after the reset
@@ -8682,23 +8678,63 @@ static void hpsa_rescan_ctlr_worker(struct work_struct 
*work)
}
spin_unlock_irqrestore(>reset_lock, flags);
 
-   if (hpsa_ctlr_needs_rescan(h) || hpsa_offline_devices_ready(h)) {
-   scsi_host_get(h->scsi_host);
+   sh = scsi_host_get(h->scsi_host);
+   if (sh != NULL) {
+   hpsa_scan_start(sh);
+   scsi_host_put(sh);
+   h->drv_req_rescan = 0;
+   }
+}
+
+/*
+ * watch for controller events
+ */
+static void hpsa_event_monitor_worker(struct work_struct *work)
+{
+   struct ctlr_info *h = container_of(to_delayed_work(work),
+   struct ctlr_info, event_monitor_work);
+   unsigned long flags;
+
+   spin_lock_irqsave(>lock, flags);
+   if (h->remove_in_progress) {
+   spin_unlock_irqrestore(>lock, flags);
+   return;
+   }
+   spin_unlock_irqrestore(>lock, flags);
+
+   if (hpsa_ctlr_needs_rescan(h)) {
hpsa_ack_ctlr_events(h);
-   hpsa_scan_start(h->scsi_host);
-   scsi_host_put(h->scsi_host);
+   hpsa_perform_rescan(h);
+   }
+
+   spin_lock_irqsave(>lock, flags);
+   if (!h->remove_in_progress)
+   schedule_delayed_work(>event_monitor_work,
+   HPSA_EVENT_MONITOR_INTERVAL);
+   spin_unlock_irqrestore(>lock, flags);
+}
+
+static void hpsa_rescan_ctlr_worker(struct work_struct *work)
+{
+   unsigned long flags;
+   struct ctlr_info *h = container_of(to_delayed_work(work),
+   struct ctlr_info, rescan_ctlr_work);
+
+   spin_lock_irqsave(>lock, flags);
+   if (h->remove_in_progress) {
+   spin_unlock_irqrestore(>lock, flags);
+   return;
+   }
+   spin_unlock_irqrestore(>lock, flags);
+
+   if (h->drv_req_rescan || hpsa_offline_devices_ready(h)) {
+   hpsa_perform_rescan(h);
} else if (h->discovery_polling) {
hpsa_disable_rld_caching(h);
if (hpsa_luns_changed(h)) {
-   struct Scsi_Host *sh = NULL;
-
dev_info(>pdev->dev,
"driver discovery polling rescan.\n");
-   sh = scsi_host_get(h->scsi_host);
-   if (sh != NULL) {
-   hpsa_scan_start(sh);
-   scsi_host_put(sh);
-   }
+   hpsa_perform_rescan(h);
}
}
spin_lock_irqsave(>lock, flags);
@@ -8964,6 +9000,9 @@ static int hpsa_init_one(struct pci_dev *pdev, const 
struct pci_device_id *ent)
INIT_DELAYED_WORK(>rescan_ctlr_work, hpsa_rescan_ctlr_worker);
queue_delayed_work(h->rescan_ctlr_wq, >rescan_ctlr_work,
h->heartbeat_sample_interval);
+   

[PATCH V4 04/12] hpsa: do not reset enclosures

2017-05-04 Thread Don Brace
Prevent enclosure resets.

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

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 9fb30c4..2990897 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -5853,6 +5853,9 @@ static int hpsa_eh_device_reset_handler(struct scsi_cmnd 
*scsicmd)
return FAILED;
}
 
+   if (dev->devtype == TYPE_ENCLOSURE)
+   return SUCCESS;
+
/* if controller locked up, we can guarantee command won't complete */
if (lockup_detected(h)) {
snprintf(msg, sizeof(msg),



[PATCH V4 05/12] hpsa: rescan later if reset in progress

2017-05-04 Thread Don Brace
 - schedule another scan.
 - mark current scan as completed

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

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 2990897..53a4f34 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -5620,6 +5620,7 @@ static void hpsa_scan_start(struct Scsi_Host *sh)
 */
if (h->reset_in_progress) {
h->drv_req_rescan = 1;
+   hpsa_scan_complete(h);
return;
}
 



[PATCH V4 07/12] hpsa: cleanup reset handler

2017-05-04 Thread Don Brace
 - mark device state sooner.

Reviewed-by: Scott Benesh 
Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |   59 +++
 drivers/scsi/hpsa.h |1 +
 2 files changed, 46 insertions(+), 14 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index a2852da..20b4e83 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -1859,10 +1859,13 @@ static void adjust_hpsa_scsi_table(struct ctlr_info *h,
 * A reset can cause a device status to change
 * re-schedule the scan to see what happened.
 */
+   spin_lock_irqsave(>reset_lock, flags);
if (h->reset_in_progress) {
h->drv_req_rescan = 1;
+   spin_unlock_irqrestore(>reset_lock, flags);
return;
}
+   spin_unlock_irqrestore(>reset_lock, flags);
 
added = kzalloc(sizeof(*added) * HPSA_MAX_DEVICES, GFP_KERNEL);
removed = kzalloc(sizeof(*removed) * HPSA_MAX_DEVICES, GFP_KERNEL);
@@ -5618,11 +5621,14 @@ static void hpsa_scan_start(struct Scsi_Host *sh)
/*
 * Do the scan after a reset completion
 */
+   spin_lock_irqsave(>reset_lock, flags);
if (h->reset_in_progress) {
h->drv_req_rescan = 1;
+   spin_unlock_irqrestore(>reset_lock, flags);
hpsa_scan_complete(h);
return;
}
+   spin_unlock_irqrestore(>reset_lock, flags);
 
hpsa_update_scsi_devices(h);
 
@@ -5834,28 +5840,38 @@ static int wait_for_device_to_become_ready(struct 
ctlr_info *h,
  */
 static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
 {
-   int rc;
+   int rc = SUCCESS;
struct ctlr_info *h;
struct hpsa_scsi_dev_t *dev;
u8 reset_type;
char msg[48];
+   unsigned long flags;
 
/* find the controller to which the command to be aborted was sent */
h = sdev_to_hba(scsicmd->device);
if (h == NULL) /* paranoia */
return FAILED;
 
-   if (lockup_detected(h))
-   return FAILED;
+   spin_lock_irqsave(>reset_lock, flags);
+   h->reset_in_progress = 1;
+   spin_unlock_irqrestore(>reset_lock, flags);
+
+   if (lockup_detected(h)) {
+   rc = FAILED;
+   goto return_reset_status;
+   }
 
dev = scsicmd->device->hostdata;
if (!dev) {
dev_err(>pdev->dev, "%s: device lookup failed\n", __func__);
-   return FAILED;
+   rc = FAILED;
+   goto return_reset_status;
}
 
-   if (dev->devtype == TYPE_ENCLOSURE)
-   return SUCCESS;
+   if (dev->devtype == TYPE_ENCLOSURE) {
+   rc = SUCCESS;
+   goto return_reset_status;
+   }
 
/* if controller locked up, we can guarantee command won't complete */
if (lockup_detected(h)) {
@@ -5863,7 +5879,8 @@ static int hpsa_eh_device_reset_handler(struct scsi_cmnd 
*scsicmd)
 "cmd %d RESET FAILED, lockup detected",
 hpsa_get_cmd_index(scsicmd));
hpsa_show_dev_msg(KERN_WARNING, h, dev, msg);
-   return FAILED;
+   rc = FAILED;
+   goto return_reset_status;
}
 
/* this reset request might be the result of a lockup; check */
@@ -5872,12 +5889,15 @@ static int hpsa_eh_device_reset_handler(struct 
scsi_cmnd *scsicmd)
 "cmd %d RESET FAILED, new lockup detected",
 hpsa_get_cmd_index(scsicmd));
hpsa_show_dev_msg(KERN_WARNING, h, dev, msg);
-   return FAILED;
+   rc = FAILED;
+   goto return_reset_status;
}
 
/* Do not attempt on controller */
-   if (is_hba_lunid(dev->scsi3addr))
-   return SUCCESS;
+   if (is_hba_lunid(dev->scsi3addr)) {
+   rc = SUCCESS;
+   goto return_reset_status;
+   }
 
if (is_logical_dev_addr_mode(dev->scsi3addr))
reset_type = HPSA_DEVICE_RESET_MSG;
@@ -5888,17 +5908,24 @@ static int hpsa_eh_device_reset_handler(struct 
scsi_cmnd *scsicmd)
reset_type == HPSA_DEVICE_RESET_MSG ? "logical " : "physical ");
hpsa_show_dev_msg(KERN_WARNING, h, dev, msg);
 
-   h->reset_in_progress = 1;
-
/* send a reset to the SCSI LUN which the command was sent to */
rc = hpsa_do_reset(h, dev, dev->scsi3addr, reset_type,
   DEFAULT_REPLY_QUEUE);
+   if (rc == 0)
+   rc = SUCCESS;
+   else
+   rc = FAILED;
+
sprintf(msg, "reset %s %s",
reset_type == HPSA_DEVICE_RESET_MSG ? "logical " : "physical ",
-   rc == 0 ? "completed successfully" 

[PATCH V4 03/12] hpsa: update reset handler

2017-05-04 Thread Don Brace
Use the return from TUR as a check for the
device state.

Reviewed-by: Scott Benesh 
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 8e22aed..9fb30c4 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -3090,7 +3090,7 @@ static int hpsa_do_reset(struct ctlr_info *h, struct 
hpsa_scsi_dev_t *dev,
if (unlikely(rc))
atomic_set(>reset_cmds_out, 0);
else
-   wait_for_device_to_become_ready(h, scsi3addr, 0);
+   rc = wait_for_device_to_become_ready(h, scsi3addr, 0);
 
mutex_unlock(>reset_mutex);
return rc;



[PATCH V4 00/12] hpsa updates

2017-05-04 Thread Don Brace
These patches are based on Linus's tree

These patches are for:
 - RedHat BZ: 1404073 - [HPE 7.3 Bug] multipath failover not reliable
 - Multipath failover support in general.

The changes are:
 - update identify physical device structure
   - align with FW
 - stop getting enclosure info for externals
   - no BMIC support
 - update reset handler
   - update to match out of box driver
 - do not reset enclosures
   - reset can sometimes hang
 - rescan later if reset in progress
   - wait for devices to settle.
 - correct resets on retried commands
   - was not calling scsi_done on retried completion
 - correct queue depth for externals
   - Code not in correct function
 - separate monitor events from rescan worker
   - allows driver to check for controller events more frequently
 without affecting controller lockup detection or check
 for changes on PTRAID devices.
 - send ioaccel requests with 0 length down raid path
   - avoid hang issues for customers running older firmware.
 - remove abort handler
   - align driver with our out of box driver
 - bump driver version
   - align version with out of box driver for multi-path changes

Changes since V1:
 - includes changes based on Martin Wilck  reviews.
- cleanup reset handler
  - added spin_lock protection around h->reset_in_progress
- this has helped solve a multipath issue, thanks Martin.
- renamed patch hpsa-separate-monitor-events-from-hearbeat-worker to
  hpsa-separate-monitor-events-from-rescan-worker to more correctly
 convey the patches intent.
  - split out some commonality between the rescan worker and the
event monitor worker.
  - updated the patch description.

Changes since V2:
 - includes a change based on Tomas Henzl  review
   - Corrected placement of spin_unlock_irqrestore in patch
 hpsa-clean-up-reset-handler
 - Thanks for your attention to hpsa Tomas

Changes since V3:
 - Removed patches hpsa-update-pci-ids and hpsa-change-driver-version
   because they are already in. Sorry about that.

---

Don Brace (11):
  hpsa: update identify physical device structure
  hpsa: do not get enclosure info for external devices
  hpsa: update reset handler
  hpsa: do not reset enclosures
  hpsa: rescan later if reset in progress
  hpsa: correct resets on retried commands
  hpsa: cleanup reset handler
  hpsa: correct queue depth for externals
  hpsa: send ioaccel requests with 0 length down raid path
  hpsa: remove abort handler
  hpsa: bump driver version

Scott Teel (1):
  hpsa: separate monitor events from rescan worker


 drivers/scsi/hpsa.c |  849 +++
 drivers/scsi/hpsa.h |4 
 drivers/scsi/hpsa_cmd.h |   20 +
 3 files changed, 208 insertions(+), 665 deletions(-)

--
Signature


[PATCH V4 01/12] hpsa: update identify physical device structure

2017-05-04 Thread Don Brace
 - align with latest spec.
 - added __attribute((aligned(512)))

Reviewed-by: Scott Teel 
Reviewed-by: Scott Benesh 
Reviewed-by: Kevin Barnett 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa_cmd.h |   20 ++--
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h
index 5961705..078afe4 100644
--- a/drivers/scsi/hpsa_cmd.h
+++ b/drivers/scsi/hpsa_cmd.h
@@ -809,10 +809,7 @@ struct bmic_identify_physical_device {
u8 max_temperature_degreesC;
u8 logical_blocks_per_phys_block_exp; /* phyblocksize = 512*2^exp */
__le16 current_queue_depth_limit;
-   u8 switch_name[10];
-   __le16 switch_port;
-   u8 alternate_paths_switch_name[40];
-   u8 alternate_paths_switch_port[8];
+   u8 reserved_switch_stuff[60];
__le16 power_on_hours; /* valid only if gas gauge supported */
__le16 percent_endurance_used; /* valid only if gas gauge supported. */
 #define BMIC_PHYS_DRIVE_SSD_WEAROUT(idphydrv) \
@@ -828,11 +825,22 @@ struct bmic_identify_physical_device {
(idphydrv->smart_carrier_authentication == 0x01)
u8 smart_carrier_app_fw_version;
u8 smart_carrier_bootloader_fw_version;
+   u8 sanitize_support_flags;
+   u8 drive_key_flags;
u8 encryption_key_name[64];
__le32 misc_drive_flags;
__le16 dek_index;
-   u8 padding[112];
-};
+   __le16 hba_drive_encryption_flags;
+   __le16 max_overwrite_time;
+   __le16 max_block_erase_time;
+   __le16 max_crypto_erase_time;
+   u8 device_connector_info[5];
+   u8 connector_name[8][8];
+   u8 page_83_id[16];
+   u8 max_link_rate[256];
+   u8 neg_phys_link_rate[256];
+   u8 box_conn_name[8];
+} __attribute((aligned(512)));
 
 struct bmic_sense_subsystem_info {
u8  primary_slot_number;



[PATCH V4 02/12] hpsa: do not get enclosure info for external devices

2017-05-04 Thread Don Brace
external shelves do not support BMICs.

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

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 73daace..8e22aed 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -3353,6 +3353,11 @@ static void hpsa_get_enclosure_info(struct ctlr_info *h,
 
bmic_device_index = GET_BMIC_DRIVE_NUMBER(>lunid[0]);
 
+   if (encl_dev->target == -1 || encl_dev->lun == -1) {
+   rc = IO_OK;
+   goto out;
+   }
+
if (bmic_device_index == 0xFF00 || MASKED_DEVICE(>lunid[0])) {
rc = IO_OK;
goto out;



Re: [PATCH] scsi: pmcraid: remove redundant check to see if request_size is less than zero

2017-05-04 Thread Tyrel Datwyler
On 05/03/2017 09:29 AM, Colin King wrote:
> From: Colin Ian King 
> 
> The 2nd check to see if request_size is less than zero is redundant
> because the first check takes error exit path on this condition. So,
> since it is redundant, remove it.
> 
> Detected by CoverityScan, CID#146149 ("Logically Dead Code")
> 
> Signed-off-by: Colin Ian King 

Reviewed-by: Tyrel Datwyler 



[PATCH V3 14/14] hpsa: bump driver version

2017-05-04 Thread Don Brace
Reviewed-by: Scott Benesh 
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 9a631e3..9934947 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -60,7 +60,7 @@
  * HPSA_DRIVER_VERSION must be 3 byte values (0-255) separated by '.'
  * with an optional trailing '-' followed by a byte value (0-255).
  */
-#define HPSA_DRIVER_VERSION "3.4.18-0"
+#define HPSA_DRIVER_VERSION "3.4.20-0"
 #define DRIVER_NAME "HP HPSA Driver (v " HPSA_DRIVER_VERSION ")"
 #define HPSA "hpsa"
 



[PATCH V3 13/14] hpsa: remove abort handler

2017-05-04 Thread Don Brace
 - simplify the driver
 - there are a lot of quirky racy conditions not handled
 - causes more aborts/resets when the number of commands to
   be aborted is large, such as in multi-path fail-overs.
 - has been turned off in our internal driver since 8/31/2015

Reviewed-by: Scott Benesh 
Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |  621 +--
 drivers/scsi/hpsa.h |1 
 2 files changed, 8 insertions(+), 614 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index ea778cc..9a631e3 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -258,7 +258,6 @@ static int hpsa_scan_finished(struct Scsi_Host *sh,
 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);
@@ -326,7 +325,7 @@ static inline bool hpsa_is_cmd_idle(struct CommandList *c)
 
 static inline bool hpsa_is_pending_event(struct CommandList *c)
 {
-   return c->abort_pending || c->reset_pending;
+   return c->reset_pending;
 }
 
 /* extract sense key, asc, and ascq from sense data.  -1 means invalid. */
@@ -581,12 +580,6 @@ static u32 soft_unresettable_controller[] = {
0x409D0E11, /* Smart Array 6400 EM */
 };
 
-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;
@@ -615,12 +608,6 @@ 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)
 {
@@ -928,8 +915,8 @@ 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)
+#define HPSA_NRESERVED_CMDS(HPSA_CMDS_RESERVED_FOR_DRIVER +\
+HPSA_MAX_CONCURRENT_PASSTHRUS)
 
 static struct scsi_host_template hpsa_driver_template = {
.module = THIS_MODULE,
@@ -941,7 +928,6 @@ static struct scsi_host_template hpsa_driver_template = {
.change_queue_depth = hpsa_change_queue_depth,
.this_id= -1,
.use_clustering = ENABLE_CLUSTERING,
-   .eh_abort_handler   = hpsa_eh_abort_handler,
.eh_device_reset_handler = hpsa_eh_device_reset_handler,
.ioctl  = hpsa_ioctl,
.slave_alloc= hpsa_slave_alloc,
@@ -2361,26 +2347,12 @@ static void hpsa_cmd_resolve_events(struct ctlr_info *h,
bool do_wake = false;
 
/*
-* 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.
-*
-* Reset c->scsi_cmd here so that the abort or reset handler will know
+* Reset c->scsi_cmd here so that the 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();   /* Declare command idle before checking for pending events. */
-   if (c->abort_pending) {
-   do_wake = true;
-   c->abort_pending = false;
-   }
if (c->reset_pending) {
unsigned long flags;
struct hpsa_scsi_dev_t *dev;
@@ -2423,20 +2395,6 @@ static void hpsa_retry_cmd(struct ctlr_info *h, struct 
CommandList *c)
queue_work_on(raw_smp_processor_id(), h->resubmit_wq, >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)
-{
-   

[PATCH V3 12/14] hpsa: send ioaccel requests with 0 length down raid path

2017-05-04 Thread Don Brace
 - Block I/O requests with 0 length transfers which go down
   the ioaccel path. This causes lockup issues down in the basecode.
   - These issues have been fixed, but there are customers who are
 experiencing the issues when running older firmware.

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

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 2ec9079..ea778cc 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -4591,7 +4591,55 @@ static int hpsa_scatter_gather(struct ctlr_info *h,
return 0;
 }
 
-#define IO_ACCEL_INELIGIBLE (1)
+#define BUFLEN 128
+static inline void warn_zero_length_transfer(struct ctlr_info *h,
+   u8 *cdb, int cdb_len,
+   const char *func)
+{
+   char buf[BUFLEN];
+   int outlen;
+   int i;
+
+   outlen = scnprintf(buf, BUFLEN,
+   "%s: Blocking zero-length request: CDB:", func);
+   for (i = 0; i < cdb_len; i++)
+   outlen += scnprintf(buf+outlen, BUFLEN - outlen,
+   "%02hhx", cdb[i]);
+   dev_warn(>pdev->dev, "%s\n", buf);
+}
+
+#define IO_ACCEL_INELIGIBLE 1
+/* zero-length transfers trigger hardware errors. */
+static bool is_zero_length_transfer(u8 *cdb)
+{
+   u32 block_cnt;
+
+   /* Block zero-length transfer sizes on certain commands. */
+   switch (cdb[0]) {
+   case READ_10:
+   case WRITE_10:
+   case VERIFY:/* 0x2F */
+   case WRITE_VERIFY:  /* 0x2E */
+   block_cnt = get_unaligned_be16([7]);
+   break;
+   case READ_12:
+   case WRITE_12:
+   case VERIFY_12: /* 0xAF */
+   case WRITE_VERIFY_12:   /* 0xAE */
+   block_cnt = get_unaligned_be32([6]);
+   break;
+   case READ_16:
+   case WRITE_16:
+   case VERIFY_16: /* 0x8F */
+   block_cnt = get_unaligned_be32([10]);
+   break;
+   default:
+   return false;
+   }
+
+   return block_cnt == 0;
+}
+
 static int fixup_ioaccel_cdb(u8 *cdb, int *cdb_len)
 {
int is_write = 0;
@@ -4658,6 +4706,12 @@ static int hpsa_scsi_ioaccel1_queue_command(struct 
ctlr_info *h,
 
BUG_ON(cmd->cmd_len > IOACCEL1_IOFLAGS_CDBLEN_MAX);
 
+   if (is_zero_length_transfer(cdb)) {
+   warn_zero_length_transfer(h, cdb, cdb_len, __func__);
+   atomic_dec(_disk->ioaccel_cmds_out);
+   return IO_ACCEL_INELIGIBLE;
+   }
+
if (fixup_ioaccel_cdb(cdb, _len)) {
atomic_dec(_disk->ioaccel_cmds_out);
return IO_ACCEL_INELIGIBLE;
@@ -4822,6 +4876,12 @@ static int hpsa_scsi_ioaccel2_queue_command(struct 
ctlr_info *h,
 
BUG_ON(scsi_sg_count(cmd) > h->maxsgentries);
 
+   if (is_zero_length_transfer(cdb)) {
+   warn_zero_length_transfer(h, cdb, cdb_len, __func__);
+   atomic_dec(_disk->ioaccel_cmds_out);
+   return IO_ACCEL_INELIGIBLE;
+   }
+
if (fixup_ioaccel_cdb(cdb, _len)) {
atomic_dec(_disk->ioaccel_cmds_out);
return IO_ACCEL_INELIGIBLE;



[PATCH V3 11/14] hpsa: separate monitor events from rescan worker

2017-05-04 Thread Don Brace
From: Scott Teel 

create new worker thread to monitor controller events
 - both the rescan and event monitor workers can cause a
   rescan to occur however for multipath we have found
   that we need to respond faster than the normal scheduled
   rescan interval for path fail-overs.
 - getting controller events only involves reading a register, but
   the rescan worker can obtain an updated LUN list when there
   is a PTRAID device present.
 - move common code to a separate function.
advantages:
 - detect controller events more frequently.
 - leave rescan thread interval at 30 seconds.

Reviewed-by: Scott Benesh 
Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |   76 +++
 drivers/scsi/hpsa.h |1 +
 2 files changed, 59 insertions(+), 18 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 5b0cc0e..2ec9079 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -1110,6 +1110,7 @@ static int is_firmware_flash_cmd(u8 *cdb)
  */
 #define HEARTBEAT_SAMPLE_INTERVAL_DURING_FLASH (240 * HZ)
 #define HEARTBEAT_SAMPLE_INTERVAL (30 * HZ)
+#define HPSA_EVENT_MONITOR_INTERVAL (15 * HZ)
 static void dial_down_lockup_detection_during_fw_flash(struct ctlr_info *h,
struct CommandList *c)
 {
@@ -8661,15 +8662,10 @@ static int hpsa_luns_changed(struct ctlr_info *h)
return rc;
 }
 
-static void hpsa_rescan_ctlr_worker(struct work_struct *work)
+static void hpsa_perform_rescan(struct ctlr_info *h)
 {
+   struct Scsi_Host *sh = NULL;
unsigned long flags;
-   struct ctlr_info *h = container_of(to_delayed_work(work),
-   struct ctlr_info, rescan_ctlr_work);
-
-
-   if (h->remove_in_progress)
-   return;
 
/*
 * Do the scan after the reset
@@ -8682,23 +8678,63 @@ static void hpsa_rescan_ctlr_worker(struct work_struct 
*work)
}
spin_unlock_irqrestore(>reset_lock, flags);
 
-   if (hpsa_ctlr_needs_rescan(h) || hpsa_offline_devices_ready(h)) {
-   scsi_host_get(h->scsi_host);
+   sh = scsi_host_get(h->scsi_host);
+   if (sh != NULL) {
+   hpsa_scan_start(sh);
+   scsi_host_put(sh);
+   h->drv_req_rescan = 0;
+   }
+}
+
+/*
+ * watch for controller events
+ */
+static void hpsa_event_monitor_worker(struct work_struct *work)
+{
+   struct ctlr_info *h = container_of(to_delayed_work(work),
+   struct ctlr_info, event_monitor_work);
+   unsigned long flags;
+
+   spin_lock_irqsave(>lock, flags);
+   if (h->remove_in_progress) {
+   spin_unlock_irqrestore(>lock, flags);
+   return;
+   }
+   spin_unlock_irqrestore(>lock, flags);
+
+   if (hpsa_ctlr_needs_rescan(h)) {
hpsa_ack_ctlr_events(h);
-   hpsa_scan_start(h->scsi_host);
-   scsi_host_put(h->scsi_host);
+   hpsa_perform_rescan(h);
+   }
+
+   spin_lock_irqsave(>lock, flags);
+   if (!h->remove_in_progress)
+   schedule_delayed_work(>event_monitor_work,
+   HPSA_EVENT_MONITOR_INTERVAL);
+   spin_unlock_irqrestore(>lock, flags);
+}
+
+static void hpsa_rescan_ctlr_worker(struct work_struct *work)
+{
+   unsigned long flags;
+   struct ctlr_info *h = container_of(to_delayed_work(work),
+   struct ctlr_info, rescan_ctlr_work);
+
+   spin_lock_irqsave(>lock, flags);
+   if (h->remove_in_progress) {
+   spin_unlock_irqrestore(>lock, flags);
+   return;
+   }
+   spin_unlock_irqrestore(>lock, flags);
+
+   if (h->drv_req_rescan || hpsa_offline_devices_ready(h)) {
+   hpsa_perform_rescan(h);
} else if (h->discovery_polling) {
hpsa_disable_rld_caching(h);
if (hpsa_luns_changed(h)) {
-   struct Scsi_Host *sh = NULL;
-
dev_info(>pdev->dev,
"driver discovery polling rescan.\n");
-   sh = scsi_host_get(h->scsi_host);
-   if (sh != NULL) {
-   hpsa_scan_start(sh);
-   scsi_host_put(sh);
-   }
+   hpsa_perform_rescan(h);
}
}
spin_lock_irqsave(>lock, flags);
@@ -8964,6 +9000,9 @@ static int hpsa_init_one(struct pci_dev *pdev, const 
struct pci_device_id *ent)
INIT_DELAYED_WORK(>rescan_ctlr_work, hpsa_rescan_ctlr_worker);
queue_delayed_work(h->rescan_ctlr_wq, >rescan_ctlr_work,
h->heartbeat_sample_interval);
+   

[PATCH V3 10/14] hpsa: correct queue depth for externals

2017-05-04 Thread Don Brace
 - queue depth assignment not in correct place, had no effect.

Reviewed-by: Scott Benesh 
Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |   22 ++
 drivers/scsi/hpsa.h |1 +
 2 files changed, 11 insertions(+), 12 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 20b4e83..5b0cc0e 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -2069,10 +2069,13 @@ static int hpsa_slave_configure(struct scsi_device 
*sdev)
sd = sdev->hostdata;
sdev->no_uld_attach = !sd || !sd->expose_device;
 
-   if (sd)
-   queue_depth = sd->queue_depth != 0 ?
-   sd->queue_depth : sdev->host->can_queue;
-   else
+   if (sd) {
+   if (sd->external)
+   queue_depth = EXTERNAL_QD;
+   else
+   queue_depth = sd->queue_depth != 0 ?
+   sd->queue_depth : sdev->host->can_queue;
+   } else
queue_depth = sdev->host->can_queue;
 
scsi_change_queue_depth(sdev, queue_depth);
@@ -3915,6 +3918,9 @@ static int hpsa_update_device_info(struct ctlr_info *h,
this_device->queue_depth = h->nr_cmds;
}
 
+   if (this_device->external)
+   this_device->queue_depth = EXTERNAL_QD;
+
if (is_OBDR_device) {
/* See if this is a One-Button-Disaster-Recovery device
 * by looking for "$DR-10" at offset 43 in inquiry data.
@@ -4123,14 +4129,6 @@ static void hpsa_get_ioaccel_drive_info(struct ctlr_info 
*h,
int rc;
struct ext_report_lun_entry *rle;
 
-   /*
-* external targets don't support BMIC
-*/
-   if (dev->external) {
-   dev->queue_depth = 7;
-   return;
-   }
-
rle = >LUN[rle_index];
 
dev->ioaccel_handle = rle->ioaccel_handle;
diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
index 5352664..61dd54a 100644
--- a/drivers/scsi/hpsa.h
+++ b/drivers/scsi/hpsa.h
@@ -57,6 +57,7 @@ struct hpsa_sas_phy {
bool added_to_port;
 };
 
+#define EXTERNAL_QD 7
 struct hpsa_scsi_dev_t {
unsigned int devtype;
int bus, target, lun;   /* as presented to the OS */



[PATCH V3 08/14] hpsa: correct resets on retried commands

2017-05-04 Thread Don Brace
 - call scsi_done when the command completes.

Reviewed-by: Scott Benesh 
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 53a4f34..a2852da 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -5465,7 +5465,7 @@ static void hpsa_command_resubmit_worker(struct 
work_struct *work)
return hpsa_cmd_free_and_done(c->h, c, cmd);
}
if (c->reset_pending)
-   return hpsa_cmd_resolve_and_free(c->h, c);
+   return hpsa_cmd_free_and_done(c->h, c, cmd);
if (c->abort_pending)
return hpsa_cmd_abort_and_free(c->h, c, cmd);
if (c->cmd_type == CMD_IOACCEL2) {



[PATCH V3 09/14] hpsa: cleanup reset handler

2017-05-04 Thread Don Brace
 - mark device state sooner.

Reviewed-by: Scott Benesh 
Reviewed-by: Scott Teel 
Reviewed-by: Kevin Barnett 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |   59 +++
 drivers/scsi/hpsa.h |1 +
 2 files changed, 46 insertions(+), 14 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index a2852da..20b4e83 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -1859,10 +1859,13 @@ static void adjust_hpsa_scsi_table(struct ctlr_info *h,
 * A reset can cause a device status to change
 * re-schedule the scan to see what happened.
 */
+   spin_lock_irqsave(>reset_lock, flags);
if (h->reset_in_progress) {
h->drv_req_rescan = 1;
+   spin_unlock_irqrestore(>reset_lock, flags);
return;
}
+   spin_unlock_irqrestore(>reset_lock, flags);
 
added = kzalloc(sizeof(*added) * HPSA_MAX_DEVICES, GFP_KERNEL);
removed = kzalloc(sizeof(*removed) * HPSA_MAX_DEVICES, GFP_KERNEL);
@@ -5618,11 +5621,14 @@ static void hpsa_scan_start(struct Scsi_Host *sh)
/*
 * Do the scan after a reset completion
 */
+   spin_lock_irqsave(>reset_lock, flags);
if (h->reset_in_progress) {
h->drv_req_rescan = 1;
+   spin_unlock_irqrestore(>reset_lock, flags);
hpsa_scan_complete(h);
return;
}
+   spin_unlock_irqrestore(>reset_lock, flags);
 
hpsa_update_scsi_devices(h);
 
@@ -5834,28 +5840,38 @@ static int wait_for_device_to_become_ready(struct 
ctlr_info *h,
  */
 static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
 {
-   int rc;
+   int rc = SUCCESS;
struct ctlr_info *h;
struct hpsa_scsi_dev_t *dev;
u8 reset_type;
char msg[48];
+   unsigned long flags;
 
/* find the controller to which the command to be aborted was sent */
h = sdev_to_hba(scsicmd->device);
if (h == NULL) /* paranoia */
return FAILED;
 
-   if (lockup_detected(h))
-   return FAILED;
+   spin_lock_irqsave(>reset_lock, flags);
+   h->reset_in_progress = 1;
+   spin_unlock_irqrestore(>reset_lock, flags);
+
+   if (lockup_detected(h)) {
+   rc = FAILED;
+   goto return_reset_status;
+   }
 
dev = scsicmd->device->hostdata;
if (!dev) {
dev_err(>pdev->dev, "%s: device lookup failed\n", __func__);
-   return FAILED;
+   rc = FAILED;
+   goto return_reset_status;
}
 
-   if (dev->devtype == TYPE_ENCLOSURE)
-   return SUCCESS;
+   if (dev->devtype == TYPE_ENCLOSURE) {
+   rc = SUCCESS;
+   goto return_reset_status;
+   }
 
/* if controller locked up, we can guarantee command won't complete */
if (lockup_detected(h)) {
@@ -5863,7 +5879,8 @@ static int hpsa_eh_device_reset_handler(struct scsi_cmnd 
*scsicmd)
 "cmd %d RESET FAILED, lockup detected",
 hpsa_get_cmd_index(scsicmd));
hpsa_show_dev_msg(KERN_WARNING, h, dev, msg);
-   return FAILED;
+   rc = FAILED;
+   goto return_reset_status;
}
 
/* this reset request might be the result of a lockup; check */
@@ -5872,12 +5889,15 @@ static int hpsa_eh_device_reset_handler(struct 
scsi_cmnd *scsicmd)
 "cmd %d RESET FAILED, new lockup detected",
 hpsa_get_cmd_index(scsicmd));
hpsa_show_dev_msg(KERN_WARNING, h, dev, msg);
-   return FAILED;
+   rc = FAILED;
+   goto return_reset_status;
}
 
/* Do not attempt on controller */
-   if (is_hba_lunid(dev->scsi3addr))
-   return SUCCESS;
+   if (is_hba_lunid(dev->scsi3addr)) {
+   rc = SUCCESS;
+   goto return_reset_status;
+   }
 
if (is_logical_dev_addr_mode(dev->scsi3addr))
reset_type = HPSA_DEVICE_RESET_MSG;
@@ -5888,17 +5908,24 @@ static int hpsa_eh_device_reset_handler(struct 
scsi_cmnd *scsicmd)
reset_type == HPSA_DEVICE_RESET_MSG ? "logical " : "physical ");
hpsa_show_dev_msg(KERN_WARNING, h, dev, msg);
 
-   h->reset_in_progress = 1;
-
/* send a reset to the SCSI LUN which the command was sent to */
rc = hpsa_do_reset(h, dev, dev->scsi3addr, reset_type,
   DEFAULT_REPLY_QUEUE);
+   if (rc == 0)
+   rc = SUCCESS;
+   else
+   rc = FAILED;
+
sprintf(msg, "reset %s %s",
reset_type == HPSA_DEVICE_RESET_MSG ? "logical " : "physical ",
-   rc == 0 ? "completed successfully" 

[PATCH V3 06/14] hpsa: do not reset enclosures

2017-05-04 Thread Don Brace
Prevent enclosure resets.

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

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 9fb30c4..2990897 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -5853,6 +5853,9 @@ static int hpsa_eh_device_reset_handler(struct scsi_cmnd 
*scsicmd)
return FAILED;
}
 
+   if (dev->devtype == TYPE_ENCLOSURE)
+   return SUCCESS;
+
/* if controller locked up, we can guarantee command won't complete */
if (lockup_detected(h)) {
snprintf(msg, sizeof(msg),



[PATCH V3 07/14] hpsa: rescan later if reset in progress

2017-05-04 Thread Don Brace
 - schedule another scan.
 - mark current scan as completed

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

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 2990897..53a4f34 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -5620,6 +5620,7 @@ static void hpsa_scan_start(struct Scsi_Host *sh)
 */
if (h->reset_in_progress) {
h->drv_req_rescan = 1;
+   hpsa_scan_complete(h);
return;
}
 



[PATCH V3 05/14] hpsa: update reset handler

2017-05-04 Thread Don Brace
Use the return from TUR as a check for the
device state.

Reviewed-by: Scott Benesh 
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 8e22aed..9fb30c4 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -3090,7 +3090,7 @@ static int hpsa_do_reset(struct ctlr_info *h, struct 
hpsa_scsi_dev_t *dev,
if (unlikely(rc))
atomic_set(>reset_cmds_out, 0);
else
-   wait_for_device_to_become_ready(h, scsi3addr, 0);
+   rc = wait_for_device_to_become_ready(h, scsi3addr, 0);
 
mutex_unlock(>reset_mutex);
return rc;



[PATCH V3 04/14] hpsa: do not get enclosure info for external devices

2017-05-04 Thread Don Brace
external shelves do not support BMICs.

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

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 73daace..8e22aed 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -3353,6 +3353,11 @@ static void hpsa_get_enclosure_info(struct ctlr_info *h,
 
bmic_device_index = GET_BMIC_DRIVE_NUMBER(>lunid[0]);
 
+   if (encl_dev->target == -1 || encl_dev->lun == -1) {
+   rc = IO_OK;
+   goto out;
+   }
+
if (bmic_device_index == 0xFF00 || MASKED_DEVICE(>lunid[0])) {
rc = IO_OK;
goto out;



[PATCH V3 03/14] hpsa: update identify physical device structure

2017-05-04 Thread Don Brace
 - align with latest spec.
 - added __attribute((aligned(512)))

Reviewed-by: Scott Teel 
Reviewed-by: Scott Benesh 
Reviewed-by: Kevin Barnett 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa_cmd.h |   20 ++--
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h
index 5961705..078afe4 100644
--- a/drivers/scsi/hpsa_cmd.h
+++ b/drivers/scsi/hpsa_cmd.h
@@ -809,10 +809,7 @@ struct bmic_identify_physical_device {
u8 max_temperature_degreesC;
u8 logical_blocks_per_phys_block_exp; /* phyblocksize = 512*2^exp */
__le16 current_queue_depth_limit;
-   u8 switch_name[10];
-   __le16 switch_port;
-   u8 alternate_paths_switch_name[40];
-   u8 alternate_paths_switch_port[8];
+   u8 reserved_switch_stuff[60];
__le16 power_on_hours; /* valid only if gas gauge supported */
__le16 percent_endurance_used; /* valid only if gas gauge supported. */
 #define BMIC_PHYS_DRIVE_SSD_WEAROUT(idphydrv) \
@@ -828,11 +825,22 @@ struct bmic_identify_physical_device {
(idphydrv->smart_carrier_authentication == 0x01)
u8 smart_carrier_app_fw_version;
u8 smart_carrier_bootloader_fw_version;
+   u8 sanitize_support_flags;
+   u8 drive_key_flags;
u8 encryption_key_name[64];
__le32 misc_drive_flags;
__le16 dek_index;
-   u8 padding[112];
-};
+   __le16 hba_drive_encryption_flags;
+   __le16 max_overwrite_time;
+   __le16 max_block_erase_time;
+   __le16 max_crypto_erase_time;
+   u8 device_connector_info[5];
+   u8 connector_name[8][8];
+   u8 page_83_id[16];
+   u8 max_link_rate[256];
+   u8 neg_phys_link_rate[256];
+   u8 box_conn_name[8];
+} __attribute((aligned(512)));
 
 struct bmic_sense_subsystem_info {
u8  primary_slot_number;



[PATCH V3 02/14] hpsa: change driver version

2017-05-04 Thread Don Brace
Reviewed-by: Gerry Morong 
Reviewed-by: Scott Teel 
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 eabb826..73daace 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -60,7 +60,7 @@
  * HPSA_DRIVER_VERSION must be 3 byte values (0-255) separated by '.'
  * with an optional trailing '-' followed by a byte value (0-255).
  */
-#define HPSA_DRIVER_VERSION "3.4.16-0"
+#define HPSA_DRIVER_VERSION "3.4.18-0"
 #define DRIVER_NAME "HP HPSA Driver (v " HPSA_DRIVER_VERSION ")"
 #define HPSA "hpsa"
 



[PATCH V3 00/14] hpsa updates

2017-05-04 Thread Don Brace
These patches are based on Linus's tree

These patches are for:
 - RedHat BZ: 1404073 - [HPE 7.3 Bug] multipath failover not reliable
 - Multipath failover support in general.

The changes are:
 - update identify physical device structure
   - align with FW
 - stop getting enclosure info for externals
   - no BMIC support
 - update reset handler
   - update to match out of box driver
 - do not reset enclosures
   - reset can sometimes hang
 - rescan later if reset in progress
   - wait for devices to settle.
 - correct resets on retried commands
   - was not calling scsi_done on retried completion
 - correct queue depth for externals
   - Code not in correct function
 - separate monitor events from rescan worker
   - allows driver to check for controller events more frequently
 without affecting controller lockup detection or check
 for changes on PTRAID devices.
 - send ioaccel requests with 0 length down raid path
   - avoid hang issues for customers running older firmware.
 - remove abort handler
   - align driver with our out of box driver
 - bump driver version
   - align version with out of box driver for multi-path changes

Changes since V1:
 - includes changes based on Martin Wilck  reviews.
- cleanup reset handler
  - added spin_lock protection around h->reset_in_progress
- this has helped solve a multipath issue, thanks Martin.
- renamed patch hpsa-separate-monitor-events-from-hearbeat-worker to
  hpsa-separate-monitor-events-from-rescan-worker to more correctly
 convey the patches intent.
  - split out some commonality between the rescan worker and the
event monitor worker.
  - updated the patch description.

Changes since V2:
 - includes a change based on Tomas Henzl  review
   - Corrected placement of spin_unlock_irqrestore in patch
 hpsa-clean-up-reset-handler
 - Thanks for your attention to hpsa Tomas

---

Don Brace (13):
  hpsa: update pci ids
  hpsa: change driver version
  hpsa: update identify physical device structure
  hpsa: do not get enclosure info for external devices
  hpsa: update reset handler
  hpsa: do not reset enclosures
  hpsa: rescan later if reset in progress
  hpsa: correct resets on retried commands
  hpsa: cleanup reset handler
  hpsa: correct queue depth for externals
  hpsa: send ioaccel requests with 0 length down raid path
  hpsa: remove abort handler
  hpsa: bump driver version

Scott Teel (1):
  hpsa: separate monitor events from rescan worker


 drivers/scsi/hpsa.c |  853 +++
 drivers/scsi/hpsa.h |4 
 drivers/scsi/hpsa_cmd.h |   20 +
 3 files changed, 212 insertions(+), 665 deletions(-)

--
Signature


[PATCH V3 01/14] hpsa: update pci ids

2017-05-04 Thread Don Brace
Reviewed-by: Gerry Morong 
Reviewed-by: Scott Teel 
Signed-off-by: Don Brace 
---
 drivers/scsi/hpsa.c |4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 9d659aa..eabb826 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -108,10 +108,12 @@ static const struct pci_device_id hpsa_pci_device_id[] = {
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSF, 0x103C, 0x3354},
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSF, 0x103C, 0x3355},
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSF, 0x103C, 0x3356},
+   {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSH, 0x103c, 0x1920},
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSH, 0x103C, 0x1921},
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSH, 0x103C, 0x1922},
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSH, 0x103C, 0x1923},
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSH, 0x103C, 0x1924},
+   {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSH, 0x103c, 0x1925},
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSH, 0x103C, 0x1926},
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSH, 0x103C, 0x1928},
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSH, 0x103C, 0x1929},
@@ -171,10 +173,12 @@ static struct board_type products[] = {
{0x3354103C, "Smart Array P420i", _access},
{0x3355103C, "Smart Array P220i", _access},
{0x3356103C, "Smart Array P721m", _access},
+   {0x1920103C, "Smart Array P430i", _access},
{0x1921103C, "Smart Array P830i", _access},
{0x1922103C, "Smart Array P430", _access},
{0x1923103C, "Smart Array P431", _access},
{0x1924103C, "Smart Array P830", _access},
+   {0x1925103C, "Smart Array P831", _access},
{0x1926103C, "Smart Array P731m", _access},
{0x1928103C, "Smart Array P230i", _access},
{0x1929103C, "Smart Array P530", _access},



RE: [PATCH V2 07/12] hpsa: cleanup reset handler

2017-05-04 Thread Don Brace
> -Original Message-
> From: Tomas Henzl [mailto:the...@redhat.com]
> Sent: Thursday, May 04, 2017 10:47 AM
> To: Don Brace ; joseph.szczy...@hpe.com;
> Gerry Morong ; John Hall
> ; j...@linux.vnet.ibm.com; Kevin Barnett
> ; Mahesh Rajashekhara
> ; Bader Ali - Saleh
> ; h...@infradead.org; Scott Teel
> ; Viswas G ; Justin
> Lindley ; Scott Benesh
> ; posw...@suse.com
> Cc: linux-scsi@vger.kernel.org
> Subject: Re: [PATCH V2 07/12] hpsa: cleanup reset handler
> 
> EXTERNAL EMAIL
> 
> 
> On 28.4.2017 20:20, Don Brace wrote:
> >  - mark device state sooner.
> >
> > Reviewed-by: Scott Benesh 
> > Reviewed-by: Scott Teel 
> > Reviewed-by: Kevin Barnett 
> > Signed-off-by: Don Brace 
> > ---
> >  drivers/scsi/hpsa.c |   59
> +++
> >  drivers/scsi/hpsa.h |1 +
> >  2 files changed, 46 insertions(+), 14 deletions(-)
> >
> > diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
> > index a2852da..71f32e9 100644
> > --- a/drivers/scsi/hpsa.c
> > +++ b/drivers/scsi/hpsa.c
> > @@ -1859,10 +1859,13 @@ static void adjust_hpsa_scsi_table(struct
> ctlr_info *h,
> >* A reset can cause a device status to change
> >* re-schedule the scan to see what happened.
> >*/
> > + spin_lock_irqsave(>reset_lock, flags);
> >   if (h->reset_in_progress) {
> > + spin_unlock_irqrestore(>reset_lock, flags);
> >   h->drv_req_rescan = 1;
> >   return;
> >   }
> > + spin_unlock_irqrestore(>reset_lock, flags);
> >
> >   added = kzalloc(sizeof(*added) * HPSA_MAX_DEVICES, GFP_KERNEL);
> >   removed = kzalloc(sizeof(*removed) * HPSA_MAX_DEVICES,
> GFP_KERNEL);
> > @@ -5618,11 +5621,14 @@ static void hpsa_scan_start(struct Scsi_Host
> *sh)
> >   /*
> >* Do the scan after a reset completion
> >*/
> > + spin_lock_irqsave(>reset_lock, flags);
> >   if (h->reset_in_progress) {
> > + spin_unlock_irqrestore(>reset_lock, flags);
> >   h->drv_req_rescan = 1;
> >   hpsa_scan_complete(h);
> >   return;
> >   }
> > + spin_unlock_irqrestore(>reset_lock, flags);
> 
> Hi Don,
> I glad the spinlock helped, but how is the code protected when another
> thread
> enters hpsa_eh_device_reset_handler in parallel when the first thread just
> called the 'spin_unlock_irqrestore(>reset_lock' ?
> 
> tomash
> 
I am wondering  that too!
I'll correct this and send up a V3.
Thanks for your review Tomas.

Thanks,
Don Brace
ESC - Smart Storage
Microsemi Corporation


> 
> 
> >
> >   hpsa_update_scsi_devices(h);
> >
> > @@ -5834,28 +5840,38 @@ static int
> wait_for_device_to_become_ready(struct ctlr_info *h,
> >   */
> >  static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
> >  {
> > - int rc;
> > + int rc = SUCCESS;
> >   struct ctlr_info *h;
> >   struct hpsa_scsi_dev_t *dev;
> >   u8 reset_type;
> >   char msg[48];
> > + unsigned long flags;
> >
> >   /* find the controller to which the command to be aborted was sent */
> >   h = sdev_to_hba(scsicmd->device);
> >   if (h == NULL) /* paranoia */
> >   return FAILED;
> >
> > - if (lockup_detected(h))
> > - return FAILED;
> > + spin_lock_irqsave(>reset_lock, flags);
> > + h->reset_in_progress = 1;
> > + spin_unlock_irqrestore(>reset_lock, flags);
> > +
> > + if (lockup_detected(h)) {
> > + rc = FAILED;
> > + goto return_reset_status;
> > + }
> >
> >   dev = scsicmd->device->hostdata;
> >   if (!dev) {
> >   dev_err(>pdev->dev, "%s: device lookup failed\n", 
> > __func__);
> > - return FAILED;
> > + rc = FAILED;
> > + goto return_reset_status;
> >   }
> >
> > - if (dev->devtype == TYPE_ENCLOSURE)
> > - return SUCCESS;
> > + if (dev->devtype == TYPE_ENCLOSURE) {
> > + rc = SUCCESS;
> > + goto return_reset_status;
> > + }
> >
> >   /* if controller locked up, we can guarantee command won't complete
> */
> >   if (lockup_detected(h)) {
> > @@ -5863,7 +5879,8 @@ static int hpsa_eh_device_reset_handler(struct
> scsi_cmnd *scsicmd)
> >"cmd %d RESET FAILED, lockup detected",
> >hpsa_get_cmd_index(scsicmd));
> >   hpsa_show_dev_msg(KERN_WARNING, h, dev, msg);
> > - return FAILED;
> > + rc = FAILED;
> > + goto return_reset_status;
> >   }
> >
> >   /* this reset request might be the result 

Re: [REEEEPOST] bnx2i + bnx2fc: convert to generic workqueue (#3)

2017-05-04 Thread Sebastian Andrzej Siewior
On 2017-04-10 19:12:49 [+0200], To Martin K . Petersen wrote:
> This is a repost to get the patches applied against v4.11-rc6. mkp's scsi
> for-next tree can be merged with no conflicts.
…

Martin, do you see any chance to get this merged? Chad replied to the
list that he is going to test it on 2017-04-10, didn't respond to the
ping 10 days later. The series stalled last time in the same way.

> The whole series is also available at
>  git://git.kernel.org/pub/scm/linux/kernel/git/bigeasy/hotplug-staging.git 
> scsi/bnx2_v2
 
Sebastian


Re: [PATCH V2 07/12] hpsa: cleanup reset handler

2017-05-04 Thread Tomas Henzl
On 28.4.2017 20:20, Don Brace wrote:
>  - mark device state sooner.
>
> Reviewed-by: Scott Benesh 
> Reviewed-by: Scott Teel 
> Reviewed-by: Kevin Barnett 
> Signed-off-by: Don Brace 
> ---
>  drivers/scsi/hpsa.c |   59 
> +++
>  drivers/scsi/hpsa.h |1 +
>  2 files changed, 46 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
> index a2852da..71f32e9 100644
> --- a/drivers/scsi/hpsa.c
> +++ b/drivers/scsi/hpsa.c
> @@ -1859,10 +1859,13 @@ static void adjust_hpsa_scsi_table(struct ctlr_info 
> *h,
>* A reset can cause a device status to change
>* re-schedule the scan to see what happened.
>*/
> + spin_lock_irqsave(>reset_lock, flags);
>   if (h->reset_in_progress) {
> + spin_unlock_irqrestore(>reset_lock, flags);
>   h->drv_req_rescan = 1;
>   return;
>   }
> + spin_unlock_irqrestore(>reset_lock, flags);
>  
>   added = kzalloc(sizeof(*added) * HPSA_MAX_DEVICES, GFP_KERNEL);
>   removed = kzalloc(sizeof(*removed) * HPSA_MAX_DEVICES, GFP_KERNEL);
> @@ -5618,11 +5621,14 @@ static void hpsa_scan_start(struct Scsi_Host *sh)
>   /*
>* Do the scan after a reset completion
>*/
> + spin_lock_irqsave(>reset_lock, flags);
>   if (h->reset_in_progress) {
> + spin_unlock_irqrestore(>reset_lock, flags);
>   h->drv_req_rescan = 1;
>   hpsa_scan_complete(h);
>   return;
>   }
> + spin_unlock_irqrestore(>reset_lock, flags);

Hi Don,
I glad the spinlock helped, but how is the code protected when another thread
enters hpsa_eh_device_reset_handler in parallel when the first thread just 
called the 'spin_unlock_irqrestore(>reset_lock' ?

tomash 

 

>  
>   hpsa_update_scsi_devices(h);
>  
> @@ -5834,28 +5840,38 @@ static int wait_for_device_to_become_ready(struct 
> ctlr_info *h,
>   */
>  static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
>  {
> - int rc;
> + int rc = SUCCESS;
>   struct ctlr_info *h;
>   struct hpsa_scsi_dev_t *dev;
>   u8 reset_type;
>   char msg[48];
> + unsigned long flags;
>  
>   /* find the controller to which the command to be aborted was sent */
>   h = sdev_to_hba(scsicmd->device);
>   if (h == NULL) /* paranoia */
>   return FAILED;
>  
> - if (lockup_detected(h))
> - return FAILED;
> + spin_lock_irqsave(>reset_lock, flags);
> + h->reset_in_progress = 1;
> + spin_unlock_irqrestore(>reset_lock, flags);
> +
> + if (lockup_detected(h)) {
> + rc = FAILED;
> + goto return_reset_status;
> + }
>  
>   dev = scsicmd->device->hostdata;
>   if (!dev) {
>   dev_err(>pdev->dev, "%s: device lookup failed\n", __func__);
> - return FAILED;
> + rc = FAILED;
> + goto return_reset_status;
>   }
>  
> - if (dev->devtype == TYPE_ENCLOSURE)
> - return SUCCESS;
> + if (dev->devtype == TYPE_ENCLOSURE) {
> + rc = SUCCESS;
> + goto return_reset_status;
> + }
>  
>   /* if controller locked up, we can guarantee command won't complete */
>   if (lockup_detected(h)) {
> @@ -5863,7 +5879,8 @@ static int hpsa_eh_device_reset_handler(struct 
> scsi_cmnd *scsicmd)
>"cmd %d RESET FAILED, lockup detected",
>hpsa_get_cmd_index(scsicmd));
>   hpsa_show_dev_msg(KERN_WARNING, h, dev, msg);
> - return FAILED;
> + rc = FAILED;
> + goto return_reset_status;
>   }
>  
>   /* this reset request might be the result of a lockup; check */
> @@ -5872,12 +5889,15 @@ static int hpsa_eh_device_reset_handler(struct 
> scsi_cmnd *scsicmd)
>"cmd %d RESET FAILED, new lockup detected",
>hpsa_get_cmd_index(scsicmd));
>   hpsa_show_dev_msg(KERN_WARNING, h, dev, msg);
> - return FAILED;
> + rc = FAILED;
> + goto return_reset_status;
>   }
>  
>   /* Do not attempt on controller */
> - if (is_hba_lunid(dev->scsi3addr))
> - return SUCCESS;
> + if (is_hba_lunid(dev->scsi3addr)) {
> + rc = SUCCESS;
> + goto return_reset_status;
> + }
>  
>   if (is_logical_dev_addr_mode(dev->scsi3addr))
>   reset_type = HPSA_DEVICE_RESET_MSG;
> @@ -5888,17 +5908,24 @@ static int hpsa_eh_device_reset_handler(struct 
> scsi_cmnd *scsicmd)
>   reset_type == HPSA_DEVICE_RESET_MSG ? "logical " : "physical ");
>   hpsa_show_dev_msg(KERN_WARNING, h, dev, msg);
>  
> - h->reset_in_progress = 1;
> -
>   /* send a reset to the SCSI LUN which the command was sent to */
>   rc = 

Re: [PATCH v2] Avoid that scsi_exit_rq() triggers a use-after-free

2017-05-04 Thread Scott Bauer
On Thu, May 04, 2017 at 03:32:44PM +, Bart Van Assche wrote:
> On Thu, 2017-05-04 at 09:15 -0600, Scott Bauer wrote:
> > On Thu, May 04, 2017 at 03:26:37PM +, Bart Van Assche wrote:
> > > On Thu, 2017-05-04 at 09:30 +0200, Christoph Hellwig wrote:
> > > > Please just add a flag to ->flags instead of adding a whole new field.
> > > > 
> > > > Otherwise this looks good to me.
> > > 
> > > Hello Christoph,
> > > 
> > > Thanks for the feedback. I will make the proposed change and post a second
> > > version.
> > 
> > BTW, what branch was your last patch based off? I had some hunk errors while
> > applying it.
> 
> Hello Scott,
> 
> That patch was based off kernel v4.11. Did you perhaps use a different kernel
> version for your tests?
> 
> Bart.

I've been working on top of Jens' for-linus
https://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git/log/?h=for-linus



Re: [PATCH v2] Avoid that scsi_exit_rq() triggers a use-after-free

2017-05-04 Thread Bart Van Assche
On Thu, 2017-05-04 at 09:15 -0600, Scott Bauer wrote:
> On Thu, May 04, 2017 at 03:26:37PM +, Bart Van Assche wrote:
> > On Thu, 2017-05-04 at 09:30 +0200, Christoph Hellwig wrote:
> > > Please just add a flag to ->flags instead of adding a whole new field.
> > > 
> > > Otherwise this looks good to me.
> > 
> > Hello Christoph,
> > 
> > Thanks for the feedback. I will make the proposed change and post a second
> > version.
> 
> BTW, what branch was your last patch based off? I had some hunk errors while
> applying it.

Hello Scott,

That patch was based off kernel v4.11. Did you perhaps use a different kernel
version for your tests?

Bart.

Re: [PATCH v2] Avoid that scsi_exit_rq() triggers a use-after-free

2017-05-04 Thread Scott Bauer
On Thu, May 04, 2017 at 03:26:37PM +, Bart Van Assche wrote:
> On Thu, 2017-05-04 at 09:30 +0200, Christoph Hellwig wrote:
> > Please just add a flag to ->flags instead of adding a whole new field.
> > 
> > Otherwise this looks good to me.
> 
> Hello Christoph,
> 
> Thanks for the feedback. I will make the proposed change and post a second
> version.
> 
> Bart.

BTW, what branch was your last patch based off? I had some hunk errors while
applying it.


Re: [PATCH v2] Avoid that scsi_exit_rq() triggers a use-after-free

2017-05-04 Thread Bart Van Assche
On Thu, 2017-05-04 at 09:30 +0200, Christoph Hellwig wrote:
> Please just add a flag to ->flags instead of adding a whole new field.
> 
> Otherwise this looks good to me.

Hello Christoph,

Thanks for the feedback. I will make the proposed change and post a second
version.

Bart.

Re: [PATCH v2] sd: Ignore sync cache failures when not supported

2017-05-04 Thread Bart Van Assche
On Thu, 2017-05-04 at 11:43 +0200, Thierry Escande wrote:
> From: Derek Basehore 
> 
> Some external hard drives don't support the sync command even though the
> hard drive has write cache enabled. In this case, upon suspend request,
> sync cache failures are ignored if the error code in the sense header is
> ILLEGAL_REQUEST. There's not much we can do for these drives, so we
> shouldn't fail to suspend for this error case. The drive may stay
> powered if that's the setup for the port it's plugged into.

Reviewed-by: Bart van Assche 

Re: [PATCH] scsi: qedf: properly update arguments position in function call

2017-05-04 Thread Chad Dupuis

On Wed, 3 May 2017, 3:17pm, Gustavo A. R. Silva wrote:

> Properly update the position of the arguments in function call.
> 
> Addresses-Coverity-ID: 1402010
> Signed-off-by: Gustavo A. R. Silva 
> ---
>  drivers/scsi/qedf/qedf_els.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/scsi/qedf/qedf_els.c b/drivers/scsi/qedf/qedf_els.c
> index 59f3e5c..107ed2b 100644
> --- a/drivers/scsi/qedf/qedf_els.c
> +++ b/drivers/scsi/qedf/qedf_els.c
> @@ -106,7 +106,7 @@ static int qedf_initiate_els(struct qedf_rport *fcport, 
> unsigned int op,
>   did = fcport->rdata->ids.port_id;
>   sid = fcport->sid;
>  
> - __fc_fill_fc_hdr(fc_hdr, FC_RCTL_ELS_REQ, sid, did,
> + __fc_fill_fc_hdr(fc_hdr, FC_RCTL_ELS_REQ, did, sid,
>  FC_TYPE_ELS, FC_FC_FIRST_SEQ | FC_FC_END_SEQ |
>  FC_FC_SEQ_INIT, 0);
>  
> 

Thanks.

Acked-by: Chad Dupuis 


Re: [PATCH] scsi: qedf: Cleanup the type of io_log->op

2017-05-04 Thread Chad Dupuis

On Wed, 3 May 2017, 5:23pm, Dan Carpenter wrote:

> We store sc_cmd->cmnd[0] which is an unsigned char in io_log->op so
> this should also be unsigned char.  The other thing is that this is
> displayed in the debugfs:
> 
>   seq_printf(s, "0x%02x:", io_log->op);
> 
> Smatch complains that the formatting won't work for negative values so
> changing it to unsigned silences that warning as well.
> 
> Signed-off-by: Dan Carpenter 
> 
> diff --git a/drivers/scsi/qedf/qedf.h b/drivers/scsi/qedf/qedf.h
> index 40aeb6bb96a2..07ee88200e91 100644
> --- a/drivers/scsi/qedf/qedf.h
> +++ b/drivers/scsi/qedf/qedf.h
> @@ -259,7 +259,7 @@ struct qedf_io_log {
>   uint16_t task_id;
>   uint32_t port_id; /* Remote port fabric ID */
>   int lun;
> - char op; /* SCSI CDB */
> + unsigned char op; /* SCSI CDB */
>   uint8_t lba[4];
>   unsigned int bufflen; /* SCSI buffer length */
>   unsigned int sg_count; /* Number of SG elements */
> 

Makes sense.

Acked-by: Chad Dupuis 


[Bug 176951] boot fails unless acpi=off Acer Travelmate X-349

2017-05-04 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=176951

Alberto Tiboni (a.tib...@gmail.com) changed:

   What|Removed |Added

 CC||a.tib...@gmail.com

--- Comment #24 from Alberto Tiboni (a.tib...@gmail.com) ---
I can confirm issue is still here: update bios at 1.08, nothing changed!

Tried Ubuntu and Lubuntu distro, 16.04, 16.10 and 17.04, both 64 and 32bits.

The only one that booted after installation was Lubuntu 16.04 32bit in legacy
mode, with grub without "quite splash" parameters.

but it works rarely: 9 on 10 times it produces a kernel panic on apci init.

Now I'm trying linux Mint, but i'm quite sure problem will be there too.

-- 
You are receiving this mail because:
You are watching the assignee of the bug.


[bug report] scsi: cxlflash: Add hardware queues attribute

2017-05-04 Thread Dan Carpenter
Hello Matthew R. Ochs,

This is a semi-automatic email about new static checker warnings.

The patch 3065267a80c8: "scsi: cxlflash: Add hardware queues 
attribute" from Apr 12, 2017, leads to the following Smatch complaint:

drivers/scsi/cxlflash/main.c:722 term_afu()
 warn: variable dereferenced before check 'cfg->afu' (see line 719)

drivers/scsi/cxlflash/main.c
   718   */
   719  for (k = cfg->afu->num_hwqs - 1; k >= 0; k--)
 
Patch introduces a new dereference.

   720  term_intr(cfg, UNMAP_THREE, k);
   721  
   722  if (cfg->afu)

But the existing code assumed it could be NULL.  Presumably it can't?

   723  stop_afu(cfg);
   724  

regards,
dan carpenter


[PATCH v2] sd: Ignore sync cache failures when not supported

2017-05-04 Thread Thierry Escande
From: Derek Basehore 

Some external hard drives don't support the sync command even though the
hard drive has write cache enabled. In this case, upon suspend request,
sync cache failures are ignored if the error code in the sense header is
ILLEGAL_REQUEST. There's not much we can do for these drives, so we
shouldn't fail to suspend for this error case. The drive may stay
powered if that's the setup for the port it's plugged into.

Signed-off-by: Derek Basehore 
Signed-off-by: Thierry Escande 
---

v2 changes:
- Change sense_key type to u8 in sd_sync_cache()

 drivers/scsi/sd.c | 22 ++
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index fcfeddc..6c6db1b 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1489,7 +1489,7 @@ static unsigned int sd_check_events(struct gendisk *disk, 
unsigned int clearing)
return retval;
 }
 
-static int sd_sync_cache(struct scsi_disk *sdkp)
+static int sd_sync_cache(struct scsi_disk *sdkp, u8 *sense_key)
 {
int retries, res;
struct scsi_device *sdp = sdkp->device;
@@ -1517,8 +1517,11 @@ static int sd_sync_cache(struct scsi_disk *sdkp)
if (res) {
sd_print_result(sdkp, "Synchronize Cache(10) failed", res);
 
-   if (driver_byte(res) & DRIVER_SENSE)
+   if (driver_byte(res) & DRIVER_SENSE) {
sd_print_sense_hdr(sdkp, );
+   if (sense_key)
+   *sense_key = sshdr.sense_key;
+   }
/* we need to evaluate the error return  */
if (scsi_sense_valid() &&
(sshdr.asc == 0x3a ||   /* medium not present */
@@ -3323,7 +3326,7 @@ static void sd_shutdown(struct device *dev)
 
if (sdkp->WCE && sdkp->media_present) {
sd_printk(KERN_NOTICE, sdkp, "Synchronizing SCSI cache\n");
-   sd_sync_cache(sdkp);
+   sd_sync_cache(sdkp, NULL);
}
 
if (system_state != SYSTEM_RESTART && sdkp->device->manage_start_stop) {
@@ -3335,6 +3338,7 @@ static void sd_shutdown(struct device *dev)
 static int sd_suspend_common(struct device *dev, bool ignore_stop_errors)
 {
struct scsi_disk *sdkp = dev_get_drvdata(dev);
+   u8 sense_key = NO_SENSE;
int ret = 0;
 
if (!sdkp)  /* E.g.: runtime suspend following sd_remove() */
@@ -3342,8 +3346,17 @@ static int sd_suspend_common(struct device *dev, bool 
ignore_stop_errors)
 
if (sdkp->WCE && sdkp->media_present) {
sd_printk(KERN_NOTICE, sdkp, "Synchronizing SCSI cache\n");
-   ret = sd_sync_cache(sdkp);
+   ret = sd_sync_cache(sdkp, _key);
if (ret) {
+   /*
+* If this drive doesn't support sync, there's not much
+* to do and suspend shouldn't fail.
+*/
+   if (sense_key == ILLEGAL_REQUEST) {
+   ret = 0;
+   goto start_stop;
+   }
+
/* ignore OFFLINE device */
if (ret == -ENODEV)
ret = 0;
@@ -3351,6 +3364,7 @@ static int sd_suspend_common(struct device *dev, bool 
ignore_stop_errors)
}
}
 
+start_stop:
if (sdkp->device->manage_start_stop) {
sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n");
/* an error is not worth aborting a system sleep */
-- 
2.7.4



Re: [PATCH v2] Avoid that scsi_exit_rq() triggers a use-after-free

2017-05-04 Thread Christoph Hellwig
Please just add a flag to ->flags instead of adding a whole new field.

Otherwise this looks good to me.