Skip to content

Commit c696f7b

Browse files
suganathprabu0512martinkpetersen
authored andcommitted
scsi: mpt3sas: Implement device_remove_in_progress check in IOCTL path
When device missing event arrives, device_remove_in_progress bit will be set and hence driver has to stop sending IOCTL commands.Now the check has been added in IOCTL path to test device_remove_in_progress bit is set, if so then IOCTL will be failed printing failure message. Signed-off-by: Chaitra P B <chaitra.basappa@broadcom.com> Signed-off-by: Sathya Prakash <sathya.prakash@broadcom.com> Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
1 parent bb35066 commit c696f7b

File tree

4 files changed

+86
-8
lines changed

4 files changed

+86
-8
lines changed

drivers/scsi/mpt3sas/mpt3sas_base.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5334,6 +5334,21 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
53345334
goto out_free_resources;
53355335
}
53365336

5337+
/* allocate memory for pending OS device add list */
5338+
ioc->pend_os_device_add_sz = (ioc->facts.MaxDevHandle / 8);
5339+
if (ioc->facts.MaxDevHandle % 8)
5340+
ioc->pend_os_device_add_sz++;
5341+
ioc->pend_os_device_add = kzalloc(ioc->pend_os_device_add_sz,
5342+
GFP_KERNEL);
5343+
if (!ioc->pend_os_device_add)
5344+
goto out_free_resources;
5345+
5346+
ioc->device_remove_in_progress_sz = ioc->pend_os_device_add_sz;
5347+
ioc->device_remove_in_progress =
5348+
kzalloc(ioc->device_remove_in_progress_sz, GFP_KERNEL);
5349+
if (!ioc->device_remove_in_progress)
5350+
goto out_free_resources;
5351+
53375352
ioc->fwfault_debug = mpt3sas_fwfault_debug;
53385353

53395354
/* base internal command bits */
@@ -5416,6 +5431,8 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
54165431
kfree(ioc->reply_post_host_index);
54175432
kfree(ioc->pd_handles);
54185433
kfree(ioc->blocking_handles);
5434+
kfree(ioc->device_remove_in_progress);
5435+
kfree(ioc->pend_os_device_add);
54195436
kfree(ioc->tm_cmds.reply);
54205437
kfree(ioc->transport_cmds.reply);
54215438
kfree(ioc->scsih_cmds.reply);
@@ -5457,6 +5474,8 @@ mpt3sas_base_detach(struct MPT3SAS_ADAPTER *ioc)
54575474
kfree(ioc->reply_post_host_index);
54585475
kfree(ioc->pd_handles);
54595476
kfree(ioc->blocking_handles);
5477+
kfree(ioc->device_remove_in_progress);
5478+
kfree(ioc->pend_os_device_add);
54605479
kfree(ioc->pfacts);
54615480
kfree(ioc->ctl_cmds.reply);
54625481
kfree(ioc->ctl_cmds.sense);

drivers/scsi/mpt3sas/mpt3sas_base.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1079,6 +1079,9 @@ struct MPT3SAS_ADAPTER {
10791079
void *pd_handles;
10801080
u16 pd_handles_sz;
10811081

1082+
void *pend_os_device_add;
1083+
u16 pend_os_device_add_sz;
1084+
10821085
/* config page */
10831086
u16 config_page_sz;
10841087
void *config_page;
@@ -1187,6 +1190,8 @@ struct MPT3SAS_ADAPTER {
11871190
struct SL_WH_EVENT_TRIGGERS_T diag_trigger_event;
11881191
struct SL_WH_SCSI_TRIGGERS_T diag_trigger_scsi;
11891192
struct SL_WH_MPI_TRIGGERS_T diag_trigger_mpi;
1193+
void *device_remove_in_progress;
1194+
u16 device_remove_in_progress_sz;
11901195
};
11911196

11921197
typedef u8 (*MPT_CALLBACK)(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index,

drivers/scsi/mpt3sas/mpt3sas_ctl.c

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,7 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg,
654654
size_t data_in_sz = 0;
655655
long ret;
656656
u16 wait_state_count;
657+
u16 device_handle = MPT3SAS_INVALID_DEVICE_HANDLE;
657658

658659
issue_reset = 0;
659660

@@ -738,10 +739,13 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg,
738739
data_in_sz = karg.data_in_size;
739740

740741
if (mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST ||
741-
mpi_request->Function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH) {
742-
if (!le16_to_cpu(mpi_request->FunctionDependent1) ||
743-
le16_to_cpu(mpi_request->FunctionDependent1) >
744-
ioc->facts.MaxDevHandle) {
742+
mpi_request->Function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH ||
743+
mpi_request->Function == MPI2_FUNCTION_SCSI_TASK_MGMT ||
744+
mpi_request->Function == MPI2_FUNCTION_SATA_PASSTHROUGH) {
745+
746+
device_handle = le16_to_cpu(mpi_request->FunctionDependent1);
747+
if (!device_handle || (device_handle >
748+
ioc->facts.MaxDevHandle)) {
745749
ret = -EINVAL;
746750
mpt3sas_base_free_smid(ioc, smid);
747751
goto out;
@@ -797,12 +801,18 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg,
797801
scsiio_request->SenseBufferLowAddress =
798802
mpt3sas_base_get_sense_buffer_dma(ioc, smid);
799803
memset(ioc->ctl_cmds.sense, 0, SCSI_SENSE_BUFFERSIZE);
804+
if (test_bit(device_handle, ioc->device_remove_in_progress)) {
805+
dtmprintk(ioc, pr_info(MPT3SAS_FMT
806+
"handle(0x%04x) :ioctl failed due to device removal in progress\n",
807+
ioc->name, device_handle));
808+
mpt3sas_base_free_smid(ioc, smid);
809+
ret = -EINVAL;
810+
goto out;
811+
}
800812
ioc->build_sg(ioc, psge, data_out_dma, data_out_sz,
801813
data_in_dma, data_in_sz);
802-
803814
if (mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST)
804-
mpt3sas_base_put_smid_scsi_io(ioc, smid,
805-
le16_to_cpu(mpi_request->FunctionDependent1));
815+
mpt3sas_base_put_smid_scsi_io(ioc, smid, device_handle);
806816
else
807817
mpt3sas_base_put_smid_default(ioc, smid);
808818
break;
@@ -827,6 +837,14 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg,
827837
}
828838
}
829839

840+
if (test_bit(device_handle, ioc->device_remove_in_progress)) {
841+
dtmprintk(ioc, pr_info(MPT3SAS_FMT
842+
"handle(0x%04x) :ioctl failed due to device removal in progress\n",
843+
ioc->name, device_handle));
844+
mpt3sas_base_free_smid(ioc, smid);
845+
ret = -EINVAL;
846+
goto out;
847+
}
830848
mpt3sas_scsih_set_tm_flag(ioc, le16_to_cpu(
831849
tm_request->DevHandle));
832850
ioc->build_sg_mpi(ioc, psge, data_out_dma, data_out_sz,
@@ -866,6 +884,20 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg,
866884
break;
867885
}
868886
case MPI2_FUNCTION_SATA_PASSTHROUGH:
887+
{
888+
if (test_bit(device_handle, ioc->device_remove_in_progress)) {
889+
dtmprintk(ioc, pr_info(MPT3SAS_FMT
890+
"handle(0x%04x) :ioctl failed due to device removal in progress\n",
891+
ioc->name, device_handle));
892+
mpt3sas_base_free_smid(ioc, smid);
893+
ret = -EINVAL;
894+
goto out;
895+
}
896+
ioc->build_sg(ioc, psge, data_out_dma, data_out_sz, data_in_dma,
897+
data_in_sz);
898+
mpt3sas_base_put_smid_default(ioc, smid);
899+
break;
900+
}
869901
case MPI2_FUNCTION_FW_DOWNLOAD:
870902
case MPI2_FUNCTION_FW_UPLOAD:
871903
{

drivers/scsi/mpt3sas/mpt3sas_scsih.c

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -788,6 +788,11 @@ _scsih_sas_device_add(struct MPT3SAS_ADAPTER *ioc,
788788
list_add_tail(&sas_device->list, &ioc->sas_device_list);
789789
spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
790790

791+
if (ioc->hide_drives) {
792+
clear_bit(sas_device->handle, ioc->pend_os_device_add);
793+
return;
794+
}
795+
791796
if (!mpt3sas_transport_port_add(ioc, sas_device->handle,
792797
sas_device->sas_address_parent)) {
793798
_scsih_sas_device_remove(ioc, sas_device);
@@ -803,7 +808,8 @@ _scsih_sas_device_add(struct MPT3SAS_ADAPTER *ioc,
803808
sas_device->sas_address_parent);
804809
_scsih_sas_device_remove(ioc, sas_device);
805810
}
806-
}
811+
} else
812+
clear_bit(sas_device->handle, ioc->pend_os_device_add);
807813
}
808814

809815
/**
@@ -3138,6 +3144,8 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 handle)
31383144
if (test_bit(handle, ioc->pd_handles))
31393145
return;
31403146

3147+
clear_bit(handle, ioc->pend_os_device_add);
3148+
31413149
spin_lock_irqsave(&ioc->sas_device_lock, flags);
31423150
sas_device = __mpt3sas_get_sdev_by_handle(ioc, handle);
31433151
if (sas_device && sas_device->starget &&
@@ -3192,6 +3200,7 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 handle)
31923200
mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
31933201
mpi_request->DevHandle = cpu_to_le16(handle);
31943202
mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
3203+
set_bit(handle, ioc->device_remove_in_progress);
31953204
mpt3sas_base_put_smid_hi_priority(ioc, smid, 0);
31963205
mpt3sas_trigger_master(ioc, MASTER_TRIGGER_DEVICE_REMOVAL);
31973206

@@ -3326,6 +3335,11 @@ _scsih_sas_control_complete(struct MPT3SAS_ADAPTER *ioc, u16 smid,
33263335
ioc->name, le16_to_cpu(mpi_reply->DevHandle), smid,
33273336
le16_to_cpu(mpi_reply->IOCStatus),
33283337
le32_to_cpu(mpi_reply->IOCLogInfo)));
3338+
if (le16_to_cpu(mpi_reply->IOCStatus) ==
3339+
MPI2_IOCSTATUS_SUCCESS) {
3340+
clear_bit(le16_to_cpu(mpi_reply->DevHandle),
3341+
ioc->device_remove_in_progress);
3342+
}
33293343
} else {
33303344
pr_err(MPT3SAS_FMT "mpi_reply not valid at %s:%d/%s()!\n",
33313345
ioc->name, __FILE__, __LINE__, __func__);
@@ -5449,6 +5463,7 @@ _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle, u8 phy_num,
54495463
device_info = le32_to_cpu(sas_device_pg0.DeviceInfo);
54505464
if (!(_scsih_is_end_device(device_info)))
54515465
return -1;
5466+
set_bit(handle, ioc->pend_os_device_add);
54525467
sas_address = le64_to_cpu(sas_device_pg0.SASAddress);
54535468

54545469
/* check if device is present */
@@ -5467,6 +5482,7 @@ _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle, u8 phy_num,
54675482
sas_device = mpt3sas_get_sdev_by_addr(ioc,
54685483
sas_address);
54695484
if (sas_device) {
5485+
clear_bit(handle, ioc->pend_os_device_add);
54705486
sas_device_put(sas_device);
54715487
return -1;
54725488
}
@@ -5790,6 +5806,9 @@ _scsih_sas_topology_change_event(struct MPT3SAS_ADAPTER *ioc,
57905806
_scsih_check_device(ioc, sas_address, handle,
57915807
phy_number, link_rate);
57925808

5809+
if (!test_bit(handle, ioc->pend_os_device_add))
5810+
break;
5811+
57935812

57945813
case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED:
57955814

@@ -7707,6 +7726,9 @@ mpt3sas_scsih_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase)
77077726
complete(&ioc->tm_cmds.done);
77087727
}
77097728

7729+
memset(ioc->pend_os_device_add, 0, ioc->pend_os_device_add_sz);
7730+
memset(ioc->device_remove_in_progress, 0,
7731+
ioc->device_remove_in_progress_sz);
77107732
_scsih_fw_event_cleanup_queue(ioc);
77117733
_scsih_flush_running_cmds(ioc);
77127734
break;

0 commit comments

Comments
 (0)