hpsa: clean up aborts
[cascardo/linux.git] / drivers / scsi / hpsa.c
index 8eab107..ae9d9e1 100644 (file)
@@ -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);
@@ -252,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)
 {
@@ -425,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 */
@@ -467,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)
@@ -493,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)
 {
@@ -667,6 +684,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 +701,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,
@@ -743,30 +764,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;
+               else
+                       c->Header.ReplyQueue = reply_queue % h->nreply_queues;
        }
 }
 
 static void set_ioaccel1_performant_mode(struct ctlr_info *h,
-                                               struct CommandList *c)
+                                               struct CommandList *c,
+                                               int reply_queue)
 {
        struct io_accel1_cmd *cp = &h->ioaccel_cmd_pool[c->cmdindex];
 
-       /* Tell the controller to post the reply to the queue for this
+       /*
+        * Tell the controller to post the reply to the queue for this
         * processor.  This seems to give the best I/O throughput.
         */
-       cp->ReplyQueue = smp_processor_id() % h->nreply_queues;
-       /* Set the bits in the address sent down to include:
+       if (likely(reply_queue == DEFAULT_REPLY_QUEUE))
+               cp->ReplyQueue = smp_processor_id() % h->nreply_queues;
+       else
+               cp->ReplyQueue = reply_queue % h->nreply_queues;
+       /*
+        * Set the bits in the address sent down to include:
         *  - performant mode bit (bit 0)
         *  - pull count (bits 1-3)
         *  - command type (bits 4-6)
@@ -776,15 +810,21 @@ static void set_ioaccel1_performant_mode(struct ctlr_info *h,
 }
 
 static void set_ioaccel2_performant_mode(struct ctlr_info *h,
-                                               struct CommandList *c)
+                                               struct CommandList *c,
+                                               int reply_queue)
 {
        struct io_accel2_cmd *cp = &h->ioaccel2_cmd_pool[c->cmdindex];
 
-       /* Tell the controller to post the reply to the queue for this
+       /*
+        * Tell the controller to post the reply to the queue for this
         * processor.  This seems to give the best I/O throughput.
         */
-       cp->reply_queue = smp_processor_id() % h->nreply_queues;
-       /* Set the bits in the address sent down to include:
+       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
@@ -821,26 +861,32 @@ static void dial_up_lockup_detection_on_fw_flash_complete(struct ctlr_info *h,
                h->heartbeat_sample_interval = HEARTBEAT_SAMPLE_INTERVAL;
 }
 
-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, int reply_queue)
 {
        dial_down_lockup_detection_during_fw_flash(h, c);
        atomic_inc(&h->commands_outstanding);
        switch (c->cmd_type) {
        case CMD_IOACCEL1:
-               set_ioaccel1_performant_mode(h, c);
+               set_ioaccel1_performant_mode(h, c, reply_queue);
                writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET);
                break;
        case CMD_IOACCEL2:
-               set_ioaccel2_performant_mode(h, c);
+               set_ioaccel2_performant_mode(h, c, reply_queue);
                writel(c->busaddr, h->vaddr + IOACCEL2_INBOUND_POSTQ_32);
                break;
        default:
-               set_performant_mode(h, c);
+               set_performant_mode(h, c, reply_queue);
                h->access.submit_command(h, c);
        }
 }
 
+static void enqueue_cmd_and_start_io(struct ctlr_info *h,
+                                       struct CommandList *c)
+{
+       __enqueue_cmd_and_start_io(h, c, DEFAULT_REPLY_QUEUE);
+}
+
 static inline int is_hba_lunid(unsigned char scsi3addr[])
 {
        return memcmp(scsi3addr, RAID_CTLR_LUNID, 8) == 0;
@@ -881,6 +927,23 @@ static int hpsa_find_target_lun(struct ctlr_info *h,
        return !found;
 }
 
+static inline void hpsa_show_dev_msg(const char *level, struct ctlr_info *h,
+       struct hpsa_scsi_dev_t *dev, char *description)
+{
+       dev_printk(level, &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,
@@ -946,17 +1009,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)++;
-
-       /* 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(KERN_INFO, h, device,
+               device->expose_state & HPSA_SCSI_ADD ? "added" : "masked");
        return 0;
 }
 
@@ -982,16 +1040,21 @@ 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;
+
+       hpsa_show_dev_msg(KERN_INFO, h, h->dev[entry], "updated");
 }
 
 /* Replace an entry from h->dev[] array. */
@@ -1014,12 +1077,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)++;
-       dev_info(&h->pdev->dev, "%s device c%db%dt%dl%d changed.\n",
-               scsi_device_type(new_entry->devtype), hostno, new_entry->bus,
-                       new_entry->target, new_entry->lun);
+       hpsa_show_dev_msg(KERN_INFO, h, new_entry, "replaced");
 }
 
 /* Remove an entry from h->dev[] array. */
@@ -1039,9 +1102,7 @@ static void hpsa_scsi_remove_entry(struct ctlr_info *h, int hostno, int entry,
        for (i = entry; i < h->ndevices-1; i++)
                h->dev[i] = h->dev[i+1];
        h->ndevices--;
-       dev_info(&h->pdev->dev, "%s device c%db%dt%dl%d removed.\n",
-               scsi_device_type(sd->devtype), hostno, sd->bus, sd->target,
-               sd->lun);
+       hpsa_show_dev_msg(KERN_INFO, h, sd, "removed");
 }
 
 #define SCSI3ADDR_EQ(a, b) ( \
@@ -1312,7 +1373,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;
+                       logical_drive->queue_depth = 8;
                }
        }
        if (nraid_map_entries)
@@ -1335,6 +1397,16 @@ static void hpsa_update_log_drive_phys_drive_ptrs(struct ctlr_info *h,
                        continue;
                if (!is_logical_dev_addr_mode(dev[i]->scsi3addr))
                        continue;
+
+               /*
+                * If offload is currently enabled, the RAID map and
+                * phys_disk[] assignment *better* not be changing
+                * and since it isn't changing, we do not need to
+                * update it.
+                */
+               if (dev[i]->offload_enabled)
+                       continue;
+
                hpsa_figure_phys_disk_ptrs(h, dev, ndevices, dev[i]);
        }
 }
@@ -1411,9 +1483,7 @@ static void adjust_hpsa_scsi_table(struct ctlr_info *h, int hostno,
                 */
                if (sd[i]->volume_offline) {
                        hpsa_show_volume_status(h, sd[i]);
-                       dev_info(&h->pdev->dev, "c%db%dt%dl%d: temporarily offline\n",
-                               h->scsi_host->host_no,
-                               sd[i]->bus, sd[i]->target, sd[i]->lun);
+                       hpsa_show_dev_msg(KERN_INFO, h, sd[i], "offline");
                        continue;
                }
 
@@ -1433,6 +1503,14 @@ static void adjust_hpsa_scsi_table(struct ctlr_info *h, int hostno,
                        /* but if it does happen, we just ignore that device */
                }
        }
+       hpsa_update_log_drive_phys_drive_ptrs(h, h->dev, h->ndevices);
+
+       /* Now that h->dev[]->phys_disk[] is coherent, we can enable
+        * any logical drives that need it enabled.
+        */
+       for (i = 0; i < h->ndevices; i++)
+               h->dev[i]->offload_enabled = h->dev[i]->offload_to_be_enabled;
+
        spin_unlock_irqrestore(&h->devlock, flags);
 
        /* Monitor devices which are in one of several NOT READY states to be
@@ -1456,20 +1534,22 @@ static void adjust_hpsa_scsi_table(struct ctlr_info *h, int hostno,
        sh = h->scsi_host;
        /* Notify scsi mid layer of any removed devices */
        for (i = 0; i < nremoved; i++) {
-               struct scsi_device *sdev =
-                       scsi_device_lookup(sh, removed[i]->bus,
-                               removed[i]->target, removed[i]->lun);
-               if (sdev != NULL) {
-                       scsi_remove_device(sdev);
-                       scsi_device_put(sdev);
-               } else {
-                       /* We don't expect to get here.
-                        * future cmds to this device will get selection
-                        * timeout as if the device was gone.
-                        */
-                       dev_warn(&h->pdev->dev, "didn't find c%db%dt%dl%d "
-                               " for removal.", hostno, removed[i]->bus,
-                               removed[i]->target, removed[i]->lun);
+               if (removed[i]->expose_state & HPSA_SCSI_ADD) {
+                       struct scsi_device *sdev =
+                               scsi_device_lookup(sh, removed[i]->bus,
+                                       removed[i]->target, removed[i]->lun);
+                       if (sdev != NULL) {
+                               scsi_remove_device(sdev);
+                               scsi_device_put(sdev);
+                       } else {
+                               /*
+                                * We don't expect to get here.
+                                * future cmds to this device will get selection
+                                * timeout as if the device was gone.
+                                */
+                               hpsa_show_dev_msg(KERN_WARNING, h, removed[i],
+                                       "didn't find device for removal.");
+                       }
                }
                kfree(removed[i]);
                removed[i] = NULL;
@@ -1477,12 +1557,13 @@ static void adjust_hpsa_scsi_table(struct ctlr_info *h, int hostno,
 
        /* Notify scsi mid layer of any added devices */
        for (i = 0; i < nadded; i++) {
+               if (!(added[i]->expose_state & HPSA_SCSI_ADD))
+                       continue;
                if (scsi_add_device(sh, added[i]->bus,
                        added[i]->target, added[i]->lun) == 0)
                        continue;
-               dev_warn(&h->pdev->dev, "scsi_add_device c%db%dt%dl%d failed, "
-                       "device not added.\n", hostno, added[i]->bus,
-                       added[i]->target, added[i]->lun);
+               hpsa_show_dev_msg(KERN_WARNING, h, added[i],
+                                       "addition failed, device not added.");
                /* now we have to remove it from h->dev,
                 * since it didn't get added to scsi mid layer
                 */
@@ -1512,7 +1593,6 @@ static struct hpsa_scsi_dev_t *lookup_hpsa_scsi_dev(struct ctlr_info *h,
        return NULL;
 }
 
-/* link sdev->hostdata to our per-device structure. */
 static int hpsa_slave_alloc(struct scsi_device *sdev)
 {
        struct hpsa_scsi_dev_t *sd;
@@ -1523,16 +1603,35 @@ static int hpsa_slave_alloc(struct scsi_device *sdev)
        spin_lock_irqsave(&h->devlock, flags);
        sd = lookup_hpsa_scsi_dev(h, sdev_channel(sdev),
                sdev_id(sdev), sdev->lun);
-       if (sd != NULL) {
-               sdev->hostdata = sd;
-               if (sd->queue_depth)
-                       scsi_change_queue_depth(sdev, sd->queue_depth);
+       if (likely(sd)) {
                atomic_set(&sd->ioaccel_cmds_out, 0);
-       }
+               sdev->hostdata = (sd->expose_state & HPSA_SCSI_ADD) ? sd : NULL;
+       } else
+               sdev->hostdata = NULL;
        spin_unlock_irqrestore(&h->devlock, flags);
        return 0;
 }
 
+/* configure scsi device based on internal per-device structure */
+static int hpsa_slave_configure(struct scsi_device *sdev)
+{
+       struct hpsa_scsi_dev_t *sd;
+       int queue_depth;
+
+       sd = sdev->hostdata;
+       sdev->no_uld_attach = !sd || !(sd->expose_state & HPSA_ULD_ATTACH);
+
+       if (sd)
+               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);
+
+       return 0;
+}
+
 static void hpsa_slave_destroy(struct scsi_device *sdev)
 {
        /* nothing to do. */
@@ -1784,6 +1883,19 @@ static void complete_scsi_command(struct CommandList *cp)
        if (cp->cmd_type == CMD_IOACCEL2 || cp->cmd_type == CMD_IOACCEL1)
                atomic_dec(&cp->phys_disk->ioaccel_cmds_out);
 
+       /*
+        * We check for lockup status here as it may be set for
+        * CMD_SCSI, CMD_IOACCEL1 and CMD_IOACCEL2 commands by
+        * fail_all_oustanding_cmds()
+        */
+       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;
+       }
+
        if (cp->cmd_type == CMD_IOACCEL2)
                return process_ioaccel2_completion(h, cp, cmd, dev);
 
@@ -1998,14 +2110,36 @@ static int hpsa_map_one(struct pci_dev *pdev,
        return 0;
 }
 
-static inline void hpsa_scsi_do_simple_cmd_core(struct ctlr_info *h,
-       struct CommandList *c)
+#define NO_TIMEOUT ((unsigned long) -1)
+#define DEFAULT_TIMEOUT 30000 /* milliseconds */
+static int hpsa_scsi_do_simple_cmd_core(struct ctlr_info *h,
+       struct CommandList *c, int reply_queue, unsigned long timeout_msecs)
 {
        DECLARE_COMPLETION_ONSTACK(wait);
 
        c->waiting = &wait;
-       enqueue_cmd_and_start_io(h, c);
-       wait_for_completion(&wait);
+       __enqueue_cmd_and_start_io(h, c, reply_queue);
+       if (timeout_msecs == NO_TIMEOUT) {
+               /* TODO: get rid of this no-timeout thing */
+               wait_for_completion_io(&wait);
+               return IO_OK;
+       }
+       if (!wait_for_completion_io_timeout(&wait,
+                                       msecs_to_jiffies(timeout_msecs))) {
+               dev_warn(&h->pdev->dev, "Command timed out.\n");
+               return -ETIMEDOUT;
+       }
+       return IO_OK;
+}
+
+static int hpsa_scsi_do_simple_cmd(struct ctlr_info *h, struct CommandList *c,
+                                  int reply_queue, unsigned long timeout_msecs)
+{
+       if (unlikely(lockup_detected(h))) {
+               c->err_info->CommandStatus = CMD_CTLR_LOCKUP;
+               return IO_OK;
+       }
+       return hpsa_scsi_do_simple_cmd_core(h, c, reply_queue, timeout_msecs);
 }
 
 static u32 lockup_detected(struct ctlr_info *h)
@@ -2020,25 +2154,19 @@ static u32 lockup_detected(struct ctlr_info *h)
        return rc;
 }
 
-static void hpsa_scsi_do_simple_cmd_core_if_no_lockup(struct ctlr_info *h,
-       struct CommandList *c)
-{
-       /* If controller lockup detected, fake a hardware error. */
-       if (unlikely(lockup_detected(h)))
-               c->err_info->CommandStatus = CMD_HARDWARE_ERR;
-       else
-               hpsa_scsi_do_simple_cmd_core(h, c);
-}
-
 #define MAX_DRIVER_CMD_RETRIES 25
-static void hpsa_scsi_do_simple_cmd_with_retry(struct ctlr_info *h,
-       struct CommandList *c, int data_direction)
+static int hpsa_scsi_do_simple_cmd_with_retry(struct ctlr_info *h,
+       struct CommandList *c, int data_direction, unsigned long timeout_msecs)
 {
        int backoff_time = 10, retry_count = 0;
+       int rc;
 
        do {
                memset(c->err_info, 0, sizeof(*c->err_info));
-               hpsa_scsi_do_simple_cmd_core(h, c);
+               rc = hpsa_scsi_do_simple_cmd(h, c, DEFAULT_REPLY_QUEUE,
+                                                 timeout_msecs);
+               if (rc)
+                       break;
                retry_count++;
                if (retry_count > 3) {
                        msleep(backoff_time);
@@ -2049,6 +2177,9 @@ static void hpsa_scsi_do_simple_cmd_with_retry(struct ctlr_info *h,
                        check_for_busy(h, c)) &&
                        retry_count <= MAX_DRIVER_CMD_RETRIES);
        hpsa_pci_unmap(h->pdev, c, 1, data_direction);
+       if (retry_count > MAX_DRIVER_CMD_RETRIES)
+               rc = -EIO;
+       return rc;
 }
 
 static void hpsa_print_cmd(struct ctlr_info *h, char *txt,
@@ -2125,6 +2256,9 @@ static void hpsa_scsi_interpret_error(struct ctlr_info *h,
        case CMD_UNABORTABLE:
                hpsa_print_cmd(h, "unabortable", cp);
                break;
+       case CMD_CTLR_LOCKUP:
+               hpsa_print_cmd(h, "controller lockup detected", cp);
+               break;
        default:
                hpsa_print_cmd(h, "unknown status", cp);
                dev_warn(d, "Unknown command status %x\n",
@@ -2152,7 +2286,10 @@ static int hpsa_scsi_do_inquiry(struct ctlr_info *h, unsigned char *scsi3addr,
                rc = -1;
                goto out;
        }
-       hpsa_scsi_do_simple_cmd_with_retry(h, c, PCI_DMA_FROMDEVICE);
+       rc = hpsa_scsi_do_simple_cmd_with_retry(h, c,
+                                       PCI_DMA_FROMDEVICE, NO_TIMEOUT);
+       if (rc)
+               goto out;
        ei = c->err_info;
        if (ei->CommandStatus != 0 && ei->CommandStatus != CMD_DATA_UNDERRUN) {
                hpsa_scsi_interpret_error(h, c);
@@ -2182,7 +2319,10 @@ static int hpsa_bmic_ctrl_mode_sense(struct ctlr_info *h,
                rc = -1;
                goto out;
        }
-       hpsa_scsi_do_simple_cmd_with_retry(h, c, PCI_DMA_FROMDEVICE);
+       rc = hpsa_scsi_do_simple_cmd_with_retry(h, c,
+                       PCI_DMA_FROMDEVICE, NO_TIMEOUT);
+       if (rc)
+               goto out;
        ei = c->err_info;
        if (ei->CommandStatus != 0 && ei->CommandStatus != CMD_DATA_UNDERRUN) {
                hpsa_scsi_interpret_error(h, c);
@@ -2194,7 +2334,7 @@ out:
        }
 
 static int hpsa_send_reset(struct ctlr_info *h, unsigned char *scsi3addr,
-       u8 reset_type)
+       u8 reset_type, int reply_queue)
 {
        int rc = IO_OK;
        struct CommandList *c;
@@ -2211,7 +2351,11 @@ static int hpsa_send_reset(struct ctlr_info *h, unsigned char *scsi3addr,
        (void) fill_cmd(c, HPSA_DEVICE_RESET_MSG, h, NULL, 0, 0,
                        scsi3addr, TYPE_MSG);
        c->Request.CDB[1] = reset_type; /* fill_cmd defaults to LUN reset */
-       hpsa_scsi_do_simple_cmd_core(h, c);
+       rc = hpsa_scsi_do_simple_cmd(h, c, reply_queue, NO_TIMEOUT);
+       if (rc) {
+               dev_warn(&h->pdev->dev, "Failed to send reset command\n");
+               goto out;
+       }
        /* no unmap needed here because no data xfer. */
 
        ei = c->err_info;
@@ -2219,6 +2363,7 @@ static int hpsa_send_reset(struct ctlr_info *h, unsigned char *scsi3addr,
                hpsa_scsi_interpret_error(h, c);
                rc = -1;
        }
+out:
        cmd_free(h, c);
        return rc;
 }
@@ -2336,15 +2481,18 @@ static int hpsa_get_raid_map(struct ctlr_info *h,
                        sizeof(this_device->raid_map), 0,
                        scsi3addr, TYPE_CMD)) {
                dev_warn(&h->pdev->dev, "Out of memory in hpsa_get_raid_map()\n");
-               cmd_free(h, c);
-               return -ENOMEM;
+               rc = -ENOMEM;
+               goto out;
        }
-       hpsa_scsi_do_simple_cmd_with_retry(h, c, PCI_DMA_FROMDEVICE);
+       rc = hpsa_scsi_do_simple_cmd_with_retry(h, c,
+                                       PCI_DMA_FROMDEVICE, NO_TIMEOUT);
+       if (rc)
+               goto out;
        ei = c->err_info;
        if (ei->CommandStatus != 0 && ei->CommandStatus != CMD_DATA_UNDERRUN) {
                hpsa_scsi_interpret_error(h, c);
-               cmd_free(h, c);
-               return -1;
+               rc = -1;
+               goto out;
        }
        cmd_free(h, c);
 
@@ -2356,6 +2504,9 @@ static int hpsa_get_raid_map(struct ctlr_info *h,
        }
        hpsa_debug_map_buff(h, rc, &this_device->raid_map);
        return rc;
+out:
+       cmd_free(h, c);
+       return rc;
 }
 
 static int hpsa_bmic_id_physical_device(struct ctlr_info *h,
@@ -2375,7 +2526,8 @@ static int hpsa_bmic_id_physical_device(struct ctlr_info *h,
        c->Request.CDB[2] = bmic_device_index & 0xff;
        c->Request.CDB[9] = (bmic_device_index >> 8) & 0xff;
 
-       hpsa_scsi_do_simple_cmd_with_retry(h, c, PCI_DMA_FROMDEVICE);
+       hpsa_scsi_do_simple_cmd_with_retry(h, c, PCI_DMA_FROMDEVICE,
+                                               NO_TIMEOUT);
        ei = c->err_info;
        if (ei->CommandStatus != 0 && ei->CommandStatus != CMD_DATA_UNDERRUN) {
                hpsa_scsi_interpret_error(h, c);
@@ -2438,6 +2590,7 @@ static void hpsa_get_ioaccel_status(struct ctlr_info *h,
 
        this_device->offload_config = 0;
        this_device->offload_enabled = 0;
+       this_device->offload_to_be_enabled = 0;
 
        buf = kzalloc(64, GFP_KERNEL);
        if (!buf)
@@ -2461,6 +2614,7 @@ static void hpsa_get_ioaccel_status(struct ctlr_info *h,
                if (hpsa_get_raid_map(h, scsi3addr, this_device))
                        this_device->offload_enabled = 0;
        }
+       this_device->offload_to_be_enabled = this_device->offload_enabled;
 out:
        kfree(buf);
        return;
@@ -2508,7 +2662,10 @@ static int hpsa_scsi_do_report_luns(struct ctlr_info *h, int logical,
        }
        if (extended_response)
                c->Request.CDB[1] = extended_response;
-       hpsa_scsi_do_simple_cmd_with_retry(h, c, PCI_DMA_FROMDEVICE);
+       rc = hpsa_scsi_do_simple_cmd_with_retry(h, c,
+                                       PCI_DMA_FROMDEVICE, NO_TIMEOUT);
+       if (rc)
+               goto out;
        ei = c->err_info;
        if (ei->CommandStatus != 0 &&
            ei->CommandStatus != CMD_DATA_UNDERRUN) {
@@ -2601,7 +2758,7 @@ static int hpsa_volume_offline(struct ctlr_info *h,
 {
        struct CommandList *c;
        unsigned char *sense, sense_key, asc, ascq;
-       int ldstat = 0;
+       int rc, ldstat = 0;
        u16 cmd_status;
        u8 scsi_status;
 #define ASC_LUN_NOT_READY 0x04
@@ -2612,7 +2769,11 @@ static int hpsa_volume_offline(struct ctlr_info *h,
        if (!c)
                return 0;
        (void) fill_cmd(c, TEST_UNIT_READY, h, NULL, 0, 0, scsi3addr, TYPE_CMD);
-       hpsa_scsi_do_simple_cmd_core(h, c);
+       rc = hpsa_scsi_do_simple_cmd(h, c, DEFAULT_REPLY_QUEUE, NO_TIMEOUT);
+       if (rc) {
+               cmd_free(h, c);
+               return 0;
+       }
        sense = c->err_info->SenseInfo;
        sense_key = sense[2];
        asc = sense[12];
@@ -2656,6 +2817,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);
+       (void) hpsa_scsi_do_simple_cmd(h, c, DEFAULT_REPLY_QUEUE, NO_TIMEOUT);
+       /* no unmap needed here because no data xfer. */
+       ei = c->err_info;
+       switch (ei->CommandStatus) {
+       case CMD_INVALID:
+               rc = 0;
+               break;
+       case CMD_UNABORTABLE:
+       case CMD_ABORT_FAILED:
+               rc = 1;
+               break;
+       default:
+               rc = 0;
+               break;
+       }
+       cmd_free(h, c);
+       return rc;
+}
+
 static int hpsa_update_device_info(struct ctlr_info *h,
        unsigned char scsi3addr[], struct hpsa_scsi_dev_t *this_device,
        unsigned char *is_OBDR_device)
@@ -2708,6 +2913,7 @@ static int hpsa_update_device_info(struct ctlr_info *h,
                this_device->raid_level = RAID_UNKNOWN;
                this_device->offload_config = 0;
                this_device->offload_enabled = 0;
+               this_device->offload_to_be_enabled = 0;
                this_device->volume_offline = 0;
                this_device->queue_depth = h->nr_cmds;
        }
@@ -2721,7 +2927,6 @@ static int hpsa_update_device_info(struct ctlr_info *h,
                                        strncmp(obdr_sig, OBDR_TAPE_SIG,
                                                OBDR_SIG_LEN) == 0);
        }
-
        kfree(inq_buff);
        return 0;
 
@@ -2730,6 +2935,31 @@ bail_out:
        return 1;
 }
 
+static void hpsa_update_device_supports_aborts(struct ctlr_info *h,
+                       struct hpsa_scsi_dev_t *dev, u8 *scsi3addr)
+{
+       unsigned long flags;
+       int rc, entry;
+       /*
+        * See if this device supports aborts.  If we already know
+        * the device, we already know if it supports aborts, otherwise
+        * we have to find out if it supports aborts by trying one.
+        */
+       spin_lock_irqsave(&h->devlock, flags);
+       rc = hpsa_scsi_find_entry(dev, h->dev, h->ndevices, &entry);
+       if ((rc == DEVICE_SAME || rc == DEVICE_UPDATED) &&
+               entry >= 0 && entry < h->ndevices) {
+               dev->supports_aborts = h->dev[entry]->supports_aborts;
+               spin_unlock_irqrestore(&h->devlock, flags);
+       } else {
+               spin_unlock_irqrestore(&h->devlock, flags);
+               dev->supports_aborts =
+                               hpsa_device_supports_aborts(h, scsi3addr);
+               if (dev->supports_aborts < 0)
+                       dev->supports_aborts = 0;
+       }
+}
+
 static unsigned char *ext_target_model[] = {
        "MSA2012",
        "MSA2024",
@@ -2835,6 +3065,7 @@ static int add_ext_target_dev(struct ctlr_info *h,
        (*n_ext_target_devs)++;
        hpsa_set_bus_target_lun(this_device,
                                tmpdevice->bus, tmpdevice->target, 0);
+       hpsa_update_device_supports_aborts(h, this_device, scsi3addr);
        set_bit(tmpdevice->target, lunzerobits);
        return 1;
 }
@@ -2850,88 +3081,23 @@ static int add_ext_target_dev(struct ctlr_info *h,
 static int hpsa_get_pdisk_of_ioaccel2(struct ctlr_info *h,
        struct CommandList *ioaccel2_cmd_to_abort, unsigned char *scsi3addr)
 {
-       struct ReportExtendedLUNdata *physicals = NULL;
-       int responsesize = 24;  /* size of physical extended response */
-       int reportsize = sizeof(*physicals) + HPSA_MAX_PHYS_LUN * responsesize;
-       u32 nphysicals = 0;     /* number of reported physical devs */
-       int found = 0;          /* found match (1) or not (0) */
-       u32 find;               /* handle we need to match */
+       struct io_accel2_cmd *c2 =
+                       &h->ioaccel2_cmd_pool[ioaccel2_cmd_to_abort->cmdindex];
+       unsigned long flags;
        int i;
-       struct scsi_cmnd *scmd; /* scsi command within request being aborted */
-       struct hpsa_scsi_dev_t *d; /* device of request being aborted */
-       struct io_accel2_cmd *c2a; /* ioaccel2 command to abort */
-       __le32 it_nexus;        /* 4 byte device handle for the ioaccel2 cmd */
-       __le32 scsi_nexus;      /* 4 byte device handle for the ioaccel2 cmd */
-
-       if (ioaccel2_cmd_to_abort->cmd_type != CMD_IOACCEL2)
-               return 0; /* no match */
-
-       /* point to the ioaccel2 device handle */
-       c2a = &h->ioaccel2_cmd_pool[ioaccel2_cmd_to_abort->cmdindex];
-       if (c2a == NULL)
-               return 0; /* no match */
-
-       scmd = (struct scsi_cmnd *) ioaccel2_cmd_to_abort->scsi_cmd;
-       if (scmd == NULL)
-               return 0; /* no match */
-
-       d = scmd->device->hostdata;
-       if (d == NULL)
-               return 0; /* no match */
-
-       it_nexus = cpu_to_le32(d->ioaccel_handle);
-       scsi_nexus = c2a->scsi_nexus;
-       find = le32_to_cpu(c2a->scsi_nexus);
-
-       if (h->raid_offload_debug > 0)
-               dev_info(&h->pdev->dev,
-                       "%s: scsi_nexus:0x%08x device id: 0x%02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x\n",
-                       __func__, scsi_nexus,
-                       d->device_id[0], d->device_id[1], d->device_id[2],
-                       d->device_id[3], d->device_id[4], d->device_id[5],
-                       d->device_id[6], d->device_id[7], d->device_id[8],
-                       d->device_id[9], d->device_id[10], d->device_id[11],
-                       d->device_id[12], d->device_id[13], d->device_id[14],
-                       d->device_id[15]);
-
-       /* Get the list of physical devices */
-       physicals = kzalloc(reportsize, GFP_KERNEL);
-       if (physicals == NULL)
-               return 0;
-       if (hpsa_scsi_do_report_phys_luns(h, physicals, reportsize)) {
-               dev_err(&h->pdev->dev,
-                       "Can't lookup %s device handle: report physical LUNs failed.\n",
-                       "HP SSD Smart Path");
-               kfree(physicals);
-               return 0;
-       }
-       nphysicals = be32_to_cpu(*((__be32 *)physicals->LUNListLength)) /
-                                                       responsesize;
-
-       /* find ioaccel2 handle in list of physicals: */
-       for (i = 0; i < nphysicals; i++) {
-               struct ext_report_lun_entry *entry = &physicals->LUN[i];
-
-               /* handle is in bytes 28-31 of each lun */
-               if (entry->ioaccel_handle != find)
-                       continue; /* didn't match */
-               found = 1;
-               memcpy(scsi3addr, entry->lunid, 8);
-               if (h->raid_offload_debug > 0)
-                       dev_info(&h->pdev->dev,
-                               "%s: Searched h=0x%08x, Found h=0x%08x, scsiaddr 0x%8phN\n",
-                               __func__, find,
-                               entry->ioaccel_handle, scsi3addr);
-               break; /* found it */
-       }
-
-       kfree(physicals);
-       if (found)
-               return 1;
-       else
-               return 0;
 
+       spin_lock_irqsave(&h->devlock, flags);
+       for (i = 0; i < h->ndevices; i++)
+               if (h->dev[i]->ioaccel_handle == le32_to_cpu(c2->scsi_nexus)) {
+                       memcpy(scsi3addr, h->dev[i]->scsi3addr,
+                               sizeof(h->dev[i]->scsi3addr));
+                       spin_unlock_irqrestore(&h->devlock, flags);
+                       return 1;
+               }
+       spin_unlock_irqrestore(&h->devlock, flags);
+       return 0;
 }
+
 /*
  * Do CISS_REPORT_PHYS and CISS_REPORT_LOG.  Data is returned in physdev,
  * logdev.  The number of luns in physdev and logdev are returned in
@@ -3142,16 +3308,19 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
                /* Figure out where the LUN ID info is coming from */
                lunaddrbytes = figure_lunaddrbytes(h, raid_ctlr_position,
                        i, nphysicals, nlogicals, physdev_list, logdev_list);
-               /* skip masked physical devices. */
-               if (lunaddrbytes[3] & 0xC0 &&
-                       i < nphysicals + (raid_ctlr_position == 0))
-                       continue;
+
+               /* skip masked non-disk devices */
+               if (MASKED_DEVICE(lunaddrbytes))
+                       if (i < nphysicals + (raid_ctlr_position == 0) &&
+                               NON_DISK_PHYS_DEV(lunaddrbytes))
+                               continue;
 
                /* Get device type, vendor, model, device id */
                if (hpsa_update_device_info(h, lunaddrbytes, tmpdevice,
                                                        &is_OBDR))
                        continue; /* skip it if we can't talk to it. */
                figure_bus_target_lun(h, lunaddrbytes, tmpdevice);
+               hpsa_update_device_supports_aborts(h, tmpdevice, lunaddrbytes);
                this_device = currentsd[ncurrent];
 
                /*
@@ -3170,6 +3339,18 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
 
                *this_device = *tmpdevice;
 
+               /* do not expose masked devices */
+               if (MASKED_DEVICE(lunaddrbytes) &&
+                       i < nphysicals + (raid_ctlr_position == 0)) {
+                       if (h->hba_mode_enabled)
+                               dev_warn(&h->pdev->dev,
+                                       "Masked physical device detected\n");
+                       this_device->expose_state = HPSA_DO_NOT_EXPOSE;
+               } else {
+                       this_device->expose_state =
+                                       HPSA_SG_ATTACH | HPSA_ULD_ATTACH;
+               }
+
                switch (this_device->devtype) {
                case TYPE_ROM:
                        /* We don't *really* support actual CD-ROM devices,
@@ -3211,6 +3392,10 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
                case TYPE_MEDIUM_CHANGER:
                        ncurrent++;
                        break;
+               case TYPE_ENCLOSURE:
+                       if (h->hba_mode_enabled)
+                               ncurrent++;
+                       break;
                case TYPE_RAID:
                        /* Only present the Smartarray HBA as a RAID controller.
                         * If it's a RAID controller other than the HBA itself
@@ -3227,7 +3412,6 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
                if (ncurrent >= HPSA_MAX_DEVICES)
                        break;
        }
-       hpsa_update_log_drive_phys_drive_ptrs(h, currentsd, ncurrent);
        adjust_hpsa_scsi_table(h, hostno, currentsd, ncurrent);
 out:
        kfree(tmpdevice);
@@ -3992,7 +4176,11 @@ static int hpsa_scsi_ioaccel_raid_map(struct ctlr_info *h,
                                                dev->phys_disk[map_index]);
 }
 
-/* Submit commands down the "normal" RAID stack path */
+/*
+ * Submit commands down the "normal" RAID stack path
+ * All callers to hpsa_ciss_submit must check lockup_detected
+ * beforehand, before (opt.) and after calling cmd_alloc
+ */
 static int hpsa_ciss_submit(struct ctlr_info *h,
        struct CommandList *c, struct scsi_cmnd *cmd,
        unsigned char scsi3addr[])
@@ -4103,7 +4291,7 @@ static int hpsa_scsi_queue_command(struct Scsi_Host *sh, struct scsi_cmnd *cmd)
        memcpy(scsi3addr, dev->scsi3addr, sizeof(scsi3addr));
 
        if (unlikely(lockup_detected(h))) {
-               cmd->result = DID_ERROR << 16;
+               cmd->result = DID_NO_CONNECT << 16;
                cmd->scsi_done(cmd);
                return 0;
        }
@@ -4113,7 +4301,7 @@ static int hpsa_scsi_queue_command(struct Scsi_Host *sh, struct scsi_cmnd *cmd)
                return SCSI_MLQUEUE_HOST_BUSY;
        }
        if (unlikely(lockup_detected(h))) {
-               cmd->result = DID_ERROR << 16;
+               cmd->result = DID_NO_CONNECT << 16;
                cmd_free(h, c);
                cmd->scsi_done(cmd);
                return 0;
@@ -4252,10 +4440,7 @@ static int hpsa_register_scsi(struct ctlr_info *h)
        sh->max_cmd_len = MAX_COMMAND_SIZE;
        sh->max_lun = HPSA_MAX_LUN;
        sh->max_id = HPSA_MAX_LUN;
-       sh->can_queue = h->nr_cmds -
-                       HPSA_CMDS_RESERVED_FOR_ABORTS -
-                       HPSA_CMDS_RESERVED_FOR_DRIVER -
-                       HPSA_MAX_CONCURRENT_PASSTHRUS;
+       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;
@@ -4311,7 +4496,10 @@ static int wait_for_device_to_become_ready(struct ctlr_info *h,
                /* 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);
-               hpsa_scsi_do_simple_cmd_core(h, c);
+               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. */
 
                if (c->err_info->CommandStatus == CMD_SUCCESS)
@@ -4322,7 +4510,7 @@ static int wait_for_device_to_become_ready(struct ctlr_info *h,
                        (c->err_info->SenseInfo[2] == NO_SENSE ||
                        c->err_info->SenseInfo[2] == UNIT_ATTENTION))
                        break;
-
+do_it_again:
                dev_warn(&h->pdev->dev, "waiting %d secs "
                        "for device to become ready.\n", waittime);
                rc = 1; /* device not ready. */
@@ -4360,14 +4548,36 @@ static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
                        "device lookup failed.\n");
                return FAILED;
        }
-       dev_warn(&h->pdev->dev, "resetting device %d:%d:%d:%d\n",
-               h->scsi_host->host_no, dev->bus, dev->target, dev->lun);
+
+       /* if controller locked up, we can guarantee command won't complete */
+       if (lockup_detected(h)) {
+               dev_warn(&h->pdev->dev,
+                       "scsi %d:%d:%d:%d RESET FAILED, lockup detected\n",
+                       h->scsi_host->host_no, dev->bus, dev->target,
+                       dev->lun);
+               return FAILED;
+       }
+
+       /* this reset request might be the result of a lockup; check */
+       if (detect_controller_lockup(h)) {
+               dev_warn(&h->pdev->dev,
+                        "scsi %d:%d:%d:%d RESET FAILED, new lockup detected\n",
+                        h->scsi_host->host_no, dev->bus, dev->target,
+                        dev->lun);
+               return FAILED;
+       }
+
+       hpsa_show_dev_msg(KERN_WARNING, h, dev, "resetting");
+
        /* send a reset to the SCSI LUN which the command was sent to */
-       rc = hpsa_send_reset(h, dev->scsi3addr, HPSA_RESET_TYPE_LUN);
+       rc = hpsa_send_reset(h, dev->scsi3addr, HPSA_RESET_TYPE_LUN,
+                            DEFAULT_REPLY_QUEUE);
        if (rc == 0 && wait_for_device_to_become_ready(h, dev->scsi3addr) == 0)
                return SUCCESS;
 
-       dev_warn(&h->pdev->dev, "resetting device failed.\n");
+       dev_warn(&h->pdev->dev,
+               "scsi %d:%d:%d:%d reset failed\n",
+               h->scsi_host->host_no, dev->bus, dev->target, dev->lun);
        return FAILED;
 }
 
@@ -4412,7 +4622,7 @@ static void hpsa_get_tag(struct ctlr_info *h,
 }
 
 static int hpsa_send_abort(struct ctlr_info *h, unsigned char *scsi3addr,
-       struct CommandList *abort, int swizzle)
+       struct CommandList *abort, int reply_queue)
 {
        int rc = IO_OK;
        struct CommandList *c;
@@ -4426,13 +4636,13 @@ static int hpsa_send_abort(struct ctlr_info *h, unsigned char *scsi3addr,
        }
 
        /* fill_cmd can't fail here, no buffer to map */
-       (void) fill_cmd(c, HPSA_ABORT_MSG, h, abort,
+       (void) fill_cmd(c, HPSA_ABORT_MSG, h, &abort->Header.tag,
                0, 0, scsi3addr, TYPE_MSG);
-       if (swizzle)
+       if (h->needs_abort_tags_swizzled)
                swizzle_abort_tag(&c->Request.CDB[4]);
-       hpsa_scsi_do_simple_cmd_core(h, c);
+       (void) hpsa_scsi_do_simple_cmd(h, c, reply_queue, NO_TIMEOUT);
        hpsa_get_tag(h, abort, &taglower, &tagupper);
-       dev_dbg(&h->pdev->dev, "%s: Tag:0x%08x:%08x: do_simple_cmd_core completed.\n",
+       dev_dbg(&h->pdev->dev, "%s: Tag:0x%08x:%08x: do_simple_cmd(abort) completed.\n",
                __func__, tagupper, taglower);
        /* no unmap needed here because no data xfer. */
 
@@ -4464,7 +4674,7 @@ static int hpsa_send_abort(struct ctlr_info *h, unsigned char *scsi3addr,
  */
 
 static int hpsa_send_reset_as_abort_ioaccel2(struct ctlr_info *h,
-       unsigned char *scsi3addr, struct CommandList *abort)
+       unsigned char *scsi3addr, struct CommandList *abort, int reply_queue)
 {
        int rc = IO_OK;
        struct scsi_cmnd *scmd; /* scsi command within request being aborted */
@@ -4483,8 +4693,9 @@ static int hpsa_send_reset_as_abort_ioaccel2(struct ctlr_info *h,
 
        if (h->raid_offload_debug > 0)
                dev_info(&h->pdev->dev,
-                       "Reset as abort: Abort requested on C%d:B%d:T%d:L%d scsi3addr 0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
+                       "scsi %d:%d:%d:%d %s scsi3addr 0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
                        h->scsi_host->host_no, dev->bus, dev->target, dev->lun,
+                       "Reset as abort",
                        scsi3addr[0], scsi3addr[1], scsi3addr[2], scsi3addr[3],
                        scsi3addr[4], scsi3addr[5], scsi3addr[6], scsi3addr[7]);
 
@@ -4506,7 +4717,7 @@ static int hpsa_send_reset_as_abort_ioaccel2(struct ctlr_info *h,
                        "Reset as abort: Resetting physical device at scsi3addr 0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
                        psa[0], psa[1], psa[2], psa[3],
                        psa[4], psa[5], psa[6], psa[7]);
-       rc = hpsa_send_reset(h, psa, HPSA_RESET_TYPE_TARGET);
+       rc = hpsa_send_reset(h, psa, HPSA_RESET_TYPE_TARGET, reply_queue);
        if (rc != 0) {
                dev_warn(&h->pdev->dev,
                        "Reset as abort: Failed on physical device at scsi3addr 0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
@@ -4533,14 +4744,8 @@ static int hpsa_send_reset_as_abort_ioaccel2(struct ctlr_info *h,
        return rc; /* success */
 }
 
-/* Some Smart Arrays need the abort tag swizzled, and some don't.  It's hard to
- * tell which kind we're dealing with, so we send the abort both ways.  There
- * shouldn't be any collisions between swizzled and unswizzled tags due to the
- * way we construct our tags but we check anyway in case the assumptions which
- * make this true someday become false.
- */
 static int hpsa_send_abort_both_ways(struct ctlr_info *h,
-       unsigned char *scsi3addr, struct CommandList *abort)
+       unsigned char *scsi3addr, struct CommandList *abort, int reply_queue)
 {
        /* ioccelerator mode 2 commands should be aborted via the
         * accelerated path, since RAID path is unaware of these commands,
@@ -4548,10 +4753,30 @@ static int hpsa_send_abort_both_ways(struct ctlr_info *h,
         * Change abort to physical device reset.
         */
        if (abort->cmd_type == CMD_IOACCEL2)
-               return hpsa_send_reset_as_abort_ioaccel2(h, scsi3addr, abort);
+               return hpsa_send_reset_as_abort_ioaccel2(h, scsi3addr,
+                                                       abort, reply_queue);
+       return hpsa_send_abort(h, scsi3addr, abort, reply_queue);
+}
 
-       return hpsa_send_abort(h, scsi3addr, abort, 0) &&
-                       hpsa_send_abort(h, scsi3addr, abort, 1);
+/* Find out which reply queue a command was meant to return on */
+static int hpsa_extract_reply_queue(struct ctlr_info *h,
+                                       struct CommandList *c)
+{
+       if (c->cmd_type == CMD_IOACCEL2)
+               return h->ioaccel2_cmd_pool[c->cmdindex].reply_queue;
+       return c->Header.ReplyQueue;
+}
+
+/*
+ * Limit concurrency of abort commands to prevent
+ * over-subscription of commands
+ */
+static inline int wait_for_available_abort_cmd(struct ctlr_info *h)
+{
+#define ABORT_CMD_WAIT_MSECS 5000
+       return !wait_event_timeout(h->abort_cmd_wait_queue,
+                       atomic_dec_if_positive(&h->abort_cmds_available) >= 0,
+                       msecs_to_jiffies(ABORT_CMD_WAIT_MSECS));
 }
 
 /* Send an abort for the specified command.
@@ -4569,27 +4794,19 @@ static int hpsa_eh_abort_handler(struct scsi_cmnd *sc)
        char msg[256];          /* For debug messaging. */
        int ml = 0;
        __le32 tagupper, taglower;
-       int refcount;
+       int refcount, reply_queue;
 
-       /* Find the controller of the command to be aborted */
-       h = sdev_to_hba(sc->device);
-       if (WARN(h == NULL,
-                       "ABORT REQUEST FAILED, Controller lookup failed.\n"))
+       if (sc == NULL)
                return FAILED;
 
-       if (lockup_detected(h))
+       if (sc->device == NULL)
                return FAILED;
 
-       /* Check that controller supports some kind of task abort */
-       if (!(HPSATMF_PHYS_TASK_ABORT & h->TMFSupportFlags) &&
-               !(HPSATMF_LOG_TASK_ABORT & h->TMFSupportFlags))
+       /* Find the controller of the command to be aborted */
+       h = sdev_to_hba(sc->device);
+       if (h == NULL)
                return FAILED;
 
-       memset(msg, 0, sizeof(msg));
-       ml += sprintf(msg+ml, "ABORT REQUEST on C%d:B%d:T%d:L%llu ",
-               h->scsi_host->host_no, sc->device->channel,
-               sc->device->id, sc->device->lun);
-
        /* Find the device of the command to be aborted */
        dev = sc->device->hostdata;
        if (!dev) {
@@ -4598,6 +4815,31 @@ static int hpsa_eh_abort_handler(struct scsi_cmnd *sc)
                return FAILED;
        }
 
+       /* If controller locked up, we can guarantee command won't complete */
+       if (lockup_detected(h)) {
+               hpsa_show_dev_msg(KERN_WARNING, h, dev,
+                                       "ABORT FAILED, lockup detected");
+               return FAILED;
+       }
+
+       /* This is a good time to check if controller lockup has occurred */
+       if (detect_controller_lockup(h)) {
+               hpsa_show_dev_msg(KERN_WARNING, h, dev,
+                                       "ABORT FAILED, new lockup detected");
+               return FAILED;
+       }
+
+       /* Check that controller supports some kind of task abort */
+       if (!(HPSATMF_PHYS_TASK_ABORT & h->TMFSupportFlags) &&
+               !(HPSATMF_LOG_TASK_ABORT & h->TMFSupportFlags))
+               return FAILED;
+
+       memset(msg, 0, sizeof(msg));
+       ml += sprintf(msg+ml, "scsi %d:%d:%d:%llu %s",
+               h->scsi_host->host_no, sc->device->channel,
+               sc->device->id, sc->device->lun,
+               "Aborting command");
+
        /* Get SCSI command to be aborted */
        abort = (struct CommandList *) sc->host_scribble;
        if (abort == NULL) {
@@ -4609,26 +4851,40 @@ static int hpsa_eh_abort_handler(struct scsi_cmnd *sc)
                cmd_free(h, abort);
                return SUCCESS;
        }
+
+       /* Don't bother trying the abort if we know it won't work. */
+       if (abort->cmd_type != CMD_IOACCEL2 &&
+               abort->cmd_type != CMD_IOACCEL1 && !dev->supports_aborts) {
+               cmd_free(h, abort);
+               return FAILED;
+       }
+
        hpsa_get_tag(h, abort, &taglower, &tagupper);
+       reply_queue = hpsa_extract_reply_queue(h, abort);
        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, "Abort request on C%d:B%d:T%d:L%d\n",
-               h->scsi_host->host_no, dev->bus, dev->target, dev->lun);
+       hpsa_show_dev_msg(KERN_WARNING, h, dev, "Aborting command");
        /*
         * Command is in flight, or possibly already completed
         * by the firmware (but not to the scsi mid layer) but we can't
         * distinguish which.  Send the abort down.
         */
-       rc = hpsa_send_abort_both_ways(h, dev->scsi3addr, abort);
+       if (wait_for_available_abort_cmd(h)) {
+               dev_warn(&h->pdev->dev,
+                       "Timed out waiting for an abort command to become available.\n");
+               cmd_free(h, abort);
+               return FAILED;
+       }
+       rc = hpsa_send_abort_both_ways(h, dev->scsi3addr, abort, reply_queue);
+       atomic_inc(&h->abort_cmds_available);
+       wake_up_all(&h->abort_cmd_wait_queue);
        if (rc != 0) {
-               dev_dbg(&h->pdev->dev, "%s Request FAILED.\n", msg);
-               dev_warn(&h->pdev->dev, "FAILED abort on device C%d:B%d:T%d:L%d\n",
-                       h->scsi_host->host_no,
-                       dev->bus, dev->target, dev->lun);
+               hpsa_show_dev_msg(KERN_WARNING, h, dev,
+                                       "FAILED to abort command");
                cmd_free(h, abort);
                return FAILED;
        }
@@ -4948,10 +5204,14 @@ static int hpsa_passthru_ioctl(struct ctlr_info *h, void __user *argp)
                c->SG[0].Len = cpu_to_le32(iocommand.buf_size);
                c->SG[0].Ext = cpu_to_le32(HPSA_SG_LAST); /* not chaining */
        }
-       hpsa_scsi_do_simple_cmd_core_if_no_lockup(h, c);
+       rc = hpsa_scsi_do_simple_cmd(h, c, DEFAULT_REPLY_QUEUE, NO_TIMEOUT);
        if (iocommand.buf_size > 0)
                hpsa_pci_unmap(h->pdev, c, 1, PCI_DMA_BIDIRECTIONAL);
        check_ioctl_unit_attention(h, c);
+       if (rc) {
+               rc = -EIO;
+               goto out;
+       }
 
        /* Copy the error information out */
        memcpy(&iocommand.error_info, c->err_info,
@@ -5078,10 +5338,15 @@ static int hpsa_big_passthru_ioctl(struct ctlr_info *h, void __user *argp)
                }
                c->SG[--i].Ext = cpu_to_le32(HPSA_SG_LAST);
        }
-       hpsa_scsi_do_simple_cmd_core_if_no_lockup(h, c);
+       status = hpsa_scsi_do_simple_cmd(h, c, DEFAULT_REPLY_QUEUE, NO_TIMEOUT);
        if (sg_used)
                hpsa_pci_unmap(h->pdev, c, sg_used, PCI_DMA_BIDIRECTIONAL);
        check_ioctl_unit_attention(h, c);
+       if (status) {
+               status = -EIO;
+               goto cleanup0;
+       }
+
        /* Copy the error information out */
        memcpy(&ioc->error_info, c->err_info, sizeof(ioc->error_info));
        if (copy_to_user(argp, ioc, sizeof(*ioc))) {
@@ -5189,7 +5454,7 @@ static int fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h,
        int cmd_type)
 {
        int pci_dir = XFER_NONE;
-       struct CommandList *a; /* for commands to be aborted */
+       u64 tag; /* for commands to be aborted */
 
        c->cmd_type = CMD_IOCTL_PEND;
        c->Header.ReplyQueue = 0;
@@ -5305,10 +5570,10 @@ static int fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h,
                        c->Request.CDB[7] = 0x00;
                        break;
                case  HPSA_ABORT_MSG:
-                       a = buff;       /* point to command to be aborted */
+                       memcpy(&tag, buff, sizeof(tag));
                        dev_dbg(&h->pdev->dev,
-                               "Abort Tag:0x%016llx request Tag:0x%016llx",
-                               a->Header.tag, c->Header.tag);
+                               "Abort Tag:0x%016llx using rqst Tag:0x%016llx",
+                               tag, c->Header.tag);
                        c->Request.CDBLen = 16;
                        c->Request.type_attr_dir =
                                        TYPE_ATTR_DIR(cmd_type,
@@ -5319,8 +5584,7 @@ static int fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h,
                        c->Request.CDB[2] = 0x00; /* reserved */
                        c->Request.CDB[3] = 0x00; /* reserved */
                        /* Tag to abort goes in CDB[4]-CDB[11] */
-                       memcpy(&c->Request.CDB[4], &a->Header.tag,
-                               sizeof(a->Header.tag));
+                       memcpy(&c->Request.CDB[4], &tag, sizeof(tag));
                        c->Request.CDB[12] = 0x00; /* reserved */
                        c->Request.CDB[13] = 0x00; /* reserved */
                        c->Request.CDB[14] = 0x00; /* reserved */
@@ -5733,7 +5997,7 @@ static int controller_reset_failed(struct CfgTable __iomem *cfgtable)
 /* This does a hard reset of the controller using PCI power management
  * states or the using the doorbell register.
  */
-static int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev)
+static int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev, u32 board_id)
 {
        u64 cfg_offset;
        u32 cfg_base_addr;
@@ -5744,7 +6008,6 @@ static int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev)
        int rc;
        struct CfgTable __iomem *cfgtable;
        u32 use_doorbell;
-       u32 board_id;
        u16 command_register;
 
        /* For controllers as old as the P600, this is very nearly
@@ -5760,11 +6023,6 @@ static int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev)
         * using the doorbell register.
         */
 
-       rc = hpsa_lookup_board_id(pdev, &board_id);
-       if (rc < 0) {
-               dev_warn(&pdev->dev, "Board ID not found\n");
-               return rc;
-       }
        if (!ctlr_is_resettable(board_id)) {
                dev_warn(&pdev->dev, "Controller not resettable\n");
                return -ENODEV;
@@ -6097,18 +6355,21 @@ static int hpsa_find_cfgtables(struct ctlr_info *h)
 
 static void hpsa_get_max_perf_mode_cmds(struct ctlr_info *h)
 {
-       h->max_commands = readl(&(h->cfgtable->MaxPerformantModeCommands));
+#define MIN_MAX_COMMANDS 16
+       BUILD_BUG_ON(MIN_MAX_COMMANDS <= HPSA_NRESERVED_CMDS);
+
+       h->max_commands = readl(&h->cfgtable->MaxPerformantModeCommands);
 
        /* Limit commands in memory limited kdump scenario. */
        if (reset_devices && h->max_commands > 32)
                h->max_commands = 32;
 
-       if (h->max_commands < 16) {
-               dev_warn(&h->pdev->dev, "Controller reports "
-                       "max supported commands of %d, an obvious lie. "
-                       "Using 16.  Ensure that firmware is up to date.\n",
-                       h->max_commands);
-               h->max_commands = 16;
+       if (h->max_commands < MIN_MAX_COMMANDS) {
+               dev_warn(&h->pdev->dev,
+                       "Controller reports max supported commands of %d Using %d instead. Ensure that firmware is up to date.\n",
+                       h->max_commands,
+                       MIN_MAX_COMMANDS);
+               h->max_commands = MIN_MAX_COMMANDS;
        }
 }
 
@@ -6222,6 +6483,8 @@ static int hpsa_wait_for_mode_change_ack(struct ctlr_info *h)
         * as we enter this code.)
         */
        for (i = 0; i < MAX_MODE_CHANGE_WAIT; i++) {
+               if (h->remove_in_progress)
+                       goto done;
                spin_lock_irqsave(&h->lock, flags);
                doorbell_value = readl(h->vaddr + SA5_DOORBELL);
                spin_unlock_irqrestore(&h->lock, flags);
@@ -6272,6 +6535,9 @@ static int hpsa_pci_init(struct ctlr_info *h)
        h->product_name = products[prod_index].product_name;
        h->access = *(products[prod_index].access);
 
+       h->needs_abort_tags_swizzled =
+               ctlr_needs_abort_tags_swizzled(h->board_id);
+
        pci_disable_link_state(h->pdev, PCIE_LINK_STATE_L0S |
                               PCIE_LINK_STATE_L1 | PCIE_LINK_STATE_CLKPM);
 
@@ -6346,7 +6612,7 @@ static void hpsa_hba_inquiry(struct ctlr_info *h)
        }
 }
 
-static int hpsa_init_reset_devices(struct pci_dev *pdev)
+static int hpsa_init_reset_devices(struct pci_dev *pdev, u32 board_id)
 {
        int rc, i;
        void __iomem *vaddr;
@@ -6382,7 +6648,7 @@ static int hpsa_init_reset_devices(struct pci_dev *pdev)
        iounmap(vaddr);
 
        /* Reset the controller with a PCI power-cycle or via doorbell */
-       rc = hpsa_kdump_hard_reset_controller(pdev);
+       rc = hpsa_kdump_hard_reset_controller(pdev, board_id);
 
        /* -ENOTSUPP here means we cannot reset the controller
         * but it's already (and still) up and running in
@@ -6617,17 +6883,21 @@ static void fail_all_outstanding_cmds(struct ctlr_info *h)
 {
        int i, refcount;
        struct CommandList *c;
+       int failcount = 0;
 
        flush_workqueue(h->resubmit_wq); /* ensure all cmds are fully built */
        for (i = 0; i < h->nr_cmds; i++) {
                c = h->cmd_pool + i;
                refcount = atomic_inc_return(&c->refcount);
                if (refcount > 1) {
-                       c->err_info->CommandStatus = CMD_HARDWARE_ERR;
+                       c->err_info->CommandStatus = CMD_CTLR_LOCKUP;
                        finish_cmd(c);
+                       failcount++;
                }
                cmd_free(h, c);
        }
+       dev_warn(&h->pdev->dev,
+               "failed %d commands in fail_all\n", failcount);
 }
 
 static void set_lockup_detected_for_all_cpus(struct ctlr_info *h, u32 value)
@@ -6653,18 +6923,19 @@ static void controller_lockup_detected(struct ctlr_info *h)
        if (!lockup_detected) {
                /* no heartbeat, but controller gave us a zero. */
                dev_warn(&h->pdev->dev,
-                       "lockup detected but scratchpad register is zero\n");
+                       "lockup detected after %d but scratchpad register is zero\n",
+                       h->heartbeat_sample_interval / HZ);
                lockup_detected = 0xffffffff;
        }
        set_lockup_detected_for_all_cpus(h, lockup_detected);
        spin_unlock_irqrestore(&h->lock, flags);
-       dev_warn(&h->pdev->dev, "Controller lockup detected: 0x%08x\n",
-                       lockup_detected);
+       dev_warn(&h->pdev->dev, "Controller lockup detected: 0x%08x after %d\n",
+                       lockup_detected, h->heartbeat_sample_interval / HZ);
        pci_disable_device(h->pdev);
        fail_all_outstanding_cmds(h);
 }
 
-static void detect_controller_lockup(struct ctlr_info *h)
+static int detect_controller_lockup(struct ctlr_info *h)
 {
        u64 now;
        u32 heartbeat;
@@ -6674,7 +6945,7 @@ static void detect_controller_lockup(struct ctlr_info *h)
        /* If we've received an interrupt recently, we're ok. */
        if (time_after64(h->last_intr_timestamp +
                                (h->heartbeat_sample_interval), now))
-               return;
+               return false;
 
        /*
         * If we've already checked the heartbeat recently, we're ok.
@@ -6683,7 +6954,7 @@ static void detect_controller_lockup(struct ctlr_info *h)
         */
        if (time_after64(h->last_heartbeat_timestamp +
                                (h->heartbeat_sample_interval), now))
-               return;
+               return false;
 
        /* If heartbeat has not changed since we last looked, we're not ok. */
        spin_lock_irqsave(&h->lock, flags);
@@ -6691,12 +6962,13 @@ static void detect_controller_lockup(struct ctlr_info *h)
        spin_unlock_irqrestore(&h->lock, flags);
        if (h->last_heartbeat == heartbeat) {
                controller_lockup_detected(h);
-               return;
+               return true;
        }
 
        /* We're ok. */
        h->last_heartbeat = heartbeat;
        h->last_heartbeat_timestamp = now;
+       return false;
 }
 
 static void hpsa_ack_ctlr_events(struct ctlr_info *h)
@@ -6843,11 +7115,18 @@ static int hpsa_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        struct ctlr_info *h;
        int try_soft_reset = 0;
        unsigned long flags;
+       u32 board_id;
 
        if (number_of_controllers == 0)
                printk(KERN_INFO DRIVER_NAME "\n");
 
-       rc = hpsa_init_reset_devices(pdev);
+       rc = hpsa_lookup_board_id(pdev, &board_id);
+       if (rc < 0) {
+               dev_warn(&pdev->dev, "Board ID not found\n");
+               return rc;
+       }
+
+       rc = hpsa_init_reset_devices(pdev, board_id);
        if (rc) {
                if (rc != -ENOTSUPP)
                        return rc;
@@ -6878,6 +7157,7 @@ reinit_after_soft_reset:
        spin_lock_init(&h->offline_device_lock);
        spin_lock_init(&h->scan_lock);
        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) {
@@ -6935,6 +7215,7 @@ reinit_after_soft_reset:
        if (hpsa_allocate_sg_chain_blocks(h))
                goto clean4;
        init_waitqueue_head(&h->scan_wait_queue);
+       init_waitqueue_head(&h->abort_cmd_wait_queue);
        h->scan_finished = 1; /* no scan currently in progress */
 
        pci_set_drvdata(pdev, h);
@@ -7040,8 +7321,10 @@ static void hpsa_flush_cache(struct ctlr_info *h)
 {
        char *flush_buf;
        struct CommandList *c;
+       int rc;
 
        /* Don't bother trying to flush the cache if locked up */
+       /* FIXME not necessary if do_simple_cmd does the check */
        if (unlikely(lockup_detected(h)))
                return;
        flush_buf = kzalloc(4, GFP_KERNEL);
@@ -7057,7 +7340,10 @@ static void hpsa_flush_cache(struct ctlr_info *h)
                RAID_CTLR_LUNID, TYPE_CMD)) {
                goto out;
        }
-       hpsa_scsi_do_simple_cmd_with_retry(h, c, PCI_DMA_TODEVICE);
+       rc = hpsa_scsi_do_simple_cmd_with_retry(h, c,
+                                       PCI_DMA_TODEVICE, NO_TIMEOUT);
+       if (rc)
+               goto out;
        if (c->err_info->CommandStatus != 0)
 out:
                dev_warn(&h->pdev->dev,