// // Complete all Ccb in a list. // VOID CcbCompleteList( PLIST_ENTRY Head, CHAR CcbStatus, USHORT StatusFlags ) { PLIST_ENTRY listEntry; PCCB ccb; while(1) { listEntry = RemoveHeadList(Head); if(listEntry==Head) break; ccb = CONTAINING_RECORD(listEntry, CCB, ListEntry); ccb->CcbStatus=CcbStatus; // // We do not allow to set CCBSTATUS_FLAG_PENDING and CCBSTATUS_FLAG_COMPLETED except for CcbCompletion function. // LSCcbSetStatusFlag(ccb, CCBSTATUS_FLAG_TIMER_COMPLETE| (StatusFlags & CCBSTATUS_FLAG_ASSIGNMASK)); LSCcbCompleteCcb(ccb); KDPrintM(DBG_LURN_ERROR, ("Completed Ccb:%p\n", ccb)); } }
NTSTATUS RemoveDeviceFromMiniport_Worker( IN PDEVICE_OBJECT DeviceObject, IN PNDSC_WORKITEM WorkitemCtx ) { PMINIPORT_DEVICE_EXTENSION HwDeviceExtension; PMINIPORT_LU_EXTENSION LuExtension; LONG LURCount; KIRQL oldIrql; PLURELATION Lur; PCCB Ccb; NTSTATUS status; ASSERT(WorkitemCtx); UNREFERENCED_PARAMETER(DeviceObject); KDPrint(1,("Entered.\n")); LuExtension = (PMINIPORT_LU_EXTENSION)WorkitemCtx->Arg1; HwDeviceExtension = (PMINIPORT_DEVICE_EXTENSION)WorkitemCtx->Arg3; Ccb = WorkitemCtx->Ccb; ACQUIRE_SPIN_LOCK(&HwDeviceExtension->LanscsiAdapterSpinLock, &oldIrql); // // We support only one LUR for now. // Lur = HwDeviceExtension->LURs[0]; HwDeviceExtension->LURs[0] = NULL; RELEASE_SPIN_LOCK(&HwDeviceExtension->LanscsiAdapterSpinLock, oldIrql); if(!Lur) { if(Ccb) { LSCcbSetStatus(Ccb, CCB_STATUS_NOT_EXIST); LSCcbCompleteCcb(Ccb); } NDScsiLogError( HwDeviceExtension, NULL, 0, 0, 0, NDASSCSI_IO_STOPIOCTL_NO_LUR, EVTLOG_UNIQUEID(EVTLOG_MODULE_IOCTL, EVTLOG_FAIL_LURNULL, 0) ); KDPrint(1,("Error! LUR is NULL!\n")); return STATUS_SUCCESS; } // // send stop CCB // status = SendCcbToLURSync(HwDeviceExtension, Lur, CCB_OPCODE_STOP); if(NT_SUCCESS(status)){ NDScsiLogError( HwDeviceExtension, NULL, 0, 0, 0, NDASSCSI_IO_STOPIOCTL_LUR_ERROR, EVTLOG_UNIQUEID(EVTLOG_MODULE_IOCTL, EVTLOG_FAIL_SENDSTOPCCB, 0xffff & status) ); KDPrint(1,("Failed to send stop ccb.\n")); } LurClose(Lur); LURCount = InterlockedDecrement(&HwDeviceExtension->LURCount); ASSERT(LURCount == 0); // // Dereference the driver object for this LUR // if(Lur != NULL) ObDereferenceObject(_NdscGlobals.DriverObject); // // Notify a bus change. // LSCcbSetStatusFlag(Ccb, CCBSTATUS_FLAG_BUSRESET_REQUIRED); LSCcbSetStatus(Ccb, CCB_STATUS_SUCCESS); LSCcbCompleteCcb(Ccb); return STATUS_SUCCESS; }
NTSTATUS AddNewDeviceToMiniport_Worker( IN PDEVICE_OBJECT DeviceObject, IN PNDSC_WORKITEM WorkitemCtx ) { PMINIPORT_DEVICE_EXTENSION HwDeviceExtension; PMINIPORT_LU_EXTENSION LuExtension; PCCB Ccb; PLURELATION_DESC LurDesc; PLURELATION Lur; NTSTATUS status; LONG LURCount; UINT32 DefaultLurFlags; ASSERT(WorkitemCtx); UNREFERENCED_PARAMETER(DeviceObject); LuExtension =(PMINIPORT_LU_EXTENSION) WorkitemCtx->Arg1; LurDesc = (PLURELATION_DESC)WorkitemCtx->Arg2; HwDeviceExtension = (PMINIPORT_DEVICE_EXTENSION)WorkitemCtx->Arg3; Ccb = WorkitemCtx->Ccb; // // Get default LUR flags. // GetDefaultLurFlags(LurDesc, &DefaultLurFlags); status = LurCreate( LurDesc, DefaultLurFlags, &Lur, 0, HwDeviceExtension->ScsiportFdoObject, LsmpLurnCallback); if(NT_SUCCESS(status)) { LURCount = InterlockedIncrement(&HwDeviceExtension->LURCount); // // We support only one LUR for now. // ASSERT(LURCount == 1); HwDeviceExtension->LURs[0] = Lur; } // // Free LUR Descriptor // ExFreePoolWithTag(LurDesc, LSMP_PTAG_IOCTL); // // Make a reference to driver object for each LUR creation // to prevent from unloading unexpectedly. // Must be decreased at each LUR deletion. // ObReferenceObject(_NdscGlobals.DriverObject); // // Notify a bus change. // LSCcbSetStatusFlag(Ccb, CCBSTATUS_FLAG_BUSRESET_REQUIRED); LSCcbCompleteCcb(Ccb); return status; }