]> git.proxmox.com Git - mirror_edk2.git/blob - EdkModulePkg/Bus/Scsi/ScsiBus/Dxe/ScsiBus.c
Partially make EdkModulePkg pass intel IPF compiler with /W4 /WX switched on.
[mirror_edk2.git] / EdkModulePkg / Bus / Scsi / ScsiBus / Dxe / 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 #include "ScsiBus.h"
23
24 EFI_STATUS
25 EFIAPI
26 SCSIBusDriverBindingSupported (
27 IN EFI_DRIVER_BINDING_PROTOCOL *This,
28 IN EFI_HANDLE Controller,
29 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
30 );
31
32 EFI_STATUS
33 EFIAPI
34 SCSIBusDriverBindingStart (
35 IN EFI_DRIVER_BINDING_PROTOCOL *This,
36 IN EFI_HANDLE Controller,
37 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
38 );
39
40 EFI_STATUS
41 EFIAPI
42 SCSIBusDriverBindingStop (
43 IN EFI_DRIVER_BINDING_PROTOCOL *This,
44 IN EFI_HANDLE Controller,
45 IN UINTN NumberOfChildren,
46 IN EFI_HANDLE *ChildHandleBuffer
47 );
48
49 EFI_DRIVER_BINDING_PROTOCOL gSCSIBusDriverBinding = {
50 SCSIBusDriverBindingSupported,
51 SCSIBusDriverBindingStart,
52 SCSIBusDriverBindingStop,
53 0xa,
54 NULL,
55 NULL
56 };
57
58 EFI_STATUS
59 EFIAPI
60 SCSIBusDriverBindingSupported (
61 IN EFI_DRIVER_BINDING_PROTOCOL *This,
62 IN EFI_HANDLE Controller,
63 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
64 )
65 /*++
66
67 Routine Description:
68
69 Arguments:
70
71 Returns:
72
73 --*/
74 // TODO: This - add argument and description to function comment
75 // TODO: Controller - add argument and description to function comment
76 // TODO: RemainingDevicePath - add argument and description to function comment
77 // TODO: EFI_UNSUPPORTED - add return value to function comment
78 // TODO: EFI_UNSUPPORTED - add return value to function comment
79 // TODO: EFI_SUCCESS - add return value to function comment
80 {
81 EFI_STATUS Status;
82
83 //
84 // If RemainingDevicePath is not NULL, it should verify that the first device
85 // path node in RemainingDevicePath is an ATAPI Device path node.
86 //
87 if (RemainingDevicePath != NULL) {
88 if ((RemainingDevicePath->Type != MESSAGING_DEVICE_PATH) ||
89 (RemainingDevicePath->SubType != MSG_ATAPI_DP) ||
90 (DevicePathNodeLength (RemainingDevicePath) != sizeof(ATAPI_DEVICE_PATH))) {
91 return EFI_UNSUPPORTED;
92 }
93 }
94 //
95 // check for the existence of SCSI Pass Thru Protocol
96 //
97 Status = gBS->OpenProtocol (
98 Controller,
99 &gEfiScsiPassThruProtocolGuid,
100 NULL,
101 This->DriverBindingHandle,
102 Controller,
103 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
104 );
105 if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
106 return EFI_UNSUPPORTED;
107 }
108
109 return EFI_SUCCESS;
110 }
111
112 EFI_STATUS
113 EFIAPI
114 SCSIBusDriverBindingStart (
115 IN EFI_DRIVER_BINDING_PROTOCOL *This,
116 IN EFI_HANDLE Controller,
117 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
118 )
119 /*++
120
121 Routine Description:
122
123 Arguments:
124
125 Returns:
126
127 --*/
128 // TODO: This - add argument and description to function comment
129 // TODO: Controller - add argument and description to function comment
130 // TODO: RemainingDevicePath - add argument and description to function comment
131 {
132 EFI_STATUS Status;
133 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
134 EFI_SCSI_PASS_THRU_PROTOCOL *ScsiPassThru;
135 UINT32 StartPun;
136 UINT64 StartLun;
137 UINT32 Pun;
138 UINT64 Lun;
139 BOOLEAN ScanOtherPuns;
140
141 StartPun = 0;
142 StartLun = 0;
143 Status = gBS->OpenProtocol (
144 Controller,
145 &gEfiDevicePathProtocolGuid,
146 (VOID **) &ParentDevicePath,
147 This->DriverBindingHandle,
148 Controller,
149 EFI_OPEN_PROTOCOL_BY_DRIVER
150 );
151 if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
152 return Status;
153 }
154
155 //
156 // Consume SCSI Pass Thru protocol.
157 //
158 Status = gBS->OpenProtocol (
159 Controller,
160 &gEfiScsiPassThruProtocolGuid,
161 (VOID **) &ScsiPassThru,
162 This->DriverBindingHandle,
163 Controller,
164 EFI_OPEN_PROTOCOL_BY_DRIVER
165 );
166 if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
167 gBS->CloseProtocol (
168 Controller,
169 &gEfiDevicePathProtocolGuid,
170 This->DriverBindingHandle,
171 Controller
172 );
173 return Status;
174 }
175
176 if (RemainingDevicePath == NULL) {
177 StartPun = 0xFFFFFFFF;
178 StartLun = 0;
179 } else {
180 ScsiPassThru->GetTargetLun (ScsiPassThru, RemainingDevicePath, &StartPun, &StartLun);
181 }
182
183 for (Pun = StartPun, ScanOtherPuns = TRUE; ScanOtherPuns;) {
184
185 if (StartPun == 0xFFFFFFFF) {
186 //
187 // Remaining Device Path is NULL, scan all the possible Puns in the
188 // SCSI Channel.
189 //
190 Status = ScsiPassThru->GetNextDevice (ScsiPassThru, &Pun, &Lun);
191 if (EFI_ERROR (Status)) {
192 //
193 // no legal Pun and Lun found any more
194 //
195 break;
196 }
197 } else {
198 //
199 // Remaining Device Path is not NULL, only scan the specified Pun.
200 //
201 Pun = StartPun;
202 Lun = StartLun;
203 ScanOtherPuns = FALSE;
204 }
205
206 //
207 // Avoid creating handle for the host adapter.
208 //
209 if (Pun == ScsiPassThru->Mode->AdapterId) {
210 continue;
211 }
212
213 //
214 // Scan for the scsi device, if it attaches to the scsi bus,
215 // then create handle and install scsi i/o protocol.
216 //
217 Status = ScsiScanCreateDevice (This, Controller, Pun, Lun, ScsiPassThru, ParentDevicePath);
218 }
219
220 return Status;
221 }
222
223 EFI_STATUS
224 EFIAPI
225 SCSIBusDriverBindingStop (
226 IN EFI_DRIVER_BINDING_PROTOCOL *This,
227 IN EFI_HANDLE Controller,
228 IN UINTN NumberOfChildren,
229 IN EFI_HANDLE *ChildHandleBuffer
230 )
231 /*++
232
233 Routine Description:
234
235 Arguments:
236
237 Returns:
238
239 --*/
240 // TODO: This - add argument and description to function comment
241 // TODO: Controller - add argument and description to function comment
242 // TODO: NumberOfChildren - add argument and description to function comment
243 // TODO: ChildHandleBuffer - add argument and description to function comment
244 // TODO: EFI_SUCCESS - add return value to function comment
245 // TODO: EFI_DEVICE_ERROR - add return value to function comment
246 // TODO: EFI_SUCCESS - add return value to function comment
247 {
248 EFI_STATUS Status;
249 BOOLEAN AllChildrenStopped;
250 UINTN Index;
251 EFI_SCSI_IO_PROTOCOL *ScsiIo;
252 SCSI_IO_DEV *ScsiIoDevice;
253 EFI_SCSI_PASS_THRU_PROTOCOL *ScsiPassThru;
254
255 if (NumberOfChildren == 0) {
256 //
257 // Close the bus driver
258 //
259 gBS->CloseProtocol (
260 Controller,
261 &gEfiScsiPassThruProtocolGuid,
262 This->DriverBindingHandle,
263 Controller
264 );
265 gBS->CloseProtocol (
266 Controller,
267 &gEfiDevicePathProtocolGuid,
268 This->DriverBindingHandle,
269 Controller
270 );
271
272 return EFI_SUCCESS;
273 }
274
275 AllChildrenStopped = TRUE;
276
277 for (Index = 0; Index < NumberOfChildren; Index++) {
278
279 Status = gBS->OpenProtocol (
280 ChildHandleBuffer[Index],
281 &gEfiScsiIoProtocolGuid,
282 (VOID **) &ScsiIo,
283 This->DriverBindingHandle,
284 Controller,
285 EFI_OPEN_PROTOCOL_GET_PROTOCOL
286 );
287 if (EFI_ERROR (Status)) {
288 AllChildrenStopped = FALSE;
289 continue;
290 }
291
292 ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (ScsiIo);
293 //
294 // Close the child handle
295 //
296 Status = gBS->CloseProtocol (
297 Controller,
298 &gEfiScsiPassThruProtocolGuid,
299 This->DriverBindingHandle,
300 ChildHandleBuffer[Index]
301 );
302
303 Status = gBS->UninstallMultipleProtocolInterfaces (
304 ChildHandleBuffer[Index],
305 &gEfiDevicePathProtocolGuid,
306 ScsiIoDevice->DevicePath,
307 &gEfiScsiIoProtocolGuid,
308 &ScsiIoDevice->ScsiIo,
309 NULL
310 );
311 if (EFI_ERROR (Status)) {
312 AllChildrenStopped = FALSE;
313 gBS->OpenProtocol (
314 Controller,
315 &gEfiScsiPassThruProtocolGuid,
316 (VOID **) &ScsiPassThru,
317 This->DriverBindingHandle,
318 ChildHandleBuffer[Index],
319 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
320 );
321 } else {
322 gBS->FreePool (ScsiIoDevice);
323 }
324 }
325
326 if (!AllChildrenStopped) {
327 return EFI_DEVICE_ERROR;
328 }
329
330 return EFI_SUCCESS;
331 }
332
333 EFI_STATUS
334 EFIAPI
335 ScsiGetDeviceType (
336 IN EFI_SCSI_IO_PROTOCOL *This,
337 OUT UINT8 *DeviceType
338 )
339 /*++
340
341 Routine Description:
342 Retrieves the device type information of the SCSI Controller.
343
344 Arguments:
345 This - Protocol instance pointer.
346 DeviceType - A pointer to the device type information
347 retrieved from the SCSI Controller.
348
349 Returns:
350 EFI_SUCCESS - Retrieves the device type information successfully.
351 EFI_INVALID_PARAMETER - The DeviceType is NULL.
352 --*/
353 {
354 SCSI_IO_DEV *ScsiIoDevice;
355
356 if (DeviceType == NULL) {
357 return EFI_INVALID_PARAMETER;
358 }
359
360 ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (This);
361 *DeviceType = ScsiIoDevice->ScsiDeviceType;
362 return EFI_SUCCESS;
363 }
364
365 STATIC
366 EFI_STATUS
367 EFIAPI
368 ScsiGetDeviceLocation (
369 IN EFI_SCSI_IO_PROTOCOL *This,
370 OUT UINT32 *Target,
371 OUT UINT64 *Lun
372 )
373 /*++
374 Routine Description:
375 Retrieves the device location in the SCSI channel.
376
377 Arguments:
378 This - Protocol instance pointer.
379 Target - A pointer to the Target ID of a SCSI device
380 on the SCSI channel.
381 Lun - A pointer to the LUN of the SCSI device on
382 the SCSI channel.
383
384 Returns:
385 EFI_SUCCESS - Retrieves the device location successfully.
386 EFI_INVALID_PARAMETER - The Target or Lun is NULL.
387 --*/
388 {
389 SCSI_IO_DEV *ScsiIoDevice;
390
391 if (Target == NULL || Lun == NULL) {
392 return EFI_INVALID_PARAMETER;
393 }
394
395 ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (This);
396
397 *Target = ScsiIoDevice->Pun;
398 *Lun = ScsiIoDevice->Lun;
399
400 return EFI_SUCCESS;
401 }
402
403 EFI_STATUS
404 EFIAPI
405 ScsiResetBus (
406 IN EFI_SCSI_IO_PROTOCOL *This
407 )
408 /*++
409
410 Routine Description:
411 Resets the SCSI Bus that the SCSI Controller is attached to.
412
413 Arguments:
414 This - Protocol instance pointer.
415
416 Returns:
417 EFI_SUCCESS - The SCSI bus is reset successfully.
418 EFI_DEVICE_ERROR - Errors encountered when resetting the SCSI bus.
419 EFI_UNSUPPORTED - The bus reset operation is not supported by the
420 SCSI Host Controller.
421 EFI_TIMEOUT - A timeout occurred while attempting to reset
422 the SCSI bus.
423 --*/
424 {
425 SCSI_IO_DEV *ScsiIoDevice;
426
427 ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (This);
428
429 return ScsiIoDevice->ScsiPassThru->ResetChannel (ScsiIoDevice->ScsiPassThru);
430
431 }
432
433 EFI_STATUS
434 EFIAPI
435 ScsiResetDevice (
436 IN EFI_SCSI_IO_PROTOCOL *This
437 )
438 /*++
439
440 Routine Description:
441 Resets the SCSI Controller that the device handle specifies.
442
443 Arguments:
444 This - Protocol instance pointer.
445
446
447 Returns:
448 EFI_SUCCESS - Reset the SCSI controller successfully.
449 EFI_DEVICE_ERROR - Errors are encountered when resetting the
450 SCSI Controller.
451 EFI_UNSUPPORTED - The SCSI bus does not support a device
452 reset operation.
453 EFI_TIMEOUT - A timeout occurred while attempting to
454 reset the SCSI Controller.
455 --*/
456 {
457 SCSI_IO_DEV *ScsiIoDevice;
458
459 ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (This);
460
461 return ScsiIoDevice->ScsiPassThru->ResetTarget (
462 ScsiIoDevice->ScsiPassThru,
463 ScsiIoDevice->Pun,
464 ScsiIoDevice->Lun
465 );
466 }
467
468 EFI_STATUS
469 EFIAPI
470 ScsiExecuteSCSICommand (
471 IN EFI_SCSI_IO_PROTOCOL *This,
472 IN OUT EFI_SCSI_IO_SCSI_REQUEST_PACKET *Packet,
473 IN EFI_EVENT Event OPTIONAL
474 )
475 /*++
476
477 Routine Description:
478 Sends a SCSI Request Packet to the SCSI Controller for execution.
479
480 Arguments:
481 This - Protocol instance pointer.
482 Packet - The SCSI request packet to send to the SCSI
483 Controller specified by the device handle.
484 Event - If the SCSI bus where the SCSI device is attached
485 does not support non-blocking I/O, then Event is
486 ignored, and blocking I/O is performed.
487 If Event is NULL, then blocking I/O is performed.
488 If Event is not NULL and non-blocking I/O is
489 supported, then non-blocking I/O is performed,
490 and Event will be signaled when the SCSI Request
491 Packet completes.
492 Returns:
493 EFI_SUCCESS - The SCSI Request Packet was sent by the host
494 successfully, and TransferLength bytes were
495 transferred to/from DataBuffer.See
496 HostAdapterStatus, TargetStatus,
497 SenseDataLength, and SenseData in that order
498 for additional status information.
499 EFI_WARN_BUFFER_TOO_SMALL - The SCSI Request Packet was executed,
500 but the entire DataBuffer could not be transferred.
501 The actual number of bytes transferred is returned
502 in TransferLength. See HostAdapterStatus,
503 TargetStatus, SenseDataLength, and SenseData in
504 that order for additional status information.
505 EFI_NOT_READY - The SCSI Request Packet could not be sent because
506 there are too many SCSI Command Packets already
507 queued.The caller may retry again later.
508 EFI_DEVICE_ERROR - A device error occurred while attempting to send
509 the SCSI Request Packet. See HostAdapterStatus,
510 TargetStatus, SenseDataLength, and SenseData in
511 that order for additional status information.
512 EFI_INVALID_PARAMETER - The contents of CommandPacket are invalid.
513 The SCSI Request Packet was not sent, so no
514 additional status information is available.
515 EFI_UNSUPPORTED - The command described by the SCSI Request Packet
516 is not supported by the SCSI initiator(i.e., SCSI
517 Host Controller). The SCSI Request Packet was not
518 sent, so no additional status information is
519 available.
520 EFI_TIMEOUT - A timeout occurred while waiting for the SCSI
521 Request Packet to execute. See HostAdapterStatus,
522 TargetStatus, SenseDataLength, and SenseData in
523 that order for additional status information.
524 --*/
525 {
526 SCSI_IO_DEV *ScsiIoDevice;
527 EFI_STATUS Status;
528
529 EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *RequestPacket;
530
531 if (Packet == NULL) {
532 return EFI_INVALID_PARAMETER;
533 }
534
535 ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (This);
536
537 RequestPacket = (EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *) Packet;
538
539 Status = ScsiIoDevice->ScsiPassThru->PassThru (
540 ScsiIoDevice->ScsiPassThru,
541 ScsiIoDevice->Pun,
542 ScsiIoDevice->Lun,
543 RequestPacket,
544 Event
545 );
546 return Status;
547 }
548
549 EFI_STATUS
550 ScsiScanCreateDevice (
551 EFI_DRIVER_BINDING_PROTOCOL *This,
552 EFI_HANDLE Controller,
553 UINT32 Pun,
554 UINT64 Lun,
555 EFI_SCSI_PASS_THRU_PROTOCOL *ScsiPassThru,
556 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath
557 )
558 /*++
559
560 Routine Description:
561
562 TODO: Add function description
563
564 Arguments:
565
566 This - TODO: add argument description
567 Controller - TODO: add argument description
568 Pun - TODO: add argument description
569 Lun - TODO: add argument description
570 ScsiPassThru - TODO: add argument description
571 ParentDevicePath - TODO: add argument description
572
573 Returns:
574
575 EFI_SUCCESS - TODO: Add description for return value
576 EFI_OUT_OF_RESOURCES - TODO: Add description for return value
577 EFI_SUCCESS - TODO: Add description for return value
578
579 --*/
580 {
581 EFI_STATUS Status;
582 SCSI_IO_DEV *ScsiIoDevice;
583 EFI_DEVICE_PATH_PROTOCOL *ScsiDevicePath;
584
585 Status = gBS->AllocatePool (
586 EfiBootServicesData,
587 sizeof (SCSI_IO_DEV),
588 (VOID **) &ScsiIoDevice
589 );
590 if (EFI_ERROR (Status)) {
591 return Status;
592 }
593
594 ZeroMem (ScsiIoDevice, sizeof (SCSI_IO_DEV));
595
596 ScsiIoDevice->Signature = SCSI_IO_DEV_SIGNATURE;
597 ScsiIoDevice->ScsiPassThru = ScsiPassThru;
598 ScsiIoDevice->Pun = Pun;
599 ScsiIoDevice->Lun = Lun;
600
601 ScsiIoDevice->ScsiIo.GetDeviceType = ScsiGetDeviceType;
602 ScsiIoDevice->ScsiIo.GetDeviceLocation = ScsiGetDeviceLocation;
603 ScsiIoDevice->ScsiIo.ResetBus = ScsiResetBus;
604 ScsiIoDevice->ScsiIo.ResetDevice = ScsiResetDevice;
605 ScsiIoDevice->ScsiIo.ExecuteSCSICommand = ScsiExecuteSCSICommand;
606
607 if (!DiscoverScsiDevice (ScsiIoDevice)) {
608 gBS->FreePool (ScsiIoDevice);
609 return EFI_SUCCESS;
610 }
611
612 //
613 // Set Device Path
614 //
615 Status = ScsiIoDevice->ScsiPassThru->BuildDevicePath (
616 ScsiIoDevice->ScsiPassThru,
617 ScsiIoDevice->Pun,
618 ScsiIoDevice->Lun,
619 &ScsiDevicePath
620 );
621 if (Status == EFI_OUT_OF_RESOURCES) {
622 gBS->FreePool (ScsiIoDevice);
623 return Status;
624 }
625
626 ScsiIoDevice->DevicePath = AppendDevicePathNode (
627 ParentDevicePath,
628 ScsiDevicePath
629 );
630 //
631 // The memory space for ScsiDevicePath is allocated in
632 // ScsiPassThru->BuildDevicePath() function; It is no longer used
633 // after EfiAppendDevicePathNode,so free the memory it occupies.
634 //
635 gBS->FreePool (ScsiDevicePath);
636
637 if (ScsiIoDevice->DevicePath == NULL) {
638 gBS->FreePool (ScsiIoDevice);
639 return EFI_OUT_OF_RESOURCES;
640 }
641
642 Status = gBS->InstallMultipleProtocolInterfaces (
643 &ScsiIoDevice->Handle,
644 &gEfiDevicePathProtocolGuid,
645 ScsiIoDevice->DevicePath,
646 &gEfiScsiIoProtocolGuid,
647 &ScsiIoDevice->ScsiIo,
648 NULL
649 );
650 if (EFI_ERROR (Status)) {
651 gBS->FreePool (ScsiIoDevice);
652 } else {
653 gBS->OpenProtocol (
654 Controller,
655 &gEfiScsiPassThruProtocolGuid,
656 (VOID **) &ScsiPassThru,
657 This->DriverBindingHandle,
658 ScsiIoDevice->Handle,
659 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
660 );
661 }
662
663 return EFI_SUCCESS;
664 }
665
666 BOOLEAN
667 DiscoverScsiDevice (
668 SCSI_IO_DEV *ScsiIoDevice
669 )
670 /*++
671
672 Routine Description:
673
674 TODO: Add function description
675
676 Arguments:
677
678 ScsiIoDevice - TODO: add argument description
679
680 Returns:
681
682 TODO: add return values
683
684 --*/
685 {
686 EFI_STATUS Status;
687 EFI_SCSI_INQUIRY_DATA InquiryData;
688 UINT32 InquiryDataLength;
689 EFI_SCSI_SENSE_DATA SenseData;
690 UINT8 SenseDataLength;
691 UINT8 HostAdapterStatus;
692 UINT8 TargetStatus;
693
694 HostAdapterStatus = 0;
695 TargetStatus = 0;
696 //
697 // Using Inquiry command to scan for the device
698 //
699 InquiryDataLength = sizeof (EFI_SCSI_INQUIRY_DATA);
700 SenseDataLength = sizeof (EFI_SCSI_SENSE_DATA);
701
702 Status = SubmitInquiryCommand (
703 &ScsiIoDevice->ScsiIo,
704 EfiScsiStallSeconds (1),
705 (VOID *) &SenseData,
706 &SenseDataLength,
707 &HostAdapterStatus,
708 &TargetStatus,
709 (VOID *) &InquiryData,
710 &InquiryDataLength,
711 FALSE
712 );
713 if (EFI_ERROR (Status)) {
714 //
715 // ParseSenseData (&SenseData,SenseDataLength);
716 //
717 return FALSE;
718 }
719 //
720 // Retrieved inquiry data successfully
721 //
722 if ((InquiryData.Peripheral_Qualifier != 0) &&
723 (InquiryData.Peripheral_Qualifier != 3)) {
724 return FALSE;
725 }
726
727 if (InquiryData.Peripheral_Qualifier == 3) {
728 if (InquiryData.Peripheral_Type != 0x1f) {
729 return FALSE;
730 }
731 }
732
733 if ((0x1e >= InquiryData.Peripheral_Type) && (InquiryData.Peripheral_Type >= 0xa)) {
734 return FALSE;
735 }
736
737 //
738 // valid device type and peripheral qualifier combination.
739 //
740 ScsiIoDevice->ScsiDeviceType = InquiryData.Peripheral_Type;
741 ScsiIoDevice->RemovableDevice = InquiryData.RMB;
742 if (InquiryData.Version == 0) {
743 ScsiIoDevice->ScsiVersion = 0;
744 } else {
745 //
746 // ANSI-approved version
747 //
748 ScsiIoDevice->ScsiVersion = (UINT8) (InquiryData.Version & 0x03);
749 }
750
751 return TRUE;
752 }