]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBus.c
remove some comments introduced by tools.
[mirror_edk2.git] / MdeModulePkg / Bus / Scsi / ScsiBusDxe / ScsiBus.c
CommitLineData
3a10d471 1/*++\r
2\r
c52fa98c 3Copyright (c) 2006, Intel Corporation\r
4All rights reserved. This program and the accompanying materials\r
5are licensed and made available under the terms and conditions of the BSD License\r
6which accompanies this distribution. The full text of the license may be found at\r
7http://opensource.org/licenses/bsd-license.php\r
8\r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
3a10d471 11\r
12Module Name:\r
13\r
14 scsibus.c\r
c52fa98c 15\r
16Abstract:\r
17\r
3a10d471 18\r
19Revision History\r
20--*/\r
21\r
ed7748fe 22\r
3a10d471 23#include <PiDxe.h>\r
24\r
ed7748fe 25\r
3a10d471 26#include <Protocol/ScsiPassThru.h>\r
70c94b3b 27#include <Protocol/ScsiPassThruExt.h>\r
3a10d471 28#include <Protocol/ScsiIo.h>\r
29#include <Protocol/ComponentName.h>\r
30#include <Protocol/DriverBinding.h>\r
31#include <Protocol/DevicePath.h>\r
ed7748fe 32\r
3a10d471 33#include <Library/DebugLib.h>\r
34#include <Library/UefiDriverEntryPoint.h>\r
35#include <Library/UefiLib.h>\r
36#include <Library/BaseMemoryLib.h>\r
70c94b3b 37#include <Library/MemoryAllocationLib.h>\r
3a10d471 38#include <Library/ScsiLib.h>\r
39#include <Library/UefiBootServicesTableLib.h>\r
40#include <Library/DevicePathLib.h>\r
41\r
42#include "ScsiBus.h"\r
43\r
44EFI_DRIVER_BINDING_PROTOCOL gSCSIBusDriverBinding = {\r
45 SCSIBusDriverBindingSupported,\r
46 SCSIBusDriverBindingStart,\r
47 SCSIBusDriverBindingStop,\r
48 0xa,\r
49 NULL,\r
50 NULL\r
51};\r
52\r
70c94b3b 53\r
54//\r
55// The ScsiBusProtocol is just used to locate ScsiBusDev\r
56// structure in the SCSIBusDriverBindingStop(). Then we can\r
57// Close all opened protocols and release this structure.\r
58//\r
59STATIC EFI_GUID mScsiBusProtocolGuid = EFI_SCSI_BUS_PROTOCOL_GUID;\r
60\r
61STATIC VOID *WorkingBuffer;\r
62\r
63STATIC\r
64EFI_STATUS\r
65EFIAPI\r
66ScsiioToPassThruPacket (\r
67 IN EFI_SCSI_IO_SCSI_REQUEST_PACKET *Packet,\r
68 IN OUT EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *CommandPacket\r
69 )\r
70;\r
71\r
72\r
73STATIC\r
74EFI_STATUS\r
75EFIAPI\r
76PassThruToScsiioPacket (\r
77 IN EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *ScsiPacket,\r
78 IN OUT EFI_SCSI_IO_SCSI_REQUEST_PACKET *Packet\r
79 )\r
80;\r
81STATIC\r
82VOID\r
83EFIAPI\r
84NotifyFunction (\r
85 EFI_EVENT Event,\r
86 VOID *Context\r
87 )\r
88;\r
89\r
3a10d471 90/**\r
91 The user Entry Point for module ScsiBus. The user code starts with this function.\r
92\r
c52fa98c 93 @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
3a10d471 94 @param[in] SystemTable A pointer to the EFI System Table.\r
c52fa98c 95\r
3a10d471 96 @retval EFI_SUCCESS The entry point is executed successfully.\r
97 @retval other Some error occurs when executing this entry point.\r
98\r
99**/\r
100EFI_STATUS\r
101EFIAPI\r
102InitializeScsiBus(\r
103 IN EFI_HANDLE ImageHandle,\r
104 IN EFI_SYSTEM_TABLE *SystemTable\r
105 )\r
106{\r
107 EFI_STATUS Status;\r
108\r
109 //\r
110 // Install driver model protocol(s).\r
111 //\r
112 Status = EfiLibInstallAllDriverProtocols (\r
113 ImageHandle,\r
114 SystemTable,\r
115 &gSCSIBusDriverBinding,\r
116 ImageHandle,\r
117 &gScsiBusComponentName,\r
118 NULL,\r
119 NULL\r
120 );\r
121 ASSERT_EFI_ERROR (Status);\r
122\r
123\r
124 return Status;\r
125}\r
126\r
127EFI_STATUS\r
128EFIAPI\r
129SCSIBusDriverBindingSupported (\r
130 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
131 IN EFI_HANDLE Controller,\r
132 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
133 )\r
134/*++\r
70c94b3b 135\r
136Routine Description:\r
137\r
138 Test to see if this driver supports ControllerHandle. Any ControllerHandle\r
139 that has ExtScsiPassThruProtocol/ScsiPassThruProtocol installed will be supported.\r
140\r
141Arguments:\r
142\r
143 This - Protocol instance pointer.\r
144 Controller - Handle of device to test\r
145 RemainingDevicePath - Not used\r
146\r
147Returns:\r
148\r
149 EFI_SUCCESS - This driver supports this device.\r
150 EFI_UNSUPPORTED - This driver does not support this device.\r
151\r
3a10d471 152--*/\r
70c94b3b 153\r
3a10d471 154{\r
155 EFI_STATUS Status;\r
70c94b3b 156 EFI_SCSI_PASS_THRU_PROTOCOL *PassThru;\r
157 EFI_EXT_SCSI_PASS_THRU_PROTOCOL *ExtPassThru;\r
3a10d471 158 //\r
70c94b3b 159 // Check for the existence of Extended SCSI Pass Thru Protocol and SCSI Pass Thru Protocol\r
3a10d471 160 //\r
161 Status = gBS->OpenProtocol (\r
162 Controller,\r
70c94b3b 163 &gEfiExtScsiPassThruProtocolGuid,\r
164 (VOID **)&ExtPassThru,\r
3a10d471 165 This->DriverBindingHandle,\r
166 Controller,\r
70c94b3b 167 EFI_OPEN_PROTOCOL_BY_DRIVER\r
3a10d471 168 );\r
c52fa98c 169\r
70c94b3b 170 if (Status == EFI_ALREADY_STARTED) {\r
171 return EFI_SUCCESS;\r
172 }\r
c52fa98c 173\r
70c94b3b 174 if (EFI_ERROR (Status)) {\r
175 Status = gBS->OpenProtocol (\r
176 Controller,\r
177 &gEfiScsiPassThruProtocolGuid,\r
178 (VOID **)&PassThru,\r
179 This->DriverBindingHandle,\r
180 Controller,\r
181 EFI_OPEN_PROTOCOL_BY_DRIVER\r
182 );\r
c52fa98c 183\r
70c94b3b 184 if (Status == EFI_ALREADY_STARTED) {\r
185 return EFI_SUCCESS;\r
186 }\r
c52fa98c 187\r
70c94b3b 188 if (EFI_ERROR (Status)) {\r
189 return Status;\r
190 }\r
191\r
192 gBS->CloseProtocol (\r
193 Controller,\r
194 &gEfiScsiPassThruProtocolGuid,\r
195 This->DriverBindingHandle,\r
196 Controller\r
197 );\r
198 return EFI_SUCCESS;\r
3a10d471 199 }\r
c52fa98c 200\r
70c94b3b 201 gBS->CloseProtocol (\r
202 Controller,\r
203 &gEfiExtScsiPassThruProtocolGuid,\r
204 This->DriverBindingHandle,\r
205 Controller\r
206 );\r
3a10d471 207\r
208 return EFI_SUCCESS;\r
209}\r
210\r
211EFI_STATUS\r
212EFIAPI\r
213SCSIBusDriverBindingStart (\r
214 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
215 IN EFI_HANDLE Controller,\r
216 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
217 )\r
218/*++\r
70c94b3b 219\r
220Routine Description:\r
221 Starting the SCSI Bus Driver\r
222\r
223Arguments:\r
224 This - Protocol instance pointer.\r
225 Controller - Handle of device to test\r
226 RemainingDevicePath - Not used\r
227\r
228Returns:\r
229 EFI_SUCCESS - This driver supports this device.\r
230 EFI_UNSUPPORTED - This driver does not support this device.\r
231 EFI_DEVICE_ERROR - This driver cannot be started due to device Error\r
232\r
3a10d471 233--*/\r
234// TODO: This - add argument and description to function comment\r
235// TODO: Controller - add argument and description to function comment\r
236// TODO: RemainingDevicePath - add argument and description to function comment\r
237{\r
238 EFI_STATUS Status;\r
3a10d471 239 UINT64 Lun;\r
240 BOOLEAN ScanOtherPuns;\r
70c94b3b 241 SCSI_BUS_DEVICE *ScsiBusDev;\r
242 BOOLEAN FromFirstTarget;\r
243 SCSI_TARGET_ID *ScsiTargetId;\r
244 UINT8 *TargetId;\r
245\r
246 TargetId = NULL;\r
247 ScanOtherPuns = TRUE;\r
248 FromFirstTarget = FALSE;\r
249 //\r
250 // Allocate SCSI_BUS_DEVICE structure\r
251 //\r
252 ScsiBusDev = NULL;\r
253 ScsiBusDev = AllocateZeroPool (sizeof (SCSI_BUS_DEVICE));\r
254 if (ScsiBusDev == NULL) {\r
255 return EFI_OUT_OF_RESOURCES;\r
256 }\r
3a10d471 257\r
70c94b3b 258 ScsiTargetId = NULL;\r
259 ScsiTargetId = AllocateZeroPool (sizeof (SCSI_TARGET_ID));\r
260 if (ScsiTargetId == NULL) {\r
261 return EFI_OUT_OF_RESOURCES;\r
262 }\r
263\r
264 TargetId = &ScsiTargetId->ScsiId.ExtScsi[0];\r
c52fa98c 265\r
3a10d471 266 Status = gBS->OpenProtocol (\r
267 Controller,\r
268 &gEfiDevicePathProtocolGuid,\r
70c94b3b 269 (VOID **) &(ScsiBusDev->DevicePath),\r
3a10d471 270 This->DriverBindingHandle,\r
271 Controller,\r
272 EFI_OPEN_PROTOCOL_BY_DRIVER\r
273 );\r
274 if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
70c94b3b 275 gBS->FreePool (ScsiBusDev);\r
3a10d471 276 return Status;\r
277 }\r
278\r
279 //\r
70c94b3b 280 // First consume Extended SCSI Pass Thru protocol, if fail, then consume\r
281 // SCSI Pass Thru protocol\r
3a10d471 282 //\r
283 Status = gBS->OpenProtocol (\r
284 Controller,\r
70c94b3b 285 &gEfiExtScsiPassThruProtocolGuid,\r
286 (VOID **) &(ScsiBusDev->ExtScsiInterface),\r
3a10d471 287 This->DriverBindingHandle,\r
288 Controller,\r
289 EFI_OPEN_PROTOCOL_BY_DRIVER\r
290 );\r
291 if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
70c94b3b 292 Status = gBS->OpenProtocol (\r
293 Controller,\r
294 &gEfiScsiPassThruProtocolGuid,\r
295 (VOID **) &(ScsiBusDev->ScsiInterface),\r
296 This->DriverBindingHandle,\r
297 Controller,\r
298 EFI_OPEN_PROTOCOL_BY_DRIVER\r
299 );\r
300 if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
301 gBS->CloseProtocol (\r
302 Controller,\r
303 &gEfiDevicePathProtocolGuid,\r
304 This->DriverBindingHandle,\r
305 Controller\r
306 );\r
307 gBS->FreePool (ScsiBusDev);\r
308 return Status;\r
c52fa98c 309 }\r
70c94b3b 310 DEBUG ((EFI_D_INFO, "Open Scsi Pass Thrugh Protocol\n"));\r
311 ScsiBusDev->ExtScsiSupport = FALSE;\r
312 } else {\r
313 DEBUG ((EFI_D_INFO, "Open Extended Scsi Pass Thrugh Protocol\n"));\r
314 ScsiBusDev->ExtScsiSupport = TRUE;\r
315 }\r
316\r
317 ScsiBusDev->Signature = SCSI_BUS_DEVICE_SIGNATURE;\r
318 //\r
319 // Attach EFI_SCSI_BUS_PROTOCOL to controller handle\r
320 //\r
321 Status = gBS->InstallProtocolInterface (\r
322 &Controller,\r
323 &mScsiBusProtocolGuid,\r
324 EFI_NATIVE_INTERFACE,\r
325 &ScsiBusDev->BusIdentify\r
326 );\r
327\r
328 if (EFI_ERROR (Status)) {\r
3a10d471 329 gBS->CloseProtocol (\r
70c94b3b 330 Controller,\r
331 &gEfiDevicePathProtocolGuid,\r
332 This->DriverBindingHandle,\r
333 Controller\r
334 );\r
335 if (ScsiBusDev->ExtScsiSupport) {\r
336 gBS->CloseProtocol (\r
337 Controller,\r
338 &gEfiExtScsiPassThruProtocolGuid,\r
339 This->DriverBindingHandle,\r
340 Controller\r
341 );\r
342 } else {\r
343 gBS->CloseProtocol (\r
344 Controller,\r
345 &gEfiScsiPassThruProtocolGuid,\r
346 This->DriverBindingHandle,\r
347 Controller\r
348 );\r
349 }\r
350 gBS->FreePool (ScsiBusDev);\r
3a10d471 351 return Status;\r
352 }\r
353\r
354 if (RemainingDevicePath == NULL) {\r
70c94b3b 355 SetMem (ScsiTargetId, TARGET_MAX_BYTES,0xFF);\r
356 Lun = 0;\r
357 FromFirstTarget = TRUE;\r
3a10d471 358 } else {\r
70c94b3b 359 if (ScsiBusDev->ExtScsiSupport) {\r
c52fa98c 360 ScsiBusDev->ExtScsiInterface->GetTargetLun (ScsiBusDev->ExtScsiInterface, RemainingDevicePath, &TargetId, &Lun);\r
70c94b3b 361 } else {\r
362 ScsiBusDev->ScsiInterface->GetTargetLun (ScsiBusDev->ScsiInterface, RemainingDevicePath, &ScsiTargetId->ScsiId.Scsi, &Lun);\r
363 }\r
3a10d471 364 }\r
365\r
70c94b3b 366 while(ScanOtherPuns) {\r
367 if (FromFirstTarget) {\r
3a10d471 368 //\r
369 // Remaining Device Path is NULL, scan all the possible Puns in the\r
370 // SCSI Channel.\r
371 //\r
70c94b3b 372 if (ScsiBusDev->ExtScsiSupport) {\r
373 Status = ScsiBusDev->ExtScsiInterface->GetNextTargetLun (ScsiBusDev->ExtScsiInterface, &TargetId, &Lun);\r
374 } else {\r
375 Status = ScsiBusDev->ScsiInterface->GetNextDevice (ScsiBusDev->ScsiInterface, &ScsiTargetId->ScsiId.Scsi, &Lun);\r
376 }\r
3a10d471 377 if (EFI_ERROR (Status)) {\r
378 //\r
379 // no legal Pun and Lun found any more\r
380 //\r
381 break;\r
382 }\r
383 } else {\r
3a10d471 384 ScanOtherPuns = FALSE;\r
385 }\r
3a10d471 386 //\r
387 // Avoid creating handle for the host adapter.\r
388 //\r
70c94b3b 389 if (ScsiBusDev->ExtScsiSupport) {\r
390 if ((ScsiTargetId->ScsiId.Scsi) == ScsiBusDev->ExtScsiInterface->Mode->AdapterId) {\r
391 continue;\r
392 }\r
393 } else {\r
394 if ((ScsiTargetId->ScsiId.Scsi) == ScsiBusDev->ScsiInterface->Mode->AdapterId) {\r
395 continue;\r
396 }\r
3a10d471 397 }\r
3a10d471 398 //\r
399 // Scan for the scsi device, if it attaches to the scsi bus,\r
400 // then create handle and install scsi i/o protocol.\r
401 //\r
70c94b3b 402 Status = ScsiScanCreateDevice (This, Controller, ScsiTargetId, Lun, ScsiBusDev);\r
3a10d471 403 }\r
3a10d471 404 return Status;\r
405}\r
406\r
407EFI_STATUS\r
408EFIAPI\r
409SCSIBusDriverBindingStop (\r
410 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
411 IN EFI_HANDLE Controller,\r
412 IN UINTN NumberOfChildren,\r
413 IN EFI_HANDLE *ChildHandleBuffer\r
414 )\r
415/*++\r
c52fa98c 416\r
3a10d471 417 Routine Description:\r
c52fa98c 418\r
3a10d471 419 Arguments:\r
c52fa98c 420\r
3a10d471 421 Returns:\r
c52fa98c 422\r
3a10d471 423--*/\r
424// TODO: This - add argument and description to function comment\r
425// TODO: Controller - add argument and description to function comment\r
426// TODO: NumberOfChildren - add argument and description to function comment\r
427// TODO: ChildHandleBuffer - add argument and description to function comment\r
428// TODO: EFI_SUCCESS - add return value to function comment\r
429// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
430// TODO: EFI_SUCCESS - add return value to function comment\r
431{\r
432 EFI_STATUS Status;\r
433 BOOLEAN AllChildrenStopped;\r
434 UINTN Index;\r
435 EFI_SCSI_IO_PROTOCOL *ScsiIo;\r
436 SCSI_IO_DEV *ScsiIoDevice;\r
70c94b3b 437 VOID *ScsiPassThru;\r
438 EFI_SCSI_BUS_PROTOCOL *Scsidentifier;\r
439 SCSI_BUS_DEVICE *ScsiBusDev;\r
3a10d471 440\r
441 if (NumberOfChildren == 0) {\r
70c94b3b 442 //\r
443 // Get the SCSI_BUS_DEVICE\r
444 //\r
445 Status = gBS->OpenProtocol (\r
446 Controller,\r
447 &mScsiBusProtocolGuid,\r
448 (VOID **) &Scsidentifier,\r
449 This->DriverBindingHandle,\r
450 Controller,\r
451 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
452 );\r
c52fa98c 453\r
70c94b3b 454 if (EFI_ERROR (Status)) {\r
455 return EFI_DEVICE_ERROR;\r
456 }\r
457\r
458 ScsiBusDev = SCSI_BUS_CONTROLLER_DEVICE_FROM_THIS (Scsidentifier);\r
459\r
460 //\r
461 // Uninstall SCSI Bus Protocol\r
462 //\r
463 gBS->UninstallProtocolInterface (\r
464 Controller,\r
465 &mScsiBusProtocolGuid,\r
466 &ScsiBusDev->BusIdentify\r
467 );\r
c52fa98c 468\r
3a10d471 469 //\r
470 // Close the bus driver\r
471 //\r
70c94b3b 472 if (ScsiBusDev->ExtScsiSupport) {\r
473 gBS->CloseProtocol (\r
474 Controller,\r
475 &gEfiExtScsiPassThruProtocolGuid,\r
476 This->DriverBindingHandle,\r
477 Controller\r
478 );\r
479 } else {\r
480 gBS->CloseProtocol (\r
481 Controller,\r
482 &gEfiScsiPassThruProtocolGuid,\r
483 This->DriverBindingHandle,\r
484 Controller\r
485 );\r
486 }\r
3a10d471 487\r
70c94b3b 488 gBS->CloseProtocol (\r
489 Controller,\r
490 &gEfiDevicePathProtocolGuid,\r
491 This->DriverBindingHandle,\r
492 Controller\r
493 );\r
494 gBS->FreePool (ScsiBusDev);\r
3a10d471 495 return EFI_SUCCESS;\r
496 }\r
497\r
498 AllChildrenStopped = TRUE;\r
499\r
500 for (Index = 0; Index < NumberOfChildren; Index++) {\r
501\r
502 Status = gBS->OpenProtocol (\r
503 ChildHandleBuffer[Index],\r
504 &gEfiScsiIoProtocolGuid,\r
505 (VOID **) &ScsiIo,\r
506 This->DriverBindingHandle,\r
507 Controller,\r
508 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
509 );\r
510 if (EFI_ERROR (Status)) {\r
511 AllChildrenStopped = FALSE;\r
512 continue;\r
513 }\r
514\r
515 ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (ScsiIo);\r
516 //\r
517 // Close the child handle\r
518 //\r
70c94b3b 519 if (ScsiIoDevice->ExtScsiSupport) {\r
520 Status = gBS->CloseProtocol (\r
521 Controller,\r
522 &gEfiExtScsiPassThruProtocolGuid,\r
523 This->DriverBindingHandle,\r
524 ChildHandleBuffer[Index]\r
525 );\r
526\r
527 } else {\r
528 Status = gBS->CloseProtocol (\r
529 Controller,\r
530 &gEfiScsiPassThruProtocolGuid,\r
531 This->DriverBindingHandle,\r
532 ChildHandleBuffer[Index]\r
533 );\r
534 }\r
3a10d471 535\r
536 Status = gBS->UninstallMultipleProtocolInterfaces (\r
537 ChildHandleBuffer[Index],\r
538 &gEfiDevicePathProtocolGuid,\r
539 ScsiIoDevice->DevicePath,\r
540 &gEfiScsiIoProtocolGuid,\r
541 &ScsiIoDevice->ScsiIo,\r
542 NULL\r
543 );\r
544 if (EFI_ERROR (Status)) {\r
545 AllChildrenStopped = FALSE;\r
70c94b3b 546 if (ScsiIoDevice->ExtScsiSupport) {\r
547 gBS->OpenProtocol (\r
548 Controller,\r
549 &gEfiExtScsiPassThruProtocolGuid,\r
c52fa98c 550 (VOID **) &(EFI_EXT_SCSI_PASS_THRU_PROTOCOL*)ScsiPassThru,\r
70c94b3b 551 This->DriverBindingHandle,\r
552 ChildHandleBuffer[Index],\r
553 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
554 );\r
555 } else {\r
556 gBS->OpenProtocol (\r
557 Controller,\r
558 &gEfiScsiPassThruProtocolGuid,\r
c52fa98c 559 (VOID **) &(EFI_SCSI_PASS_THRU_PROTOCOL*)ScsiPassThru,\r
70c94b3b 560 This->DriverBindingHandle,\r
561 ChildHandleBuffer[Index],\r
562 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
563 );\r
564 }\r
3a10d471 565 } else {\r
566 gBS->FreePool (ScsiIoDevice);\r
567 }\r
568 }\r
569\r
570 if (!AllChildrenStopped) {\r
571 return EFI_DEVICE_ERROR;\r
572 }\r
573\r
574 return EFI_SUCCESS;\r
575}\r
576\r
577EFI_STATUS\r
578EFIAPI\r
579ScsiGetDeviceType (\r
580 IN EFI_SCSI_IO_PROTOCOL *This,\r
581 OUT UINT8 *DeviceType\r
582 )\r
583/*++\r
584\r
585 Routine Description:\r
586 Retrieves the device type information of the SCSI Controller.\r
c52fa98c 587\r
3a10d471 588 Arguments:\r
589 This - Protocol instance pointer.\r
590 DeviceType - A pointer to the device type information\r
c52fa98c 591 retrieved from the SCSI Controller.\r
3a10d471 592\r
593 Returns:\r
594 EFI_SUCCESS - Retrieves the device type information successfully.\r
595 EFI_INVALID_PARAMETER - The DeviceType is NULL.\r
596--*/\r
597{\r
598 SCSI_IO_DEV *ScsiIoDevice;\r
599\r
600 if (DeviceType == NULL) {\r
601 return EFI_INVALID_PARAMETER;\r
602 }\r
603\r
604 ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (This);\r
605 *DeviceType = ScsiIoDevice->ScsiDeviceType;\r
606 return EFI_SUCCESS;\r
607}\r
608\r
3a10d471 609EFI_STATUS\r
610EFIAPI\r
611ScsiGetDeviceLocation (\r
612 IN EFI_SCSI_IO_PROTOCOL *This,\r
70c94b3b 613 IN OUT UINT8 **Target,\r
3a10d471 614 OUT UINT64 *Lun\r
615 )\r
616/*++\r
617 Routine Description:\r
618 Retrieves the device location in the SCSI channel.\r
c52fa98c 619\r
3a10d471 620 Arguments:\r
621 This - Protocol instance pointer.\r
c52fa98c 622 Target - A pointer to the Target ID of a SCSI device\r
623 on the SCSI channel.\r
624 Lun - A pointer to the LUN of the SCSI device on\r
3a10d471 625 the SCSI channel.\r
626\r
627 Returns:\r
628 EFI_SUCCESS - Retrieves the device location successfully.\r
629 EFI_INVALID_PARAMETER - The Target or Lun is NULL.\r
630--*/\r
631{\r
632 SCSI_IO_DEV *ScsiIoDevice;\r
633\r
634 if (Target == NULL || Lun == NULL) {\r
635 return EFI_INVALID_PARAMETER;\r
636 }\r
637\r
638 ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (This);\r
639\r
70c94b3b 640 CopyMem (*Target,&ScsiIoDevice->Pun, TARGET_MAX_BYTES);\r
641\r
3a10d471 642 *Lun = ScsiIoDevice->Lun;\r
643\r
644 return EFI_SUCCESS;\r
645}\r
646\r
647EFI_STATUS\r
648EFIAPI\r
649ScsiResetBus (\r
650 IN EFI_SCSI_IO_PROTOCOL *This\r
651 )\r
652/*++\r
653\r
654 Routine Description:\r
655 Resets the SCSI Bus that the SCSI Controller is attached to.\r
c52fa98c 656\r
3a10d471 657 Arguments:\r
658 This - Protocol instance pointer.\r
659\r
660 Returns:\r
661 EFI_SUCCESS - The SCSI bus is reset successfully.\r
662 EFI_DEVICE_ERROR - Errors encountered when resetting the SCSI bus.\r
663 EFI_UNSUPPORTED - The bus reset operation is not supported by the\r
664 SCSI Host Controller.\r
c52fa98c 665 EFI_TIMEOUT - A timeout occurred while attempting to reset\r
3a10d471 666 the SCSI bus.\r
667--*/\r
668{\r
669 SCSI_IO_DEV *ScsiIoDevice;\r
670\r
671 ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (This);\r
672\r
70c94b3b 673 if (ScsiIoDevice->ExtScsiSupport){\r
674 return ScsiIoDevice->ExtScsiPassThru->ResetChannel (ScsiIoDevice->ExtScsiPassThru);\r
675 } else {\r
676 return ScsiIoDevice->ScsiPassThru->ResetChannel (ScsiIoDevice->ScsiPassThru);\r
677 }\r
3a10d471 678}\r
679\r
680EFI_STATUS\r
681EFIAPI\r
682ScsiResetDevice (\r
683 IN EFI_SCSI_IO_PROTOCOL *This\r
684 )\r
685/*++\r
686\r
687 Routine Description:\r
688 Resets the SCSI Controller that the device handle specifies.\r
c52fa98c 689\r
3a10d471 690 Arguments:\r
691 This - Protocol instance pointer.\r
c52fa98c 692\r
3a10d471 693\r
694 Returns:\r
695 EFI_SUCCESS - Reset the SCSI controller successfully.\r
696 EFI_DEVICE_ERROR - Errors are encountered when resetting the\r
697 SCSI Controller.\r
c52fa98c 698 EFI_UNSUPPORTED - The SCSI bus does not support a device\r
3a10d471 699 reset operation.\r
c52fa98c 700 EFI_TIMEOUT - A timeout occurred while attempting to\r
3a10d471 701 reset the SCSI Controller.\r
702--*/\r
703{\r
704 SCSI_IO_DEV *ScsiIoDevice;\r
70c94b3b 705 UINT8 Target[TARGET_MAX_BYTES];\r
3a10d471 706\r
707 ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (This);\r
70c94b3b 708 CopyMem (Target,&ScsiIoDevice->Pun, TARGET_MAX_BYTES);\r
709\r
3a10d471 710\r
70c94b3b 711 if (ScsiIoDevice->ExtScsiSupport) {\r
712 return ScsiIoDevice->ExtScsiPassThru->ResetTargetLun (\r
713 ScsiIoDevice->ExtScsiPassThru,\r
714 Target,\r
715 ScsiIoDevice->Lun\r
716 );\r
717 } else {\r
718 return ScsiIoDevice->ScsiPassThru->ResetTarget (\r
719 ScsiIoDevice->ScsiPassThru,\r
720 ScsiIoDevice->Pun.ScsiId.Scsi,\r
721 ScsiIoDevice->Lun\r
722 );\r
723 }\r
3a10d471 724}\r
725\r
726EFI_STATUS\r
727EFIAPI\r
728ScsiExecuteSCSICommand (\r
729 IN EFI_SCSI_IO_PROTOCOL *This,\r
730 IN OUT EFI_SCSI_IO_SCSI_REQUEST_PACKET *Packet,\r
731 IN EFI_EVENT Event OPTIONAL\r
732 )\r
733/*++\r
734\r
735 Routine Description:\r
736 Sends a SCSI Request Packet to the SCSI Controller for execution.\r
c52fa98c 737\r
3a10d471 738 Arguments:\r
739 This - Protocol instance pointer.\r
c52fa98c 740 Packet - The SCSI request packet to send to the SCSI\r
3a10d471 741 Controller specified by the device handle.\r
742 Event - If the SCSI bus where the SCSI device is attached\r
c52fa98c 743 does not support non-blocking I/O, then Event is\r
744 ignored, and blocking I/O is performed.\r
3a10d471 745 If Event is NULL, then blocking I/O is performed.\r
c52fa98c 746 If Event is not NULL and non-blocking I/O is\r
3a10d471 747 supported, then non-blocking I/O is performed,\r
748 and Event will be signaled when the SCSI Request\r
749 Packet completes.\r
750 Returns:\r
c52fa98c 751 EFI_SUCCESS - The SCSI Request Packet was sent by the host\r
752 successfully, and TransferLength bytes were\r
753 transferred to/from DataBuffer.See\r
754 HostAdapterStatus, TargetStatus,\r
3a10d471 755 SenseDataLength, and SenseData in that order\r
756 for additional status information.\r
c52fa98c 757 EFI_WARN_BUFFER_TOO_SMALL - The SCSI Request Packet was executed,\r
3a10d471 758 but the entire DataBuffer could not be transferred.\r
759 The actual number of bytes transferred is returned\r
c52fa98c 760 in TransferLength. See HostAdapterStatus,\r
761 TargetStatus, SenseDataLength, and SenseData in\r
3a10d471 762 that order for additional status information.\r
c52fa98c 763 EFI_NOT_READY - The SCSI Request Packet could not be sent because\r
764 there are too many SCSI Command Packets already\r
3a10d471 765 queued.The caller may retry again later.\r
c52fa98c 766 EFI_DEVICE_ERROR - A device error occurred while attempting to send\r
767 the SCSI Request Packet. See HostAdapterStatus,\r
768 TargetStatus, SenseDataLength, and SenseData in\r
3a10d471 769 that order for additional status information.\r
c52fa98c 770 EFI_INVALID_PARAMETER - The contents of CommandPacket are invalid.\r
771 The SCSI Request Packet was not sent, so no\r
3a10d471 772 additional status information is available.\r
773 EFI_UNSUPPORTED - The command described by the SCSI Request Packet\r
c52fa98c 774 is not supported by the SCSI initiator(i.e., SCSI\r
3a10d471 775 Host Controller). The SCSI Request Packet was not\r
c52fa98c 776 sent, so no additional status information is\r
3a10d471 777 available.\r
c52fa98c 778 EFI_TIMEOUT - A timeout occurred while waiting for the SCSI\r
3a10d471 779 Request Packet to execute. See HostAdapterStatus,\r
c52fa98c 780 TargetStatus, SenseDataLength, and SenseData in\r
3a10d471 781 that order for additional status information.\r
782--*/\r
783{\r
784 SCSI_IO_DEV *ScsiIoDevice;\r
785 EFI_STATUS Status;\r
70c94b3b 786 UINT8 Target[TARGET_MAX_BYTES];\r
787 EFI_EVENT PacketEvent;\r
788 EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *ExtRequestPacket;\r
c52fa98c 789 SCSI_EVENT_DATA EventData;\r
3a10d471 790\r
70c94b3b 791 PacketEvent = NULL;\r
c52fa98c 792\r
3a10d471 793 if (Packet == NULL) {\r
794 return EFI_INVALID_PARAMETER;\r
795 }\r
796\r
797 ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (This);\r
70c94b3b 798 CopyMem (Target,&ScsiIoDevice->Pun, TARGET_MAX_BYTES);\r
c52fa98c 799\r
70c94b3b 800 if (ScsiIoDevice->ExtScsiSupport) {\r
801 ExtRequestPacket = (EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *) Packet;\r
802 Status = ScsiIoDevice->ExtScsiPassThru->PassThru (\r
803 ScsiIoDevice->ExtScsiPassThru,\r
804 Target,\r
805 ScsiIoDevice->Lun,\r
806 ExtRequestPacket,\r
807 Event\r
808 );\r
809 } else {\r
3a10d471 810\r
70c94b3b 811 Status = gBS->AllocatePool (\r
812 EfiBootServicesData,\r
813 sizeof(EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET),\r
814 (VOID**)&WorkingBuffer\r
815 );\r
3a10d471 816\r
70c94b3b 817 if (EFI_ERROR (Status)) {\r
818 return EFI_DEVICE_ERROR;\r
819 }\r
820\r
821 //\r
c52fa98c 822 // Convert package into EFI1.0, EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET.\r
70c94b3b 823 //\r
824 Status = ScsiioToPassThruPacket(Packet, (EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET*)WorkingBuffer);\r
825 if (EFI_ERROR(Status)) {\r
c52fa98c 826 gBS->FreePool(WorkingBuffer);\r
70c94b3b 827 return Status;\r
828 }\r
829\r
830 if ((ScsiIoDevice->ScsiPassThru->Mode->Attributes & EFI_SCSI_PASS_THRU_ATTRIBUTES_NONBLOCKIO) && (Event != NULL)) {\r
831 EventData.Data1 = (VOID*)Packet;\r
832 EventData.Data2 = Event;\r
833 //\r
834 // Create Event\r
835 //\r
836 Status = gBS->CreateEvent (\r
837 EVT_NOTIFY_SIGNAL,\r
838 TPL_CALLBACK,\r
839 NotifyFunction,\r
840 &EventData,\r
841 &PacketEvent\r
842 );\r
843 if (EFI_ERROR(Status)) {\r
844 gBS->FreePool(WorkingBuffer);\r
845 return Status;\r
846 }\r
c52fa98c 847\r
70c94b3b 848 Status = ScsiIoDevice->ScsiPassThru->PassThru (\r
849 ScsiIoDevice->ScsiPassThru,\r
850 ScsiIoDevice->Pun.ScsiId.Scsi,\r
851 ScsiIoDevice->Lun,\r
852 WorkingBuffer,\r
853 PacketEvent\r
854 );\r
855\r
856 if (EFI_ERROR(Status)) {\r
857 gBS->FreePool(WorkingBuffer);\r
858 gBS->CloseEvent(PacketEvent);\r
859 return Status;\r
860 }\r
c52fa98c 861\r
70c94b3b 862 } else {\r
863 //\r
864 // If there's no event or SCSI Device doesn't support NON-BLOCKING, just convert\r
865 // EFI1.0 PassThru packet back to UEFI2.0 SCSI IO Packet.\r
866 //\r
867 Status = ScsiIoDevice->ScsiPassThru->PassThru (\r
868 ScsiIoDevice->ScsiPassThru,\r
869 ScsiIoDevice->Pun.ScsiId.Scsi,\r
870 ScsiIoDevice->Lun,\r
871 WorkingBuffer,\r
872 Event\r
873 );\r
874 if (EFI_ERROR(Status)) {\r
875 gBS->FreePool(WorkingBuffer);\r
876 return Status;\r
877 }\r
878\r
879 PassThruToScsiioPacket((EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET*)WorkingBuffer,Packet);\r
880 //\r
881 // After converting EFI1.0 PassThru Packet back to UEFI2.0 SCSI IO Packet,\r
882 // free WorkingBuffer.\r
883 //\r
884 gBS->FreePool(WorkingBuffer);\r
885 }\r
886 }\r
3a10d471 887 return Status;\r
888}\r
889\r
890EFI_STATUS\r
c52fa98c 891EFIAPI\r
3a10d471 892ScsiScanCreateDevice (\r
893 EFI_DRIVER_BINDING_PROTOCOL *This,\r
894 EFI_HANDLE Controller,\r
70c94b3b 895 SCSI_TARGET_ID *TargetId,\r
3a10d471 896 UINT64 Lun,\r
70c94b3b 897 SCSI_BUS_DEVICE *ScsiBusDev\r
3a10d471 898 )\r
899/*++\r
900\r
901Routine Description:\r
902\r
70c94b3b 903 Scan SCSI Bus to discover the device, and attach ScsiIoProtocol to it.\r
3a10d471 904\r
905Arguments:\r
906\r
70c94b3b 907 This - Protocol instance pointer\r
908 Controller - Controller handle\r
909 Pun - The Pun of the SCSI device on the SCSI channel.\r
910 Lun - The Lun of the SCSI device on the SCSI channel.\r
911 ScsiBusDev - The pointer of SCSI_BUS_DEVICE\r
3a10d471 912\r
913Returns:\r
914\r
70c94b3b 915 EFI_SUCCESS - Successfully to discover the device and attach ScsiIoProtocol to it.\r
916 EFI_OUT_OF_RESOURCES - Fail to discover the device.\r
3a10d471 917\r
918--*/\r
919{\r
920 EFI_STATUS Status;\r
921 SCSI_IO_DEV *ScsiIoDevice;\r
922 EFI_DEVICE_PATH_PROTOCOL *ScsiDevicePath;\r
923\r
924 Status = gBS->AllocatePool (\r
925 EfiBootServicesData,\r
926 sizeof (SCSI_IO_DEV),\r
927 (VOID **) &ScsiIoDevice\r
928 );\r
929 if (EFI_ERROR (Status)) {\r
930 return Status;\r
931 }\r
932\r
933 ZeroMem (ScsiIoDevice, sizeof (SCSI_IO_DEV));\r
934\r
935 ScsiIoDevice->Signature = SCSI_IO_DEV_SIGNATURE;\r
70c94b3b 936 CopyMem(&ScsiIoDevice->Pun, TargetId, TARGET_MAX_BYTES);\r
3a10d471 937 ScsiIoDevice->Lun = Lun;\r
938\r
70c94b3b 939 if (ScsiBusDev->ExtScsiSupport) {\r
940 ScsiIoDevice->ExtScsiPassThru = ScsiBusDev->ExtScsiInterface;\r
941 ScsiIoDevice->ExtScsiSupport = TRUE;\r
942 ScsiIoDevice->ScsiIo.IoAlign = ScsiIoDevice->ExtScsiPassThru->Mode->IoAlign;\r
943\r
944 } else {\r
945 ScsiIoDevice->ScsiPassThru = ScsiBusDev->ScsiInterface;\r
946 ScsiIoDevice->ExtScsiSupport = FALSE;\r
947 ScsiIoDevice->ScsiIo.IoAlign = ScsiIoDevice->ScsiPassThru->Mode->IoAlign;\r
948 }\r
949\r
3a10d471 950 ScsiIoDevice->ScsiIo.GetDeviceType = ScsiGetDeviceType;\r
70c94b3b 951 ScsiIoDevice->ScsiIo.GetDeviceLocation = ScsiGetDeviceLocation;\r
3a10d471 952 ScsiIoDevice->ScsiIo.ResetBus = ScsiResetBus;\r
953 ScsiIoDevice->ScsiIo.ResetDevice = ScsiResetDevice;\r
24e734d2 954 ScsiIoDevice->ScsiIo.ExecuteScsiCommand = ScsiExecuteSCSICommand;\r
3a10d471 955\r
70c94b3b 956\r
3a10d471 957 if (!DiscoverScsiDevice (ScsiIoDevice)) {\r
958 gBS->FreePool (ScsiIoDevice);\r
70c94b3b 959 return EFI_OUT_OF_RESOURCES;\r
3a10d471 960 }\r
70c94b3b 961\r
3a10d471 962 //\r
963 // Set Device Path\r
964 //\r
70c94b3b 965 if (ScsiIoDevice->ExtScsiSupport){\r
966 Status = ScsiIoDevice->ExtScsiPassThru->BuildDevicePath (\r
967 ScsiIoDevice->ExtScsiPassThru,\r
968 &ScsiIoDevice->Pun.ScsiId.ExtScsi[0],\r
969 ScsiIoDevice->Lun,\r
970 &ScsiDevicePath\r
971 );\r
972 if (Status == EFI_OUT_OF_RESOURCES) {\r
973 gBS->FreePool (ScsiIoDevice);\r
974 return Status;\r
975 }\r
976 } else {\r
977 Status = ScsiIoDevice->ScsiPassThru->BuildDevicePath (\r
978 ScsiIoDevice->ScsiPassThru,\r
979 ScsiIoDevice->Pun.ScsiId.Scsi,\r
980 ScsiIoDevice->Lun,\r
981 &ScsiDevicePath\r
982 );\r
983 if (Status == EFI_OUT_OF_RESOURCES) {\r
984 gBS->FreePool (ScsiIoDevice);\r
985 return Status;\r
986 }\r
3a10d471 987 }\r
c52fa98c 988\r
3a10d471 989 ScsiIoDevice->DevicePath = AppendDevicePathNode (\r
70c94b3b 990 ScsiBusDev->DevicePath,\r
3a10d471 991 ScsiDevicePath\r
992 );\r
993 //\r
994 // The memory space for ScsiDevicePath is allocated in\r
995 // ScsiPassThru->BuildDevicePath() function; It is no longer used\r
996 // after EfiAppendDevicePathNode,so free the memory it occupies.\r
997 //\r
998 gBS->FreePool (ScsiDevicePath);\r
999\r
1000 if (ScsiIoDevice->DevicePath == NULL) {\r
1001 gBS->FreePool (ScsiIoDevice);\r
1002 return EFI_OUT_OF_RESOURCES;\r
1003 }\r
c52fa98c 1004\r
3a10d471 1005 Status = gBS->InstallMultipleProtocolInterfaces (\r
1006 &ScsiIoDevice->Handle,\r
1007 &gEfiDevicePathProtocolGuid,\r
1008 ScsiIoDevice->DevicePath,\r
1009 &gEfiScsiIoProtocolGuid,\r
1010 &ScsiIoDevice->ScsiIo,\r
1011 NULL\r
1012 );\r
1013 if (EFI_ERROR (Status)) {\r
1014 gBS->FreePool (ScsiIoDevice);\r
70c94b3b 1015 return EFI_OUT_OF_RESOURCES;\r
3a10d471 1016 } else {\r
70c94b3b 1017 if (ScsiBusDev->ExtScsiSupport) {\r
1018 gBS->OpenProtocol (\r
1019 Controller,\r
1020 &gEfiExtScsiPassThruProtocolGuid,\r
1021 (VOID **) &(ScsiBusDev->ExtScsiInterface),\r
1022 This->DriverBindingHandle,\r
1023 ScsiIoDevice->Handle,\r
1024 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
1025 );\r
1026 } else {\r
1027 gBS->OpenProtocol (\r
1028 Controller,\r
1029 &gEfiScsiPassThruProtocolGuid,\r
1030 (VOID **) &(ScsiBusDev->ScsiInterface),\r
1031 This->DriverBindingHandle,\r
1032 ScsiIoDevice->Handle,\r
1033 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
1034 );\r
1035 }\r
3a10d471 1036 }\r
3a10d471 1037 return EFI_SUCCESS;\r
1038}\r
1039\r
1040BOOLEAN\r
c52fa98c 1041EFIAPI\r
3a10d471 1042DiscoverScsiDevice (\r
1043 SCSI_IO_DEV *ScsiIoDevice\r
1044 )\r
1045/*++\r
1046\r
1047Routine Description:\r
1048\r
70c94b3b 1049 Discovery SCSI Device\r
3a10d471 1050\r
1051Arguments:\r
1052\r
70c94b3b 1053 ScsiIoDevice - The pointer of SCSI_IO_DEV\r
3a10d471 1054\r
1055Returns:\r
1056\r
70c94b3b 1057 TRUE - Find SCSI Device and verify it.\r
c52fa98c 1058 FALSE - Unable to find SCSI Device.\r
3a10d471 1059\r
1060--*/\r
1061{\r
1062 EFI_STATUS Status;\r
3a10d471 1063 UINT32 InquiryDataLength;\r
3a10d471 1064 UINT8 SenseDataLength;\r
1065 UINT8 HostAdapterStatus;\r
1066 UINT8 TargetStatus;\r
70c94b3b 1067 EFI_SCSI_SENSE_DATA SenseData;\r
1068 EFI_SCSI_INQUIRY_DATA InquiryData;\r
3a10d471 1069\r
1070 HostAdapterStatus = 0;\r
1071 TargetStatus = 0;\r
1072 //\r
1073 // Using Inquiry command to scan for the device\r
1074 //\r
1075 InquiryDataLength = sizeof (EFI_SCSI_INQUIRY_DATA);\r
1076 SenseDataLength = sizeof (EFI_SCSI_SENSE_DATA);\r
1077\r
1078 Status = SubmitInquiryCommand (\r
1079 &ScsiIoDevice->ScsiIo,\r
1080 EfiScsiStallSeconds (1),\r
1081 (VOID *) &SenseData,\r
1082 &SenseDataLength,\r
1083 &HostAdapterStatus,\r
1084 &TargetStatus,\r
1085 (VOID *) &InquiryData,\r
1086 &InquiryDataLength,\r
1087 FALSE\r
1088 );\r
1089 if (EFI_ERROR (Status)) {\r
1090 //\r
1091 // ParseSenseData (&SenseData,SenseDataLength);\r
1092 //\r
1093 return FALSE;\r
1094 }\r
1095 //\r
1096 // Retrieved inquiry data successfully\r
1097 //\r
1098 if ((InquiryData.Peripheral_Qualifier != 0) &&\r
1099 (InquiryData.Peripheral_Qualifier != 3)) {\r
1100 return FALSE;\r
1101 }\r
1102\r
1103 if (InquiryData.Peripheral_Qualifier == 3) {\r
1104 if (InquiryData.Peripheral_Type != 0x1f) {\r
1105 return FALSE;\r
1106 }\r
1107 }\r
1108\r
70c94b3b 1109 if (0x1e >= InquiryData.Peripheral_Type >= 0xa) {\r
3a10d471 1110 return FALSE;\r
1111 }\r
c52fa98c 1112\r
3a10d471 1113 //\r
1114 // valid device type and peripheral qualifier combination.\r
1115 //\r
1116 ScsiIoDevice->ScsiDeviceType = InquiryData.Peripheral_Type;\r
1117 ScsiIoDevice->RemovableDevice = InquiryData.RMB;\r
1118 if (InquiryData.Version == 0) {\r
1119 ScsiIoDevice->ScsiVersion = 0;\r
1120 } else {\r
1121 //\r
1122 // ANSI-approved version\r
1123 //\r
1124 ScsiIoDevice->ScsiVersion = (UINT8) (InquiryData.Version & 0x03);\r
1125 }\r
1126\r
1127 return TRUE;\r
1128}\r
70c94b3b 1129\r
1130\r
1131STATIC\r
1132EFI_STATUS\r
1133EFIAPI\r
1134ScsiioToPassThruPacket (\r
1135 IN EFI_SCSI_IO_SCSI_REQUEST_PACKET *Packet,\r
1136 IN OUT EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *CommandPacket\r
1137 )\r
1138/*++\r
1139\r
1140Routine Description:\r
1141\r
c52fa98c 1142 Convert EFI_SCSI_IO_SCSI_REQUEST_PACKET packet to\r
70c94b3b 1143 EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET packet\r
c52fa98c 1144\r
70c94b3b 1145Arguments:\r
1146\r
1147 Packet - The pointer of EFI_SCSI_IO_SCSI_REQUEST_PACKET\r
1148 CommandPacket - The pointer of EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET\r
c52fa98c 1149\r
70c94b3b 1150Returns:\r
1151\r
1152 NONE\r
1153\r
1154--*/\r
1155{\r
1156 //\r
1157 //EFI 1.10 doesn't support Bi-Direction Command.\r
1158 //\r
1159 if (Packet->DataDirection == EFI_SCSI_IO_DATA_DIRECTION_BIDIRECTIONAL) {\r
1160 return EFI_UNSUPPORTED;\r
1161 }\r
c52fa98c 1162\r
70c94b3b 1163 ZeroMem (CommandPacket, sizeof (EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET));\r
1164\r
1165 CommandPacket->Timeout = Packet->Timeout;\r
1166 CommandPacket->Cdb = Packet->Cdb;\r
1167 CommandPacket->CdbLength = Packet->CdbLength;\r
1168 CommandPacket->DataDirection = Packet->DataDirection;\r
1169 CommandPacket->HostAdapterStatus = Packet->HostAdapterStatus;\r
1170 CommandPacket->TargetStatus = Packet->TargetStatus;\r
1171 CommandPacket->SenseData = Packet->SenseData;\r
1172 CommandPacket->SenseDataLength = Packet->SenseDataLength;\r
1173\r
1174 if (Packet->DataDirection == EFI_SCSI_IO_DATA_DIRECTION_READ) {\r
1175 CommandPacket->DataBuffer = Packet->InDataBuffer;\r
1176 CommandPacket->TransferLength = Packet->InTransferLength;\r
1177 } else if (Packet->DataDirection == EFI_SCSI_IO_DATA_DIRECTION_WRITE) {\r
1178 CommandPacket->DataBuffer = Packet->OutDataBuffer;\r
1179 CommandPacket->TransferLength = Packet->OutTransferLength;\r
1180 }\r
1181 return EFI_SUCCESS;\r
1182}\r
1183\r
1184\r
1185STATIC\r
1186EFI_STATUS\r
1187EFIAPI\r
1188PassThruToScsiioPacket (\r
1189 IN EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *ScsiPacket,\r
1190 IN OUT EFI_SCSI_IO_SCSI_REQUEST_PACKET *Packet\r
1191 )\r
1192/*++\r
1193\r
1194Routine Description:\r
1195\r
c52fa98c 1196 Convert EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET packet to\r
70c94b3b 1197 EFI_SCSI_IO_SCSI_REQUEST_PACKET packet\r
c52fa98c 1198\r
70c94b3b 1199Arguments:\r
1200\r
1201 ScsiPacket - The pointer of EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET\r
1202 Packet - The pointer of EFI_SCSI_IO_SCSI_REQUEST_PACKET\r
c52fa98c 1203\r
70c94b3b 1204Returns:\r
1205\r
1206 NONE\r
1207\r
1208--*/\r
1209{\r
1210 Packet->Timeout = ScsiPacket->Timeout;\r
1211 Packet->Cdb = ScsiPacket->Cdb;\r
1212 Packet->CdbLength = ScsiPacket->CdbLength;\r
1213 Packet->DataDirection = ScsiPacket->DataDirection;\r
1214 Packet->HostAdapterStatus = ScsiPacket->HostAdapterStatus;\r
1215 Packet->TargetStatus = ScsiPacket->TargetStatus;\r
1216 Packet->SenseData = ScsiPacket->SenseData;\r
1217 Packet->SenseDataLength = ScsiPacket->SenseDataLength;\r
1218\r
1219 if (ScsiPacket->DataDirection == EFI_SCSI_IO_DATA_DIRECTION_READ) {\r
1220 Packet->InDataBuffer = ScsiPacket->DataBuffer;\r
1221 Packet->InTransferLength = ScsiPacket->TransferLength;\r
1222 } else if (Packet->DataDirection == EFI_SCSI_IO_DATA_DIRECTION_WRITE) {\r
1223 Packet->OutDataBuffer = ScsiPacket->DataBuffer;\r
1224 Packet->OutTransferLength = ScsiPacket->TransferLength;\r
1225 }\r
c52fa98c 1226\r
70c94b3b 1227 return EFI_SUCCESS;\r
1228}\r
1229\r
1230\r
1231\r
1232STATIC\r
1233VOID\r
1234EFIAPI\r
1235NotifyFunction (\r
1236 EFI_EVENT Event,\r
1237 VOID *Context\r
1238 )\r
1239/*++\r
1240\r
1241Routine Description:\r
1242\r
c52fa98c 1243 Notify Function in which convert EFI1.0 PassThru Packet back to UEF2.0\r
70c94b3b 1244 SCSI IO Packet.\r
c52fa98c 1245\r
70c94b3b 1246Arguments:\r
1247\r
1248 Event - The instance of EFI_EVENT.\r
1249 Context - The parameter passed in.\r
c52fa98c 1250\r
70c94b3b 1251Returns:\r
1252\r
1253 NONE\r
1254\r
c52fa98c 1255--*/\r
70c94b3b 1256{\r
1257 EFI_SCSI_IO_SCSI_REQUEST_PACKET *Packet;\r
1258 EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *ScsiPacket;\r
1259 EFI_EVENT CallerEvent;\r
c52fa98c 1260 SCSI_EVENT_DATA *PassData;\r
70c94b3b 1261\r
1262 PassData = (SCSI_EVENT_DATA*)Context;\r
1263 Packet = (EFI_SCSI_IO_SCSI_REQUEST_PACKET *)PassData->Data1;\r
1264 ScsiPacket = (EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET*)WorkingBuffer;\r
1265\r
1266 //\r
1267 // Convert EFI1.0 PassThru packet to UEFI2.0 SCSI IO Packet.\r
1268 //\r
1269 PassThruToScsiioPacket(ScsiPacket, Packet);\r
c52fa98c 1270\r
70c94b3b 1271 //\r
1272 // After converting EFI1.0 PassThru Packet back to UEFI2.0 SCSI IO Packet,\r
1273 // free WorkingBuffer.\r
1274 //\r
1275 gBS->FreePool(WorkingBuffer);\r
1276\r
1277 //\r
1278 // Signal Event to tell caller to pick up UEFI2.0 SCSI IO Packet.\r
1279 //\r
1280 CallerEvent = PassData->Data2;\r
1281 gBS->CloseEvent(Event);\r
1282 gBS->SignalEvent(CallerEvent);\r
1283}\r