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