]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/IScsiDxe/IScsiExtScsiPassThru.c
sync comments, fix function header, rename variable name to follow coding style.
[mirror_edk2.git] / MdeModulePkg / Universal / Network / IScsiDxe / IScsiExtScsiPassThru.c
CommitLineData
12618416 1/** @file\r
2 The IScsi's EFI_EXT_SCSI_PASS_THRU_PROTOCOL driver\r
6a690e23 3\r
7a444476 4Copyright (c) 2004 - 2007, Intel Corporation\r
5All rights reserved. This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
6a690e23 12\r
13Module Name:\r
14\r
15 IScsiExtScsiPassThru.c\r
16\r
17Abstract:\r
12618416 18 The IScsi's EFI_EXT_SCSI_PASS_THRU_PROTOCOL driver\r
6a690e23 19\r
12618416 20**/\r
6a690e23 21\r
22#include "IScsiImpl.h"\r
23\r
12618416 24/**\r
25 This function sends out the SCSI command via iSCSI transport layer and returned\r
26 back the data received from the iSCSI target. \r
27\r
28 @param This[in] The EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance.\r
29\r
30 @param Target[in] The Target ID of device to send the SCSI Request Packet. \r
31\r
32 @param Lun[in] The LUN of the device to send the SCSI Request Packet.\r
33\r
34 @param Packet[in][out] The SCSI Request Packet to send to the device.\r
35\r
36 @param Event[in] The event used in non-blocking mode, it should be always NULL.\r
37\r
38 @retval EFI_STATUS\r
39\r
40**/\r
6a690e23 41EFI_STATUS\r
42EFIAPI\r
43IScsiExtScsiPassThruFunction (\r
44 IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,\r
45 IN UINT8 *Target,\r
46 IN UINT64 Lun,\r
47 IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet,\r
48 IN EFI_EVENT Event OPTIONAL\r
49 )\r
6a690e23 50{\r
51 if (Target[0] != 0) {\r
52 return EFI_INVALID_PARAMETER;\r
53 }\r
54\r
55 if ((Packet == NULL) || (Packet->Cdb == NULL)) {\r
56 return EFI_INVALID_PARAMETER;\r
57 }\r
58\r
59 return IScsiExecuteScsiCommand (This, Target, Lun, Packet);\r
60}\r
61\r
12618416 62/**\r
63 Retrieve the list of legal Target IDs for SCSI devices on a SCSI channel.\r
6a690e23 64\r
12618416 65 @param This[in] The EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance.\r
6a690e23 66\r
12618416 67 @param Target[in][out] On input, a pointer to the Target ID of a SCSI device present on the\r
68 SCSI channel. On output, a pointer to the Target ID of the next SCSI\r
69 device present on a SCSI channel. An input value of 0xFFFFFFFF retrieves\r
70 the Target ID of the first SCSI device present on a SCSI channel.\r
6a690e23 71\r
12618416 72 @param Lun[in][out] On input, a pointer to the LUN of a SCSI device present on the SCSI\r
73 channel. On output, a pointer to the LUN of the next SCSI device\r
74 present on a SCSI channel.\r
6a690e23 75\r
12618416 76 @retval EFI_SUCCESS The Target ID and Lun of the next SCSI device \r
77 on the SCSI channel was returned in Target and Lun.\r
6a690e23 78\r
12618416 79 @retval EFI_NOT_FOUND There are no more SCSI devices on this SCSI channel.\r
6a690e23 80\r
12618416 81 @retval EFI_INVALID_PARAMETER Target is not 0xFFFFFFFF,and Target and Lun were not\r
82 returned on a previous call to GetNextDevice().\r
6a690e23 83\r
12618416 84**/\r
85EFI_STATUS\r
86EFIAPI\r
87IScsiExtScsiPassThruGetNextTargetLun (\r
88 IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,\r
89 IN OUT UINT8 **Target,\r
90 IN OUT UINT64 *Lun\r
91 )\r
6a690e23 92{\r
93 ISCSI_DRIVER_DATA *Private;\r
94 ISCSI_SESSION_CONFIG_NVDATA *ConfigNvData;\r
95 UINT8 TargetId[TARGET_MAX_BYTES];\r
96\r
97 Private = ISCSI_DRIVER_DATA_FROM_EXT_SCSI_PASS_THRU (This);\r
98 ConfigNvData = &Private->Session.ConfigData.NvData;\r
99\r
e48e37fc 100 if ((*Target)[0] == 0 && (CompareMem (Lun, ConfigNvData->BootLun, sizeof (UINT64)) == 0)) {\r
6a690e23 101 //\r
102 // Only one <Target, Lun> pair per iSCSI Driver instance.\r
103 //\r
104 return EFI_NOT_FOUND;\r
105 }\r
106\r
e48e37fc 107 SetMem (TargetId, TARGET_MAX_BYTES, 0xFF);\r
108 if (CompareMem (*Target, TargetId, TARGET_MAX_BYTES) == 0) {\r
6a690e23 109 (*Target)[0] = 0;\r
e48e37fc 110 CopyMem (Lun, ConfigNvData->BootLun, sizeof (UINT64));\r
6a690e23 111\r
112 return EFI_SUCCESS;\r
113 }\r
114\r
115 return EFI_INVALID_PARAMETER;\r
116}\r
117\r
12618416 118/**\r
119 Allocate and build a device path node for a SCSI device on a SCSI channel.\r
120\r
121 @param This[in] Protocol instance pointer.\r
122\r
123 @param Target[in] The Target ID of the SCSI device for which\r
124 a device path node is to be allocated and built.\r
125\r
126 @param Lun[in] The LUN of the SCSI device for which a device \r
127 path node is to be allocated and built.\r
128\r
129 @param DevicePath[in][out] A pointer to a single device path node that \r
130 describes the SCSI device specified by \r
131 Target and Lun. This function is responsible \r
132 for allocating the buffer DevicePath with the boot\r
133 service AllocatePool(). It is the caller's \r
134 responsibility to free DevicePath when the caller\r
135 is finished with DevicePath. \r
136\r
137 @retval EFI_SUCCESS The device path node that describes the SCSI device\r
138 specified by Target and Lun was allocated and \r
139 returned in DevicePath.\r
140\r
141 @retval EFI_NOT_FOUND The SCSI devices specified by Target and Lun does\r
142 not exist on the SCSI channel.\r
143\r
144 @retval EFI_INVALID_PARAMETER DevicePath is NULL.\r
145\r
146 @retval EFI_OUT_OF_RESOURCES There are not enough resources to allocate \r
147 DevicePath.\r
148\r
149**/\r
6a690e23 150EFI_STATUS\r
151EFIAPI\r
152IScsiExtScsiPassThruBuildDevicePath (\r
153 IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,\r
154 IN UINT8 *Target,\r
155 IN UINT64 Lun,\r
156 IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath\r
157 )\r
6a690e23 158{\r
159 ISCSI_DRIVER_DATA *Private;\r
160 ISCSI_SESSION *Session;\r
161 ISCSI_SESSION_CONFIG_NVDATA *ConfigNvData;\r
162 ISCSI_CHAP_AUTH_CONFIG_NVDATA *AuthConfig;\r
163 EFI_DEV_PATH *Node;\r
164 UINTN DevPathNodeLen;\r
165\r
166 if ((DevicePath == NULL)) {\r
167 return EFI_INVALID_PARAMETER;\r
168 }\r
169\r
170 if (Target[0] != 0) {\r
171 return EFI_NOT_FOUND;\r
172 }\r
173\r
174 Private = ISCSI_DRIVER_DATA_FROM_EXT_SCSI_PASS_THRU (This);\r
175 Session = &Private->Session;\r
176 ConfigNvData = &Session->ConfigData.NvData;\r
177 AuthConfig = &Session->AuthData.AuthConfig;\r
178\r
e48e37fc 179 if (CompareMem (&Lun, ConfigNvData->BootLun, sizeof (UINT64)) != 0) {\r
6a690e23 180 return EFI_NOT_FOUND;\r
181 }\r
182\r
183 DevPathNodeLen = sizeof (ISCSI_DEVICE_PATH) + AsciiStrLen (ConfigNvData->TargetName) + 1;\r
e48e37fc 184 Node = AllocatePool (DevPathNodeLen);\r
6a690e23 185 if (Node == NULL) {\r
186 return EFI_OUT_OF_RESOURCES;\r
187 }\r
188\r
189 Node->DevPath.Type = MESSAGING_DEVICE_PATH;\r
190 Node->DevPath.SubType = MSG_ISCSI_DP;\r
1232b214 191 SetDevicePathNodeLength (&Node->DevPath, (UINT16)DevPathNodeLen);\r
6a690e23 192\r
193 //\r
194 // 0 for TCP, others are reserved.\r
195 //\r
196 Node->Iscsi.NetworkProtocol = 0;\r
197\r
198 Node->Iscsi.LoginOption = 0;\r
199 switch (AuthConfig->CHAPType) {\r
200 case ISCSI_CHAP_NONE:\r
201 Node->Iscsi.LoginOption |= 0x0800;\r
202 break;\r
203\r
204 case ISCSI_CHAP_UNI:\r
205 Node->Iscsi.LoginOption |= 0x1000;\r
206 break;\r
207\r
208 default:\r
209 break;\r
210 }\r
211\r
e48e37fc 212 CopyMem (&Node->Iscsi.Lun, ConfigNvData->BootLun, sizeof (UINT64));\r
6a690e23 213 Node->Iscsi.TargetPortalGroupTag = Session->TargetPortalGroupTag;\r
214 AsciiStrCpy ((CHAR8 *) Node + sizeof (ISCSI_DEVICE_PATH), ConfigNvData->TargetName);\r
215\r
216 *DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) Node;\r
217\r
218 return EFI_SUCCESS;\r
219}\r
220\r
12618416 221/**\r
222 Translate a device path node to a Target ID and LUN.\r
223\r
224 @param This[in] Protocol instance pointer.\r
225\r
226 @param DevicePath[in] A pointer to the device path node that \r
227 describes a SCSI device on the SCSI channel.\r
228\r
229 @param Target[out] A pointer to the Target ID of a SCSI device \r
230 on the SCSI channel. \r
231\r
232 @param Lun[out] A pointer to the LUN of a SCSI device on \r
233 the SCSI channel. \r
234\r
235 @retval EFI_SUCCESS DevicePath was successfully translated to a \r
236 Target ID and LUN, and they were returned \r
237 in Target and Lun.\r
238\r
239 @retval EFI_INVALID_PARAMETER DevicePath/Target/Lun is NULL.\r
240\r
241 @retval EFI_UNSUPPORTED This driver does not support the device path \r
242 node type in DevicePath.\r
243\r
244 @retval EFI_NOT_FOUND A valid translation from DevicePath to a \r
245 Target ID and LUN does not exist.\r
246\r
247**/\r
6a690e23 248EFI_STATUS\r
249EFIAPI\r
250IScsiExtScsiPassThruGetTargetLun (\r
251 IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,\r
252 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
253 OUT UINT8 **Target,\r
254 OUT UINT64 *Lun\r
255 )\r
6a690e23 256{\r
257 ISCSI_DRIVER_DATA *Private;\r
258 ISCSI_SESSION_CONFIG_NVDATA *ConfigNvData;\r
259\r
260 if ((DevicePath == NULL) || (Target == NULL) || (Lun == NULL)) {\r
261 return EFI_INVALID_PARAMETER;\r
262 }\r
263\r
264 if ((DevicePath->Type != MESSAGING_DEVICE_PATH) ||\r
265 (DevicePath->SubType != MSG_ISCSI_DP) ||\r
266 (DevicePathNodeLength (DevicePath) <= sizeof (ISCSI_DEVICE_PATH))\r
267 ) {\r
268 return EFI_UNSUPPORTED;\r
269 }\r
270\r
271 Private = ISCSI_DRIVER_DATA_FROM_EXT_SCSI_PASS_THRU (This);\r
272 ConfigNvData = &Private->Session.ConfigData.NvData;\r
273\r
e48e37fc 274 ZeroMem (*Target, TARGET_MAX_BYTES);\r
6a690e23 275\r
276 if (AsciiStrCmp (ConfigNvData->TargetName, (CHAR8 *) DevicePath + sizeof (ISCSI_DEVICE_PATH)) != 0) {\r
277 return EFI_UNSUPPORTED;\r
278 }\r
279\r
e48e37fc 280 CopyMem (Lun, ConfigNvData->BootLun, sizeof (UINT64));\r
6a690e23 281\r
282 return EFI_SUCCESS;\r
283}\r
284\r
12618416 285/**\r
286 Resets a SCSI channel.This operation resets all the SCSI devices connected to\r
287 the SCSI channel.\r
288\r
289 @param This[in] Protocol instance pointer.\r
290\r
291 @retval EFI_UNSUPPORTED It's not supported.\r
292\r
293**/\r
6a690e23 294EFI_STATUS\r
295EFIAPI\r
296IScsiExtScsiPassThruResetChannel (\r
297 IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This\r
298 )\r
12618416 299{\r
300 return EFI_UNSUPPORTED;\r
301}\r
6a690e23 302\r
12618416 303/**\r
304 Resets a SCSI device that is connected to a SCSI channel.\r
6a690e23 305\r
12618416 306 @param This[in] Protocol instance pointer.\r
6a690e23 307\r
12618416 308 @param Target[in] The Target ID of the SCSI device to reset.\r
6a690e23 309\r
12618416 310 @param Lun[in] The LUN of the SCSI device to reset.\r
6a690e23 311\r
12618416 312 @retval EFI_UNSUPPORTED It's not supported.\r
6a690e23 313\r
12618416 314**/\r
6a690e23 315EFI_STATUS\r
316EFIAPI\r
317IScsiExtScsiPassThruResetTargetLun (\r
318 IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,\r
319 IN UINT8 *Target,\r
320 IN UINT64 Lun\r
321 )\r
12618416 322{\r
323 return EFI_UNSUPPORTED;\r
324}\r
6a690e23 325\r
12618416 326/**\r
327 Retrieve the list of legal Target IDs for SCSI devices on a SCSI channel.\r
6a690e23 328\r
12618416 329 @param This[in] Protocol instance pointer.\r
6a690e23 330\r
12618416 331 @param Target[in] On input, a pointer to the Target ID of a SCSI \r
332 device present on the SCSI channel. On output, \r
333 a pointer to the Target ID of the next SCSI device\r
334 present on a SCSI channel. An input value of \r
335 0xFFFFFFFF retrieves the Target ID of the first \r
336 SCSI device present on a SCSI channel.\r
6a690e23 337\r
12618416 338 @retval EFI_SUCCESS The Target ID and Lun of the next SCSI device \r
339 on the SCSI channel was returned in Target and Lun.\r
6a690e23 340\r
12618416 341 @retval EFI_NOT_FOUND There are no more SCSI devices on this SCSI channel.\r
6a690e23 342\r
12618416 343 @retval EFI_INVALID_PARAMETER Target is not 0xFFFFFFFF,and Target and Lun were not\r
344 returned on a previous call to GetNextDevice().\r
6a690e23 345\r
12618416 346**/\r
6a690e23 347EFI_STATUS\r
348EFIAPI\r
349IScsiExtScsiPassThruGetNextTarget (\r
350 IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,\r
351 IN OUT UINT8 **Target\r
352 )\r
6a690e23 353{\r
354 UINT8 TargetId[TARGET_MAX_BYTES];\r
355\r
e48e37fc 356 SetMem (TargetId, TARGET_MAX_BYTES, 0xFF);\r
6a690e23 357\r
e48e37fc 358 if (CompareMem (*Target, TargetId, TARGET_MAX_BYTES) == 0) {\r
6a690e23 359 (*Target)[0] = 0;\r
360 return EFI_SUCCESS;\r
361 } else if ((*Target)[0] == 0) {\r
362 return EFI_NOT_FOUND;\r
363 } else {\r
364 return EFI_INVALID_PARAMETER;\r
365 }\r
366}\r
367\r
368EFI_EXT_SCSI_PASS_THRU_PROTOCOL gIScsiExtScsiPassThruProtocolTemplate = {\r
369 NULL,\r
370 IScsiExtScsiPassThruFunction,\r
371 IScsiExtScsiPassThruGetNextTargetLun,\r
372 IScsiExtScsiPassThruBuildDevicePath,\r
373 IScsiExtScsiPassThruGetTargetLun,\r
374 IScsiExtScsiPassThruResetChannel,\r
375 IScsiExtScsiPassThruResetTargetLun,\r
376 IScsiExtScsiPassThruGetNextTarget\r
377};\r