Skip to content

Commit

Permalink
vioscsi: Implement HwUnitControl routine
Browse files Browse the repository at this point in the history
If multiple LUNs exist in the same storage controler, the
HwUnitControl routine needs to be implemented. This routine
handles operations occurring on LUNs.
When the disk is deleted on the host, the HwUnitControl
routine completes the pending I/Os for the deleted disk.

Signed-off-by: Annie Li <[email protected]>
  • Loading branch information
annie-li authored and YanVugenfirer committed Jun 13, 2024
1 parent 0968bf7 commit 35331da
Showing 1 changed file with 90 additions and 0 deletions.
90 changes: 90 additions & 0 deletions vioscsi/vioscsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ HW_STARTIO VioScsiStartIo;
HW_FIND_ADAPTER VioScsiFindAdapter;
HW_RESET_BUS VioScsiResetBus;
HW_ADAPTER_CONTROL VioScsiAdapterControl;
HW_UNIT_CONTROL VioScsiUnitControl;
HW_INTERRUPT VioScsiInterrupt;
HW_DPC_ROUTINE VioScsiCompleteDpcRoutine;
HW_PASSIVE_INITIALIZE_ROUTINE VioScsiIoPassiveInitializeRoutine;
Expand Down Expand Up @@ -122,6 +123,13 @@ VioScsiAdapterControl(
IN PVOID Parameters
);

SCSI_UNIT_CONTROL_STATUS
VioScsiUnitControl(
IN PVOID DeviceExtension,
IN SCSI_UNIT_CONTROL_TYPE ControlType,
IN PVOID Parameters
);

UCHAR
VioScsiProcessPnP(
IN PVOID DeviceExtension,
Expand Down Expand Up @@ -366,6 +374,7 @@ DriverEntry(
hwInitData.HwInterrupt = VioScsiInterrupt;
hwInitData.HwResetBus = VioScsiResetBus;
hwInitData.HwAdapterControl = VioScsiAdapterControl;
hwInitData.HwUnitControl = VioScsiUnitControl;
hwInitData.HwBuildIo = VioScsiBuildIo;

hwInitData.NeedPhysicalAddresses = TRUE;
Expand Down Expand Up @@ -1250,6 +1259,87 @@ EXIT_FN();
return status;
}

SCSI_UNIT_CONTROL_STATUS
VioScsiUnitControl(
IN PVOID DeviceExtension,
IN SCSI_UNIT_CONTROL_TYPE ControlType,
IN PVOID Parameters
)
{
PSCSI_SUPPORTED_CONTROL_TYPE_LIST ControlTypeList;
ULONG AdjustedMaxControlType;
ULONG index;
PADAPTER_EXTENSION adaptExt;
SCSI_UNIT_CONTROL_STATUS Status = ScsiUnitControlUnsuccessful;
BOOLEAN SupportedControlTypes[11] = { 0 };

ENTER_FN();
adaptExt = (PADAPTER_EXTENSION)DeviceExtension;
SupportedControlTypes[0] = 1; //ScsiQuerySupportedControlTypes
SupportedControlTypes[2] = 1; //ScsiUnitStart
SupportedControlTypes[9] = 1; //ScsiUnitRemove
SupportedControlTypes[10] = 1; //ScsiUnitSurpriseRemoval

RhelDbgPrint(TRACE_LEVEL_INFORMATION, " Unit Control Type %d\n", ControlType);
switch (ControlType) {
case ScsiQuerySupportedControlTypes:
ControlTypeList = (PSCSI_SUPPORTED_CONTROL_TYPE_LIST)Parameters;
AdjustedMaxControlType = (ControlTypeList->MaxControlType < 11) ?
ControlTypeList->MaxControlType : 11;
for (index = 0; index < AdjustedMaxControlType; index++) {
ControlTypeList->SupportedTypeList[index] =
SupportedControlTypes[index];
}
Status = ScsiUnitControlSuccess;
break;
case ScsiUnitStart:
Status = ScsiUnitControlSuccess;
break;
case ScsiUnitRemove:
case ScsiUnitSurpriseRemoval:
ULONG QueuNum;
ULONG MsgId;
STOR_LOCK_HANDLE LockHandle = { 0 };
PSTOR_ADDR_BTL8 stor_addr = (PSTOR_ADDR_BTL8)Parameters;

for (index = 0; index < adaptExt->num_queues; index++) {
PREQUEST_LIST element = &adaptExt->processing_srbs[index];
QueuNum = index + VIRTIO_SCSI_REQUEST_QUEUE_0;
MsgId = QUEUE_TO_MESSAGE(QueuNum);
VioScsiVQLock(DeviceExtension, MsgId, &LockHandle, FALSE);
if (!IsListEmpty(&element->srb_list))
{
PLIST_ENTRY entry = element->srb_list.Flink;
while (entry != &element->srb_list) {
PSRB_EXTENSION currSrbExt = CONTAINING_RECORD(entry, SRB_EXTENSION, list_entry);
PSCSI_REQUEST_BLOCK currSrb = currSrbExt->Srb;
if (SRB_PATH_ID(currSrb) == stor_addr->Path &&
SRB_TARGET_ID(currSrb) == stor_addr->Target &&
SRB_LUN(currSrb) == stor_addr->Lun) {
SRB_SET_SRB_STATUS(currSrb, SRB_STATUS_NO_DEVICE);
CompleteRequest(DeviceExtension, (PSRB_TYPE)currSrb);
RhelDbgPrint(TRACE_LEVEL_INFORMATION,
" Complete pending I/Os on Path %d Target %d Lun %d \n",
SRB_PATH_ID(currSrb),
SRB_TARGET_ID(currSrb),
SRB_LUN(currSrb));
element->srb_cnt--;
}
}
}
VioScsiVQUnlock(DeviceExtension, MsgId, &LockHandle, FALSE);
}
Status = ScsiUnitControlSuccess;
break;
default:
RhelDbgPrint(TRACE_LEVEL_ERROR, " Unsupported Unit ControlType %d\n", ControlType);
break;
}

EXIT_FN();
return Status;
}

BOOLEAN
VioScsiBuildIo(
IN PVOID DeviceExtension,
Expand Down

0 comments on commit 35331da

Please sign in to comment.