xref: /reactos/drivers/storage/port/scsiport/pdo.c (revision 40462c92)
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