diff options
author | Don Brace <don.brace@microsemi.com> | 2017-03-10 15:35:11 -0500 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2017-03-15 13:36:22 -0400 |
commit | 85b29008d8af6d94a0723aaa8d93cfb6e041158b (patch) | |
tree | 1f74c0641fc5c48acfc3f8c1b882033c09f4c21c | |
parent | 22487b66594f18f2a7c211f3ab8bb02dec74d37b (diff) |
scsi: hpsa: update check for logical volume status
- Add in a new case for volume offline. Resolves internal testing bug
for multilun array management.
- Return correct status for failed TURs.
Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
Reviewed-by: Scott Teel <scott.teel@microsemi.com>
Signed-off-by: Don Brace <don.brace@microsemi.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r-- | drivers/scsi/hpsa.c | 35 | ||||
-rw-r--r-- | drivers/scsi/hpsa_cmd.h | 2 |
2 files changed, 18 insertions, 19 deletions
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 524a0c755ed7..90b76c4c6d36 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c | |||
@@ -3714,7 +3714,7 @@ exit_failed: | |||
3714 | * # (integer code indicating one of several NOT READY states | 3714 | * # (integer code indicating one of several NOT READY states |
3715 | * describing why a volume is to be kept offline) | 3715 | * describing why a volume is to be kept offline) |
3716 | */ | 3716 | */ |
3717 | static int hpsa_volume_offline(struct ctlr_info *h, | 3717 | static unsigned char hpsa_volume_offline(struct ctlr_info *h, |
3718 | unsigned char scsi3addr[]) | 3718 | unsigned char scsi3addr[]) |
3719 | { | 3719 | { |
3720 | struct CommandList *c; | 3720 | struct CommandList *c; |
@@ -3735,7 +3735,7 @@ static int hpsa_volume_offline(struct ctlr_info *h, | |||
3735 | DEFAULT_TIMEOUT); | 3735 | DEFAULT_TIMEOUT); |
3736 | if (rc) { | 3736 | if (rc) { |
3737 | cmd_free(h, c); | 3737 | cmd_free(h, c); |
3738 | return 0; | 3738 | return HPSA_VPD_LV_STATUS_UNSUPPORTED; |
3739 | } | 3739 | } |
3740 | sense = c->err_info->SenseInfo; | 3740 | sense = c->err_info->SenseInfo; |
3741 | if (c->err_info->SenseLen > sizeof(c->err_info->SenseInfo)) | 3741 | if (c->err_info->SenseLen > sizeof(c->err_info->SenseInfo)) |
@@ -3746,19 +3746,13 @@ static int hpsa_volume_offline(struct ctlr_info *h, | |||
3746 | cmd_status = c->err_info->CommandStatus; | 3746 | cmd_status = c->err_info->CommandStatus; |
3747 | scsi_status = c->err_info->ScsiStatus; | 3747 | scsi_status = c->err_info->ScsiStatus; |
3748 | cmd_free(h, c); | 3748 | cmd_free(h, c); |
3749 | /* Is the volume 'not ready'? */ | ||
3750 | if (cmd_status != CMD_TARGET_STATUS || | ||
3751 | scsi_status != SAM_STAT_CHECK_CONDITION || | ||
3752 | sense_key != NOT_READY || | ||
3753 | asc != ASC_LUN_NOT_READY) { | ||
3754 | return 0; | ||
3755 | } | ||
3756 | 3749 | ||
3757 | /* Determine the reason for not ready state */ | 3750 | /* Determine the reason for not ready state */ |
3758 | ldstat = hpsa_get_volume_status(h, scsi3addr); | 3751 | ldstat = hpsa_get_volume_status(h, scsi3addr); |
3759 | 3752 | ||
3760 | /* Keep volume offline in certain cases: */ | 3753 | /* Keep volume offline in certain cases: */ |
3761 | switch (ldstat) { | 3754 | switch (ldstat) { |
3755 | case HPSA_LV_FAILED: | ||
3762 | case HPSA_LV_UNDERGOING_ERASE: | 3756 | case HPSA_LV_UNDERGOING_ERASE: |
3763 | case HPSA_LV_NOT_AVAILABLE: | 3757 | case HPSA_LV_NOT_AVAILABLE: |
3764 | case HPSA_LV_UNDERGOING_RPI: | 3758 | case HPSA_LV_UNDERGOING_RPI: |
@@ -3780,7 +3774,7 @@ static int hpsa_volume_offline(struct ctlr_info *h, | |||
3780 | default: | 3774 | default: |
3781 | break; | 3775 | break; |
3782 | } | 3776 | } |
3783 | return 0; | 3777 | return HPSA_LV_OK; |
3784 | } | 3778 | } |
3785 | 3779 | ||
3786 | /* | 3780 | /* |
@@ -3853,10 +3847,10 @@ static int hpsa_update_device_info(struct ctlr_info *h, | |||
3853 | /* Do an inquiry to the device to see what it is. */ | 3847 | /* Do an inquiry to the device to see what it is. */ |
3854 | if (hpsa_scsi_do_inquiry(h, scsi3addr, 0, inq_buff, | 3848 | if (hpsa_scsi_do_inquiry(h, scsi3addr, 0, inq_buff, |
3855 | (unsigned char) OBDR_TAPE_INQ_SIZE) != 0) { | 3849 | (unsigned char) OBDR_TAPE_INQ_SIZE) != 0) { |
3856 | /* Inquiry failed (msg printed already) */ | ||
3857 | dev_err(&h->pdev->dev, | 3850 | dev_err(&h->pdev->dev, |
3858 | "hpsa_update_device_info: inquiry failed\n"); | 3851 | "%s: inquiry failed, device will be skipped.\n", |
3859 | rc = -EIO; | 3852 | __func__); |
3853 | rc = HPSA_INQUIRY_FAILED; | ||
3860 | goto bail_out; | 3854 | goto bail_out; |
3861 | } | 3855 | } |
3862 | 3856 | ||
@@ -3885,15 +3879,19 @@ static int hpsa_update_device_info(struct ctlr_info *h, | |||
3885 | if ((this_device->devtype == TYPE_DISK || | 3879 | if ((this_device->devtype == TYPE_DISK || |
3886 | this_device->devtype == TYPE_ZBC) && | 3880 | this_device->devtype == TYPE_ZBC) && |
3887 | is_logical_dev_addr_mode(scsi3addr)) { | 3881 | is_logical_dev_addr_mode(scsi3addr)) { |
3888 | int volume_offline; | 3882 | unsigned char volume_offline; |
3889 | 3883 | ||
3890 | hpsa_get_raid_level(h, scsi3addr, &this_device->raid_level); | 3884 | hpsa_get_raid_level(h, scsi3addr, &this_device->raid_level); |
3891 | if (h->fw_support & MISC_FW_RAID_OFFLOAD_BASIC) | 3885 | if (h->fw_support & MISC_FW_RAID_OFFLOAD_BASIC) |
3892 | hpsa_get_ioaccel_status(h, scsi3addr, this_device); | 3886 | hpsa_get_ioaccel_status(h, scsi3addr, this_device); |
3893 | volume_offline = hpsa_volume_offline(h, scsi3addr); | 3887 | volume_offline = hpsa_volume_offline(h, scsi3addr); |
3894 | if (volume_offline < 0 || volume_offline > 0xff) | 3888 | if (volume_offline == HPSA_LV_FAILED) { |
3895 | volume_offline = HPSA_VPD_LV_STATUS_UNSUPPORTED; | 3889 | rc = HPSA_LV_FAILED; |
3896 | this_device->volume_offline = volume_offline & 0xff; | 3890 | dev_err(&h->pdev->dev, |
3891 | "%s: LV failed, device will be skipped.\n", | ||
3892 | __func__); | ||
3893 | goto bail_out; | ||
3894 | } | ||
3897 | } else { | 3895 | } else { |
3898 | this_device->raid_level = RAID_UNKNOWN; | 3896 | this_device->raid_level = RAID_UNKNOWN; |
3899 | this_device->offload_config = 0; | 3897 | this_device->offload_config = 0; |
@@ -4379,8 +4377,7 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h) | |||
4379 | goto out; | 4377 | goto out; |
4380 | } | 4378 | } |
4381 | if (rc) { | 4379 | if (rc) { |
4382 | dev_warn(&h->pdev->dev, | 4380 | h->drv_req_rescan = 1; |
4383 | "Inquiry failed, skipping device.\n"); | ||
4384 | continue; | 4381 | continue; |
4385 | } | 4382 | } |
4386 | 4383 | ||
diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h index a584cdf07058..5961705eef76 100644 --- a/drivers/scsi/hpsa_cmd.h +++ b/drivers/scsi/hpsa_cmd.h | |||
@@ -156,6 +156,7 @@ | |||
156 | #define CFGTBL_BusType_Fibre2G 0x00000200l | 156 | #define CFGTBL_BusType_Fibre2G 0x00000200l |
157 | 157 | ||
158 | /* VPD Inquiry types */ | 158 | /* VPD Inquiry types */ |
159 | #define HPSA_INQUIRY_FAILED 0x02 | ||
159 | #define HPSA_VPD_SUPPORTED_PAGES 0x00 | 160 | #define HPSA_VPD_SUPPORTED_PAGES 0x00 |
160 | #define HPSA_VPD_LV_DEVICE_ID 0x83 | 161 | #define HPSA_VPD_LV_DEVICE_ID 0x83 |
161 | #define HPSA_VPD_LV_DEVICE_GEOMETRY 0xC1 | 162 | #define HPSA_VPD_LV_DEVICE_GEOMETRY 0xC1 |
@@ -166,6 +167,7 @@ | |||
166 | /* Logical volume states */ | 167 | /* Logical volume states */ |
167 | #define HPSA_VPD_LV_STATUS_UNSUPPORTED 0xff | 168 | #define HPSA_VPD_LV_STATUS_UNSUPPORTED 0xff |
168 | #define HPSA_LV_OK 0x0 | 169 | #define HPSA_LV_OK 0x0 |
170 | #define HPSA_LV_FAILED 0x01 | ||
169 | #define HPSA_LV_NOT_AVAILABLE 0x0b | 171 | #define HPSA_LV_NOT_AVAILABLE 0x0b |
170 | #define HPSA_LV_UNDERGOING_ERASE 0x0F | 172 | #define HPSA_LV_UNDERGOING_ERASE 0x0F |
171 | #define HPSA_LV_UNDERGOING_RPI 0x12 | 173 | #define HPSA_LV_UNDERGOING_RPI 0x12 |