USBDescriptors.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. /*
  2. * Copyright (c) 2021, Jesse Buhagiar <jooster669@gmail.com>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/Types.h>
  8. namespace Kernel::USB {
  9. struct [[gnu::packed]] USBDescriptorCommon {
  10. u8 length;
  11. u8 descriptor_type;
  12. };
  13. //
  14. // Device Descriptor
  15. // =================
  16. //
  17. // This descriptor type (stored on the device), represents the device, and gives
  18. // information related to it, such as the USB specification it complies to,
  19. // as well as the vendor and product ID of the device.
  20. //
  21. // https://beyondlogic.org/usbnutshell/usb5.shtml#DeviceDescriptors
  22. struct [[gnu::packed]] USBDeviceDescriptor {
  23. USBDescriptorCommon descriptor_header;
  24. u16 usb_spec_compliance_bcd;
  25. u8 device_class;
  26. u8 device_sub_class;
  27. u8 device_protocol;
  28. u8 max_packet_size;
  29. u16 vendor_id;
  30. u16 product_id;
  31. u16 device_release_bcd;
  32. u8 manufacturer_id_descriptor_index;
  33. u8 product_string_descriptor_index;
  34. u8 serial_number_descriptor_index;
  35. u8 num_configurations;
  36. };
  37. static_assert(sizeof(USBDeviceDescriptor) == 18);
  38. //
  39. // Configuration Descriptor
  40. // ========================
  41. //
  42. // A USB device can have multiple configurations, which tells us about how the
  43. // device is physically configured (e.g how it's powered, max power consumption etc).
  44. //
  45. struct [[gnu::packed]] USBConfigurationDescriptor {
  46. USBDescriptorCommon descriptor_header;
  47. u16 total_length;
  48. u8 number_of_interfaces;
  49. u8 configuration_value;
  50. u8 configuration_string_descriptor_index;
  51. u8 attributes_bitmap;
  52. u8 max_power_in_ma;
  53. };
  54. //
  55. // Interface Descriptor
  56. // ====================
  57. //
  58. // An interface descriptor describes to us one or more endpoints, grouped
  59. // together to define a singular function of a device.
  60. // As an example, a USB webcam might have two interface descriptors; one
  61. // for the camera, and one for the microphone.
  62. //
  63. struct [[gnu::packed]] USBInterfaceDescriptor {
  64. USBDescriptorCommon descriptor_header;
  65. u8 interface_id;
  66. u8 alternate_setting;
  67. u8 number_of_endpoints;
  68. u8 interface_class_code;
  69. u8 interface_sub_class_code;
  70. u8 interface_protocol;
  71. u8 interface_string_descriptor_index;
  72. };
  73. //
  74. // Endpoint Descriptor
  75. // ===================
  76. //
  77. // The lowest leaf in the configuration tree. And endpoint descriptor describes
  78. // the physical transfer properties of the endpoint (that isn't endpoint0).
  79. // The description given by this structure is used by a pipe to create a
  80. // "connection" from the host to the device.
  81. // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/usb-endpoints-and-their-pipes
  82. struct [[gnu::packed]] USBEndpointDescriptor {
  83. USBDescriptorCommon descriptor_header;
  84. u8 endpoint_address;
  85. u8 endpoint_attributes_bitmap;
  86. u16 max_packet_size;
  87. u8 poll_interval_in_frames;
  88. };
  89. //
  90. // USB 1.1/2.0 Hub Descriptor
  91. // ==============
  92. //
  93. struct [[gnu::packed]] USBHubDescriptor {
  94. USBDescriptorCommon descriptor_header;
  95. u8 number_of_downstream_ports;
  96. u16 hub_characteristics;
  97. u8 power_on_to_power_good_time;
  98. u8 hub_controller_current;
  99. // NOTE: This does not contain DeviceRemovable or PortPwrCtrlMask because a struct cannot have two VLAs in a row.
  100. };
  101. static constexpr u8 DESCRIPTOR_TYPE_DEVICE = 0x01;
  102. static constexpr u8 DESCRIPTOR_TYPE_CONFIGURATION = 0x02;
  103. static constexpr u8 DESCRIPTOR_TYPE_STRING = 0x03;
  104. static constexpr u8 DESCRIPTOR_TYPE_INTERFACE = 0x04;
  105. static constexpr u8 DESCRIPTOR_TYPE_ENDPOINT = 0x05;
  106. static constexpr u8 DESCRIPTOR_TYPE_DEVICE_QUALIFIER = 0x06;
  107. static constexpr u8 DESCRIPTOR_TYPE_HUB = 0x29;
  108. }