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