]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBus.c
Make MdePkg GCC clean
[mirror_edk2.git] / MdeModulePkg / Bus / Scsi / ScsiBusDxe / ScsiBus.c
... / ...
CommitLineData
1/*++\r
2\r
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
11\r
12Module Name:\r
13\r
14 scsibus.c\r
15\r
16Abstract:\r
17\r
18\r
19Revision History\r
20--*/\r
21\r
22\r
23#include <PiDxe.h>\r
24\r
25\r
26#include <Protocol/ScsiPassThru.h>\r
27#include <Protocol/ScsiPassThruExt.h>\r
28#include <Protocol/ScsiIo.h>\r
29#include <Protocol/ComponentName.h>\r
30#include <Protocol/DriverBinding.h>\r
31#include <Protocol/DevicePath.h>\r
32\r
33#include <Library/DebugLib.h>\r
34#include <Library/UefiDriverEntryPoint.h>\r
35#include <Library/UefiLib.h>\r
36#include <Library/BaseMemoryLib.h>\r
37#include <Library/MemoryAllocationLib.h>\r
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
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
90/**\r
91 The user Entry Point for module ScsiBus. The user code starts with this function.\r
92\r
93 @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
94 @param[in] SystemTable A pointer to the EFI System Table.\r
95\r
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
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
152--*/\r
153\r
154{\r
155 EFI_STATUS Status;\r
156 EFI_SCSI_PASS_THRU_PROTOCOL *PassThru;\r
157 EFI_EXT_SCSI_PASS_THRU_PROTOCOL *ExtPassThru;\r
158 //\r
159 // Check for the existence of Extended SCSI Pass Thru Protocol and SCSI Pass Thru Protocol\r
160 //\r
161 Status = gBS->OpenProtocol (\r
162 Controller,\r
163 &gEfiExtScsiPassThruProtocolGuid,\r
164 (VOID **)&ExtPassThru,\r
165 This->DriverBindingHandle,\r
166 Controller,\r
167 EFI_OPEN_PROTOCOL_BY_DRIVER\r
168 );\r
169\r
170 if (Status == EFI_ALREADY_STARTED) {\r
171 return EFI_SUCCESS;\r
172 }\r
173\r
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
183\r
184 if (Status == EFI_ALREADY_STARTED) {\r
185 return EFI_SUCCESS;\r
186 }\r
187\r
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
199 }\r
200\r
201 gBS->CloseProtocol (\r
202 Controller,\r
203 &gEfiExtScsiPassThruProtocolGuid,\r
204 This->DriverBindingHandle,\r
205 Controller\r
206 );\r
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
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
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
239 UINT64 Lun;\r
240 BOOLEAN ScanOtherPuns;\r
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
257\r
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
265\r
266 Status = gBS->OpenProtocol (\r
267 Controller,\r
268 &gEfiDevicePathProtocolGuid,\r
269 (VOID **) &(ScsiBusDev->DevicePath),\r
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
275 gBS->FreePool (ScsiBusDev);\r
276 return Status;\r
277 }\r
278\r
279 //\r
280 // First consume Extended SCSI Pass Thru protocol, if fail, then consume\r
281 // SCSI Pass Thru protocol\r
282 //\r
283 Status = gBS->OpenProtocol (\r
284 Controller,\r
285 &gEfiExtScsiPassThruProtocolGuid,\r
286 (VOID **) &(ScsiBusDev->ExtScsiInterface),\r
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
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
309 }\r
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
329 gBS->CloseProtocol (\r
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
351 return Status;\r
352 }\r
353\r
354 if (RemainingDevicePath == NULL) {\r
355 SetMem (ScsiTargetId, TARGET_MAX_BYTES,0xFF);\r
356 Lun = 0;\r
357 FromFirstTarget = TRUE;\r
358 } else {\r
359 if (ScsiBusDev->ExtScsiSupport) {\r
360 ScsiBusDev->ExtScsiInterface->GetTargetLun (ScsiBusDev->ExtScsiInterface, RemainingDevicePath, &TargetId, &Lun);\r
361 } else {\r
362 ScsiBusDev->ScsiInterface->GetTargetLun (ScsiBusDev->ScsiInterface, RemainingDevicePath, &ScsiTargetId->ScsiId.Scsi, &Lun);\r
363 }\r
364 }\r
365\r
366 while(ScanOtherPuns) {\r
367 if (FromFirstTarget) {\r
368 //\r
369 // Remaining Device Path is NULL, scan all the possible Puns in the\r
370 // SCSI Channel.\r
371 //\r
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
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
384 ScanOtherPuns = FALSE;\r
385 }\r
386 //\r
387 // Avoid creating handle for the host adapter.\r
388 //\r
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
397 }\r
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
402 Status = ScsiScanCreateDevice (This, Controller, ScsiTargetId, Lun, ScsiBusDev);\r
403 }\r
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
416\r
417 Routine Description:\r
418\r
419 Arguments:\r
420\r
421 Returns:\r
422\r
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
437 VOID *ScsiPassThru;\r
438 EFI_SCSI_BUS_PROTOCOL *Scsidentifier;\r
439 SCSI_BUS_DEVICE *ScsiBusDev;\r
440\r
441 if (NumberOfChildren == 0) {\r
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
453\r
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
468\r
469 //\r
470 // Close the bus driver\r
471 //\r
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
487\r
488 gBS->CloseProtocol (\r
489 Controller,\r
490 &gEfiDevicePathProtocolGuid,\r
491 This->DriverBindingHandle,\r
492 Controller\r
493 );\r
494 gBS->FreePool (ScsiBusDev);\r
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
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
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
546 if (ScsiIoDevice->ExtScsiSupport) {\r
547 gBS->OpenProtocol (\r
548 Controller,\r
549 &gEfiExtScsiPassThruProtocolGuid,\r
550 (VOID **) &(EFI_EXT_SCSI_PASS_THRU_PROTOCOL*)ScsiPassThru,\r
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
559 (VOID **) &(EFI_SCSI_PASS_THRU_PROTOCOL*)ScsiPassThru,\r
560 This->DriverBindingHandle,\r
561 ChildHandleBuffer[Index],\r
562 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
563 );\r
564 }\r
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
587\r
588 Arguments:\r
589 This - Protocol instance pointer.\r
590 DeviceType - A pointer to the device type information\r
591 retrieved from the SCSI Controller.\r
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
609EFI_STATUS\r
610EFIAPI\r
611ScsiGetDeviceLocation (\r
612 IN EFI_SCSI_IO_PROTOCOL *This,\r
613 IN OUT UINT8 **Target,\r
614 OUT UINT64 *Lun\r
615 )\r
616/*++\r
617 Routine Description:\r
618 Retrieves the device location in the SCSI channel.\r
619\r
620 Arguments:\r
621 This - Protocol instance pointer.\r
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
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
640 CopyMem (*Target,&ScsiIoDevice->Pun, TARGET_MAX_BYTES);\r
641\r
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
656\r
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
665 EFI_TIMEOUT - A timeout occurred while attempting to reset\r
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
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
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
689\r
690 Arguments:\r
691 This - Protocol instance pointer.\r
692\r
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
698 EFI_UNSUPPORTED - The SCSI bus does not support a device\r
699 reset operation.\r
700 EFI_TIMEOUT - A timeout occurred while attempting to\r
701 reset the SCSI Controller.\r
702--*/\r
703{\r
704 SCSI_IO_DEV *ScsiIoDevice;\r
705 UINT8 Target[TARGET_MAX_BYTES];\r
706\r
707 ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (This);\r
708 CopyMem (Target,&ScsiIoDevice->Pun, TARGET_MAX_BYTES);\r
709\r
710\r
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
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
737\r
738 Arguments:\r
739 This - Protocol instance pointer.\r
740 Packet - The SCSI request packet to send to the SCSI\r
741 Controller specified by the device handle.\r
742 Event - If the SCSI bus where the SCSI device is attached\r
743 does not support non-blocking I/O, then Event is\r
744 ignored, and blocking I/O is performed.\r
745 If Event is NULL, then blocking I/O is performed.\r
746 If Event is not NULL and non-blocking I/O is\r
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
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
755 SenseDataLength, and SenseData in that order\r
756 for additional status information.\r
757 EFI_WARN_BUFFER_TOO_SMALL - The SCSI Request Packet was executed,\r
758 but the entire DataBuffer could not be transferred.\r
759 The actual number of bytes transferred is returned\r
760 in TransferLength. See HostAdapterStatus,\r
761 TargetStatus, SenseDataLength, and SenseData in\r
762 that order for additional status information.\r
763 EFI_NOT_READY - The SCSI Request Packet could not be sent because\r
764 there are too many SCSI Command Packets already\r
765 queued.The caller may retry again later.\r
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
769 that order for additional status information.\r
770 EFI_INVALID_PARAMETER - The contents of CommandPacket are invalid.\r
771 The SCSI Request Packet was not sent, so no\r
772 additional status information is available.\r
773 EFI_UNSUPPORTED - The command described by the SCSI Request Packet\r
774 is not supported by the SCSI initiator(i.e., SCSI\r
775 Host Controller). The SCSI Request Packet was not\r
776 sent, so no additional status information is\r
777 available.\r
778 EFI_TIMEOUT - A timeout occurred while waiting for the SCSI\r
779 Request Packet to execute. See HostAdapterStatus,\r
780 TargetStatus, SenseDataLength, and SenseData in\r
781 that order for additional status information.\r
782--*/\r
783{\r
784 SCSI_IO_DEV *ScsiIoDevice;\r
785 EFI_STATUS Status;\r
786 UINT8 Target[TARGET_MAX_BYTES];\r
787 EFI_EVENT PacketEvent;\r
788 EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *ExtRequestPacket;\r
789 SCSI_EVENT_DATA EventData;\r
790\r
791 PacketEvent = NULL;\r
792\r
793 if (Packet == NULL) {\r
794 return EFI_INVALID_PARAMETER;\r
795 }\r
796\r
797 ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (This);\r
798 CopyMem (Target,&ScsiIoDevice->Pun, TARGET_MAX_BYTES);\r
799\r
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
810\r
811 Status = gBS->AllocatePool (\r
812 EfiBootServicesData,\r
813 sizeof(EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET),\r
814 (VOID**)&WorkingBuffer\r
815 );\r
816\r
817 if (EFI_ERROR (Status)) {\r
818 return EFI_DEVICE_ERROR;\r
819 }\r
820\r
821 //\r
822 // Convert package into EFI1.0, EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET.\r
823 //\r
824 Status = ScsiioToPassThruPacket(Packet, (EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET*)WorkingBuffer);\r
825 if (EFI_ERROR(Status)) {\r
826 gBS->FreePool(WorkingBuffer);\r
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
847\r
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
861\r
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
887 return Status;\r
888}\r
889\r
890EFI_STATUS\r
891EFIAPI\r
892ScsiScanCreateDevice (\r
893 EFI_DRIVER_BINDING_PROTOCOL *This,\r
894 EFI_HANDLE Controller,\r
895 SCSI_TARGET_ID *TargetId,\r
896 UINT64 Lun,\r
897 SCSI_BUS_DEVICE *ScsiBusDev\r
898 )\r
899/*++\r
900\r
901Routine Description:\r
902\r
903 Scan SCSI Bus to discover the device, and attach ScsiIoProtocol to it.\r
904\r
905Arguments:\r
906\r
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
912\r
913Returns:\r
914\r
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
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
936 CopyMem(&ScsiIoDevice->Pun, TargetId, TARGET_MAX_BYTES);\r
937 ScsiIoDevice->Lun = Lun;\r
938\r
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
950 ScsiIoDevice->ScsiIo.GetDeviceType = ScsiGetDeviceType;\r
951 ScsiIoDevice->ScsiIo.GetDeviceLocation = ScsiGetDeviceLocation;\r
952 ScsiIoDevice->ScsiIo.ResetBus = ScsiResetBus;\r
953 ScsiIoDevice->ScsiIo.ResetDevice = ScsiResetDevice;\r
954 ScsiIoDevice->ScsiIo.ExecuteScsiCommand = ScsiExecuteSCSICommand;\r
955\r
956\r
957 if (!DiscoverScsiDevice (ScsiIoDevice)) {\r
958 gBS->FreePool (ScsiIoDevice);\r
959 return EFI_OUT_OF_RESOURCES;\r
960 }\r
961\r
962 //\r
963 // Set Device Path\r
964 //\r
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
987 }\r
988\r
989 ScsiIoDevice->DevicePath = AppendDevicePathNode (\r
990 ScsiBusDev->DevicePath,\r
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
1004\r
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
1015 return EFI_OUT_OF_RESOURCES;\r
1016 } else {\r
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
1036 }\r
1037 return EFI_SUCCESS;\r
1038}\r
1039\r
1040BOOLEAN\r
1041EFIAPI\r
1042DiscoverScsiDevice (\r
1043 SCSI_IO_DEV *ScsiIoDevice\r
1044 )\r
1045/*++\r
1046\r
1047Routine Description:\r
1048\r
1049 Discovery SCSI Device\r
1050\r
1051Arguments:\r
1052\r
1053 ScsiIoDevice - The pointer of SCSI_IO_DEV\r
1054\r
1055Returns:\r
1056\r
1057 TRUE - Find SCSI Device and verify it.\r
1058 FALSE - Unable to find SCSI Device.\r
1059\r
1060--*/\r
1061{\r
1062 EFI_STATUS Status;\r
1063 UINT32 InquiryDataLength;\r
1064 UINT8 SenseDataLength;\r
1065 UINT8 HostAdapterStatus;\r
1066 UINT8 TargetStatus;\r
1067 EFI_SCSI_SENSE_DATA SenseData;\r
1068 EFI_SCSI_INQUIRY_DATA InquiryData;\r
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 = ScsiInquiryCommand (\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
1109 if (0x1e >= InquiryData.Peripheral_Type >= 0xa) {\r
1110 return FALSE;\r
1111 }\r
1112\r
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
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
1142 Convert EFI_SCSI_IO_SCSI_REQUEST_PACKET packet to\r
1143 EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET packet\r
1144\r
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
1149\r
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
1162\r
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
1196 Convert EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET packet to\r
1197 EFI_SCSI_IO_SCSI_REQUEST_PACKET packet\r
1198\r
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
1203\r
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
1226\r
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
1243 Notify Function in which convert EFI1.0 PassThru Packet back to UEF2.0\r
1244 SCSI IO Packet.\r
1245\r
1246Arguments:\r
1247\r
1248 Event - The instance of EFI_EVENT.\r
1249 Context - The parameter passed in.\r
1250\r
1251Returns:\r
1252\r
1253 NONE\r
1254\r
1255--*/\r
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
1260 SCSI_EVENT_DATA *PassData;\r
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
1270\r
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