Skip to content

Commit d1c8b86

Browse files
Kumar Meiyappangregkh
authored andcommitted
scsi: smartpqi: Correct device removal for multi-actuator devices
[ Upstream commit cc9befc ] 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> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 41d8a93 commit d1c8b86

2 files changed

Lines changed: 25 additions & 10 deletions

File tree

drivers/scsi/smartpqi/smartpqi.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1130,7 +1130,7 @@ struct pqi_scsi_dev {
11301130
u8 phy_id;
11311131
u8 ncq_prio_enable;
11321132
u8 ncq_prio_support;
1133-
u8 multi_lun_device_lun_count;
1133+
u8 lun_count;
11341134
bool raid_bypass_configured; /* RAID bypass configured */
11351135
bool raid_bypass_enabled; /* RAID bypass enabled */
11361136
u32 next_bypass_group[RAID_MAP_MAX_DATA_DISKS_PER_ROW];

drivers/scsi/smartpqi/smartpqi_init.c

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1610,9 +1610,7 @@ static int pqi_get_physical_device_info(struct pqi_ctrl_info *ctrl_info,
16101610
&id_phys->alternate_paths_phys_connector,
16111611
sizeof(device->phys_connector));
16121612
device->bay = id_phys->phys_bay_in_box;
1613-
device->multi_lun_device_lun_count = id_phys->multi_lun_device_lun_count;
1614-
if (!device->multi_lun_device_lun_count)
1615-
device->multi_lun_device_lun_count = 1;
1613+
device->lun_count = id_phys->multi_lun_device_lun_count;
16161614
if ((id_phys->even_more_flags & PQI_DEVICE_PHY_MAP_SUPPORTED) &&
16171615
id_phys->phy_count)
16181616
device->phy_id =
@@ -1746,7 +1744,7 @@ static bool pqi_keep_device_offline(struct pqi_ctrl_info *ctrl_info,
17461744
return offline;
17471745
}
17481746

1749-
static int pqi_get_device_info(struct pqi_ctrl_info *ctrl_info,
1747+
static int pqi_get_device_info_phys_logical(struct pqi_ctrl_info *ctrl_info,
17501748
struct pqi_scsi_dev *device,
17511749
struct bmic_identify_physical_device *id_phys)
17521750
{
@@ -1763,6 +1761,20 @@ static int pqi_get_device_info(struct pqi_ctrl_info *ctrl_info,
17631761
return rc;
17641762
}
17651763

1764+
static int pqi_get_device_info(struct pqi_ctrl_info *ctrl_info,
1765+
struct pqi_scsi_dev *device,
1766+
struct bmic_identify_physical_device *id_phys)
1767+
{
1768+
int rc;
1769+
1770+
rc = pqi_get_device_info_phys_logical(ctrl_info, device, id_phys);
1771+
1772+
if (rc == 0 && device->lun_count == 0)
1773+
device->lun_count = 1;
1774+
1775+
return rc;
1776+
}
1777+
17661778
static void pqi_show_volume_status(struct pqi_ctrl_info *ctrl_info,
17671779
struct pqi_scsi_dev *device)
17681780
{
@@ -1897,7 +1909,7 @@ static inline void pqi_remove_device(struct pqi_ctrl_info *ctrl_info, struct pqi
18971909
int rc;
18981910
int lun;
18991911

1900-
for (lun = 0; lun < device->multi_lun_device_lun_count; lun++) {
1912+
for (lun = 0; lun < device->lun_count; lun++) {
19011913
rc = pqi_device_wait_for_pending_io(ctrl_info, device, lun,
19021914
PQI_REMOVE_DEVICE_PENDING_IO_TIMEOUT_MSECS);
19031915
if (rc)
@@ -2076,6 +2088,7 @@ static void pqi_scsi_update_device(struct pqi_ctrl_info *ctrl_info,
20762088
existing_device->sas_address = new_device->sas_address;
20772089
existing_device->queue_depth = new_device->queue_depth;
20782090
existing_device->device_offline = false;
2091+
existing_device->lun_count = new_device->lun_count;
20792092

20802093
if (pqi_is_logical_device(existing_device)) {
20812094
existing_device->is_external_raid_device = new_device->is_external_raid_device;
@@ -2108,10 +2121,6 @@ static void pqi_scsi_update_device(struct pqi_ctrl_info *ctrl_info,
21082121
existing_device->phy_connected_dev_type = new_device->phy_connected_dev_type;
21092122
memcpy(existing_device->box, new_device->box, sizeof(existing_device->box));
21102123
memcpy(existing_device->phys_connector, new_device->phys_connector, sizeof(existing_device->phys_connector));
2111-
2112-
existing_device->multi_lun_device_lun_count = new_device->multi_lun_device_lun_count;
2113-
if (existing_device->multi_lun_device_lun_count == 0)
2114-
existing_device->multi_lun_device_lun_count = 1;
21152124
}
21162125
}
21172126

@@ -6484,6 +6493,12 @@ static void pqi_slave_destroy(struct scsi_device *sdev)
64846493
return;
64856494
}
64866495

6496+
device->lun_count--;
6497+
if (device->lun_count > 0) {
6498+
mutex_unlock(&ctrl_info->scan_mutex);
6499+
return;
6500+
}
6501+
64876502
spin_lock_irqsave(&ctrl_info->scsi_device_list_lock, flags);
64886503
list_del(&device->scsi_device_list_entry);
64896504
spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags);

0 commit comments

Comments
 (0)