1 /* 2 * PROJECT: ReactOS Storage Stack / SCSIPORT storage port library 3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) 4 * PURPOSE: Logical Unit (PDO) functions 5 * COPYRIGHT: Eric Kohl (eric.kohl@reactos.org) 6 * Aleksey Bragin (aleksey@reactos.org) 7 */ 8 9 #include "scsiport.h" 10 11 #define NDEBUG 12 #include <debug.h> 13 14 15 PSCSI_PORT_LUN_EXTENSION 16 SpiAllocateLunExtension( 17 _In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension) 18 { 19 PSCSI_PORT_LUN_EXTENSION LunExtension; 20 ULONG LunExtensionSize; 21 22 DPRINT("SpiAllocateLunExtension(%p)\n", DeviceExtension); 23 24 /* Round LunExtensionSize first to the sizeof LONGLONG */ 25 LunExtensionSize = (DeviceExtension->LunExtensionSize + 26 sizeof(LONGLONG) - 1) & ~(sizeof(LONGLONG) - 1); 27 28 LunExtensionSize += sizeof(SCSI_PORT_LUN_EXTENSION); 29 DPRINT("LunExtensionSize %lu\n", LunExtensionSize); 30 31 LunExtension = ExAllocatePoolWithTag(NonPagedPool, LunExtensionSize, TAG_SCSIPORT); 32 if (LunExtension == NULL) 33 { 34 DPRINT1("Out of resources!\n"); 35 return NULL; 36 } 37 38 /* Zero everything */ 39 RtlZeroMemory(LunExtension, LunExtensionSize); 40 41 /* Initialize a list of requests */ 42 InitializeListHead(&LunExtension->SrbInfo.Requests); 43 44 /* Initialize timeout counter */ 45 LunExtension->RequestTimeout = -1; 46 47 /* Set maximum queue size */ 48 LunExtension->MaxQueueCount = 256; 49 50 /* Initialize request queue */ 51 KeInitializeDeviceQueue(&LunExtension->DeviceQueue); 52 53 return LunExtension; 54 } 55 56 PSCSI_PORT_LUN_EXTENSION 57 SpiGetLunExtension( 58 _In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, 59 _In_ UCHAR PathId, 60 _In_ UCHAR TargetId, 61 _In_ UCHAR Lun) 62 { 63 PSCSI_PORT_LUN_EXTENSION LunExtension; 64 65 DPRINT("SpiGetLunExtension(%p %u %u %u) called\n", 66 DeviceExtension, PathId, TargetId, Lun); 67 68 /* Get appropriate list */ 69 LunExtension = DeviceExtension->LunExtensionList[(TargetId + Lun) % LUS_NUMBER]; 70 71 /* Iterate it until we find what we need */ 72 while (LunExtension) 73 { 74 if (LunExtension->TargetId == TargetId && 75 LunExtension->Lun == Lun && 76 LunExtension->PathId == PathId) 77 { 78 /* All matches, return */ 79 return LunExtension; 80 } 81 82 /* Advance to the next item */ 83 LunExtension = LunExtension->Next; 84 } 85 86 /* We did not find anything */ 87 DPRINT("Nothing found\n"); 88 return NULL; 89 } 90 91 PSCSI_REQUEST_BLOCK_INFO 92 SpiGetSrbData( 93 _In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, 94 _In_ UCHAR PathId, 95 _In_ UCHAR TargetId, 96 _In_ UCHAR Lun, 97 _In_ UCHAR QueueTag) 98 { 99 PSCSI_PORT_LUN_EXTENSION LunExtension; 100 101 if (QueueTag == SP_UNTAGGED) 102 { 103 /* Untagged request, get LU and return pointer to SrbInfo */ 104 LunExtension = SpiGetLunExtension(DeviceExtension, 105 PathId, 106 TargetId, 107 Lun); 108 109 /* Return NULL in case of error */ 110 if (!LunExtension) 111 return(NULL); 112 113 /* Return the pointer to SrbInfo */ 114 return &LunExtension->SrbInfo; 115 } 116 else 117 { 118 /* Make sure the tag is valid, if it is - return the data */ 119 if (QueueTag > DeviceExtension->SrbDataCount || QueueTag < 1) 120 return NULL; 121 else 122 return &DeviceExtension->SrbInfo[QueueTag -1]; 123 } 124 } 125