/** Retrieve the indexed configure for the device. USB device returns the configuration together with the interfaces for this configuration. Configuration descriptor is also of variable length. @param UsbDev The Usb interface. @param Index The index of the configuration. @return The created configuration descriptor. **/ EFI_USB_CONFIG_DESCRIPTOR * UsbGetOneConfig ( IN USB_DEVICE *UsbDev, IN UINT8 Index ) { EFI_USB_CONFIG_DESCRIPTOR Desc; EFI_STATUS Status; VOID *Buf; // // First get four bytes which contains the total length // for this configuration. // Status = UsbCtrlGetDesc (UsbDev, USB_DESC_TYPE_CONFIG, Index, 0, &Desc, 8); if (EFI_ERROR (Status)) { DEBUG (( EFI_D_ERROR, "UsbGetOneConfig: failed to get descript length(%d) %r\n", Desc.TotalLength, Status)); return NULL; } DEBUG (( EFI_D_INFO, "UsbGetOneConfig: total length is %d\n", Desc.TotalLength)); // // Reject if TotalLength even cannot cover itself. // if (Desc.TotalLength < OFFSET_OF (EFI_USB_CONFIG_DESCRIPTOR, TotalLength) + sizeof (Desc.TotalLength)) { return NULL; } Buf = AllocateZeroPool (Desc.TotalLength); if (Buf == NULL) { return NULL; } Status = UsbCtrlGetDesc (UsbDev, USB_DESC_TYPE_CONFIG, Index, 0, Buf, Desc.TotalLength); if (EFI_ERROR (Status)) { DEBUG (( EFI_D_ERROR, "UsbGetOneConfig: failed to get full descript %r\n", Status)); FreePool (Buf); return NULL; } return Buf; }
/** Retrieve the indexed string for the language. It requires two steps to get a string, first to get the string's length. Then the string itself. @param UsbDev The usb device. @param Index The index the string to retrieve. @param LangId Language ID. @return The created string descriptor or NULL. **/ EFI_USB_STRING_DESCRIPTOR * UsbGetOneString ( IN USB_DEVICE *UsbDev, IN UINT8 Index, IN UINT16 LangId ) { EFI_USB_STRING_DESCRIPTOR Desc; EFI_STATUS Status; UINT8 *Buf; // // First get two bytes which contains the string length. // Status = UsbCtrlGetDesc (UsbDev, USB_DESC_TYPE_STRING, Index, LangId, &Desc, 2); // // Reject if Length even cannot cover itself, or odd because Unicode string byte length should be even. // if (EFI_ERROR (Status) || (Desc.Length < OFFSET_OF (EFI_USB_STRING_DESCRIPTOR, Length) + sizeof (Desc.Length)) || (Desc.Length % 2 != 0) ) { return NULL; } Buf = AllocateZeroPool (Desc.Length); if (Buf == NULL) { return NULL; } Status = UsbCtrlGetDesc ( UsbDev, USB_DESC_TYPE_STRING, Index, LangId, Buf, Desc.Length ); if (EFI_ERROR (Status)) { FreePool (Buf); return NULL; } return (EFI_USB_STRING_DESCRIPTOR *) Buf; }
/** Get the device descriptor for the device. @param UsbDev The Usb device to retrieve descriptor from. @retval EFI_SUCCESS The device descriptor is returned. @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. **/ EFI_STATUS UsbGetDevDesc ( IN USB_DEVICE *UsbDev ) { USB_DEVICE_DESC *DevDesc; EFI_STATUS Status; DevDesc = AllocateZeroPool (sizeof (USB_DEVICE_DESC)); if (DevDesc == NULL) { return EFI_OUT_OF_RESOURCES; } Status = UsbCtrlGetDesc ( UsbDev, USB_DESC_TYPE_DEVICE, 0, 0, DevDesc, sizeof (EFI_USB_DEVICE_DESCRIPTOR) ); if (EFI_ERROR (Status)) { gBS->FreePool (DevDesc); } else { UsbDev->DevDesc = DevDesc; } return Status; }
/** Return the max packet size for endpoint zero. This function is the first function called to get descriptors during bus enumeration. @param UsbDev The usb device. @retval EFI_SUCCESS The max packet size of endpoint zero is retrieved. @retval EFI_DEVICE_ERROR Failed to retrieve it. **/ EFI_STATUS UsbGetMaxPacketSize0 ( IN USB_DEVICE *UsbDev ) { EFI_USB_DEVICE_DESCRIPTOR DevDesc; EFI_STATUS Status; UINTN Index; // // Get the first 8 bytes of the device descriptor which contains // max packet size for endpoint 0, which is at least 8. // for (Index = 0; Index < 3; Index++) { Status = UsbCtrlGetDesc (UsbDev, USB_DESC_TYPE_DEVICE, 0, 0, &DevDesc, 8); if (!EFI_ERROR (Status)) { if ((DevDesc.BcdUSB == 0x0300) && (DevDesc.MaxPacketSize0 == 9)) { UsbDev->MaxPacket0 = 1 << 9; return EFI_SUCCESS; } UsbDev->MaxPacket0 = DevDesc.MaxPacketSize0; return EFI_SUCCESS; } gBS->Stall (USB_RETRY_MAX_PACK_SIZE_STALL); } return EFI_DEVICE_ERROR; }
/** Retrieve the indexed string for the language. It requires two steps to get a string, first to get the string's length. Then the string itself. @param UsbDev The usb device. @param Index The index the string to retrieve. @param LangId Language ID. @return The created string descriptor or NULL. **/ EFI_USB_STRING_DESCRIPTOR * UsbGetOneString ( IN USB_DEVICE *UsbDev, IN UINT8 Index, IN UINT16 LangId ) { EFI_USB_STRING_DESCRIPTOR Desc; EFI_STATUS Status; UINT8 *Buf; // // First get two bytes which contains the string length. // Status = UsbCtrlGetDesc (UsbDev, USB_DESC_TYPE_STRING, Index, LangId, &Desc, 2); if (EFI_ERROR (Status)) { return NULL; } Buf = AllocateZeroPool (Desc.Length); if (Buf == NULL) { return NULL; } Status = UsbCtrlGetDesc ( UsbDev, USB_DESC_TYPE_STRING, Index, LangId, Buf, Desc.Length ); if (EFI_ERROR (Status)) { FreePool (Buf); return NULL; } return (EFI_USB_STRING_DESCRIPTOR *) Buf; }