scsi: hpsa: Check for vpd support before sending

Before using vendor-specific VPD pages for getting raid_level and
device_id, check for page support.  If page isn't supported, don't try
to use it.  Also, pay attention to return status on hpsa_get_device_id.

[mkp: fix boolean return warnings reported by kbuild test robot]

Reviewed-by: Scott Benesh <scott.benest@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>
This commit is contained in:
Scott Teel 2016-09-09 16:30:29 -05:00 committed by Martin K. Petersen
parent d49c2077c0
commit 8383278d28
2 changed files with 38 additions and 13 deletions

View File

@ -293,6 +293,8 @@ static int detect_controller_lockup(struct ctlr_info *h);
static void hpsa_disable_rld_caching(struct ctlr_info *h); static void hpsa_disable_rld_caching(struct ctlr_info *h);
static inline int hpsa_scsi_do_report_phys_luns(struct ctlr_info *h, static inline int hpsa_scsi_do_report_phys_luns(struct ctlr_info *h,
struct ReportExtendedLUNdata *buf, int bufsize); struct ReportExtendedLUNdata *buf, int bufsize);
static bool hpsa_vpd_page_supported(struct ctlr_info *h,
unsigned char scsi3addr[], u8 page);
static int hpsa_luns_changed(struct ctlr_info *h); static int hpsa_luns_changed(struct ctlr_info *h);
static bool hpsa_cmd_dev_match(struct ctlr_info *h, struct CommandList *c, static bool hpsa_cmd_dev_match(struct ctlr_info *h, struct CommandList *c,
struct hpsa_scsi_dev_t *dev, struct hpsa_scsi_dev_t *dev,
@ -3088,11 +3090,19 @@ static void hpsa_get_raid_level(struct ctlr_info *h,
buf = kzalloc(64, GFP_KERNEL); buf = kzalloc(64, GFP_KERNEL);
if (!buf) if (!buf)
return; return;
rc = hpsa_scsi_do_inquiry(h, scsi3addr, VPD_PAGE | 0xC1, buf, 64);
if (!hpsa_vpd_page_supported(h, scsi3addr,
HPSA_VPD_LV_DEVICE_GEOMETRY))
goto exit;
rc = hpsa_scsi_do_inquiry(h, scsi3addr, VPD_PAGE |
HPSA_VPD_LV_DEVICE_GEOMETRY, buf, 64);
if (rc == 0) if (rc == 0)
*raid_level = buf[8]; *raid_level = buf[8];
if (*raid_level > RAID_UNKNOWN) if (*raid_level > RAID_UNKNOWN)
*raid_level = RAID_UNKNOWN; *raid_level = RAID_UNKNOWN;
exit:
kfree(buf); kfree(buf);
return; return;
} }
@ -3450,7 +3460,7 @@ static void hpsa_get_sas_address(struct ctlr_info *h, unsigned char *scsi3addr,
} }
/* Get a device id from inquiry page 0x83 */ /* Get a device id from inquiry page 0x83 */
static int hpsa_vpd_page_supported(struct ctlr_info *h, static bool hpsa_vpd_page_supported(struct ctlr_info *h,
unsigned char scsi3addr[], u8 page) unsigned char scsi3addr[], u8 page)
{ {
int rc; int rc;
@ -3460,7 +3470,7 @@ static int hpsa_vpd_page_supported(struct ctlr_info *h,
buf = kzalloc(256, GFP_KERNEL); buf = kzalloc(256, GFP_KERNEL);
if (!buf) if (!buf)
return 0; return false;
/* Get the size of the page list first */ /* Get the size of the page list first */
rc = hpsa_scsi_do_inquiry(h, scsi3addr, rc = hpsa_scsi_do_inquiry(h, scsi3addr,
@ -3487,10 +3497,10 @@ static int hpsa_vpd_page_supported(struct ctlr_info *h,
goto exit_supported; goto exit_supported;
exit_unsupported: exit_unsupported:
kfree(buf); kfree(buf);
return 0; return false;
exit_supported: exit_supported:
kfree(buf); kfree(buf);
return 1; return true;
} }
static void hpsa_get_ioaccel_status(struct ctlr_info *h, static void hpsa_get_ioaccel_status(struct ctlr_info *h,
@ -3539,18 +3549,25 @@ static int hpsa_get_device_id(struct ctlr_info *h, unsigned char *scsi3addr,
int rc; int rc;
unsigned char *buf; unsigned char *buf;
if (buflen > 16) /* Does controller have VPD for device id? */
buflen = 16; if (!hpsa_vpd_page_supported(h, scsi3addr, HPSA_VPD_LV_DEVICE_ID))
return 1; /* not supported */
buf = kzalloc(64, GFP_KERNEL); buf = kzalloc(64, GFP_KERNEL);
if (!buf) if (!buf)
return -ENOMEM; return -ENOMEM;
rc = hpsa_scsi_do_inquiry(h, scsi3addr, VPD_PAGE | 0x83, buf, 64);
if (rc == 0) rc = hpsa_scsi_do_inquiry(h, scsi3addr, VPD_PAGE |
memcpy(device_id, &buf[index], buflen); HPSA_VPD_LV_DEVICE_ID, buf, 64);
if (rc == 0) {
if (buflen > 16)
buflen = 16;
memcpy(device_id, &buf[8], buflen);
}
kfree(buf); kfree(buf);
return rc != 0; return rc; /*0 - got id, otherwise, didn't */
} }
static int hpsa_scsi_do_report_luns(struct ctlr_info *h, int logical, static int hpsa_scsi_do_report_luns(struct ctlr_info *h, int logical,
@ -3821,8 +3838,15 @@ static int hpsa_update_device_info(struct ctlr_info *h,
sizeof(this_device->model)); sizeof(this_device->model));
memset(this_device->device_id, 0, memset(this_device->device_id, 0,
sizeof(this_device->device_id)); sizeof(this_device->device_id));
hpsa_get_device_id(h, scsi3addr, this_device->device_id, 8, if (hpsa_get_device_id(h, scsi3addr, this_device->device_id, 8,
sizeof(this_device->device_id)); sizeof(this_device->device_id)))
dev_err(&h->pdev->dev,
"hpsa%d: %s: can't get device id for host %d:C0:T%d:L%d\t%s\t%.16s\n",
h->ctlr, __func__,
h->scsi_host->host_no,
this_device->target, this_device->lun,
scsi_device_type(this_device->devtype),
this_device->model);
if ((this_device->devtype == TYPE_DISK || if ((this_device->devtype == TYPE_DISK ||
this_device->devtype == TYPE_ZBC) && this_device->devtype == TYPE_ZBC) &&

View File

@ -157,6 +157,7 @@
/* VPD Inquiry types */ /* VPD Inquiry types */
#define HPSA_VPD_SUPPORTED_PAGES 0x00 #define HPSA_VPD_SUPPORTED_PAGES 0x00
#define HPSA_VPD_LV_DEVICE_ID 0x83
#define HPSA_VPD_LV_DEVICE_GEOMETRY 0xC1 #define HPSA_VPD_LV_DEVICE_GEOMETRY 0xC1
#define HPSA_VPD_LV_IOACCEL_STATUS 0xC2 #define HPSA_VPD_LV_IOACCEL_STATUS 0xC2
#define HPSA_VPD_LV_STATUS 0xC3 #define HPSA_VPD_LV_STATUS 0xC3