VOID IoctlToLanscsiBus_Worker( IN PDEVICE_OBJECT DeviceObject, IN PLSMP_WORKITEM_CTX WorkitemCtx ) { PKEVENT AlarmEvent; AlarmEvent = (PKEVENT)WorkitemCtx->Arg3; UNREFERENCED_PARAMETER(DeviceObject); IoctlToLanscsiBus( (ULONG)WorkitemCtx->Ccb, WorkitemCtx->Arg1, (ULONG)WorkitemCtx->Arg2, NULL, 0, NULL ); if(AlarmEvent) KeSetEvent(AlarmEvent, IO_NO_INCREMENT, FALSE); if(WorkitemCtx->Arg2 && WorkitemCtx->Arg1) ExFreePoolWithTag(WorkitemCtx->Arg1, LSMP_PTAG_IOCTL); }
VOID IoctlToLanscsiBus_Worker( IN PDEVICE_OBJECT DeviceObject, IN PNDSC_WORKITEM WorkitemCtx ) { UNREFERENCED_PARAMETER(DeviceObject); IoctlToLanscsiBus( PtrToUlong(WorkitemCtx->Ccb), WorkitemCtx->Arg1, PtrToUlong(WorkitemCtx->Arg2), NULL, 0, NULL ); if(WorkitemCtx->Arg2 && WorkitemCtx->Arg1) ExFreePoolWithTag(WorkitemCtx->Arg1, NDSC_PTAG_IOCTL); }
// // Update Adapter status without Lur. // NTSTATUS UpdateStatusInLSBus( ULONG SlotNo, ULONG AdapterStatus ) { NDASBUS_SETPDOINFO BusSet; ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); // // Update Status in LanscsiBus // BusSet.Size = sizeof(BusSet); BusSet.SlotNo = SlotNo; BusSet.AdapterStatus = AdapterStatus; BusSet.SupportedFeatures = BusSet.EnabledFeatures = 0; return IoctlToLanscsiBus( IOCTL_NDASBUS_SETPDOINFO, &BusSet, sizeof(NDASBUS_SETPDOINFO), NULL, 0, NULL); }
VOID UpdatePdoInfoInLSBus( PMINIPORT_DEVICE_EXTENSION HwDeviceExtension, UINT32 AdapterStatus ) { PNDASBUS_SETPDOINFO busSet; NDAS_FEATURES supportedFeatures, enabledFeatures; ASSERT(HwDeviceExtension); // // Query to the LUR // if(HwDeviceExtension->LURs[0]) { KDPrint(4,("going to default LuExtention 0.\n")); supportedFeatures = HwDeviceExtension->LURs[0]->SupportedNdasFeatures; enabledFeatures = HwDeviceExtension->LURs[0]->EnabledNdasFeatures; } else { KDPrint(2,("No LUR available..\n")); supportedFeatures = enabledFeatures = 0; return; } KDPrint(2,("Set AdapterStatus=%x Supp=%x Enab=%x\n", AdapterStatus, supportedFeatures, enabledFeatures)); // // Send to LSBus // busSet = (PNDASBUS_SETPDOINFO)ExAllocatePoolWithTag(NonPagedPool, sizeof(NDASBUS_SETPDOINFO), NDSC_PTAG_IOCTL); if(busSet == NULL) { return; } busSet->Size = sizeof(NDASBUS_SETPDOINFO); busSet->SlotNo = HwDeviceExtension->SlotNumber; busSet->AdapterStatus = AdapterStatus; busSet->SupportedFeatures = supportedFeatures; busSet->EnabledFeatures = enabledFeatures; if(KeGetCurrentIrql() == PASSIVE_LEVEL) { IoctlToLanscsiBus( IOCTL_NDASBUS_SETPDOINFO, busSet, sizeof(NDASBUS_SETPDOINFO), NULL, 0, NULL); ExFreePoolWithTag(busSet, NDSC_PTAG_IOCTL); } else { // // IoctlToLanscsiBus_Worker() will free memory of BusSet. // IoctlToLanscsiBusByWorker( HwDeviceExtension->ScsiportFdoObject, IOCTL_NDASBUS_SETPDOINFO, busSet, sizeof(NDASBUS_SETPDOINFO) ); } }
// // query scsiport PDO // ULONG GetScsiAdapterPdoEnumInfo( IN PMINIPORT_DEVICE_EXTENSION HwDeviceExtension, IN ULONG SystemIoBusNumber, OUT PLONG AddDevInfoLength, OUT PVOID *AddDevInfo, OUT PULONG AddDevInfoFlags ) { NTSTATUS status; NDASBUS_QUERY_INFORMATION BusQuery; PNDASBUS_INFORMATION BusInfo; LONG BufferNeeded; KDPrint(2,("SystemIoBusNumber:%d\n", SystemIoBusNumber)); ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); BusQuery.Size = sizeof(NDASBUS_QUERY_INFORMATION); BusQuery.InfoClass = INFORMATION_PDOENUM; BusQuery.SlotNo = SystemIoBusNumber; // // Get a buffer length needed. // status = IoctlToLanscsiBus( IOCTL_NDASBUS_QUERY_INFORMATION, &BusQuery, sizeof(NDASBUS_QUERY_INFORMATION), NULL, 0, &BufferNeeded ); if(status != STATUS_BUFFER_TOO_SMALL || BufferNeeded <= 0) { KDPrint(2,("IoctlToLanscsiBus() Failed.\n")); return SP_RETURN_NOT_FOUND; } // // // BusInfo= (PNDASBUS_INFORMATION)ExAllocatePoolWithTag(NonPagedPool, BufferNeeded, NDSC_PTAG_IOCTL); if(BusInfo == NULL) return SP_RETURN_ERROR; status = IoctlToLanscsiBus( IOCTL_NDASBUS_QUERY_INFORMATION, &BusQuery, sizeof(NDASBUS_QUERY_INFORMATION), BusInfo, BufferNeeded, &BufferNeeded ); if(!NT_SUCCESS(status)) { ExFreePoolWithTag(BusInfo, NDSC_PTAG_IOCTL); return SP_RETURN_NOT_FOUND; } HwDeviceExtension->AdapterMaxDataTransferLength = BusInfo->PdoEnumInfo.MaxRequestLength; if(HwDeviceExtension->AdapterMaxDataTransferLength == 0) { HwDeviceExtension->AdapterMaxDataTransferLength = NDAS_MAX_TRANSFER_LENGTH; } HwDeviceExtension->EnumFlags = BusInfo->PdoEnumInfo.Flags; *AddDevInfoFlags = BusInfo->PdoEnumInfo.Flags; KDPrint(2,("MaxRequestLength:%d\n", BusInfo->PdoEnumInfo.MaxRequestLength)); if(BusInfo->PdoEnumInfo.Flags & PDOENUM_FLAG_LURDESC) { ULONG LurDescLen; PLURELATION_DESC lurDesc; PLURELATION_DESC lurDescOrig; lurDescOrig = (PLURELATION_DESC)BusInfo->PdoEnumInfo.AddDevInfo; LurDescLen = lurDescOrig->Length; // // Verify sanity // if(lurDescOrig->Type != LUR_DESC_STRUCT_TYPE) { ExFreePoolWithTag(BusInfo,NDSC_PTAG_IOCTL); KDPrint(2,("LurDescOrig has invalid type: %04x\n", lurDescOrig->Type)); return SP_RETURN_NOT_FOUND; } if(lurDescOrig->CntEcrKeyLength > NDAS_CONTENTENCRYPT_KEY_LENGTH) { ExFreePoolWithTag(BusInfo,NDSC_PTAG_IOCTL); KDPrint(2,("LurDescOrig has invalid key length: %d\n", lurDescOrig->CntEcrKeyLength)); return SP_RETURN_NOT_FOUND; } // // Allocate pool for the LUREALTION descriptor // copy LUREALTION descriptor // lurDesc = (PLURELATION_DESC)ExAllocatePoolWithTag(NonPagedPool, LurDescLen, NDSC_PTAG_ENUMINFO); if(lurDesc == NULL) { ExFreePoolWithTag(BusInfo,NDSC_PTAG_IOCTL); return SP_RETURN_NOT_FOUND; } RtlCopyMemory(lurDesc, &BusInfo->PdoEnumInfo.AddDevInfo, LurDescLen); *AddDevInfo = lurDesc; *AddDevInfoLength = LurDescLen; } else { ASSERT(FALSE); return SP_RETURN_NOT_FOUND; } ExFreePoolWithTag(BusInfo,NDSC_PTAG_IOCTL); return SP_RETURN_FOUND; }
VOID UpdatePdoInfoInLSBus( PMINIPORT_DEVICE_EXTENSION HwDeviceExtension, UINT32 AdapterStatus ) { PBUSENUM_SETPDOINFO BusSet; UINT32 DesiredAccess; UINT32 GrantedAccess; ASSERT(HwDeviceExtension); // // Query to the LUR // if(HwDeviceExtension->LURs[0]) { KDPrint(3,("going to default LuExtention 0.\n")); DesiredAccess = HwDeviceExtension->LURs[0]->DesiredAccess; GrantedAccess = HwDeviceExtension->LURs[0]->GrantedAccess; } else { KDPrint(1,("No LUR available..\n")); DesiredAccess = GrantedAccess = 0; return; } // // Send to LSBus // BusSet = (PBUSENUM_SETPDOINFO)ExAllocatePoolWithTag(NonPagedPool, sizeof(BUSENUM_SETPDOINFO), LSMP_PTAG_IOCTL); if(BusSet == NULL) { return; } BusSet->Size = sizeof(BUSENUM_SETPDOINFO); BusSet->SlotNo = HwDeviceExtension->SlotNumber; BusSet->AdapterStatus = AdapterStatus; BusSet->DesiredAccess = DesiredAccess; BusSet->GrantedAccess = GrantedAccess; if(KeGetCurrentIrql() == PASSIVE_LEVEL) { IoctlToLanscsiBus( IOCTL_LANSCSI_SETPDOINFO, BusSet, sizeof(BUSENUM_SETPDOINFO), NULL, 0, NULL); if(HwDeviceExtension->AlarmEventToService) { KeSetEvent(HwDeviceExtension->AlarmEventToService, IO_NO_INCREMENT, FALSE); } ExFreePoolWithTag(BusSet, LSMP_PTAG_IOCTL); } else { // // IoctlToLanscsiBus_Worker() will free memory of BusSet. // IoctlToLanscsiBusByWorker( HwDeviceExtension->ScsiportFdoObject, IOCTL_LANSCSI_SETPDOINFO, BusSet, sizeof(BUSENUM_SETPDOINFO), HwDeviceExtension->AlarmEventToService ); } }
// // query scsiport PDO // ULONG GetScsiAdapterPdoEnumInfo( IN PMINIPORT_DEVICE_EXTENSION HwDeviceExtension, IN ULONG SystemIoBusNumber, OUT PLONG AddTargetDataLength, OUT PLANSCSI_ADD_TARGET_DATA *AddTargetData ) { NTSTATUS status; BUSENUM_QUERY_INFORMATION BusQuery; PBUSENUM_INFORMATION BusInfo; LONG BufferNeeded; LONG addTargetDataLength; PLANSCSI_ADD_TARGET_DATA addTargetData; KDPrint(1,("SystemIoBusNumber:%d\n", SystemIoBusNumber)); ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); BusQuery.Size = sizeof(BUSENUM_QUERY_INFORMATION); BusQuery.InfoClass = INFORMATION_PDOENUM; BusQuery.SlotNo = SystemIoBusNumber; // // Get a buffer length needed. // status = IoctlToLanscsiBus( IOCTL_BUSENUM_QUERY_INFORMATION, &BusQuery, sizeof(BUSENUM_QUERY_INFORMATION), NULL, 0, &BufferNeeded ); if(status != STATUS_BUFFER_TOO_SMALL || BufferNeeded <= 0) { KDPrint(1,("IoctlToLanscsiBus() Failed.\n")); return SP_RETURN_NOT_FOUND; } // // // BusInfo= (PBUSENUM_INFORMATION)ExAllocatePoolWithTag(NonPagedPool, BufferNeeded, LSMP_PTAG_IOCTL); status = IoctlToLanscsiBus( IOCTL_BUSENUM_QUERY_INFORMATION, &BusQuery, sizeof(BUSENUM_QUERY_INFORMATION), BusInfo, BufferNeeded, &BufferNeeded ); if(!NT_SUCCESS(status)) { ExFreePoolWithTag(BusInfo, LSMP_PTAG_IOCTL); return SP_RETURN_NOT_FOUND; } ASSERT(BusInfo->PdoEnumInfo.DisconEventToService); ASSERT(BusInfo->PdoEnumInfo.AlarmEventToService); HwDeviceExtension->MaxBlocksPerRequest = BusInfo->PdoEnumInfo.MaxBlocksPerRequest; HwDeviceExtension->DisconEventToService = BusInfo->PdoEnumInfo.DisconEventToService; HwDeviceExtension->AlarmEventToService = BusInfo->PdoEnumInfo.AlarmEventToService; KDPrint(1,("MaxBlocksPerRequest:%d DisconEventToService:%p AlarmEventToService:%p\n", BusInfo->PdoEnumInfo.MaxBlocksPerRequest, BusInfo->PdoEnumInfo.DisconEventToService, BusInfo->PdoEnumInfo.AlarmEventToService )); // // copy LANSCSI_ADD_TARGET_DATA // addTargetDataLength = sizeof(LANSCSI_ADD_TARGET_DATA) + (BusInfo->PdoEnumInfo.AddTargetData.ulNumberOfUnitDiskList - 1) * sizeof(LSBUS_UNITDISK); addTargetData = (PLANSCSI_ADD_TARGET_DATA)ExAllocatePoolWithTag(NonPagedPool, addTargetDataLength, LSMP_PTAG_IOCTL); if(addTargetData == NULL) { ExFreePoolWithTag(BusInfo,LSMP_PTAG_IOCTL); return SP_RETURN_NOT_FOUND; } RtlCopyMemory(addTargetData, &BusInfo->PdoEnumInfo.AddTargetData, addTargetDataLength); *AddTargetData = addTargetData; *AddTargetDataLength = addTargetDataLength; ExFreePoolWithTag(BusInfo,LSMP_PTAG_IOCTL); return SP_RETURN_FOUND; }