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