diff options
author | Don Brace <don.brace@microsemi.com> | 2017-10-20 16:52:10 -0500 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2017-10-25 04:55:21 -0400 |
commit | 0a7c3bb8951278aae25b3b53eb5f97cca4147cf3 (patch) | |
tree | f4242ec6fef0cb4d78b1e398d69f06225d963451 /drivers/scsi/hpsa.c | |
parent | 0ff365f51a4290a63f1044c599df98196223d4bc (diff) |
scsi: hpsa: add enclosure logical identifier
Add support for enclosure logical identifier
Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Reviewed-by: Scott Teel <scott.teel@microsemi.com>
Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/hpsa.c')
-rw-r--r-- | drivers/scsi/hpsa.c | 69 |
1 files changed, 67 insertions, 2 deletions
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index a536ed620e6e..5428a4cbbded 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -2965,6 +2965,57 @@ static void hpsa_scsi_interpret_error(struct ctlr_info *h, } } +static int hpsa_do_receive_diagnostic(struct ctlr_info *h, u8 *scsi3addr, + u8 page, u8 *buf, size_t bufsize) +{ + int rc = IO_OK; + struct CommandList *c; + struct ErrorInfo *ei; + + c = cmd_alloc(h); + if (fill_cmd(c, RECEIVE_DIAGNOSTIC, h, buf, bufsize, + page, scsi3addr, TYPE_CMD)) { + rc = -1; + goto out; + } + 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); + rc = -1; + } +out: + cmd_free(h, c); + return rc; +} + +static u64 hpsa_get_enclosure_logical_identifier(struct ctlr_info *h, + u8 *scsi3addr) +{ + u8 *buf; + u64 sa = 0; + int rc = 0; + + buf = kzalloc(1024, GFP_KERNEL); + if (!buf) + return 0; + + rc = hpsa_do_receive_diagnostic(h, scsi3addr, RECEIVE_DIAGNOSTIC, + buf, 1024); + + if (rc) + goto out; + + sa = get_unaligned_be64(buf+12); + +out: + kfree(buf); + return sa; +} + static int hpsa_scsi_do_inquiry(struct ctlr_info *h, unsigned char *scsi3addr, u16 page, unsigned char *buf, unsigned char bufsize) @@ -3400,6 +3451,9 @@ static void hpsa_get_enclosure_info(struct ctlr_info *h, bmic_device_index = GET_BMIC_DRIVE_NUMBER(&rle->lunid[0]); + encl_dev->sas_address = + hpsa_get_enclosure_logical_identifier(h, scsi3addr); + if (encl_dev->target == -1 || encl_dev->lun == -1) { rc = IO_OK; goto out; @@ -6571,6 +6625,17 @@ static int fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h, c->Request.CDB[0] = HPSA_INQUIRY; c->Request.CDB[4] = size & 0xFF; break; + case RECEIVE_DIAGNOSTIC: + c->Request.CDBLen = 6; + c->Request.type_attr_dir = + TYPE_ATTR_DIR(cmd_type, ATTR_SIMPLE, XFER_READ); + c->Request.Timeout = 0; + c->Request.CDB[0] = cmd; + c->Request.CDB[1] = 1; + c->Request.CDB[2] = 1; + c->Request.CDB[3] = (size >> 8) & 0xFF; + c->Request.CDB[4] = size & 0xFF; + break; case HPSA_REPORT_LOG: case HPSA_REPORT_PHYS: /* Talking to controller so It's a physical command @@ -9508,7 +9573,7 @@ static int hpsa_add_sas_host(struct ctlr_info *h) struct hpsa_sas_port *hpsa_sas_port; struct hpsa_sas_phy *hpsa_sas_phy; - parent_dev = &h->scsi_host->shost_gendev; + parent_dev = &h->scsi_host->shost_dev; hpsa_sas_node = hpsa_alloc_sas_node(parent_dev); if (!hpsa_sas_node) @@ -9599,7 +9664,7 @@ hpsa_sas_get_linkerrors(struct sas_phy *phy) static int hpsa_sas_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier) { - *identifier = 0; + *identifier = rphy->identify.sas_address; return 0; } |