USBDevice.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. /*
  2. * Copyright (c) 2021, Jesse Buhagiar <jooster669@gmail.com>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <AK/OwnPtr.h>
  7. #include <AK/Types.h>
  8. #include <AK/Vector.h>
  9. #include <Kernel/Bus/USB/UHCIController.h>
  10. #include <Kernel/Bus/USB/USBDescriptors.h>
  11. #include <Kernel/Bus/USB/USBDevice.h>
  12. #include <Kernel/Bus/USB/USBRequest.h>
  13. static u32 s_next_usb_address = 1; // Next address we hand out to a device once it's plugged into the machine
  14. namespace Kernel::USB {
  15. KResultOr<NonnullRefPtr<Device>> Device::try_create(PortNumber port, DeviceSpeed speed)
  16. {
  17. auto pipe_or_error = Pipe::try_create_pipe(Pipe::Type::Control, Pipe::Direction::Bidirectional, 0, 8, 0);
  18. if (pipe_or_error.is_error())
  19. return pipe_or_error.error();
  20. auto device = AK::try_create<Device>(port, speed, pipe_or_error.release_value());
  21. if (!device)
  22. return ENOMEM;
  23. auto enumerate_result = device->enumerate();
  24. if (enumerate_result.is_error())
  25. return enumerate_result;
  26. return device.release_nonnull();
  27. }
  28. Device::Device(PortNumber port, DeviceSpeed speed, NonnullOwnPtr<Pipe> default_pipe)
  29. : m_device_port(port)
  30. , m_device_speed(speed)
  31. , m_address(0)
  32. , m_default_pipe(move(default_pipe))
  33. {
  34. }
  35. KResult Device::enumerate()
  36. {
  37. USBDeviceDescriptor dev_descriptor {};
  38. // FIXME: 0x100 is a magic number for now, as I'm not quite sure how these are constructed....
  39. // Send 8-bytes to get at least the `max_packet_size` from the device
  40. auto transfer_length_or_error = m_default_pipe->control_transfer(USB_DEVICE_REQUEST_DEVICE_TO_HOST, USB_REQUEST_GET_DESCRIPTOR, 0x100, 0, 8, &dev_descriptor);
  41. if (transfer_length_or_error.is_error())
  42. return transfer_length_or_error.error();
  43. auto transfer_length = transfer_length_or_error.release_value();
  44. // FIXME: This shouldn't crash! Do some correct error handling on me please!
  45. VERIFY(transfer_length > 0);
  46. // Ensure that this is actually a valid device descriptor...
  47. VERIFY(dev_descriptor.descriptor_header.descriptor_type == DESCRIPTOR_TYPE_DEVICE);
  48. m_default_pipe->set_max_packet_size(dev_descriptor.max_packet_size);
  49. transfer_length_or_error = m_default_pipe->control_transfer(USB_DEVICE_REQUEST_DEVICE_TO_HOST, USB_REQUEST_GET_DESCRIPTOR, 0x100, 0, sizeof(USBDeviceDescriptor), &dev_descriptor);
  50. if (transfer_length_or_error.is_error())
  51. return transfer_length_or_error.error();
  52. transfer_length = transfer_length_or_error.release_value();
  53. // FIXME: This shouldn't crash! Do some correct error handling on me please!
  54. VERIFY(transfer_length > 0);
  55. // Ensure that this is actually a valid device descriptor...
  56. VERIFY(dev_descriptor.descriptor_header.descriptor_type == DESCRIPTOR_TYPE_DEVICE);
  57. if constexpr (USB_DEBUG) {
  58. dbgln("USB Device Descriptor for {:04x}:{:04x}", dev_descriptor.vendor_id, dev_descriptor.product_id);
  59. dbgln("Device Class: {:02x}", dev_descriptor.device_class);
  60. dbgln("Device Sub-Class: {:02x}", dev_descriptor.device_sub_class);
  61. dbgln("Device Protocol: {:02x}", dev_descriptor.device_protocol);
  62. dbgln("Max Packet Size: {:02x} bytes", dev_descriptor.max_packet_size);
  63. dbgln("Number of configurations: {:02x}", dev_descriptor.num_configurations);
  64. }
  65. // Attempt to set devices address on the bus
  66. transfer_length_or_error = m_default_pipe->control_transfer(USB_DEVICE_REQUEST_HOST_TO_DEVICE, USB_REQUEST_SET_ADDRESS, s_next_usb_address, 0, 0, nullptr);
  67. if (transfer_length_or_error.is_error())
  68. return transfer_length_or_error.error();
  69. transfer_length = transfer_length_or_error.release_value();
  70. VERIFY(transfer_length > 0);
  71. m_address = s_next_usb_address++;
  72. memcpy(&m_device_descriptor, &dev_descriptor, sizeof(USBDeviceDescriptor));
  73. return KSuccess;
  74. }
  75. Device::~Device()
  76. {
  77. }
  78. }