From 19be606be1df35479333bd04e2cdaddc9d77e38c Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Thu, 13 Oct 2016 13:10:08 -0300 Subject: scsi: hpsa: Remove unneeded void pointer cast It's not necessary to cast the result of kmalloc, since void pointers are promoted to any other type. This also fixes following coccinelle warning: casting value returned by memory allocation function to (BIG_IOCTL_Command_struct *) is useless. Signed-off-by: Javier Martinez Canillas Acked-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/hpsa.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/scsi/hpsa.c') diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index d007ec18179a..4e82b692298e 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -6657,8 +6657,7 @@ static int hpsa_big_passthru_ioctl(struct ctlr_info *h, void __user *argp) return -EINVAL; if (!capable(CAP_SYS_RAWIO)) return -EPERM; - ioc = (BIG_IOCTL_Command_struct *) - kmalloc(sizeof(*ioc), GFP_KERNEL); + ioc = kmalloc(sizeof(*ioc), GFP_KERNEL); if (!ioc) { status = -ENOMEM; goto cleanup1; -- cgit From bc2bb1543e62a5d0ae51ccdfde697dc97957f2a1 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 9 Nov 2016 10:42:22 -0800 Subject: scsi: hpsa: use pci_alloc_irq_vectors and automatic irq affinity This patch converts over hpsa to use the pci_alloc_irq_vectors including the PCI_IRQ_AFFINITY flag that automatically assigns spread out irq affinity to the I/O queues. It also cleans up the per-ctrl interrupt state due to the use of the pci_irq_vector and pci_free_irq_vectors helpers that don't need to know the exact irq type. Additionally it changes a little oddity in the existing code that was using different array indixes into the per-vector arrays depending on whether a controller is using a single INTx or single MSI irq. [mkp: fixed typo] Signed-off-by: Christoph Hellwig Acked-by: Don Brace Tested-by: Don Brace Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/hpsa.c | 143 ++++++++++++++++++---------------------------------- 1 file changed, 50 insertions(+), 93 deletions(-) (limited to 'drivers/scsi/hpsa.c') diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 4e82b692298e..9459925566f2 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -1001,7 +1001,7 @@ static void set_performant_mode(struct ctlr_info *h, struct CommandList *c, { if (likely(h->transMethod & CFGTBL_Trans_Performant)) { c->busaddr |= 1 | (h->blockFetchTable[c->Header.SGList] << 1); - if (unlikely(!h->msix_vector)) + if (unlikely(!h->msix_vectors)) return; if (likely(reply_queue == DEFAULT_REPLY_QUEUE)) c->Header.ReplyQueue = @@ -5618,7 +5618,7 @@ static int hpsa_scsi_host_alloc(struct ctlr_info *h) sh->sg_tablesize = h->maxsgentries; sh->transportt = hpsa_sas_transport_template; sh->hostdata[0] = (unsigned long) h; - sh->irq = h->intr[h->intr_mode]; + sh->irq = pci_irq_vector(h->pdev, 0); sh->unique_id = sh->irq; h->scsi_host = sh; @@ -7651,67 +7651,41 @@ static int find_PCI_BAR_index(struct pci_dev *pdev, unsigned long pci_bar_addr) static void hpsa_disable_interrupt_mode(struct ctlr_info *h) { - if (h->msix_vector) { - if (h->pdev->msix_enabled) - pci_disable_msix(h->pdev); - h->msix_vector = 0; - } else if (h->msi_vector) { - if (h->pdev->msi_enabled) - pci_disable_msi(h->pdev); - h->msi_vector = 0; - } + pci_free_irq_vectors(h->pdev); + h->msix_vectors = 0; } /* If MSI/MSI-X is supported by the kernel we will try to enable it on * controllers that are capable. If not, we use legacy INTx mode. */ -static void hpsa_interrupt_mode(struct ctlr_info *h) +static int hpsa_interrupt_mode(struct ctlr_info *h) { -#ifdef CONFIG_PCI_MSI - int err, i; - struct msix_entry hpsa_msix_entries[MAX_REPLY_QUEUES]; - - for (i = 0; i < MAX_REPLY_QUEUES; i++) { - hpsa_msix_entries[i].vector = 0; - hpsa_msix_entries[i].entry = i; - } + unsigned int flags = PCI_IRQ_LEGACY; + int ret; /* Some boards advertise MSI but don't really support it */ - if ((h->board_id == 0x40700E11) || (h->board_id == 0x40800E11) || - (h->board_id == 0x40820E11) || (h->board_id == 0x40830E11)) - goto default_int_mode; - if (pci_find_capability(h->pdev, PCI_CAP_ID_MSIX)) { - dev_info(&h->pdev->dev, "MSI-X capable controller\n"); - h->msix_vector = MAX_REPLY_QUEUES; - if (h->msix_vector > num_online_cpus()) - h->msix_vector = num_online_cpus(); - err = pci_enable_msix_range(h->pdev, hpsa_msix_entries, - 1, h->msix_vector); - if (err < 0) { - dev_warn(&h->pdev->dev, "MSI-X init failed %d\n", err); - h->msix_vector = 0; - goto single_msi_mode; - } else if (err < h->msix_vector) { - dev_warn(&h->pdev->dev, "only %d MSI-X vectors " - "available\n", err); + switch (h->board_id) { + case 0x40700E11: + case 0x40800E11: + case 0x40820E11: + case 0x40830E11: + break; + default: + ret = pci_alloc_irq_vectors(h->pdev, 1, MAX_REPLY_QUEUES, + PCI_IRQ_MSIX | PCI_IRQ_AFFINITY); + if (ret > 0) { + h->msix_vectors = ret; + return 0; } - h->msix_vector = err; - for (i = 0; i < h->msix_vector; i++) - h->intr[i] = hpsa_msix_entries[i].vector; - return; - } -single_msi_mode: - if (pci_find_capability(h->pdev, PCI_CAP_ID_MSI)) { - dev_info(&h->pdev->dev, "MSI capable controller\n"); - if (!pci_enable_msi(h->pdev)) - h->msi_vector = 1; - else - dev_warn(&h->pdev->dev, "MSI init failed\n"); + + flags |= PCI_IRQ_MSI; + break; } -default_int_mode: -#endif /* CONFIG_PCI_MSI */ - /* if we get here we're going to use the default interrupt mode */ - h->intr[h->intr_mode] = h->pdev->irq; + + ret = pci_alloc_irq_vectors(h->pdev, 1, 1, flags); + if (ret < 0) + return ret; + return 0; } static int hpsa_lookup_board_id(struct pci_dev *pdev, u32 *board_id) @@ -8067,7 +8041,9 @@ static int hpsa_pci_init(struct ctlr_info *h) pci_set_master(h->pdev); - hpsa_interrupt_mode(h); + err = hpsa_interrupt_mode(h); + if (err) + goto clean1; err = hpsa_pci_find_memory_BAR(h->pdev, &h->paddr); if (err) goto clean2; /* intmode+region, pci */ @@ -8103,6 +8079,7 @@ clean3: /* vaddr, intmode+region, pci */ h->vaddr = NULL; clean2: /* intmode+region, pci */ hpsa_disable_interrupt_mode(h); +clean1: /* * call pci_disable_device before pci_release_regions per * Documentation/PCI/pci.txt @@ -8236,34 +8213,20 @@ clean_up: return -ENOMEM; } -static void hpsa_irq_affinity_hints(struct ctlr_info *h) -{ - int i, cpu; - - cpu = cpumask_first(cpu_online_mask); - for (i = 0; i < h->msix_vector; i++) { - irq_set_affinity_hint(h->intr[i], get_cpu_mask(cpu)); - cpu = cpumask_next(cpu, cpu_online_mask); - } -} - /* clear affinity hints and free MSI-X, MSI, or legacy INTx vectors */ static void hpsa_free_irqs(struct ctlr_info *h) { int i; - if (!h->msix_vector || h->intr_mode != PERF_MODE_INT) { + if (!h->msix_vectors || h->intr_mode != PERF_MODE_INT) { /* Single reply queue, only one irq to free */ - i = h->intr_mode; - irq_set_affinity_hint(h->intr[i], NULL); - free_irq(h->intr[i], &h->q[i]); - h->q[i] = 0; + free_irq(pci_irq_vector(h->pdev, 0), &h->q[i]); + h->q[h->intr_mode] = 0; return; } - for (i = 0; i < h->msix_vector; i++) { - irq_set_affinity_hint(h->intr[i], NULL); - free_irq(h->intr[i], &h->q[i]); + for (i = 0; i < h->msix_vectors; i++) { + free_irq(pci_irq_vector(h->pdev, i), &h->q[i]); h->q[i] = 0; } for (; i < MAX_REPLY_QUEUES; i++) @@ -8284,11 +8247,11 @@ static int hpsa_request_irqs(struct ctlr_info *h, for (i = 0; i < MAX_REPLY_QUEUES; i++) h->q[i] = (u8) i; - if (h->intr_mode == PERF_MODE_INT && h->msix_vector > 0) { + if (h->intr_mode == PERF_MODE_INT && h->msix_vectors > 0) { /* If performant mode and MSI-X, use multiple reply queues */ - for (i = 0; i < h->msix_vector; i++) { + for (i = 0; i < h->msix_vectors; i++) { sprintf(h->intrname[i], "%s-msix%d", h->devname, i); - rc = request_irq(h->intr[i], msixhandler, + rc = request_irq(pci_irq_vector(h->pdev, i), msixhandler, 0, h->intrname[i], &h->q[i]); if (rc) { @@ -8296,9 +8259,9 @@ static int hpsa_request_irqs(struct ctlr_info *h, dev_err(&h->pdev->dev, "failed to get irq %d for %s\n", - h->intr[i], h->devname); + pci_irq_vector(h->pdev, i), h->devname); for (j = 0; j < i; j++) { - free_irq(h->intr[j], &h->q[j]); + free_irq(pci_irq_vector(h->pdev, j), &h->q[j]); h->q[j] = 0; } for (; j < MAX_REPLY_QUEUES; j++) @@ -8306,33 +8269,27 @@ static int hpsa_request_irqs(struct ctlr_info *h, return rc; } } - hpsa_irq_affinity_hints(h); } else { /* Use single reply pool */ - if (h->msix_vector > 0 || h->msi_vector) { - if (h->msix_vector) - sprintf(h->intrname[h->intr_mode], - "%s-msix", h->devname); - else - sprintf(h->intrname[h->intr_mode], - "%s-msi", h->devname); - rc = request_irq(h->intr[h->intr_mode], + if (h->msix_vectors > 0 || h->pdev->msi_enabled) { + sprintf(h->intrname[0], "%s-msi%s", h->devname, + h->msix_vectors ? "x" : ""); + rc = request_irq(pci_irq_vector(h->pdev, 0), msixhandler, 0, - h->intrname[h->intr_mode], + h->intrname[0], &h->q[h->intr_mode]); } else { sprintf(h->intrname[h->intr_mode], "%s-intx", h->devname); - rc = request_irq(h->intr[h->intr_mode], + rc = request_irq(pci_irq_vector(h->pdev, 0), intxhandler, IRQF_SHARED, - h->intrname[h->intr_mode], + h->intrname[0], &h->q[h->intr_mode]); } - irq_set_affinity_hint(h->intr[h->intr_mode], NULL); } if (rc) { dev_err(&h->pdev->dev, "failed to get irq %d for %s\n", - h->intr[h->intr_mode], h->devname); + pci_irq_vector(h->pdev, 0), h->devname); hpsa_free_irqs(h); return -ENODEV; } @@ -9518,7 +9475,7 @@ static int hpsa_put_ctlr_into_performant_mode(struct ctlr_info *h) return rc; } - h->nreply_queues = h->msix_vector > 0 ? h->msix_vector : 1; + h->nreply_queues = h->msix_vectors > 0 ? h->msix_vectors : 1; hpsa_get_max_perf_mode_cmds(h); /* Performant mode ring buffer and supporting data structures */ h->reply_queue_size = h->max_commands * sizeof(u64); -- cgit From 7dc62d935459fc48778d9306f2094a8fd16614dd Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Mon, 14 Nov 2016 12:59:35 +0000 Subject: scsi: hpsa: free irq on q indexed by h->intr_mode and not i Use correct index on q, use h->intr_mode instead of i. Issue detected using static analysis with cppcheck Fixes: bc2bb1543e62a5d0 ("scsi: hpsa: use pci_alloc_irq_vectors and automatic irq affinity") Signed-off-by: Colin Ian King Reviewed-by: Christoph Hellwig Acked-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/hpsa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/scsi/hpsa.c') diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 9459925566f2..0d4f21c95a40 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -8220,7 +8220,7 @@ static void hpsa_free_irqs(struct ctlr_info *h) if (!h->msix_vectors || h->intr_mode != PERF_MODE_INT) { /* Single reply queue, only one irq to free */ - free_irq(pci_irq_vector(h->pdev, 0), &h->q[i]); + free_irq(pci_irq_vector(h->pdev, 0), &h->q[h->intr_mode]); h->q[h->intr_mode] = 0; return; } -- cgit From bfd7546cd19abf0f8a08c1339a917fe326fcfc71 Mon Sep 17 00:00:00 2001 From: Don Brace Date: Tue, 15 Nov 2016 14:45:32 -0600 Subject: scsi: hpsa: correct logical resets - driver was not calling done in some cases which causes the volume to be offlined. - avoid doing rescan during a reset. Reviewed-by: Scott Teel Reviewed-by: Kevin Barnett Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/hpsa.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'drivers/scsi/hpsa.c') diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 0d4f21c95a40..5b1ba5861275 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -276,6 +276,9 @@ static int hpsa_find_cfg_addrs(struct pci_dev *pdev, void __iomem *vaddr, static int hpsa_pci_find_memory_BAR(struct pci_dev *pdev, unsigned long *memory_bar); static int hpsa_lookup_board_id(struct pci_dev *pdev, u32 *board_id); +static int wait_for_device_to_become_ready(struct ctlr_info *h, + unsigned char lunaddr[], + int reply_queue); static int hpsa_wait_for_board_state(struct pci_dev *pdev, void __iomem *vaddr, int wait_for_ready); static inline void finish_cmd(struct CommandList *c); @@ -2540,7 +2543,7 @@ static void complete_scsi_command(struct CommandList *cp) if ((unlikely(hpsa_is_pending_event(cp)))) { if (cp->reset_pending) - return hpsa_cmd_resolve_and_free(h, cp); + return hpsa_cmd_free_and_done(h, cp, cmd); if (cp->abort_pending) return hpsa_cmd_abort_and_free(h, cp, cmd); } @@ -3079,6 +3082,8 @@ static int hpsa_do_reset(struct ctlr_info *h, struct hpsa_scsi_dev_t *dev, if (unlikely(rc)) atomic_set(&dev->reset_cmds_out, 0); + else + wait_for_device_to_become_ready(h, scsi3addr, 0); mutex_unlock(&h->reset_mutex); return rc; @@ -5563,6 +5568,14 @@ static void hpsa_scan_start(struct Scsi_Host *sh) if (unlikely(lockup_detected(h))) return hpsa_scan_complete(h); + /* + * Do the scan after a reset completion + */ + if (h->reset_in_progress) { + h->drv_req_rescan = 1; + return; + } + hpsa_update_scsi_devices(h); hpsa_scan_complete(h); @@ -8590,6 +8603,14 @@ static void hpsa_rescan_ctlr_worker(struct work_struct *work) if (h->remove_in_progress) return; + /* + * Do the scan after the reset + */ + if (h->reset_in_progress) { + h->drv_req_rescan = 1; + return; + } + if (hpsa_ctlr_needs_rescan(h) || hpsa_offline_devices_ready(h)) { scsi_host_get(h->scsi_host); hpsa_ack_ctlr_events(h); -- cgit From 1ccde7004ff66cdcbe4c8005f3bb44dda6ab0b99 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 18 Nov 2016 08:32:47 +0100 Subject: scsi: hpsa: use correct DID_NO_CONNECT hostbyte NOT_READY is a sense key, not a legit scsi hostbyte value. Use DID_NO_CONNECT instead. Signed-off-by: Hannes Reinecke Acked-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/hpsa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/scsi/hpsa.c') diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 5b1ba5861275..b9f1bab4dfb7 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -5487,7 +5487,7 @@ static int hpsa_scsi_queue_command(struct Scsi_Host *sh, struct scsi_cmnd *cmd) dev = cmd->device->hostdata; if (!dev) { - cmd->result = NOT_READY << 16; /* host byte */ + cmd->result = DID_NO_CONNECT << 16; cmd->scsi_done(cmd); return 0; } -- cgit From 16961204a0ebcb87b89ed3be14b0a484c754d7e4 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 18 Nov 2016 08:32:49 +0100 Subject: scsi: hpsa: add 'ctlr_num' sysfs attribute Add a sysfs attribute 'ctlr_num' holding the current HPSA controller number. This is required to construct compability 'cciss' links. [mkp: fixed typo] Signed-off-by: Hannes Reinecke Acked-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/hpsa.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers/scsi/hpsa.c') diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index b9f1bab4dfb7..216c137d96ea 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -867,6 +867,16 @@ static ssize_t path_info_show(struct device *dev, return output_len; } +static ssize_t host_show_ctlr_num(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ctlr_info *h; + struct Scsi_Host *shost = class_to_shost(dev); + + h = shost_to_hba(shost); + return snprintf(buf, 20, "%d\n", h->ctlr); +} + static DEVICE_ATTR(raid_level, S_IRUGO, raid_level_show, NULL); static DEVICE_ATTR(lunid, S_IRUGO, lunid_show, NULL); static DEVICE_ATTR(unique_id, S_IRUGO, unique_id_show, NULL); @@ -890,6 +900,8 @@ static DEVICE_ATTR(resettable, S_IRUGO, host_show_resettable, NULL); static DEVICE_ATTR(lockup_detected, S_IRUGO, host_show_lockup_detected, NULL); +static DEVICE_ATTR(ctlr_num, S_IRUGO, + host_show_ctlr_num, NULL); static struct device_attribute *hpsa_sdev_attrs[] = { &dev_attr_raid_level, @@ -910,6 +922,7 @@ static struct device_attribute *hpsa_shost_attrs[] = { &dev_attr_hp_ssd_smart_path_status, &dev_attr_raid_offload_debug, &dev_attr_lockup_detected, + &dev_attr_ctlr_num, NULL, }; -- cgit From 609a70df07af1ff857257fb2e93c3ef281e30710 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Wed, 30 Nov 2016 23:35:47 +0100 Subject: scsi: hpsa: use %phN for short hex dumps Passing one instead of 8 or 16 arguments reduces the size of the generated code somewhat: add/remove: 2/3 grow/shrink: 1/4 up/down: 1772/-2137 (-365) There's one more candidate, unique_id_show, but that uses %02X, and I'm not sure it would be ok to start using lowercase there, so I've left it alone for now. Signed-off-by: Rasmus Villemoes Acked-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/hpsa.c | 40 +++++++++++++--------------------------- 1 file changed, 13 insertions(+), 27 deletions(-) (limited to 'drivers/scsi/hpsa.c') diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 216c137d96ea..220ccd40dcbc 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -703,9 +703,7 @@ static ssize_t lunid_show(struct device *dev, } memcpy(lunid, hdev->scsi3addr, sizeof(lunid)); spin_unlock_irqrestore(&h->lock, flags); - return snprintf(buf, 20, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n", - lunid[0], lunid[1], lunid[2], lunid[3], - lunid[4], lunid[5], lunid[6], lunid[7]); + return snprintf(buf, 20, "0x%8phN\n", lunid); } static ssize_t unique_id_show(struct device *dev, @@ -2839,14 +2837,8 @@ static void hpsa_print_cmd(struct ctlr_info *h, char *txt, const u8 *cdb = c->Request.CDB; const u8 *lun = c->Header.LUN.LunAddrBytes; - dev_warn(&h->pdev->dev, "%s: LUN:%02x%02x%02x%02x%02x%02x%02x%02x" - " CDB:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", - txt, lun[0], lun[1], lun[2], lun[3], - lun[4], lun[5], lun[6], lun[7], - cdb[0], cdb[1], cdb[2], cdb[3], - cdb[4], cdb[5], cdb[6], cdb[7], - cdb[8], cdb[9], cdb[10], cdb[11], - cdb[12], cdb[13], cdb[14], cdb[15]); + dev_warn(&h->pdev->dev, "%s: LUN:%8phN CDB:%16phN\n", + txt, lun, cdb); } static void hpsa_scsi_interpret_error(struct ctlr_info *h, @@ -6019,11 +6011,9 @@ static int hpsa_send_reset_as_abort_ioaccel2(struct ctlr_info *h, if (h->raid_offload_debug > 0) dev_info(&h->pdev->dev, - "scsi %d:%d:%d:%d %s scsi3addr 0x%02x%02x%02x%02x%02x%02x%02x%02x\n", + "scsi %d:%d:%d:%d %s scsi3addr 0x%8phN\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]); + "Reset as abort", scsi3addr); if (!dev->offload_enabled) { dev_warn(&h->pdev->dev, @@ -6040,32 +6030,28 @@ static int hpsa_send_reset_as_abort_ioaccel2(struct ctlr_info *h, /* send the reset */ if (h->raid_offload_debug > 0) dev_info(&h->pdev->dev, - "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]); + "Reset as abort: Resetting physical device at scsi3addr 0x%8phN\n", + psa); rc = hpsa_do_reset(h, dev, psa, HPSA_PHYS_TARGET_RESET, 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", - psa[0], psa[1], psa[2], psa[3], - psa[4], psa[5], psa[6], psa[7]); + "Reset as abort: Failed on physical device at scsi3addr 0x%8phN\n", + psa); return rc; /* failed to reset */ } /* wait for device to recover */ if (wait_for_device_to_become_ready(h, psa, reply_queue) != 0) { dev_warn(&h->pdev->dev, - "Reset as abort: Failed: Device never recovered from reset: 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]); + "Reset as abort: Failed: Device never recovered from reset: 0x%8phN\n", + psa); return -1; /* failed to recover */ } /* device recovered */ dev_info(&h->pdev->dev, - "Reset as abort: Device recovered from reset: 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]); + "Reset as abort: Device recovered from reset: scsi3addr 0x%8phN\n", + psa); return rc; /* success */ } -- cgit From 2a80d5458a027f6d514987c09f0b51f45c3a5be4 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 2 Dec 2016 11:36:13 +0100 Subject: scsi: hpsa: fallback to use legacy REPORT PHYS command Older SmartArray controllers (eg SmartArray 64xx) do not support the extended REPORT PHYS command, so fallback to use the legacy version here. Signed-off-by: Hannes Reinecke Acked-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/hpsa.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) (limited to 'drivers/scsi/hpsa.c') diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 220ccd40dcbc..f5ab690b3091 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -3632,8 +3632,32 @@ out: static inline int hpsa_scsi_do_report_phys_luns(struct ctlr_info *h, struct ReportExtendedLUNdata *buf, int bufsize) { - return hpsa_scsi_do_report_luns(h, 0, buf, bufsize, - HPSA_REPORT_PHYS_EXTENDED); + int rc; + struct ReportLUNdata *lbuf; + + rc = hpsa_scsi_do_report_luns(h, 0, buf, bufsize, + HPSA_REPORT_PHYS_EXTENDED); + if (!rc || !hpsa_allow_any) + return rc; + + /* REPORT PHYS EXTENDED is not supported */ + lbuf = kzalloc(sizeof(*lbuf), GFP_KERNEL); + if (!lbuf) + return -ENOMEM; + + rc = hpsa_scsi_do_report_luns(h, 0, lbuf, sizeof(*lbuf), 0); + if (!rc) { + int i; + u32 nphys; + + /* Copy ReportLUNdata header */ + memcpy(buf, lbuf, 8); + nphys = be32_to_cpu(*((__be32 *)lbuf->LUNListLength)) / 8; + for (i = 0; i < nphys; i++) + memcpy(buf->LUN[i].lunid, lbuf->LUN[i], 8); + } + kfree(lbuf); + return rc; } static inline int hpsa_scsi_do_report_log_luns(struct ctlr_info *h, -- cgit