]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBus.c
MdeModulePkg: Apply uncrustify changes
[mirror_edk2.git] / MdeModulePkg / Bus / Scsi / ScsiBusDxe / ScsiBus.c
CommitLineData
3b2dbece 1/** @file\r
2 SCSI Bus driver that layers on every SCSI Pass Thru and\r
3 Extended SCSI Pass Thru protocol in the system.\r
3a10d471 4\r
1ff7ed2c 5Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
9d510e61 6SPDX-License-Identifier: BSD-2-Clause-Patent\r
3a10d471 7\r
3b2dbece 8**/\r
3a10d471 9\r
3a10d471 10#include "ScsiBus.h"\r
11\r
1436aea4 12EFI_DRIVER_BINDING_PROTOCOL gSCSIBusDriverBinding = {\r
3a10d471 13 SCSIBusDriverBindingSupported,\r
14 SCSIBusDriverBindingStart,\r
15 SCSIBusDriverBindingStop,\r
16 0xa,\r
17 NULL,\r
18 NULL\r
19};\r
20\r
9beb888e 21VOID *mWorkingBuffer;\r
22\r
23/**\r
24 Convert EFI_SCSI_IO_SCSI_REQUEST_PACKET packet to EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET packet.\r
70c94b3b 25\r
9beb888e 26 @param Packet The pointer of EFI_SCSI_IO_SCSI_REQUEST_PACKET\r
27 @param CommandPacket The pointer of EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET\r
28\r
29**/\r
70c94b3b 30EFI_STATUS\r
31EFIAPI\r
32ScsiioToPassThruPacket (\r
33 IN EFI_SCSI_IO_SCSI_REQUEST_PACKET *Packet,\r
9beb888e 34 OUT EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *CommandPacket\r
ed66e1bc 35 );\r
70c94b3b 36\r
9beb888e 37/**\r
38 Convert EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET packet to EFI_SCSI_IO_SCSI_REQUEST_PACKET packet.\r
39\r
40 @param ScsiPacket The pointer of EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET\r
41 @param Packet The pointer of EFI_SCSI_IO_SCSI_REQUEST_PACKET\r
70c94b3b 42\r
9beb888e 43**/\r
70c94b3b 44EFI_STATUS\r
45EFIAPI\r
46PassThruToScsiioPacket (\r
47 IN EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *ScsiPacket,\r
9beb888e 48 OUT EFI_SCSI_IO_SCSI_REQUEST_PACKET *Packet\r
ed66e1bc 49 );\r
9beb888e 50\r
51/**\r
52 Notify Function in which convert EFI1.0 PassThru Packet back to UEF2.0\r
53 SCSI IO Packet.\r
54\r
55 @param Event The instance of EFI_EVENT.\r
56 @param Context The parameter passed in.\r
57\r
58**/\r
70c94b3b 59VOID\r
60EFIAPI\r
61NotifyFunction (\r
9beb888e 62 IN EFI_EVENT Event,\r
63 IN VOID *Context\r
ed66e1bc 64 );\r
70c94b3b 65\r
957fe093
SZ
66/**\r
67 Allocates an aligned buffer for SCSI device.\r
68\r
69 This function allocates an aligned buffer for the SCSI device to perform\r
70 SCSI pass through operations. The alignment requirement is from SCSI pass\r
71 through interface.\r
72\r
73 @param ScsiIoDevice The SCSI child device involved for the operation.\r
74 @param BufferSize The request buffer size.\r
75\r
76 @return A pointer to the aligned buffer or NULL if the allocation fails.\r
77\r
78**/\r
79VOID *\r
80AllocateAlignedBuffer (\r
1436aea4
MK
81 IN SCSI_IO_DEV *ScsiIoDevice,\r
82 IN UINTN BufferSize\r
957fe093
SZ
83 )\r
84{\r
85 return AllocateAlignedPages (EFI_SIZE_TO_PAGES (BufferSize), ScsiIoDevice->ScsiIo.IoAlign);\r
86}\r
87\r
88/**\r
89 Frees an aligned buffer for SCSI device.\r
90\r
91 This function frees an aligned buffer for the SCSI device to perform\r
92 SCSI pass through operations.\r
93\r
94 @param Buffer The aligned buffer to be freed.\r
95 @param BufferSize The request buffer size.\r
96\r
97**/\r
98VOID\r
99FreeAlignedBuffer (\r
1436aea4
MK
100 IN VOID *Buffer,\r
101 IN UINTN BufferSize\r
957fe093
SZ
102 )\r
103{\r
104 if (Buffer != NULL) {\r
105 FreeAlignedPages (Buffer, EFI_SIZE_TO_PAGES (BufferSize));\r
106 }\r
107}\r
108\r
3a10d471 109/**\r
110 The user Entry Point for module ScsiBus. The user code starts with this function.\r
111\r
9beb888e 112 @param ImageHandle The firmware allocated handle for the EFI image.\r
113 @param SystemTable A pointer to the EFI System Table.\r
c52fa98c 114\r
9beb888e 115 @retval EFI_SUCCESS The entry point is executed successfully.\r
116 @retval other Some error occurs when executing this entry point.\r
3a10d471 117\r
118**/\r
119EFI_STATUS\r
120EFIAPI\r
1436aea4
MK
121InitializeScsiBus (\r
122 IN EFI_HANDLE ImageHandle,\r
123 IN EFI_SYSTEM_TABLE *SystemTable\r
3a10d471 124 )\r
125{\r
1436aea4 126 EFI_STATUS Status;\r
3a10d471 127\r
128 //\r
129 // Install driver model protocol(s).\r
130 //\r
70da5bc2 131 Status = EfiLibInstallDriverBindingComponentName2 (\r
3a10d471 132 ImageHandle,\r
133 SystemTable,\r
134 &gSCSIBusDriverBinding,\r
135 ImageHandle,\r
136 &gScsiBusComponentName,\r
70da5bc2 137 &gScsiBusComponentName2\r
3a10d471 138 );\r
139 ASSERT_EFI_ERROR (Status);\r
140\r
3a10d471 141 return Status;\r
142}\r
143\r
9beb888e 144/**\r
145 Test to see if this driver supports ControllerHandle.\r
146\r
147 This service is called by the EFI boot service ConnectController(). In order\r
148 to make drivers as small as possible, there are a few calling restrictions for\r
149 this service. ConnectController() must follow these calling restrictions. If\r
150 any other agent wishes to call Supported() it must also follow these calling\r
151 restrictions.\r
152\r
153 @param This Protocol instance pointer.\r
154 @param ControllerHandle Handle of device to test\r
155 @param RemainingDevicePath Optional parameter use to pick a specific child\r
156 device to start.\r
157\r
158 @retval EFI_SUCCESS This driver supports this device\r
159 @retval EFI_ALREADY_STARTED This driver is already running on this device\r
160 @retval other This driver does not support this device\r
161\r
162**/\r
3a10d471 163EFI_STATUS\r
164EFIAPI\r
165SCSIBusDriverBindingSupported (\r
166 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
167 IN EFI_HANDLE Controller,\r
168 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
169 )\r
3a10d471 170{\r
1436aea4
MK
171 EFI_STATUS Status;\r
172 EFI_SCSI_PASS_THRU_PROTOCOL *PassThru;\r
173 EFI_EXT_SCSI_PASS_THRU_PROTOCOL *ExtPassThru;\r
174 UINT64 Lun;\r
175 UINT8 *TargetId;\r
176 SCSI_TARGET_ID ScsiTargetId;\r
af4a6385 177\r
d548f0a1 178 TargetId = &ScsiTargetId.ScsiId.ExtScsi[0];\r
179 SetMem (TargetId, TARGET_MAX_BYTES, 0xFF);\r
180\r
181 //\r
d1102dba 182 // To keep backward compatibility, UEFI ExtPassThru Protocol is supported as well as\r
d548f0a1 183 // EFI PassThru Protocol. From priority perspective, ExtPassThru Protocol is firstly\r
184 // tried to open on host controller handle. If fails, then PassThru Protocol is tried instead.\r
185 //\r
186 Status = gBS->OpenProtocol (\r
187 Controller,\r
188 &gEfiExtScsiPassThruProtocolGuid,\r
189 (VOID **)&ExtPassThru,\r
190 This->DriverBindingHandle,\r
191 Controller,\r
192 EFI_OPEN_PROTOCOL_BY_DRIVER\r
193 );\r
194\r
195 if (Status == EFI_ALREADY_STARTED) {\r
196 return EFI_SUCCESS;\r
1436aea4 197 } else if (!EFI_ERROR (Status)) {\r
af4a6385 198 //\r
d548f0a1 199 // Check if RemainingDevicePath is NULL or the End of Device Path Node,\r
200 // if yes, return EFI_SUCCESS.\r
af4a6385 201 //\r
d548f0a1 202 if ((RemainingDevicePath == NULL) || IsDevicePathEnd (RemainingDevicePath)) {\r
67f7e376 203 //\r
204 // Close protocol regardless of RemainingDevicePath validation\r
205 //\r
206 gBS->CloseProtocol (\r
207 Controller,\r
208 &gEfiExtScsiPassThruProtocolGuid,\r
209 This->DriverBindingHandle,\r
210 Controller\r
d1102dba 211 );\r
d548f0a1 212 return EFI_SUCCESS;\r
213 } else {\r
214 //\r
215 // If RemainingDevicePath isn't the End of Device Path Node, check its validation\r
216 //\r
217 Status = ExtPassThru->GetTargetLun (ExtPassThru, RemainingDevicePath, &TargetId, &Lun);\r
af4a6385 218 //\r
d548f0a1 219 // Close protocol regardless of RemainingDevicePath validation\r
af4a6385 220 //\r
d548f0a1 221 gBS->CloseProtocol (\r
222 Controller,\r
223 &gEfiExtScsiPassThruProtocolGuid,\r
224 This->DriverBindingHandle,\r
225 Controller\r
d1102dba 226 );\r
1436aea4 227 if (!EFI_ERROR (Status)) {\r
d548f0a1 228 return EFI_SUCCESS;\r
af4a6385 229 }\r
230 }\r
231 }\r
232\r
3a10d471 233 //\r
d1102dba 234 // Come here in 2 condition:\r
d548f0a1 235 // 1. ExtPassThru doesn't exist.\r
236 // 2. ExtPassThru exists but RemainingDevicePath is invalid.\r
3a10d471 237 //\r
238 Status = gBS->OpenProtocol (\r
239 Controller,\r
d548f0a1 240 &gEfiScsiPassThruProtocolGuid,\r
241 (VOID **)&PassThru,\r
3a10d471 242 This->DriverBindingHandle,\r
243 Controller,\r
70c94b3b 244 EFI_OPEN_PROTOCOL_BY_DRIVER\r
3a10d471 245 );\r
d1102dba 246\r
70c94b3b 247 if (Status == EFI_ALREADY_STARTED) {\r
248 return EFI_SUCCESS;\r
249 }\r
d1102dba 250\r
70c94b3b 251 if (EFI_ERROR (Status)) {\r
d548f0a1 252 return Status;\r
3a10d471 253 }\r
d1102dba 254\r
af4a6385 255 //\r
d548f0a1 256 // Test RemainingDevicePath is valid or not.\r
af4a6385 257 //\r
d548f0a1 258 if ((RemainingDevicePath != NULL) && !IsDevicePathEnd (RemainingDevicePath)) {\r
259 Status = PassThru->GetTargetLun (PassThru, RemainingDevicePath, &ScsiTargetId.ScsiId.Scsi, &Lun);\r
260 }\r
d1102dba 261\r
70c94b3b 262 gBS->CloseProtocol (\r
d548f0a1 263 Controller,\r
264 &gEfiScsiPassThruProtocolGuid,\r
265 This->DriverBindingHandle,\r
266 Controller\r
267 );\r
268 return Status;\r
3a10d471 269}\r
270\r
9beb888e 271/**\r
272 Start this driver on ControllerHandle.\r
273\r
274 This service is called by the EFI boot service ConnectController(). In order\r
275 to make drivers as small as possible, there are a few calling restrictions for\r
276 this service. ConnectController() must follow these calling restrictions. If\r
277 any other agent wishes to call Start() it must also follow these calling\r
278 restrictions.\r
279\r
280 @param This Protocol instance pointer.\r
281 @param ControllerHandle Handle of device to bind driver to\r
282 @param RemainingDevicePath Optional parameter use to pick a specific child\r
283 device to start.\r
284\r
285 @retval EFI_SUCCESS This driver is added to ControllerHandle\r
286 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle\r
287 @retval other This driver does not support this device\r
288\r
289**/\r
3a10d471 290EFI_STATUS\r
291EFIAPI\r
292SCSIBusDriverBindingStart (\r
293 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
294 IN EFI_HANDLE Controller,\r
295 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
296 )\r
3a10d471 297{\r
1436aea4
MK
298 UINT64 Lun;\r
299 UINT8 *TargetId;\r
300 BOOLEAN ScanOtherPuns;\r
301 BOOLEAN FromFirstTarget;\r
302 BOOLEAN ExtScsiSupport;\r
303 EFI_STATUS Status;\r
304 EFI_STATUS DevicePathStatus;\r
305 EFI_STATUS PassThruStatus;\r
306 SCSI_BUS_DEVICE *ScsiBusDev;\r
307 SCSI_TARGET_ID ScsiTargetId;\r
308 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
309 EFI_SCSI_PASS_THRU_PROTOCOL *ScsiInterface;\r
310 EFI_EXT_SCSI_PASS_THRU_PROTOCOL *ExtScsiInterface;\r
311 EFI_SCSI_BUS_PROTOCOL *BusIdentify;\r
f36d6e66 312\r
313 TargetId = NULL;\r
f36d6e66 314 ScanOtherPuns = TRUE;\r
70c94b3b 315 FromFirstTarget = FALSE;\r
f36d6e66 316 ExtScsiSupport = FALSE;\r
317 PassThruStatus = EFI_SUCCESS;\r
d1102dba 318\r
d548f0a1 319 TargetId = &ScsiTargetId.ScsiId.ExtScsi[0];\r
320 SetMem (TargetId, TARGET_MAX_BYTES, 0xFF);\r
d1102dba 321\r
f36d6e66 322 DevicePathStatus = gBS->OpenProtocol (\r
323 Controller,\r
324 &gEfiDevicePathProtocolGuid,\r
1436aea4 325 (VOID **)&ParentDevicePath,\r
f36d6e66 326 This->DriverBindingHandle,\r
327 Controller,\r
328 EFI_OPEN_PROTOCOL_BY_DRIVER\r
329 );\r
330 if (EFI_ERROR (DevicePathStatus) && (DevicePathStatus != EFI_ALREADY_STARTED)) {\r
331 return DevicePathStatus;\r
3a10d471 332 }\r
333\r
37623a5c 334 //\r
335 // Report Status Code to indicate SCSI bus starts\r
336 //\r
337 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
338 EFI_PROGRESS_CODE,\r
339 (EFI_IO_BUS_SCSI | EFI_IOB_PC_INIT),\r
340 ParentDevicePath\r
d1102dba 341 );\r
37623a5c 342\r
3a10d471 343 //\r
d1102dba 344 // To keep backward compatibility, UEFI ExtPassThru Protocol is supported as well as\r
f36d6e66 345 // EFI PassThru Protocol. From priority perspective, ExtPassThru Protocol is firstly\r
346 // tried to open on host controller handle. If fails, then PassThru Protocol is tried instead.\r
3a10d471 347 //\r
348 Status = gBS->OpenProtocol (\r
349 Controller,\r
70c94b3b 350 &gEfiExtScsiPassThruProtocolGuid,\r
1436aea4 351 (VOID **)&ExtScsiInterface,\r
3a10d471 352 This->DriverBindingHandle,\r
353 Controller,\r
354 EFI_OPEN_PROTOCOL_BY_DRIVER\r
355 );\r
f36d6e66 356 //\r
357 // Fail to open UEFI ExtendPassThru Protocol, then try to open EFI PassThru Protocol instead.\r
358 //\r
1436aea4 359 if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {\r
70c94b3b 360 Status = gBS->OpenProtocol (\r
361 Controller,\r
362 &gEfiScsiPassThruProtocolGuid,\r
1436aea4 363 (VOID **)&ScsiInterface,\r
70c94b3b 364 This->DriverBindingHandle,\r
365 Controller,\r
366 EFI_OPEN_PROTOCOL_BY_DRIVER\r
367 );\r
f36d6e66 368 //\r
369 // Fail to open EFI PassThru Protocol, Close the DevicePathProtocol if it is opened by this time.\r
370 //\r
371 if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {\r
1436aea4 372 if (!EFI_ERROR (DevicePathStatus)) {\r
f36d6e66 373 gBS->CloseProtocol (\r
374 Controller,\r
375 &gEfiDevicePathProtocolGuid,\r
376 This->DriverBindingHandle,\r
377 Controller\r
378 );\r
d1102dba 379 }\r
1436aea4 380\r
70c94b3b 381 return Status;\r
d1102dba 382 }\r
70c94b3b 383 } else {\r
f36d6e66 384 //\r
d1102dba
LG
385 // Succeed to open ExtPassThru Protocol, and meanwhile open PassThru Protocol\r
386 // with BY_DRIVER if it is also present on the handle. The intent is to prevent\r
f36d6e66 387 // another SCSI Bus Driver to work on the same host handle.\r
388 //\r
389 ExtScsiSupport = TRUE;\r
390 PassThruStatus = gBS->OpenProtocol (\r
391 Controller,\r
392 &gEfiScsiPassThruProtocolGuid,\r
1436aea4 393 (VOID **)&ScsiInterface,\r
f36d6e66 394 This->DriverBindingHandle,\r
395 Controller,\r
396 EFI_OPEN_PROTOCOL_BY_DRIVER\r
397 );\r
70c94b3b 398 }\r
d1102dba 399\r
f36d6e66 400 if (Status != EFI_ALREADY_STARTED) {\r
401 //\r
402 // Go through here means either ExtPassThru or PassThru Protocol is successfully opened\r
403 // on this handle for this time. Then construct Host controller private data.\r
404 //\r
405 ScsiBusDev = NULL;\r
1436aea4 406 ScsiBusDev = AllocateZeroPool (sizeof (SCSI_BUS_DEVICE));\r
f36d6e66 407 if (ScsiBusDev == NULL) {\r
408 Status = EFI_OUT_OF_RESOURCES;\r
409 goto ErrorExit;\r
410 }\r
1436aea4
MK
411\r
412 ScsiBusDev->Signature = SCSI_BUS_DEVICE_SIGNATURE;\r
413 ScsiBusDev->ExtScsiSupport = ExtScsiSupport;\r
414 ScsiBusDev->DevicePath = ParentDevicePath;\r
70c94b3b 415 if (ScsiBusDev->ExtScsiSupport) {\r
f36d6e66 416 ScsiBusDev->ExtScsiInterface = ExtScsiInterface;\r
70c94b3b 417 } else {\r
1436aea4 418 ScsiBusDev->ScsiInterface = ScsiInterface;\r
70c94b3b 419 }\r
f36d6e66 420\r
421 //\r
422 // Install EFI_SCSI_BUS_PROTOCOL to the controller handle, So ScsiBusDev could be\r
423 // retrieved on this controller handle. With ScsiBusDev, we can know which PassThru\r
424 // Protocol is present on the handle, UEFI ExtPassThru Protocol or EFI PassThru Protocol.\r
d1102dba 425 //\r
f36d6e66 426 Status = gBS->InstallProtocolInterface (\r
427 &Controller,\r
c8ad2d7a 428 &gEfiCallerIdGuid,\r
f36d6e66 429 EFI_NATIVE_INTERFACE,\r
430 &ScsiBusDev->BusIdentify\r
431 );\r
432 if (EFI_ERROR (Status)) {\r
433 goto ErrorExit;\r
434 }\r
435 } else {\r
436 //\r
437 // Go through here means Start() is re-invoked again, nothing special is required to do except\r
438 // picking up Host controller private information.\r
439 //\r
440 Status = gBS->OpenProtocol (\r
441 Controller,\r
c8ad2d7a 442 &gEfiCallerIdGuid,\r
1436aea4 443 (VOID **)&BusIdentify,\r
f36d6e66 444 This->DriverBindingHandle,\r
445 Controller,\r
446 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
447 );\r
448\r
449 if (EFI_ERROR (Status)) {\r
450 return Status;\r
451 }\r
1436aea4 452\r
f36d6e66 453 ScsiBusDev = SCSI_BUS_CONTROLLER_DEVICE_FROM_THIS (BusIdentify);\r
3a10d471 454 }\r
455\r
37623a5c 456 //\r
457 // Report Status Code to indicate detecting devices on bus\r
458 //\r
459 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
460 EFI_PROGRESS_CODE,\r
461 (EFI_IO_BUS_SCSI | EFI_IOB_PC_DETECT),\r
462 ParentDevicePath\r
463 );\r
464\r
1436aea4 465 Lun = 0;\r
3a10d471 466 if (RemainingDevicePath == NULL) {\r
af4a6385 467 //\r
d1102dba 468 // If RemainingDevicePath is NULL,\r
af4a6385 469 // must enumerate all SCSI devices anyway\r
470 //\r
70c94b3b 471 FromFirstTarget = TRUE;\r
af4a6385 472 } else if (!IsDevicePathEnd (RemainingDevicePath)) {\r
473 //\r
d1102dba 474 // If RemainingDevicePath isn't the End of Device Path Node,\r
af4a6385 475 // only scan the specified device by RemainingDevicePath\r
476 //\r
70c94b3b 477 if (ScsiBusDev->ExtScsiSupport) {\r
d1102dba 478 Status = ScsiBusDev->ExtScsiInterface->GetTargetLun (ScsiBusDev->ExtScsiInterface, RemainingDevicePath, &TargetId, &Lun);\r
70c94b3b 479 } else {\r
d10a41e6 480 Status = ScsiBusDev->ScsiInterface->GetTargetLun (ScsiBusDev->ScsiInterface, RemainingDevicePath, &ScsiTargetId.ScsiId.Scsi, &Lun);\r
70c94b3b 481 }\r
af4a6385 482\r
d10a41e6 483 if (EFI_ERROR (Status)) {\r
484 return Status;\r
485 }\r
af4a6385 486 } else {\r
487 //\r
488 // If RemainingDevicePath is the End of Device Path Node,\r
cc530cd1 489 // skip enumerate any device and return EFI_SUCCESS\r
d1102dba 490 //\r
af4a6385 491 ScanOtherPuns = FALSE;\r
3a10d471 492 }\r
493\r
1436aea4 494 while (ScanOtherPuns) {\r
70c94b3b 495 if (FromFirstTarget) {\r
3a10d471 496 //\r
497 // Remaining Device Path is NULL, scan all the possible Puns in the\r
498 // SCSI Channel.\r
499 //\r
70c94b3b 500 if (ScsiBusDev->ExtScsiSupport) {\r
501 Status = ScsiBusDev->ExtScsiInterface->GetNextTargetLun (ScsiBusDev->ExtScsiInterface, &TargetId, &Lun);\r
502 } else {\r
d548f0a1 503 Status = ScsiBusDev->ScsiInterface->GetNextDevice (ScsiBusDev->ScsiInterface, &ScsiTargetId.ScsiId.Scsi, &Lun);\r
70c94b3b 504 }\r
1436aea4 505\r
3a10d471 506 if (EFI_ERROR (Status)) {\r
507 //\r
508 // no legal Pun and Lun found any more\r
509 //\r
510 break;\r
511 }\r
512 } else {\r
3a10d471 513 ScanOtherPuns = FALSE;\r
514 }\r
1436aea4 515\r
3a10d471 516 //\r
517 // Avoid creating handle for the host adapter.\r
518 //\r
70c94b3b 519 if (ScsiBusDev->ExtScsiSupport) {\r
d548f0a1 520 if ((ScsiTargetId.ScsiId.Scsi) == ScsiBusDev->ExtScsiInterface->Mode->AdapterId) {\r
70c94b3b 521 continue;\r
522 }\r
523 } else {\r
d548f0a1 524 if ((ScsiTargetId.ScsiId.Scsi) == ScsiBusDev->ScsiInterface->Mode->AdapterId) {\r
70c94b3b 525 continue;\r
526 }\r
3a10d471 527 }\r
1436aea4 528\r
3a10d471 529 //\r
530 // Scan for the scsi device, if it attaches to the scsi bus,\r
531 // then create handle and install scsi i/o protocol.\r
532 //\r
d548f0a1 533 Status = ScsiScanCreateDevice (This, Controller, &ScsiTargetId, Lun, ScsiBusDev);\r
3a10d471 534 }\r
1436aea4 535\r
f36d6e66 536 return EFI_SUCCESS;\r
9b38ff34 537\r
f36d6e66 538ErrorExit:\r
d1102dba 539\r
f36d6e66 540 if (ScsiBusDev != NULL) {\r
9b38ff34 541 FreePool (ScsiBusDev);\r
f36d6e66 542 }\r
d1102dba 543\r
f36d6e66 544 if (ExtScsiSupport) {\r
545 gBS->CloseProtocol (\r
546 Controller,\r
547 &gEfiExtScsiPassThruProtocolGuid,\r
548 This->DriverBindingHandle,\r
549 Controller\r
550 );\r
551 if (!EFI_ERROR (PassThruStatus)) {\r
552 gBS->CloseProtocol (\r
553 Controller,\r
554 &gEfiScsiPassThruProtocolGuid,\r
555 This->DriverBindingHandle,\r
556 Controller\r
557 );\r
558 }\r
559 } else {\r
560 gBS->CloseProtocol (\r
561 Controller,\r
562 &gEfiScsiPassThruProtocolGuid,\r
563 This->DriverBindingHandle,\r
564 Controller\r
565 );\r
566 }\r
1436aea4 567\r
3a10d471 568 return Status;\r
569}\r
570\r
9beb888e 571/**\r
572 Stop this driver on ControllerHandle.\r
573\r
574 This service is called by the EFI boot service DisconnectController().\r
575 In order to make drivers as small as possible, there are a few calling\r
576 restrictions for this service. DisconnectController() must follow these\r
577 calling restrictions. If any other agent wishes to call Stop() it must also\r
578 follow these calling restrictions.\r
d1102dba 579\r
9beb888e 580 @param This Protocol instance pointer.\r
581 @param ControllerHandle Handle of device to stop driver on\r
582 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of\r
583 children is zero stop the entire bus driver.\r
584 @param ChildHandleBuffer List of Child Handles to Stop.\r
585\r
586 @retval EFI_SUCCESS This driver is removed ControllerHandle\r
587 @retval other This driver was not removed from this device\r
588\r
589**/\r
3a10d471 590EFI_STATUS\r
591EFIAPI\r
592SCSIBusDriverBindingStop (\r
1436aea4
MK
593 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
594 IN EFI_HANDLE Controller,\r
595 IN UINTN NumberOfChildren,\r
596 IN EFI_HANDLE *ChildHandleBuffer\r
3a10d471 597 )\r
3a10d471 598{\r
1436aea4
MK
599 EFI_STATUS Status;\r
600 BOOLEAN AllChildrenStopped;\r
601 UINTN Index;\r
602 EFI_SCSI_IO_PROTOCOL *ScsiIo;\r
603 SCSI_IO_DEV *ScsiIoDevice;\r
604 VOID *ScsiPassThru;\r
605 EFI_SCSI_BUS_PROTOCOL *Scsidentifier;\r
606 SCSI_BUS_DEVICE *ScsiBusDev;\r
3a10d471 607\r
608 if (NumberOfChildren == 0) {\r
70c94b3b 609 //\r
610 // Get the SCSI_BUS_DEVICE\r
611 //\r
612 Status = gBS->OpenProtocol (\r
613 Controller,\r
c8ad2d7a 614 &gEfiCallerIdGuid,\r
1436aea4 615 (VOID **)&Scsidentifier,\r
70c94b3b 616 This->DriverBindingHandle,\r
617 Controller,\r
618 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
619 );\r
c52fa98c 620\r
70c94b3b 621 if (EFI_ERROR (Status)) {\r
622 return EFI_DEVICE_ERROR;\r
623 }\r
624\r
625 ScsiBusDev = SCSI_BUS_CONTROLLER_DEVICE_FROM_THIS (Scsidentifier);\r
626\r
627 //\r
628 // Uninstall SCSI Bus Protocol\r
629 //\r
630 gBS->UninstallProtocolInterface (\r
631 Controller,\r
c8ad2d7a 632 &gEfiCallerIdGuid,\r
70c94b3b 633 &ScsiBusDev->BusIdentify\r
634 );\r
c52fa98c 635\r
3a10d471 636 //\r
637 // Close the bus driver\r
638 //\r
70c94b3b 639 if (ScsiBusDev->ExtScsiSupport) {\r
1e5914b5 640 //\r
641 // Close ExtPassThru Protocol from this controller handle\r
642 //\r
70c94b3b 643 gBS->CloseProtocol (\r
644 Controller,\r
645 &gEfiExtScsiPassThruProtocolGuid,\r
646 This->DriverBindingHandle,\r
647 Controller\r
648 );\r
1e5914b5 649 //\r
650 // When Start() succeeds to open ExtPassThru, it always tries to open PassThru BY_DRIVER.\r
cc530cd1 651 // Its intent is to prevent another SCSI Bus Driver from working on the same host handle.\r
1e5914b5 652 // So Stop() needs to try to close PassThru if present here.\r
653 //\r
654 gBS->CloseProtocol (\r
655 Controller,\r
656 &gEfiScsiPassThruProtocolGuid,\r
657 This->DriverBindingHandle,\r
658 Controller\r
659 );\r
70c94b3b 660 } else {\r
661 gBS->CloseProtocol (\r
662 Controller,\r
663 &gEfiScsiPassThruProtocolGuid,\r
664 This->DriverBindingHandle,\r
665 Controller\r
666 );\r
667 }\r
3a10d471 668\r
70c94b3b 669 gBS->CloseProtocol (\r
670 Controller,\r
671 &gEfiDevicePathProtocolGuid,\r
672 This->DriverBindingHandle,\r
673 Controller\r
674 );\r
6c94a00d 675 FreePool (ScsiBusDev);\r
3a10d471 676 return EFI_SUCCESS;\r
677 }\r
678\r
679 AllChildrenStopped = TRUE;\r
680\r
681 for (Index = 0; Index < NumberOfChildren; Index++) {\r
3a10d471 682 Status = gBS->OpenProtocol (\r
683 ChildHandleBuffer[Index],\r
684 &gEfiScsiIoProtocolGuid,\r
1436aea4 685 (VOID **)&ScsiIo,\r
3a10d471 686 This->DriverBindingHandle,\r
687 Controller,\r
688 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
689 );\r
690 if (EFI_ERROR (Status)) {\r
691 AllChildrenStopped = FALSE;\r
692 continue;\r
693 }\r
694\r
695 ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (ScsiIo);\r
696 //\r
697 // Close the child handle\r
698 //\r
70c94b3b 699 if (ScsiIoDevice->ExtScsiSupport) {\r
700 Status = gBS->CloseProtocol (\r
701 Controller,\r
702 &gEfiExtScsiPassThruProtocolGuid,\r
703 This->DriverBindingHandle,\r
704 ChildHandleBuffer[Index]\r
705 );\r
70c94b3b 706 } else {\r
707 Status = gBS->CloseProtocol (\r
708 Controller,\r
709 &gEfiScsiPassThruProtocolGuid,\r
710 This->DriverBindingHandle,\r
711 ChildHandleBuffer[Index]\r
712 );\r
713 }\r
3a10d471 714\r
715 Status = gBS->UninstallMultipleProtocolInterfaces (\r
716 ChildHandleBuffer[Index],\r
717 &gEfiDevicePathProtocolGuid,\r
718 ScsiIoDevice->DevicePath,\r
719 &gEfiScsiIoProtocolGuid,\r
720 &ScsiIoDevice->ScsiIo,\r
721 NULL\r
722 );\r
723 if (EFI_ERROR (Status)) {\r
724 AllChildrenStopped = FALSE;\r
70c94b3b 725 if (ScsiIoDevice->ExtScsiSupport) {\r
726 gBS->OpenProtocol (\r
727 Controller,\r
728 &gEfiExtScsiPassThruProtocolGuid,\r
84b5c78e 729 &ScsiPassThru,\r
70c94b3b 730 This->DriverBindingHandle,\r
731 ChildHandleBuffer[Index],\r
732 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
733 );\r
734 } else {\r
735 gBS->OpenProtocol (\r
736 Controller,\r
737 &gEfiScsiPassThruProtocolGuid,\r
84b5c78e 738 &ScsiPassThru,\r
70c94b3b 739 This->DriverBindingHandle,\r
740 ChildHandleBuffer[Index],\r
741 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
742 );\r
743 }\r
3a10d471 744 } else {\r
6c94a00d 745 FreePool (ScsiIoDevice);\r
3a10d471 746 }\r
747 }\r
748\r
749 if (!AllChildrenStopped) {\r
750 return EFI_DEVICE_ERROR;\r
751 }\r
752\r
753 return EFI_SUCCESS;\r
754}\r
755\r
9beb888e 756/**\r
757 Retrieves the device type information of the SCSI Controller.\r
758\r
759 @param This Protocol instance pointer.\r
760 @param DeviceType A pointer to the device type information retrieved from\r
d1102dba 761 the SCSI Controller.\r
9beb888e 762\r
763 @retval EFI_SUCCESS Retrieves the device type information successfully.\r
764 @retval EFI_INVALID_PARAMETER The DeviceType is NULL.\r
d1102dba 765\r
9beb888e 766**/\r
3a10d471 767EFI_STATUS\r
768EFIAPI\r
769ScsiGetDeviceType (\r
1436aea4
MK
770 IN EFI_SCSI_IO_PROTOCOL *This,\r
771 OUT UINT8 *DeviceType\r
3a10d471 772 )\r
3a10d471 773{\r
1436aea4 774 SCSI_IO_DEV *ScsiIoDevice;\r
3a10d471 775\r
776 if (DeviceType == NULL) {\r
777 return EFI_INVALID_PARAMETER;\r
778 }\r
779\r
1436aea4
MK
780 ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (This);\r
781 *DeviceType = ScsiIoDevice->ScsiDeviceType;\r
3a10d471 782 return EFI_SUCCESS;\r
783}\r
784\r
9beb888e 785/**\r
786 Retrieves the device location in the SCSI channel.\r
787\r
788 @param This Protocol instance pointer.\r
789 @param Target A pointer to the Target ID of a SCSI device\r
790 on the SCSI channel.\r
791 @param Lun A pointer to the LUN of the SCSI device on\r
792 the SCSI channel.\r
793\r
794 @retval EFI_SUCCESS Retrieves the device location successfully.\r
795 @retval EFI_INVALID_PARAMETER The Target or Lun is NULL.\r
796\r
797**/\r
3a10d471 798EFI_STATUS\r
799EFIAPI\r
800ScsiGetDeviceLocation (\r
1436aea4
MK
801 IN EFI_SCSI_IO_PROTOCOL *This,\r
802 IN OUT UINT8 **Target,\r
803 OUT UINT64 *Lun\r
3a10d471 804 )\r
3a10d471 805{\r
1436aea4 806 SCSI_IO_DEV *ScsiIoDevice;\r
3a10d471 807\r
1436aea4 808 if ((Target == NULL) || (Lun == NULL)) {\r
3a10d471 809 return EFI_INVALID_PARAMETER;\r
810 }\r
811\r
f36d6e66 812 ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (This);\r
3a10d471 813\r
1436aea4 814 CopyMem (*Target, &ScsiIoDevice->Pun, TARGET_MAX_BYTES);\r
70c94b3b 815\r
1436aea4 816 *Lun = ScsiIoDevice->Lun;\r
3a10d471 817\r
818 return EFI_SUCCESS;\r
819}\r
820\r
9beb888e 821/**\r
822 Resets the SCSI Bus that the SCSI Controller is attached to.\r
823\r
824 @param This Protocol instance pointer.\r
825\r
826 @retval EFI_SUCCESS The SCSI bus is reset successfully.\r
827 @retval EFI_DEVICE_ERROR Errors encountered when resetting the SCSI bus.\r
828 @retval EFI_UNSUPPORTED The bus reset operation is not supported by the\r
829 SCSI Host Controller.\r
d1102dba 830 @retval EFI_TIMEOUT A timeout occurred while attempting to reset\r
9beb888e 831 the SCSI bus.\r
832**/\r
3a10d471 833EFI_STATUS\r
834EFIAPI\r
835ScsiResetBus (\r
1436aea4 836 IN EFI_SCSI_IO_PROTOCOL *This\r
3a10d471 837 )\r
3a10d471 838{\r
1436aea4 839 SCSI_IO_DEV *ScsiIoDevice;\r
3a10d471 840\r
841 ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (This);\r
842\r
37623a5c 843 //\r
844 // Report Status Code to indicate reset happens\r
845 //\r
846 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
847 EFI_PROGRESS_CODE,\r
848 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_PC_RESET),\r
849 ScsiIoDevice->ScsiBusDeviceData->DevicePath\r
850 );\r
851\r
1436aea4 852 if (ScsiIoDevice->ExtScsiSupport) {\r
70c94b3b 853 return ScsiIoDevice->ExtScsiPassThru->ResetChannel (ScsiIoDevice->ExtScsiPassThru);\r
854 } else {\r
855 return ScsiIoDevice->ScsiPassThru->ResetChannel (ScsiIoDevice->ScsiPassThru);\r
856 }\r
3a10d471 857}\r
858\r
9beb888e 859/**\r
860 Resets the SCSI Controller that the device handle specifies.\r
861\r
862 @param This Protocol instance pointer.\r
863\r
864 @retval EFI_SUCCESS Reset the SCSI controller successfully.\r
865 @retval EFI_DEVICE_ERROR Errors are encountered when resetting the SCSI Controller.\r
866 @retval EFI_UNSUPPORTED The SCSI bus does not support a device reset operation.\r
867 @retval EFI_TIMEOUT A timeout occurred while attempting to reset the\r
868 SCSI Controller.\r
869**/\r
3a10d471 870EFI_STATUS\r
871EFIAPI\r
872ScsiResetDevice (\r
1436aea4 873 IN EFI_SCSI_IO_PROTOCOL *This\r
3a10d471 874 )\r
3a10d471 875{\r
f36d6e66 876 SCSI_IO_DEV *ScsiIoDevice;\r
70c94b3b 877 UINT8 Target[TARGET_MAX_BYTES];\r
3a10d471 878\r
879 ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (This);\r
37623a5c 880\r
881 //\r
882 // Report Status Code to indicate reset happens\r
883 //\r
884 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
885 EFI_PROGRESS_CODE,\r
886 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_PC_RESET),\r
887 ScsiIoDevice->ScsiBusDeviceData->DevicePath\r
888 );\r
d1102dba 889\r
1436aea4 890 CopyMem (Target, &ScsiIoDevice->Pun, TARGET_MAX_BYTES);\r
3a10d471 891\r
70c94b3b 892 if (ScsiIoDevice->ExtScsiSupport) {\r
893 return ScsiIoDevice->ExtScsiPassThru->ResetTargetLun (\r
1436aea4
MK
894 ScsiIoDevice->ExtScsiPassThru,\r
895 Target,\r
896 ScsiIoDevice->Lun\r
897 );\r
70c94b3b 898 } else {\r
899 return ScsiIoDevice->ScsiPassThru->ResetTarget (\r
1436aea4
MK
900 ScsiIoDevice->ScsiPassThru,\r
901 ScsiIoDevice->Pun.ScsiId.Scsi,\r
902 ScsiIoDevice->Lun\r
903 );\r
70c94b3b 904 }\r
3a10d471 905}\r
906\r
9beb888e 907/**\r
f36d6e66 908 Sends a SCSI Request Packet to the SCSI Controller for execution.\r
f36d6e66 909\r
9beb888e 910 @param This Protocol instance pointer.\r
d1102dba 911 @param CommandPacket The SCSI request packet to send to the SCSI\r
f36d6e66 912 Controller specified by the device handle.\r
9beb888e 913 @param Event If the SCSI bus where the SCSI device is attached\r
d1102dba
LG
914 does not support non-blocking I/O, then Event is\r
915 ignored, and blocking I/O is performed.\r
f36d6e66 916 If Event is NULL, then blocking I/O is performed.\r
d1102dba 917 If Event is not NULL and non-blocking I/O is\r
f36d6e66 918 supported, then non-blocking I/O is performed,\r
919 and Event will be signaled when the SCSI Request\r
920 Packet completes.\r
9beb888e 921\r
d1102dba
LG
922 @retval EFI_SUCCESS The SCSI Request Packet was sent by the host\r
923 successfully, and TransferLength bytes were\r
924 transferred to/from DataBuffer.See\r
925 HostAdapterStatus, TargetStatus,\r
9beb888e 926 SenseDataLength, and SenseData in that order\r
927 for additional status information.\r
d1102dba 928 @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed,\r
9beb888e 929 but the entire DataBuffer could not be transferred.\r
930 The actual number of bytes transferred is returned\r
d1102dba
LG
931 in TransferLength. See HostAdapterStatus,\r
932 TargetStatus, SenseDataLength, and SenseData in\r
9beb888e 933 that order for additional status information.\r
d1102dba
LG
934 @retval EFI_NOT_READY The SCSI Request Packet could not be sent because\r
935 there are too many SCSI Command Packets already\r
9beb888e 936 queued.The caller may retry again later.\r
d1102dba
LG
937 @retval EFI_DEVICE_ERROR A device error occurred while attempting to send\r
938 the SCSI Request Packet. See HostAdapterStatus,\r
939 TargetStatus, SenseDataLength, and SenseData in\r
9beb888e 940 that order for additional status information.\r
d1102dba
LG
941 @retval EFI_INVALID_PARAMETER The contents of CommandPacket are invalid.\r
942 The SCSI Request Packet was not sent, so no\r
9beb888e 943 additional status information is available.\r
944 @retval EFI_UNSUPPORTED The command described by the SCSI Request Packet\r
d1102dba 945 is not supported by the SCSI initiator(i.e., SCSI\r
9beb888e 946 Host Controller). The SCSI Request Packet was not\r
d1102dba 947 sent, so no additional status information is\r
9beb888e 948 available.\r
d1102dba 949 @retval EFI_TIMEOUT A timeout occurred while waiting for the SCSI\r
9beb888e 950 Request Packet to execute. See HostAdapterStatus,\r
d1102dba 951 TargetStatus, SenseDataLength, and SenseData in\r
9beb888e 952 that order for additional status information.\r
953**/\r
954EFI_STATUS\r
955EFIAPI\r
956ScsiExecuteSCSICommand (\r
1436aea4
MK
957 IN EFI_SCSI_IO_PROTOCOL *This,\r
958 IN OUT EFI_SCSI_IO_SCSI_REQUEST_PACKET *Packet,\r
959 IN EFI_EVENT Event OPTIONAL\r
9beb888e 960 )\r
3a10d471 961{\r
f36d6e66 962 SCSI_IO_DEV *ScsiIoDevice;\r
963 EFI_STATUS Status;\r
70c94b3b 964 UINT8 Target[TARGET_MAX_BYTES];\r
965 EFI_EVENT PacketEvent;\r
966 EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *ExtRequestPacket;\r
d1102dba 967 SCSI_EVENT_DATA EventData;\r
3a10d471 968\r
70c94b3b 969 PacketEvent = NULL;\r
d1102dba 970\r
3a10d471 971 if (Packet == NULL) {\r
972 return EFI_INVALID_PARAMETER;\r
973 }\r
974\r
1436aea4
MK
975 ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (This);\r
976 CopyMem (Target, &ScsiIoDevice->Pun, TARGET_MAX_BYTES);\r
c52fa98c 977\r
70c94b3b 978 if (ScsiIoDevice->ExtScsiSupport) {\r
1436aea4 979 ExtRequestPacket = (EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *)Packet;\r
0d12e6a0
HW
980\r
981 if (((ScsiIoDevice->ExtScsiPassThru->Mode->Attributes & EFI_SCSI_PASS_THRU_ATTRIBUTES_NONBLOCKIO) != 0) && (Event != NULL)) {\r
982 Status = ScsiIoDevice->ExtScsiPassThru->PassThru (\r
983 ScsiIoDevice->ExtScsiPassThru,\r
984 Target,\r
985 ScsiIoDevice->Lun,\r
986 ExtRequestPacket,\r
987 Event\r
988 );\r
989 } else {\r
990 //\r
991 // If there's no event or the SCSI Device doesn't support NON-BLOCKING,\r
992 // let the 'Event' parameter for PassThru() be NULL.\r
993 //\r
994 Status = ScsiIoDevice->ExtScsiPassThru->PassThru (\r
995 ScsiIoDevice->ExtScsiPassThru,\r
996 Target,\r
997 ScsiIoDevice->Lun,\r
998 ExtRequestPacket,\r
999 NULL\r
1000 );\r
1436aea4 1001 if ((!EFI_ERROR (Status)) && (Event != NULL)) {\r
0d12e6a0 1002 //\r
9f840a9e
HW
1003 // Signal Event to tell caller to pick up the SCSI IO packet if the\r
1004 // PassThru() succeeds.\r
0d12e6a0
HW
1005 //\r
1006 gBS->SignalEvent (Event);\r
1007 }\r
1008 }\r
70c94b3b 1009 } else {\r
1436aea4 1010 mWorkingBuffer = AllocatePool (sizeof (EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET));\r
3a10d471 1011\r
9b38ff34 1012 if (mWorkingBuffer == NULL) {\r
70c94b3b 1013 return EFI_DEVICE_ERROR;\r
1014 }\r
1015\r
1016 //\r
c52fa98c 1017 // Convert package into EFI1.0, EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET.\r
70c94b3b 1018 //\r
1436aea4
MK
1019 Status = ScsiioToPassThruPacket (Packet, (EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *)mWorkingBuffer);\r
1020 if (EFI_ERROR (Status)) {\r
1021 FreePool (mWorkingBuffer);\r
70c94b3b 1022 return Status;\r
1023 }\r
1024\r
7077edb3 1025 if (((ScsiIoDevice->ScsiPassThru->Mode->Attributes & EFI_SCSI_PASS_THRU_ATTRIBUTES_NONBLOCKIO) != 0) && (Event != NULL)) {\r
1436aea4 1026 EventData.Data1 = (VOID *)Packet;\r
70c94b3b 1027 EventData.Data2 = Event;\r
1028 //\r
1029 // Create Event\r
1030 //\r
1031 Status = gBS->CreateEvent (\r
1436aea4
MK
1032 EVT_NOTIFY_SIGNAL,\r
1033 TPL_NOTIFY,\r
1034 NotifyFunction,\r
1035 &EventData,\r
1036 &PacketEvent\r
1037 );\r
1038 if (EFI_ERROR (Status)) {\r
1039 FreePool (mWorkingBuffer);\r
70c94b3b 1040 return Status;\r
1041 }\r
c52fa98c 1042\r
70c94b3b 1043 Status = ScsiIoDevice->ScsiPassThru->PassThru (\r
1436aea4
MK
1044 ScsiIoDevice->ScsiPassThru,\r
1045 ScsiIoDevice->Pun.ScsiId.Scsi,\r
1046 ScsiIoDevice->Lun,\r
1047 mWorkingBuffer,\r
1048 PacketEvent\r
1049 );\r
70c94b3b 1050\r
1436aea4
MK
1051 if (EFI_ERROR (Status)) {\r
1052 FreePool (mWorkingBuffer);\r
1053 gBS->CloseEvent (PacketEvent);\r
70c94b3b 1054 return Status;\r
1055 }\r
70c94b3b 1056 } else {\r
1057 //\r
1058 // If there's no event or SCSI Device doesn't support NON-BLOCKING, just convert\r
1059 // EFI1.0 PassThru packet back to UEFI2.0 SCSI IO Packet.\r
1060 //\r
1061 Status = ScsiIoDevice->ScsiPassThru->PassThru (\r
1436aea4
MK
1062 ScsiIoDevice->ScsiPassThru,\r
1063 ScsiIoDevice->Pun.ScsiId.Scsi,\r
1064 ScsiIoDevice->Lun,\r
1065 mWorkingBuffer,\r
1066 NULL\r
1067 );\r
1068 if (EFI_ERROR (Status)) {\r
1069 FreePool (mWorkingBuffer);\r
70c94b3b 1070 return Status;\r
1071 }\r
1072\r
1436aea4 1073 PassThruToScsiioPacket ((EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *)mWorkingBuffer, Packet);\r
70c94b3b 1074 //\r
1075 // After converting EFI1.0 PassThru Packet back to UEFI2.0 SCSI IO Packet,\r
9beb888e 1076 // free mWorkingBuffer.\r
70c94b3b 1077 //\r
1436aea4 1078 FreePool (mWorkingBuffer);\r
0d12e6a0
HW
1079\r
1080 //\r
1081 // Signal Event to tell caller to pick up the SCSI IO Packet.\r
1082 //\r
1083 if (Event != NULL) {\r
1084 gBS->SignalEvent (Event);\r
1085 }\r
70c94b3b 1086 }\r
1087 }\r
1436aea4 1088\r
3a10d471 1089 return Status;\r
1090}\r
1091\r
9beb888e 1092/**\r
70c94b3b 1093 Scan SCSI Bus to discover the device, and attach ScsiIoProtocol to it.\r
3a10d471 1094\r
9beb888e 1095 @param This Protocol instance pointer\r
1096 @param Controller Controller handle\r
cc530cd1 1097 @param TargetId Target to be scanned\r
9beb888e 1098 @param Lun The Lun of the SCSI device on the SCSI channel.\r
1099 @param ScsiBusDev The pointer of SCSI_BUS_DEVICE\r
3a10d471 1100\r
9beb888e 1101 @retval EFI_SUCCESS Successfully to discover the device and attach\r
1102 ScsiIoProtocol to it.\r
1103 @retval EFI_OUT_OF_RESOURCES Fail to discover the device.\r
3a10d471 1104\r
9beb888e 1105**/\r
1106EFI_STATUS\r
1107EFIAPI\r
1108ScsiScanCreateDevice (\r
1436aea4
MK
1109 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
1110 IN EFI_HANDLE Controller,\r
1111 IN SCSI_TARGET_ID *TargetId,\r
1112 IN UINT64 Lun,\r
1113 IN OUT SCSI_BUS_DEVICE *ScsiBusDev\r
9beb888e 1114 )\r
3a10d471 1115{\r
1116 EFI_STATUS Status;\r
1117 SCSI_IO_DEV *ScsiIoDevice;\r
1118 EFI_DEVICE_PATH_PROTOCOL *ScsiDevicePath;\r
cbd2a4b3 1119 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
1120 EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath;\r
1436aea4 1121 EFI_HANDLE DeviceHandle;\r
cbd2a4b3 1122\r
1123 DevicePath = NULL;\r
1124 RemainingDevicePath = NULL;\r
1125 ScsiDevicePath = NULL;\r
1126 ScsiIoDevice = NULL;\r
1127\r
1128 //\r
1129 // Build Device Path\r
1130 //\r
1436aea4 1131 if (ScsiBusDev->ExtScsiSupport) {\r
cbd2a4b3 1132 Status = ScsiBusDev->ExtScsiInterface->BuildDevicePath (\r
1133 ScsiBusDev->ExtScsiInterface,\r
1134 &TargetId->ScsiId.ExtScsi[0],\r
1135 Lun,\r
1136 &ScsiDevicePath\r
1137 );\r
1138 } else {\r
e7c2a83b 1139 Status = ScsiBusDev->ScsiInterface->BuildDevicePath (\r
1140 ScsiBusDev->ScsiInterface,\r
1141 TargetId->ScsiId.Scsi,\r
1142 Lun,\r
1143 &ScsiDevicePath\r
1144 );\r
cbd2a4b3 1145 }\r
1146\r
1436aea4 1147 if (EFI_ERROR (Status)) {\r
cbd2a4b3 1148 return Status;\r
1149 }\r
1150\r
1151 DevicePath = AppendDevicePathNode (\r
1152 ScsiBusDev->DevicePath,\r
1153 ScsiDevicePath\r
1154 );\r
1155\r
1156 if (DevicePath == NULL) {\r
1157 Status = EFI_OUT_OF_RESOURCES;\r
1158 goto ErrorExit;\r
1159 }\r
1160\r
1436aea4 1161 DeviceHandle = NULL;\r
cbd2a4b3 1162 RemainingDevicePath = DevicePath;\r
1436aea4
MK
1163 Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &RemainingDevicePath, &DeviceHandle);\r
1164 if (!EFI_ERROR (Status) && (DeviceHandle != NULL) && IsDevicePathEnd (RemainingDevicePath)) {\r
cbd2a4b3 1165 //\r
1166 // The device has been started, directly return to fast boot.\r
1167 //\r
1168 Status = EFI_ALREADY_STARTED;\r
1169 goto ErrorExit;\r
1170 }\r
3a10d471 1171\r
9beb888e 1172 ScsiIoDevice = AllocateZeroPool (sizeof (SCSI_IO_DEV));\r
1173 if (ScsiIoDevice == NULL) {\r
cbd2a4b3 1174 Status = EFI_OUT_OF_RESOURCES;\r
1175 goto ErrorExit;\r
3a10d471 1176 }\r
1177\r
1436aea4
MK
1178 ScsiIoDevice->Signature = SCSI_IO_DEV_SIGNATURE;\r
1179 ScsiIoDevice->ScsiBusDeviceData = ScsiBusDev;\r
1180 CopyMem (&ScsiIoDevice->Pun, TargetId, TARGET_MAX_BYTES);\r
1181 ScsiIoDevice->Lun = Lun;\r
3a10d471 1182\r
70c94b3b 1183 if (ScsiBusDev->ExtScsiSupport) {\r
1436aea4
MK
1184 ScsiIoDevice->ExtScsiPassThru = ScsiBusDev->ExtScsiInterface;\r
1185 ScsiIoDevice->ExtScsiSupport = TRUE;\r
1186 ScsiIoDevice->ScsiIo.IoAlign = ScsiIoDevice->ExtScsiPassThru->Mode->IoAlign;\r
70c94b3b 1187 } else {\r
1436aea4
MK
1188 ScsiIoDevice->ScsiPassThru = ScsiBusDev->ScsiInterface;\r
1189 ScsiIoDevice->ExtScsiSupport = FALSE;\r
1190 ScsiIoDevice->ScsiIo.IoAlign = ScsiIoDevice->ScsiPassThru->Mode->IoAlign;\r
70c94b3b 1191 }\r
1192\r
3a10d471 1193 ScsiIoDevice->ScsiIo.GetDeviceType = ScsiGetDeviceType;\r
70c94b3b 1194 ScsiIoDevice->ScsiIo.GetDeviceLocation = ScsiGetDeviceLocation;\r
3a10d471 1195 ScsiIoDevice->ScsiIo.ResetBus = ScsiResetBus;\r
1196 ScsiIoDevice->ScsiIo.ResetDevice = ScsiResetDevice;\r
24e734d2 1197 ScsiIoDevice->ScsiIo.ExecuteScsiCommand = ScsiExecuteSCSICommand;\r
3a10d471 1198\r
37623a5c 1199 //\r
1200 // Report Status Code here since the new SCSI device will be discovered\r
1201 //\r
1202 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
1203 EFI_PROGRESS_CODE,\r
1204 (EFI_IO_BUS_SCSI | EFI_IOB_PC_ENABLE),\r
1205 ScsiBusDev->DevicePath\r
1206 );\r
1207\r
3a10d471 1208 if (!DiscoverScsiDevice (ScsiIoDevice)) {\r
cbd2a4b3 1209 Status = EFI_OUT_OF_RESOURCES;\r
1210 goto ErrorExit;\r
3a10d471 1211 }\r
70c94b3b 1212\r
cbd2a4b3 1213 ScsiIoDevice->DevicePath = DevicePath;\r
c52fa98c 1214\r
3a10d471 1215 Status = gBS->InstallMultipleProtocolInterfaces (\r
1216 &ScsiIoDevice->Handle,\r
1217 &gEfiDevicePathProtocolGuid,\r
1218 ScsiIoDevice->DevicePath,\r
1219 &gEfiScsiIoProtocolGuid,\r
1220 &ScsiIoDevice->ScsiIo,\r
1221 NULL\r
1222 );\r
1223 if (EFI_ERROR (Status)) {\r
cbd2a4b3 1224 goto ErrorExit;\r
3a10d471 1225 } else {\r
70c94b3b 1226 if (ScsiBusDev->ExtScsiSupport) {\r
1227 gBS->OpenProtocol (\r
cbd2a4b3 1228 Controller,\r
1229 &gEfiExtScsiPassThruProtocolGuid,\r
1436aea4 1230 (VOID **)&(ScsiBusDev->ExtScsiInterface),\r
cbd2a4b3 1231 This->DriverBindingHandle,\r
1232 ScsiIoDevice->Handle,\r
1233 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
1234 );\r
1436aea4 1235 } else {\r
70c94b3b 1236 gBS->OpenProtocol (\r
cbd2a4b3 1237 Controller,\r
1238 &gEfiScsiPassThruProtocolGuid,\r
1436aea4 1239 (VOID **)&(ScsiBusDev->ScsiInterface),\r
cbd2a4b3 1240 This->DriverBindingHandle,\r
1241 ScsiIoDevice->Handle,\r
1242 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
1243 );\r
1436aea4 1244 }\r
3a10d471 1245 }\r
1436aea4 1246\r
3a10d471 1247 return EFI_SUCCESS;\r
cbd2a4b3 1248\r
1249ErrorExit:\r
d1102dba 1250\r
cbd2a4b3 1251 //\r
1252 // The memory space for ScsiDevicePath is allocated in\r
1253 // ScsiPassThru->BuildDevicePath() function; It is no longer used\r
1254 // after AppendDevicePathNode,so free the memory it occupies.\r
1255 //\r
1256 FreePool (ScsiDevicePath);\r
1257\r
1258 if (DevicePath != NULL) {\r
1259 FreePool (DevicePath);\r
1260 }\r
1261\r
1262 if (ScsiIoDevice != NULL) {\r
1263 FreePool (ScsiIoDevice);\r
1264 }\r
1265\r
1266 return Status;\r
3a10d471 1267}\r
1268\r
9beb888e 1269/**\r
70c94b3b 1270 Discovery SCSI Device\r
3a10d471 1271\r
9beb888e 1272 @param ScsiIoDevice The pointer of SCSI_IO_DEV\r
3a10d471 1273\r
9beb888e 1274 @retval TRUE Find SCSI Device and verify it.\r
1275 @retval FALSE Unable to find SCSI Device.\r
3a10d471 1276\r
9beb888e 1277**/\r
1278BOOLEAN\r
1279DiscoverScsiDevice (\r
1436aea4 1280 IN OUT SCSI_IO_DEV *ScsiIoDevice\r
9beb888e 1281 )\r
3a10d471 1282{\r
1436aea4
MK
1283 EFI_STATUS Status;\r
1284 UINT32 InquiryDataLength;\r
1285 UINT8 SenseDataLength;\r
1286 UINT8 HostAdapterStatus;\r
1287 UINT8 TargetStatus;\r
1288 EFI_SCSI_INQUIRY_DATA *InquiryData;\r
1289 EFI_SCSI_SENSE_DATA *SenseData;\r
1290 UINT8 MaxRetry;\r
1291 UINT8 Index;\r
1292 BOOLEAN ScsiDeviceFound;\r
3a10d471 1293\r
1294 HostAdapterStatus = 0;\r
1295 TargetStatus = 0;\r
ce13d2d8 1296 SenseData = NULL;\r
957fe093
SZ
1297\r
1298 InquiryData = AllocateAlignedBuffer (ScsiIoDevice, sizeof (EFI_SCSI_INQUIRY_DATA));\r
1299 if (InquiryData == NULL) {\r
1300 ScsiDeviceFound = FALSE;\r
1301 goto Done;\r
1302 }\r
1303\r
ce13d2d8
LE
1304 SenseData = AllocateAlignedBuffer (\r
1305 ScsiIoDevice,\r
1306 sizeof (EFI_SCSI_SENSE_DATA)\r
1307 );\r
1308 if (SenseData == NULL) {\r
1309 ScsiDeviceFound = FALSE;\r
1310 goto Done;\r
1311 }\r
1312\r
3a10d471 1313 //\r
1314 // Using Inquiry command to scan for the device\r
1315 //\r
1316 InquiryDataLength = sizeof (EFI_SCSI_INQUIRY_DATA);\r
ce13d2d8 1317 SenseDataLength = sizeof (EFI_SCSI_SENSE_DATA);\r
957fe093 1318 ZeroMem (InquiryData, InquiryDataLength);\r
ce13d2d8 1319 ZeroMem (SenseData, SenseDataLength);\r
cbd2a4b3 1320\r
1321 MaxRetry = 2;\r
1322 for (Index = 0; Index < MaxRetry; Index++) {\r
1323 Status = ScsiInquiryCommand (\r
1436aea4
MK
1324 &ScsiIoDevice->ScsiIo,\r
1325 SCSI_BUS_TIMEOUT,\r
1326 SenseData,\r
1327 &SenseDataLength,\r
1328 &HostAdapterStatus,\r
1329 &TargetStatus,\r
1330 (VOID *)InquiryData,\r
1331 &InquiryDataLength,\r
1332 FALSE\r
1333 );\r
cbd2a4b3 1334 if (!EFI_ERROR (Status)) {\r
ce13d2d8
LE
1335 if ((HostAdapterStatus == EFI_SCSI_IO_STATUS_HOST_ADAPTER_OK) &&\r
1336 (TargetStatus == EFI_SCSI_IO_STATUS_TARGET_CHECK_CONDITION) &&\r
1337 (SenseData->Error_Code == 0x70) &&\r
1436aea4
MK
1338 (SenseData->Sense_Key == EFI_SCSI_SK_ILLEGAL_REQUEST))\r
1339 {\r
ce13d2d8
LE
1340 ScsiDeviceFound = FALSE;\r
1341 goto Done;\r
1342 }\r
1436aea4 1343\r
cbd2a4b3 1344 break;\r
c09e481b 1345 }\r
1436aea4 1346\r
c09e481b
LE
1347 if ((Status == EFI_BAD_BUFFER_SIZE) ||\r
1348 (Status == EFI_INVALID_PARAMETER) ||\r
1436aea4
MK
1349 (Status == EFI_UNSUPPORTED))\r
1350 {\r
957fe093
SZ
1351 ScsiDeviceFound = FALSE;\r
1352 goto Done;\r
cbd2a4b3 1353 }\r
1354 }\r
3a10d471 1355\r
cbd2a4b3 1356 if (Index == MaxRetry) {\r
957fe093
SZ
1357 ScsiDeviceFound = FALSE;\r
1358 goto Done;\r
3a10d471 1359 }\r
d1102dba 1360\r
3a10d471 1361 //\r
1362 // Retrieved inquiry data successfully\r
1363 //\r
897efb97 1364 if (InquiryData->Peripheral_Qualifier != 0) {\r
957fe093
SZ
1365 ScsiDeviceFound = FALSE;\r
1366 goto Done;\r
3a10d471 1367 }\r
1368\r
1ff7ed2c 1369 if ((InquiryData->Peripheral_Type >= EFI_SCSI_TYPE_RESERVED_LOW) &&\r
1436aea4
MK
1370 (InquiryData->Peripheral_Type <= EFI_SCSI_TYPE_RESERVED_HIGH))\r
1371 {\r
957fe093
SZ
1372 ScsiDeviceFound = FALSE;\r
1373 goto Done;\r
3a10d471 1374 }\r
c52fa98c 1375\r
3a10d471 1376 //\r
1377 // valid device type and peripheral qualifier combination.\r
1378 //\r
957fe093
SZ
1379 ScsiIoDevice->ScsiDeviceType = InquiryData->Peripheral_Type;\r
1380 ScsiIoDevice->RemovableDevice = InquiryData->Rmb;\r
1381 if (InquiryData->Version == 0) {\r
3a10d471 1382 ScsiIoDevice->ScsiVersion = 0;\r
1383 } else {\r
1384 //\r
1385 // ANSI-approved version\r
1386 //\r
1436aea4 1387 ScsiIoDevice->ScsiVersion = (UINT8)(InquiryData->Version & 0x07);\r
3a10d471 1388 }\r
1389\r
957fe093
SZ
1390 ScsiDeviceFound = TRUE;\r
1391\r
1392Done:\r
ce13d2d8 1393 FreeAlignedBuffer (SenseData, sizeof (EFI_SCSI_SENSE_DATA));\r
957fe093
SZ
1394 FreeAlignedBuffer (InquiryData, sizeof (EFI_SCSI_INQUIRY_DATA));\r
1395\r
1396 return ScsiDeviceFound;\r
3a10d471 1397}\r
70c94b3b 1398\r
9beb888e 1399/**\r
1400 Convert EFI_SCSI_IO_SCSI_REQUEST_PACKET packet to EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET packet.\r
1401\r
1402 @param Packet The pointer of EFI_SCSI_IO_SCSI_REQUEST_PACKET\r
1403 @param CommandPacket The pointer of EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET\r
1404\r
1405**/\r
70c94b3b 1406EFI_STATUS\r
1407EFIAPI\r
1408ScsiioToPassThruPacket (\r
1409 IN EFI_SCSI_IO_SCSI_REQUEST_PACKET *Packet,\r
9beb888e 1410 OUT EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *CommandPacket\r
70c94b3b 1411 )\r
70c94b3b 1412{\r
1413 //\r
1436aea4 1414 // EFI 1.10 doesn't support Bi-Direction Command.\r
70c94b3b 1415 //\r
1416 if (Packet->DataDirection == EFI_SCSI_IO_DATA_DIRECTION_BIDIRECTIONAL) {\r
1417 return EFI_UNSUPPORTED;\r
1418 }\r
c52fa98c 1419\r
70c94b3b 1420 ZeroMem (CommandPacket, sizeof (EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET));\r
1421\r
1422 CommandPacket->Timeout = Packet->Timeout;\r
1423 CommandPacket->Cdb = Packet->Cdb;\r
1424 CommandPacket->CdbLength = Packet->CdbLength;\r
1425 CommandPacket->DataDirection = Packet->DataDirection;\r
1426 CommandPacket->HostAdapterStatus = Packet->HostAdapterStatus;\r
1427 CommandPacket->TargetStatus = Packet->TargetStatus;\r
1428 CommandPacket->SenseData = Packet->SenseData;\r
1429 CommandPacket->SenseDataLength = Packet->SenseDataLength;\r
1430\r
1431 if (Packet->DataDirection == EFI_SCSI_IO_DATA_DIRECTION_READ) {\r
1436aea4 1432 CommandPacket->DataBuffer = Packet->InDataBuffer;\r
70c94b3b 1433 CommandPacket->TransferLength = Packet->InTransferLength;\r
1434 } else if (Packet->DataDirection == EFI_SCSI_IO_DATA_DIRECTION_WRITE) {\r
1436aea4 1435 CommandPacket->DataBuffer = Packet->OutDataBuffer;\r
70c94b3b 1436 CommandPacket->TransferLength = Packet->OutTransferLength;\r
1437 }\r
1436aea4 1438\r
70c94b3b 1439 return EFI_SUCCESS;\r
1440}\r
1441\r
9beb888e 1442/**\r
1443 Convert EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET packet to EFI_SCSI_IO_SCSI_REQUEST_PACKET packet.\r
1444\r
1445 @param ScsiPacket The pointer of EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET\r
1446 @param Packet The pointer of EFI_SCSI_IO_SCSI_REQUEST_PACKET\r
1447\r
1448**/\r
70c94b3b 1449EFI_STATUS\r
1450EFIAPI\r
1451PassThruToScsiioPacket (\r
1452 IN EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *ScsiPacket,\r
9beb888e 1453 OUT EFI_SCSI_IO_SCSI_REQUEST_PACKET *Packet\r
70c94b3b 1454 )\r
70c94b3b 1455{\r
1456 Packet->Timeout = ScsiPacket->Timeout;\r
1457 Packet->Cdb = ScsiPacket->Cdb;\r
1458 Packet->CdbLength = ScsiPacket->CdbLength;\r
1459 Packet->DataDirection = ScsiPacket->DataDirection;\r
1460 Packet->HostAdapterStatus = ScsiPacket->HostAdapterStatus;\r
1461 Packet->TargetStatus = ScsiPacket->TargetStatus;\r
1462 Packet->SenseData = ScsiPacket->SenseData;\r
1463 Packet->SenseDataLength = ScsiPacket->SenseDataLength;\r
1464\r
1465 if (ScsiPacket->DataDirection == EFI_SCSI_IO_DATA_DIRECTION_READ) {\r
1436aea4 1466 Packet->InDataBuffer = ScsiPacket->DataBuffer;\r
70c94b3b 1467 Packet->InTransferLength = ScsiPacket->TransferLength;\r
1468 } else if (Packet->DataDirection == EFI_SCSI_IO_DATA_DIRECTION_WRITE) {\r
1436aea4 1469 Packet->OutDataBuffer = ScsiPacket->DataBuffer;\r
70c94b3b 1470 Packet->OutTransferLength = ScsiPacket->TransferLength;\r
1471 }\r
c52fa98c 1472\r
70c94b3b 1473 return EFI_SUCCESS;\r
1474}\r
1475\r
9beb888e 1476/**\r
1477 Notify Function in which convert EFI1.0 PassThru Packet back to UEF2.0\r
1478 SCSI IO Packet.\r
70c94b3b 1479\r
9beb888e 1480 @param Event The instance of EFI_EVENT.\r
1481 @param Context The parameter passed in.\r
70c94b3b 1482\r
9beb888e 1483**/\r
70c94b3b 1484VOID\r
1485EFIAPI\r
1486NotifyFunction (\r
9beb888e 1487 IN EFI_EVENT Event,\r
1488 IN VOID *Context\r
70c94b3b 1489 )\r
70c94b3b 1490{\r
1436aea4
MK
1491 EFI_SCSI_IO_SCSI_REQUEST_PACKET *Packet;\r
1492 EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *ScsiPacket;\r
1493 EFI_EVENT CallerEvent;\r
1494 SCSI_EVENT_DATA *PassData;\r
70c94b3b 1495\r
1436aea4
MK
1496 PassData = (SCSI_EVENT_DATA *)Context;\r
1497 Packet = (EFI_SCSI_IO_SCSI_REQUEST_PACKET *)PassData->Data1;\r
1498 ScsiPacket = (EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *)mWorkingBuffer;\r
70c94b3b 1499\r
1500 //\r
1501 // Convert EFI1.0 PassThru packet to UEFI2.0 SCSI IO Packet.\r
1502 //\r
1436aea4 1503 PassThruToScsiioPacket (ScsiPacket, Packet);\r
c52fa98c 1504\r
70c94b3b 1505 //\r
1506 // After converting EFI1.0 PassThru Packet back to UEFI2.0 SCSI IO Packet,\r
9beb888e 1507 // free mWorkingBuffer.\r
70c94b3b 1508 //\r
1436aea4 1509 gBS->FreePool (mWorkingBuffer);\r
70c94b3b 1510\r
1511 //\r
1512 // Signal Event to tell caller to pick up UEFI2.0 SCSI IO Packet.\r
1513 //\r
1514 CallerEvent = PassData->Data2;\r
1436aea4
MK
1515 gBS->CloseEvent (Event);\r
1516 gBS->SignalEvent (CallerEvent);\r
70c94b3b 1517}\r