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