Hi,

using QEMU, when I specify a nonzero LUN for the hard disk that sits on
the "SCSI bus" that embodies the USB Bulk Only Transfer device, then
UsbMassStorageDxe fails to recognize the hard disk.

(1) Consider the following QEMU command line snippet:

  -drive id=disk1,if=none,format=raw,readonly,file=$APPDISK \
  -device qemu-xhci,id=xhci1,p3=15,addr=02.0 \
  -device usb-bot,bus=xhci1.0,port=3,id=bot1 \
  -device scsi-hd,drive=disk1,bus=bot1.0,lun=0,bootindex=1 \

For this (i.e., lun=0), I see the following INQUIRY exchange between
UsbMassStorageDxe and QEMU:

> Lun=0 InquiryCmd {
> Lun=0 InquiryCmd 000000 12 00 00 00 24 00 00 00 00 00 00 00
> Lun=0 InquiryCmd }
> Lun=0 InquiryData {
> Lun=0 InquiryData 000000 00 00 05 12 1F 00 00 10 51 45 4D 55 20 20 20 20
> Lun=0 InquiryData 000010 51 45 4D 55 20 48 41 52 44 44 49 53 4B 20 20 20
> Lun=0 InquiryData 000020 32 2E 35 2B
> Lun=0 InquiryData }

The vendor and product ID fields translate to "QEMU____" and
"QEMU_HARDDISK___", respectively. (For easier reading, I replaced the
space characters with underscores, for the sake of better
readability/wrapping.)

In this case, edk2 recognizes the disk and things work fine.

(In fact, for lun=0, the QemuBootOrderLib pattern matching / translation
works fine as well -- verifying which was my original goal, before I ran
into the issues below, for nonzero LUNs. But, I digress.)


(2) If I change the cmdline to "lun=5", then the exchange is:

> Lun=0 InquiryCmd {
> Lun=0 InquiryCmd 000000 12 00 00 00 24 00 00 00 00 00 00 00
> Lun=0 InquiryCmd }
> Lun=0 InquiryData {
> Lun=0 InquiryData 000000 3F 00 05 12 1F 00 00 10 51 45 4D 55 20 20 20 20
> Lun=0 InquiryData 000010 51 45 4D 55 20 54 41 52 47 45 54 20 20 20 20 20
> Lun=0 InquiryData 000020 32 2E 35 00
> Lun=0 InquiryData }

Here the product ID is unchanged, but the vendor ID becomes
"QEMU_TARGET_____".

And, edk2 fails to recognize the device:

> UsbBootGetParams: Found an unsupported peripheral type[31]
> UsbMassInitMedia: UsbBootGetParams (Unsupported)
> UsbMassInitNonLun: UsbMassInitMedia (Unsupported)
> USBMassDriverBindingStart: UsbMassInitNonLun (Unsupported)

This happens because the first byte in the response is 0x3F. QEMU sets
this byte in

>         r->buf[0] = TYPE_NOT_PRESENT | TYPE_INACTIVE;

in function scsi_target_emulate_inquiry(), file "hw/scsi/scsi-bus.c".

And edk2 parses the byte in UsbBootInquiry() and UsbBootGetParams()
(file "MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBoot.c"):

> typedef struct {
>   UINT8             Pdt;            ///< Peripheral Device Type (low 5 bits)
>   UINT8             Removable;      ///< Removable Media (highest bit)
>   UINT8             Reserved0[2];
>   UINT8             AddLen;         ///< Additional length
>   UINT8             Reserved1[3];
>   UINT8             VendorID[8];
>   UINT8             ProductID[16];
>   UINT8             ProductRevision[4];
> } USB_BOOT_INQUIRY_DATA;

> #define USB_BOOT_PDT(Pdt)           ((Pdt) & 0x1f)

>   UsbMass->Pdt          = (UINT8) (USB_BOOT_PDT (UsbMass->InquiryData.Pdt));

>   //
>   // According to USB Mass Storage Specification for Bootability, only 
> following
>   // 4 Peripheral Device Types are in spec.
>   //
>   if ((UsbMass->Pdt != USB_PDT_DIRECT_ACCESS) &&
>        (UsbMass->Pdt != USB_PDT_CDROM) &&
>        (UsbMass->Pdt != USB_PDT_OPTICAL) &&
>        (UsbMass->Pdt != USB_PDT_SIMPLE_DIRECT)) {
>     DEBUG ((EFI_D_ERROR, "UsbBootGetParams: Found an unsupported peripheral 
> type[%d]\n", UsbMass->Pdt));
>     return EFI_UNSUPPORTED;
>   }

It looks likely that at least one of edk2 and QEMU has a bug. Which one
is it?

Or is the command line incorrect perhaps? (I.e., is it invalid to
specify *only* lun=5? Does the LUN space have to be contiguous?)


(3) Starting again from the original command line, if I change "lun=0"
to "lun=1" (rather than to "lun=5"), then OVMF even hangs, with the
following log:

> UsbMassInitMultiLun: Start to initialize No.0 logic unit
> Lun=0 InquiryCmd {
> Lun=0 InquiryCmd 000000 12 00 00 00 24 00 00 00 00 00 00 00
> Lun=0 InquiryCmd }
> Lun=0 InquiryData {
> Lun=0 InquiryData 000000 3F 00 05 12 1F 00 00 10 51 45 4D 55 20 20 20 20
> Lun=0 InquiryData 000010 51 45 4D 55 20 54 41 52 47 45 54 20 20 20 20 20
> Lun=0 InquiryData 000020 32 2E 35 00
> Lun=0 InquiryData }
> UsbBootGetParams: Found an unsupported peripheral type[31]
> UsbMassInitMedia: UsbBootGetParams (Unsupported)
> UsbMassInitMultiLun: UsbMassInitMedia (Unsupported)
> UsbMassInitMultiLun: Start to initialize No.1 logic unit
> Lun=32 InquiryCmd {
> Lun=32 InquiryCmd 000000 12 20 00 00 24 00 00 00 00 00 00 00
> Lun=32 InquiryCmd }
> Lun=32 InquiryData {
> Lun=32 InquiryData 000000 00 00 05 12 1F 00 00 10 51 45 4D 55 20 20 20 20
> Lun=32 InquiryData 000010 51 45 4D 55 20 48 41 52 44 44 49 53 4B 20 20 20
> Lun=32 InquiryData 000020 32 2E 35 2B
> Lun=32 InquiryData }
> UsbBootExecCmd: Success to Exec 0x0 Cmd (Result = 1)
> UsbBootRequestSense: (Invalid Parameter) with error code (70) sense key 5/25/0
> UsbMassInitMedia: UsbBootGetParams (Media changed)
> InstallProtocolInterface: 09576E91-6D3F-11D2-8E39-00A0C969723B 3DC7DD98
> InstallProtocolInterface: 964E5B21-6459-11D2-8E39-00A0C969723B 3DBFA6B8
> InstallProtocolInterface: D432A67F-14DC-484B-B3BB-3F0291849327 3DBFA730
> UsbMassInitMultiLun: Success to initialize No.1 logic unit
> InstallProtocolInterface: CE345171-BA0B-11D2-8E4F-00A0C969723B 3DBFA2A0
>  BlockSize : 512
>  LastBlock : 136B
> UsbBootExecCmd: Success to Exec 0x28 Cmd (Result = 1)
> UsbBootRequestSense: (Invalid Parameter) with error code (70) sense key 5/25/0
> UsbBootExecCmd: Success to Exec 0x28 Cmd (Result = 1)
> UsbBootRequestSense: (Invalid Parameter) with error code (70) sense key 5/25/0
> UsbBootExecCmd: Success to Exec 0x28 Cmd (Result = 1)
> UsbBootRequestSense: (Invalid Parameter) with error code (70) sense key 5/25/0
> UsbBootExecCmd: Success to Exec 0x28 Cmd (Result = 1)
> UsbBootRequestSense: (Invalid Parameter) with error code (70) sense key 5/25/0
> UsbBootExecCmd: Success to Exec 0x28 Cmd (Result = 1)
> UsbBootRequestSense: (Invalid Parameter) with error code (70) sense key 5/25/0
> UsbBootExecCmd: Success to Exec 0x28 Cmd (Result = 1)
> UsbBootRequestSense: (Invalid Parameter) with error code (70) sense key 5/25/0
> UsbMassReadBlocks: UsbBootReadBlocks (Invalid Parameter) -> Reset
> XhcUsbPortReset!
> XhcSetRootHubPortFeature: status Success
> XhcClearRootHubPortFeature: status Success
> XhcClearRootHubPortFeature: status Success
> Disable device slot 1!
> Enable Slot Successfully, The Slot ID = 0x1
>     Address 1 assigned successfully
> UsbIoPortReset: device is now ADDRESSED at 1
> ASSERT MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c(1915): TrsRing != ((void *) 0)

In this case, edk2 seems to recognize that a nonzero LUN is available on
the target, but the initialization never completes, and then an
assertion fails, apparently in the lower-level XHCI transport code.


The information that I'm primarily looking for here is which bug tracker
I should file these under, the edk2 bugzilla, or the QEMU launchpad.

Thanks,
Laszlo
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to