scsi: smartpqi: Correct device removal for multi-actuator devices
Correct device count for multi-actuator drives which can cause kernel panics. Reviewed-by: Scott Benesh <scott.benesh@microchip.com> Reviewed-by: Scott Teel <scott.teel@microchip.com> Reviewed-by: Mike Mcgowan <mike.mcgowan@microchip.com> Reviewed-by: Kevin Barnett <kevin.barnett@microchip.com> Signed-off-by: Kumar Meiyappan <Kumar.Meiyappan@microchip.com> Signed-off-by: Don Brace <don.brace@microchip.com> Link: https://lore.kernel.org/r/166793531872.322537.9003385780343419275.stgit@brunhilda Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
cbe42ac156
commit
cc9befcbbb
|
@ -1130,7 +1130,7 @@ struct pqi_scsi_dev {
|
|||
u8 phy_id;
|
||||
u8 ncq_prio_enable;
|
||||
u8 ncq_prio_support;
|
||||
u8 multi_lun_device_lun_count;
|
||||
u8 lun_count;
|
||||
bool raid_bypass_configured; /* RAID bypass configured */
|
||||
bool raid_bypass_enabled; /* RAID bypass enabled */
|
||||
u32 next_bypass_group[RAID_MAP_MAX_DATA_DISKS_PER_ROW];
|
||||
|
|
|
@ -1623,9 +1623,7 @@ static int pqi_get_physical_device_info(struct pqi_ctrl_info *ctrl_info,
|
|||
&id_phys->alternate_paths_phys_connector,
|
||||
sizeof(device->phys_connector));
|
||||
device->bay = id_phys->phys_bay_in_box;
|
||||
device->multi_lun_device_lun_count = id_phys->multi_lun_device_lun_count;
|
||||
if (!device->multi_lun_device_lun_count)
|
||||
device->multi_lun_device_lun_count = 1;
|
||||
device->lun_count = id_phys->multi_lun_device_lun_count;
|
||||
if ((id_phys->even_more_flags & PQI_DEVICE_PHY_MAP_SUPPORTED) &&
|
||||
id_phys->phy_count)
|
||||
device->phy_id =
|
||||
|
@ -1759,7 +1757,7 @@ out:
|
|||
return offline;
|
||||
}
|
||||
|
||||
static int pqi_get_device_info(struct pqi_ctrl_info *ctrl_info,
|
||||
static int pqi_get_device_info_phys_logical(struct pqi_ctrl_info *ctrl_info,
|
||||
struct pqi_scsi_dev *device,
|
||||
struct bmic_identify_physical_device *id_phys)
|
||||
{
|
||||
|
@ -1776,6 +1774,20 @@ static int pqi_get_device_info(struct pqi_ctrl_info *ctrl_info,
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int pqi_get_device_info(struct pqi_ctrl_info *ctrl_info,
|
||||
struct pqi_scsi_dev *device,
|
||||
struct bmic_identify_physical_device *id_phys)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = pqi_get_device_info_phys_logical(ctrl_info, device, id_phys);
|
||||
|
||||
if (rc == 0 && device->lun_count == 0)
|
||||
device->lun_count = 1;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void pqi_show_volume_status(struct pqi_ctrl_info *ctrl_info,
|
||||
struct pqi_scsi_dev *device)
|
||||
{
|
||||
|
@ -1910,7 +1922,7 @@ static inline void pqi_remove_device(struct pqi_ctrl_info *ctrl_info, struct pqi
|
|||
int rc;
|
||||
int lun;
|
||||
|
||||
for (lun = 0; lun < device->multi_lun_device_lun_count; lun++) {
|
||||
for (lun = 0; lun < device->lun_count; lun++) {
|
||||
rc = pqi_device_wait_for_pending_io(ctrl_info, device, lun,
|
||||
PQI_REMOVE_DEVICE_PENDING_IO_TIMEOUT_MSECS);
|
||||
if (rc)
|
||||
|
@ -2089,6 +2101,7 @@ static void pqi_scsi_update_device(struct pqi_ctrl_info *ctrl_info,
|
|||
existing_device->sas_address = new_device->sas_address;
|
||||
existing_device->queue_depth = new_device->queue_depth;
|
||||
existing_device->device_offline = false;
|
||||
existing_device->lun_count = new_device->lun_count;
|
||||
|
||||
if (pqi_is_logical_device(existing_device)) {
|
||||
existing_device->is_external_raid_device = new_device->is_external_raid_device;
|
||||
|
@ -2121,10 +2134,6 @@ static void pqi_scsi_update_device(struct pqi_ctrl_info *ctrl_info,
|
|||
existing_device->phy_connected_dev_type = new_device->phy_connected_dev_type;
|
||||
memcpy(existing_device->box, new_device->box, sizeof(existing_device->box));
|
||||
memcpy(existing_device->phys_connector, new_device->phys_connector, sizeof(existing_device->phys_connector));
|
||||
|
||||
existing_device->multi_lun_device_lun_count = new_device->multi_lun_device_lun_count;
|
||||
if (existing_device->multi_lun_device_lun_count == 0)
|
||||
existing_device->multi_lun_device_lun_count = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6502,6 +6511,12 @@ static void pqi_slave_destroy(struct scsi_device *sdev)
|
|||
return;
|
||||
}
|
||||
|
||||
device->lun_count--;
|
||||
if (device->lun_count > 0) {
|
||||
mutex_unlock(&ctrl_info->scan_mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&ctrl_info->scsi_device_list_lock, flags);
|
||||
list_del(&device->scsi_device_list_entry);
|
||||
spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags);
|
||||
|
|
Loading…
Reference in New Issue