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