UHCIController.cpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738
  1. /*
  2. * Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org>
  3. * Copyright (c) 2020, Jesse Buhagiar <jooster669@gmail.com>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #include <AK/Platform.h>
  8. #include <Kernel/Bus/USB/UHCIController.h>
  9. #include <Kernel/Bus/USB/USBRequest.h>
  10. #include <Kernel/CommandLine.h>
  11. #include <Kernel/Debug.h>
  12. #include <Kernel/Memory/AnonymousVMObject.h>
  13. #include <Kernel/Memory/MemoryManager.h>
  14. #include <Kernel/Process.h>
  15. #include <Kernel/Sections.h>
  16. #include <Kernel/StdLib.h>
  17. #include <Kernel/Time/TimeManagement.h>
  18. static constexpr u8 MAXIMUM_NUMBER_OF_TDS = 128; // Upper pool limit. This consumes the second page we have allocated
  19. static constexpr u8 MAXIMUM_NUMBER_OF_QHS = 64;
  20. static constexpr u8 RETRY_COUNTER_RELOAD = 3;
  21. namespace Kernel::USB {
  22. static constexpr u16 UHCI_USBCMD_RUN = 0x0001;
  23. static constexpr u16 UHCI_USBCMD_HOST_CONTROLLER_RESET = 0x0002;
  24. static constexpr u16 UHCI_USBCMD_GLOBAL_RESET = 0x0004;
  25. static constexpr u16 UHCI_USBCMD_ENTER_GLOBAL_SUSPEND_MODE = 0x0008;
  26. static constexpr u16 UHCI_USBCMD_FORCE_GLOBAL_RESUME = 0x0010;
  27. static constexpr u16 UHCI_USBCMD_SOFTWARE_DEBUG = 0x0020;
  28. static constexpr u16 UHCI_USBCMD_CONFIGURE_FLAG = 0x0040;
  29. static constexpr u16 UHCI_USBCMD_MAX_PACKET = 0x0080;
  30. static constexpr u16 UHCI_USBSTS_HOST_CONTROLLER_HALTED = 0x0020;
  31. static constexpr u16 UHCI_USBSTS_HOST_CONTROLLER_PROCESS_ERROR = 0x0010;
  32. static constexpr u16 UHCI_USBSTS_PCI_BUS_ERROR = 0x0008;
  33. static constexpr u16 UHCI_USBSTS_RESUME_RECEIVED = 0x0004;
  34. static constexpr u16 UHCI_USBSTS_USB_ERROR_INTERRUPT = 0x0002;
  35. static constexpr u16 UHCI_USBSTS_USB_INTERRUPT = 0x0001;
  36. static constexpr u8 UHCI_USBINTR_TIMEOUT_CRC_ENABLE = 0x01;
  37. static constexpr u8 UHCI_USBINTR_RESUME_INTR_ENABLE = 0x02;
  38. static constexpr u8 UHCI_USBINTR_IOC_ENABLE = 0x04;
  39. static constexpr u8 UHCI_USBINTR_SHORT_PACKET_INTR_ENABLE = 0x08;
  40. static constexpr u16 UHCI_FRAMELIST_FRAME_COUNT = 1024; // Each entry is 4 bytes in our allocated page
  41. static constexpr u16 UHCI_FRAMELIST_FRAME_INVALID = 0x0001;
  42. // Port stuff
  43. static constexpr u8 UHCI_ROOT_PORT_COUNT = 2;
  44. static constexpr u16 UHCI_PORTSC_CURRRENT_CONNECT_STATUS = 0x0001;
  45. static constexpr u16 UHCI_PORTSC_CONNECT_STATUS_CHANGED = 0x0002;
  46. static constexpr u16 UHCI_PORTSC_PORT_ENABLED = 0x0004;
  47. static constexpr u16 UHCI_PORTSC_PORT_ENABLE_CHANGED = 0x0008;
  48. static constexpr u16 UHCI_PORTSC_LINE_STATUS = 0x0030;
  49. static constexpr u16 UHCI_PORTSC_RESUME_DETECT = 0x40;
  50. static constexpr u16 UHCI_PORTSC_LOW_SPEED_DEVICE = 0x0100;
  51. static constexpr u16 UHCI_PORTSC_PORT_RESET = 0x0200;
  52. static constexpr u16 UHCI_PORTSC_SUSPEND = 0x1000;
  53. static constexpr u16 UCHI_PORTSC_NON_WRITE_CLEAR_BIT_MASK = 0x1FF5; // This is used to mask out the Write Clear bits making sure we don't accidentally clear them.
  54. // *BSD and a few other drivers seem to use this number
  55. static constexpr u8 UHCI_NUMBER_OF_ISOCHRONOUS_TDS = 128;
  56. static constexpr u16 UHCI_NUMBER_OF_FRAMES = 1024;
  57. KResultOr<NonnullRefPtr<UHCIController>> UHCIController::try_to_initialize(PCI::Address address)
  58. {
  59. // NOTE: This assumes that address is pointing to a valid UHCI controller.
  60. auto controller = adopt_ref_if_nonnull(new (nothrow) UHCIController(address));
  61. if (!controller)
  62. return ENOMEM;
  63. auto init_result = controller->initialize();
  64. if (init_result.is_error())
  65. return init_result;
  66. return controller.release_nonnull();
  67. }
  68. KResult UHCIController::initialize()
  69. {
  70. dmesgln("UHCI: Controller found {} @ {}", PCI::get_id(pci_address()), pci_address());
  71. dmesgln("UHCI: I/O base {}", m_io_base);
  72. dmesgln("UHCI: Interrupt line: {}", PCI::get_interrupt_line(pci_address()));
  73. spawn_port_proc();
  74. auto reset_result = reset();
  75. if (reset_result.is_error())
  76. return reset_result;
  77. auto start_result = start();
  78. return start_result;
  79. }
  80. UNMAP_AFTER_INIT UHCIController::UHCIController(PCI::Address address)
  81. : PCI::Device(address)
  82. , m_io_base(PCI::get_BAR4(pci_address()) & ~1)
  83. {
  84. }
  85. UNMAP_AFTER_INIT UHCIController::~UHCIController()
  86. {
  87. }
  88. KResult UHCIController::reset()
  89. {
  90. if (auto stop_result = stop(); stop_result.is_error())
  91. return stop_result;
  92. write_usbcmd(UHCI_USBCMD_HOST_CONTROLLER_RESET);
  93. // FIXME: Timeout
  94. for (;;) {
  95. if (read_usbcmd() & UHCI_USBCMD_HOST_CONTROLLER_RESET)
  96. continue;
  97. break;
  98. }
  99. // Let's allocate the physical page for the Frame List (which is 4KiB aligned)
  100. auto maybe_framelist_vmobj = Memory::AnonymousVMObject::try_create_physically_contiguous_with_size(PAGE_SIZE);
  101. if (maybe_framelist_vmobj.is_error())
  102. return maybe_framelist_vmobj.error();
  103. m_framelist = MM.allocate_kernel_region_with_vmobject(maybe_framelist_vmobj.release_value(), PAGE_SIZE, "UHCI Framelist", Memory::Region::Access::Write);
  104. dbgln("UHCI: Allocated framelist at physical address {}", m_framelist->physical_page(0)->paddr());
  105. dbgln("UHCI: Framelist is at virtual address {}", m_framelist->vaddr());
  106. write_sofmod(64); // 1mS frame time
  107. if (auto result = create_structures(); result.is_error())
  108. return result;
  109. setup_schedule();
  110. write_flbaseadd(m_framelist->physical_page(0)->paddr().get()); // Frame list (physical) address
  111. write_frnum(0); // Set the initial frame number
  112. // FIXME: Work out why interrupts lock up the entire system....
  113. // Disable UHCI Controller from raising an IRQ
  114. write_usbintr(0);
  115. dbgln("UHCI: Reset completed");
  116. return KSuccess;
  117. }
  118. UNMAP_AFTER_INIT KResult UHCIController::create_structures()
  119. {
  120. // Let's allocate memory for both the QH and TD pools
  121. // First the QH pool and all of the Interrupt QH's
  122. auto maybe_qh_pool_vmobject = Memory::AnonymousVMObject::try_create_physically_contiguous_with_size(2 * PAGE_SIZE);
  123. if (maybe_qh_pool_vmobject.is_error())
  124. return maybe_qh_pool_vmobject.error();
  125. m_qh_pool = MM.allocate_kernel_region_with_vmobject(maybe_qh_pool_vmobject.release_value(), 2 * PAGE_SIZE, "UHCI Queue Head Pool", Memory::Region::Access::Write);
  126. memset(m_qh_pool->vaddr().as_ptr(), 0, 2 * PAGE_SIZE); // Zero out both pages
  127. // Let's populate our free qh list (so we have some we can allocate later on)
  128. m_free_qh_pool.resize(MAXIMUM_NUMBER_OF_TDS);
  129. for (size_t i = 0; i < m_free_qh_pool.size(); i++) {
  130. auto placement_addr = reinterpret_cast<void*>(m_qh_pool->vaddr().get() + (i * sizeof(QueueHead)));
  131. auto paddr = static_cast<u32>(m_qh_pool->physical_page(0)->paddr().get() + (i * sizeof(QueueHead)));
  132. m_free_qh_pool.at(i) = new (placement_addr) QueueHead(paddr);
  133. }
  134. // Create the Full Speed, Low Speed Control and Bulk Queue Heads
  135. m_interrupt_transfer_queue = allocate_queue_head();
  136. m_lowspeed_control_qh = allocate_queue_head();
  137. m_fullspeed_control_qh = allocate_queue_head();
  138. m_bulk_qh = allocate_queue_head();
  139. m_dummy_qh = allocate_queue_head();
  140. // Now the Transfer Descriptor pool
  141. auto maybe_td_pool_vmobject = Memory::AnonymousVMObject::try_create_physically_contiguous_with_size(2 * PAGE_SIZE);
  142. if (maybe_td_pool_vmobject.is_error())
  143. return maybe_td_pool_vmobject.error();
  144. m_td_pool = MM.allocate_kernel_region_with_vmobject(maybe_td_pool_vmobject.release_value(), 2 * PAGE_SIZE, "UHCI Transfer Descriptor Pool", Memory::Region::Access::Write);
  145. memset(m_td_pool->vaddr().as_ptr(), 0, 2 * PAGE_SIZE);
  146. // Set up the Isochronous Transfer Descriptor list
  147. m_iso_td_list.resize(UHCI_NUMBER_OF_ISOCHRONOUS_TDS);
  148. for (size_t i = 0; i < m_iso_td_list.size(); i++) {
  149. auto placement_addr = reinterpret_cast<void*>(m_td_pool->vaddr().get() + (i * sizeof(Kernel::USB::TransferDescriptor)));
  150. auto paddr = static_cast<u32>(m_td_pool->physical_page(0)->paddr().get() + (i * sizeof(Kernel::USB::TransferDescriptor)));
  151. // Place a new Transfer Descriptor with a 1:1 in our region
  152. // The pointer returned by `new()` lines up exactly with the value
  153. // that we store in `paddr`, meaning our member functions directly
  154. // access the raw descriptor (that we later send to the controller)
  155. m_iso_td_list.at(i) = new (placement_addr) Kernel::USB::TransferDescriptor(paddr);
  156. auto transfer_descriptor = m_iso_td_list.at(i);
  157. transfer_descriptor->set_in_use(true); // Isochronous transfers are ALWAYS marked as in use (in case we somehow get allocated one...)
  158. transfer_descriptor->set_isochronous();
  159. transfer_descriptor->link_queue_head(m_interrupt_transfer_queue->paddr());
  160. if constexpr (UHCI_VERBOSE_DEBUG)
  161. transfer_descriptor->print();
  162. }
  163. m_free_td_pool.resize(MAXIMUM_NUMBER_OF_TDS);
  164. for (size_t i = 0; i < m_free_td_pool.size(); i++) {
  165. auto placement_addr = reinterpret_cast<void*>(m_td_pool->vaddr().offset(PAGE_SIZE).get() + (i * sizeof(Kernel::USB::TransferDescriptor)));
  166. auto paddr = static_cast<u32>(m_td_pool->physical_page(1)->paddr().get() + (i * sizeof(Kernel::USB::TransferDescriptor)));
  167. // Place a new Transfer Descriptor with a 1:1 in our region
  168. // The pointer returned by `new()` lines up exactly with the value
  169. // that we store in `paddr`, meaning our member functions directly
  170. // access the raw descriptor (that we later send to the controller)
  171. m_free_td_pool.at(i) = new (placement_addr) Kernel::USB::TransferDescriptor(paddr);
  172. if constexpr (UHCI_VERBOSE_DEBUG) {
  173. auto transfer_descriptor = m_free_td_pool.at(i);
  174. transfer_descriptor->print();
  175. }
  176. }
  177. if constexpr (UHCI_DEBUG) {
  178. dbgln("UHCI: Pool information:");
  179. dbgln(" qh_pool: {}, length: {}", PhysicalAddress(m_qh_pool->physical_page(0)->paddr()), m_qh_pool->range().size());
  180. dbgln(" td_pool: {}, length: {}", PhysicalAddress(m_td_pool->physical_page(0)->paddr()), m_td_pool->range().size());
  181. }
  182. return KSuccess;
  183. }
  184. UNMAP_AFTER_INIT void UHCIController::setup_schedule()
  185. {
  186. //
  187. // https://github.com/alkber/minix3-usbsubsystem/blob/master/usb/uhci-hcd.c
  188. //
  189. // This lad probably has the best explanation as to how this is actually done. I'll try and
  190. // explain it here to so that there's no need for anyone to go hunting for this shit again, because
  191. // the USB spec and Intel explain next to nothing.
  192. // According to the USB spec (and the UHCI datasheet), 90% of the bandwidth should be used for
  193. // Isochronous and """Interrupt""" related transfers, with the rest being used for control and bulk
  194. // transfers.
  195. // That is, most of the time, the schedule is going to be executing either an Isochronous transfer
  196. // in our framelist, or an Interrupt transfer. The allocation in `create_structures` reflects this.
  197. //
  198. // Each frame has it's own Isochronous transfer Transfer Descriptor(s) that point to each other
  199. // horizontally in the list. The end of these transfers then point to the Interrupt Queue Headers,
  200. // in which we can attach Transfer Descriptors (related to Interrupt Transfers). These are attached
  201. // to the Queue Head _vertically_. We need to ensure that these are executed every 8ms, so they are inserted
  202. // at different points in the schedule (TODO: How do we do this?!?!). After the Interrupt Transfer Queue Heads,
  203. // we attach the Control Queue Heads. We need two in total, one for Low Speed devices, and one for Full Speed
  204. // USB devices. Finally, we attach the Bulk Transfer Queue Head.
  205. // Not specified in the datasheet, however, is another Queue Head with an "inactive" Transfer Descriptor. This
  206. // is to circumvent a bug in the silicon of the PIIX4's UHCI controller.
  207. // https://github.com/openbsd/src/blob/master/sys/dev/usb/uhci.c#L390
  208. //
  209. m_interrupt_transfer_queue->link_next_queue_head(m_lowspeed_control_qh);
  210. m_interrupt_transfer_queue->terminate_element_link_ptr();
  211. m_lowspeed_control_qh->link_next_queue_head(m_fullspeed_control_qh);
  212. m_lowspeed_control_qh->terminate_element_link_ptr();
  213. m_fullspeed_control_qh->link_next_queue_head(m_bulk_qh);
  214. m_fullspeed_control_qh->terminate_element_link_ptr();
  215. m_bulk_qh->link_next_queue_head(m_dummy_qh);
  216. m_bulk_qh->terminate_element_link_ptr();
  217. auto piix4_td_hack = allocate_transfer_descriptor();
  218. piix4_td_hack->terminate();
  219. piix4_td_hack->set_max_len(0x7ff); // Null data packet
  220. piix4_td_hack->set_device_address(0x7f);
  221. piix4_td_hack->set_packet_id(PacketID::IN);
  222. m_dummy_qh->terminate_with_stray_descriptor(piix4_td_hack);
  223. m_dummy_qh->terminate_element_link_ptr();
  224. u32* framelist = reinterpret_cast<u32*>(m_framelist->vaddr().as_ptr());
  225. for (int frame = 0; frame < UHCI_NUMBER_OF_FRAMES; frame++) {
  226. // Each frame pointer points to iso_td % NUM_ISO_TDS
  227. framelist[frame] = m_iso_td_list.at(frame % UHCI_NUMBER_OF_ISOCHRONOUS_TDS)->paddr();
  228. }
  229. m_interrupt_transfer_queue->print();
  230. m_lowspeed_control_qh->print();
  231. m_fullspeed_control_qh->print();
  232. m_bulk_qh->print();
  233. m_dummy_qh->print();
  234. }
  235. QueueHead* UHCIController::allocate_queue_head() const
  236. {
  237. for (QueueHead* queue_head : m_free_qh_pool) {
  238. if (!queue_head->in_use()) {
  239. queue_head->set_in_use(true);
  240. dbgln_if(UHCI_DEBUG, "UHCI: Allocated a new Queue Head! Located @ {} ({})", VirtualAddress(queue_head), PhysicalAddress(queue_head->paddr()));
  241. return queue_head;
  242. }
  243. }
  244. return nullptr; // Huh!? We're outta queue heads!
  245. }
  246. TransferDescriptor* UHCIController::allocate_transfer_descriptor() const
  247. {
  248. for (TransferDescriptor* transfer_descriptor : m_free_td_pool) {
  249. if (!transfer_descriptor->in_use()) {
  250. transfer_descriptor->set_in_use(true);
  251. dbgln_if(UHCI_DEBUG, "UHCI: Allocated a new Transfer Descriptor! Located @ {} ({})", VirtualAddress(transfer_descriptor), PhysicalAddress(transfer_descriptor->paddr()));
  252. return transfer_descriptor;
  253. }
  254. }
  255. return nullptr; // Huh?! We're outta TDs!!
  256. }
  257. KResult UHCIController::stop()
  258. {
  259. write_usbcmd(read_usbcmd() & ~UHCI_USBCMD_RUN);
  260. // FIXME: Timeout
  261. for (;;) {
  262. if (read_usbsts() & UHCI_USBSTS_HOST_CONTROLLER_HALTED)
  263. break;
  264. }
  265. return KSuccess;
  266. }
  267. KResult UHCIController::start()
  268. {
  269. write_usbcmd(read_usbcmd() | UHCI_USBCMD_RUN);
  270. // FIXME: Timeout
  271. for (;;) {
  272. if (!(read_usbsts() & UHCI_USBSTS_HOST_CONTROLLER_HALTED))
  273. break;
  274. }
  275. dbgln("UHCI: Started");
  276. auto root_hub_or_error = UHCIRootHub::try_create(*this);
  277. if (root_hub_or_error.is_error())
  278. return root_hub_or_error.error();
  279. m_root_hub = root_hub_or_error.release_value();
  280. auto result = m_root_hub->setup({});
  281. if (result.is_error())
  282. return result;
  283. return KSuccess;
  284. }
  285. TransferDescriptor* UHCIController::create_transfer_descriptor(Pipe& pipe, PacketID direction, size_t data_len)
  286. {
  287. TransferDescriptor* td = allocate_transfer_descriptor();
  288. if (td == nullptr) {
  289. return nullptr;
  290. }
  291. u16 max_len = (data_len > 0) ? (data_len - 1) : 0x7ff;
  292. VERIFY(max_len <= 0x4FF || max_len == 0x7FF); // According to the datasheet, anything in the range of 0x500 to 0x7FE are illegal
  293. td->set_token((max_len << TD_TOKEN_MAXLEN_SHIFT) | ((pipe.data_toggle() ? 1 : 0) << TD_TOKEN_DATA_TOGGLE_SHIFT) | (pipe.endpoint_address() << TD_TOKEN_ENDPOINT_SHIFT) | (pipe.device_address() << TD_TOKEN_DEVICE_ADDR_SHIFT) | (static_cast<u8>(direction)));
  294. pipe.set_toggle(!pipe.data_toggle());
  295. if (pipe.type() == Pipe::Type::Isochronous) {
  296. td->set_isochronous();
  297. } else {
  298. if (direction == PacketID::IN) {
  299. td->set_short_packet_detect();
  300. }
  301. }
  302. // Set low-speed bit if the device connected to port is a low=speed device (probably unlikely...)
  303. if (pipe.device_speed() == Pipe::DeviceSpeed::LowSpeed) {
  304. td->set_lowspeed();
  305. }
  306. td->set_active();
  307. td->set_error_retry_counter(RETRY_COUNTER_RELOAD);
  308. return td;
  309. }
  310. KResult UHCIController::create_chain(Pipe& pipe, PacketID direction, Ptr32<u8>& buffer_address, size_t max_size, size_t transfer_size, TransferDescriptor** td_chain, TransferDescriptor** last_td)
  311. {
  312. // We need to create `n` transfer descriptors based on the max
  313. // size of each transfer (which we've learned from the device already by reading
  314. // its device descriptor, or 8 bytes). Each TD then has its buffer pointer
  315. // set to the initial buffer address + (max_size * index), where index is
  316. // the ID of the TD in the chain.
  317. size_t byte_count = 0;
  318. TransferDescriptor* current_td = nullptr;
  319. TransferDescriptor* prev_td = nullptr;
  320. TransferDescriptor* first_td = nullptr;
  321. // Keep creating transfer descriptors while we still have some data
  322. while (byte_count < transfer_size) {
  323. size_t packet_size = transfer_size - byte_count;
  324. if (packet_size > max_size) {
  325. packet_size = max_size;
  326. }
  327. current_td = create_transfer_descriptor(pipe, direction, packet_size);
  328. if (current_td == nullptr) {
  329. free_descriptor_chain(first_td);
  330. return ENOMEM;
  331. }
  332. if (Checked<FlatPtr>::addition_would_overflow(reinterpret_cast<FlatPtr>(&*buffer_address), byte_count))
  333. return EOVERFLOW;
  334. auto buffer_pointer = Ptr32<u8>(buffer_address + byte_count);
  335. current_td->set_buffer_address(buffer_pointer);
  336. byte_count += packet_size;
  337. if (prev_td != nullptr)
  338. prev_td->insert_next_transfer_descriptor(current_td);
  339. else
  340. first_td = current_td;
  341. prev_td = current_td;
  342. }
  343. *last_td = current_td;
  344. *td_chain = first_td;
  345. return KSuccess;
  346. }
  347. void UHCIController::free_descriptor_chain(TransferDescriptor* first_descriptor)
  348. {
  349. TransferDescriptor* descriptor = first_descriptor;
  350. while (descriptor) {
  351. descriptor->free();
  352. descriptor = descriptor->next_td();
  353. }
  354. }
  355. KResultOr<size_t> UHCIController::submit_control_transfer(Transfer& transfer)
  356. {
  357. Pipe& pipe = transfer.pipe(); // Short circuit the pipe related to this transfer
  358. bool direction_in = (transfer.request().request_type & USB_REQUEST_TRANSFER_DIRECTION_DEVICE_TO_HOST) == USB_REQUEST_TRANSFER_DIRECTION_DEVICE_TO_HOST;
  359. dbgln_if(UHCI_DEBUG, "UHCI: Received control transfer for address {}. Root Hub is at address {}.", pipe.device_address(), m_root_hub->device_address());
  360. // Short-circuit the root hub.
  361. if (pipe.device_address() == m_root_hub->device_address())
  362. return m_root_hub->handle_control_transfer(transfer);
  363. TransferDescriptor* setup_td = create_transfer_descriptor(pipe, PacketID::SETUP, sizeof(USBRequestData));
  364. if (!setup_td)
  365. return ENOMEM;
  366. setup_td->set_buffer_address(transfer.buffer_physical().as_ptr());
  367. // Create a new descriptor chain
  368. TransferDescriptor* last_data_descriptor;
  369. TransferDescriptor* data_descriptor_chain;
  370. auto buffer_address = Ptr32<u8>(transfer.buffer_physical().as_ptr() + sizeof(USBRequestData));
  371. if (auto result = create_chain(pipe, direction_in ? PacketID::IN : PacketID::OUT, buffer_address, pipe.max_packet_size(), transfer.transfer_data_size(), &data_descriptor_chain, &last_data_descriptor); result.is_error())
  372. return result;
  373. // Status TD always has toggle set to 1
  374. pipe.set_toggle(true);
  375. TransferDescriptor* status_td = create_transfer_descriptor(pipe, direction_in ? PacketID::OUT : PacketID::IN, 0);
  376. if (!status_td) {
  377. free_descriptor_chain(data_descriptor_chain);
  378. return ENOMEM;
  379. }
  380. status_td->terminate();
  381. // Link transfers together
  382. if (data_descriptor_chain) {
  383. setup_td->insert_next_transfer_descriptor(data_descriptor_chain);
  384. last_data_descriptor->insert_next_transfer_descriptor(status_td);
  385. } else {
  386. setup_td->insert_next_transfer_descriptor(status_td);
  387. }
  388. // Cool, everything should be chained together now! Let's print it out
  389. if constexpr (UHCI_VERBOSE_DEBUG) {
  390. dbgln("Setup TD");
  391. setup_td->print();
  392. if (data_descriptor_chain) {
  393. dbgln("Data TD");
  394. data_descriptor_chain->print();
  395. }
  396. dbgln("Status TD");
  397. status_td->print();
  398. }
  399. QueueHead* transfer_queue = allocate_queue_head();
  400. if (!transfer_queue) {
  401. free_descriptor_chain(data_descriptor_chain);
  402. return 0;
  403. }
  404. transfer_queue->attach_transfer_descriptor_chain(setup_td);
  405. transfer_queue->set_transfer(&transfer);
  406. m_fullspeed_control_qh->attach_transfer_queue(*transfer_queue);
  407. size_t transfer_size = 0;
  408. while (!transfer.complete())
  409. transfer_size = poll_transfer_queue(*transfer_queue);
  410. free_descriptor_chain(transfer_queue->get_first_td());
  411. transfer_queue->free();
  412. return transfer_size;
  413. }
  414. size_t UHCIController::poll_transfer_queue(QueueHead& transfer_queue)
  415. {
  416. Transfer* transfer = transfer_queue.transfer();
  417. TransferDescriptor* descriptor = transfer_queue.get_first_td();
  418. bool transfer_still_in_progress = false;
  419. size_t transfer_size = 0;
  420. while (descriptor) {
  421. u32 status = descriptor->status();
  422. if (status & TransferDescriptor::StatusBits::Active) {
  423. transfer_still_in_progress = true;
  424. break;
  425. }
  426. if (status & TransferDescriptor::StatusBits::ErrorMask) {
  427. transfer->set_complete();
  428. transfer->set_error_occurred();
  429. dbgln_if(UHCI_DEBUG, "UHCIController: Transfer failed! Reason: {:08x}", status);
  430. return 0;
  431. }
  432. transfer_size += descriptor->actual_packet_length();
  433. descriptor = descriptor->next_td();
  434. }
  435. if (!transfer_still_in_progress)
  436. transfer->set_complete();
  437. return transfer_size;
  438. }
  439. void UHCIController::spawn_port_proc()
  440. {
  441. RefPtr<Thread> usb_hotplug_thread;
  442. Process::create_kernel_process(usb_hotplug_thread, "UHCIHotplug", [&] {
  443. for (;;) {
  444. if (m_root_hub)
  445. m_root_hub->check_for_port_updates();
  446. (void)Thread::current()->sleep(Time::from_seconds(1));
  447. }
  448. });
  449. }
  450. bool UHCIController::handle_irq(const RegisterState&)
  451. {
  452. u32 status = read_usbsts();
  453. // Shared IRQ. Not ours!
  454. if (!status)
  455. return false;
  456. if constexpr (UHCI_DEBUG) {
  457. dbgln("UHCI: Interrupt happened!");
  458. dbgln("Value of USBSTS: {:#04x}", read_usbsts());
  459. }
  460. // Write back USBSTS to clear bits
  461. write_usbsts(status);
  462. return true;
  463. }
  464. void UHCIController::get_port_status(Badge<UHCIRootHub>, u8 port, HubStatus& hub_port_status)
  465. {
  466. // The check is done by UHCIRootHub.
  467. VERIFY(port < NUMBER_OF_ROOT_PORTS);
  468. u16 status = port == 0 ? read_portsc1() : read_portsc2();
  469. if (status & UHCI_PORTSC_CURRRENT_CONNECT_STATUS)
  470. hub_port_status.status |= PORT_STATUS_CURRENT_CONNECT_STATUS;
  471. if (status & UHCI_PORTSC_CONNECT_STATUS_CHANGED)
  472. hub_port_status.change |= PORT_STATUS_CONNECT_STATUS_CHANGED;
  473. if (status & UHCI_PORTSC_PORT_ENABLED)
  474. hub_port_status.status |= PORT_STATUS_PORT_ENABLED;
  475. if (status & UHCI_PORTSC_PORT_ENABLE_CHANGED)
  476. hub_port_status.change |= PORT_STATUS_PORT_ENABLED_CHANGED;
  477. if (status & UHCI_PORTSC_LOW_SPEED_DEVICE)
  478. hub_port_status.status |= PORT_STATUS_LOW_SPEED_DEVICE_ATTACHED;
  479. if (status & UHCI_PORTSC_PORT_RESET)
  480. hub_port_status.status |= PORT_STATUS_RESET;
  481. if (m_port_reset_change_statuses & (1 << port))
  482. hub_port_status.change |= PORT_STATUS_RESET_CHANGED;
  483. if (status & UHCI_PORTSC_SUSPEND)
  484. hub_port_status.status |= PORT_STATUS_SUSPEND;
  485. if (m_port_suspend_change_statuses & (1 << port))
  486. hub_port_status.change |= PORT_STATUS_SUSPEND_CHANGED;
  487. // UHCI ports are always powered.
  488. hub_port_status.status |= PORT_STATUS_PORT_POWER;
  489. dbgln_if(UHCI_DEBUG, "UHCI: get_port_status status=0x{:04x} change=0x{:04x}", hub_port_status.status, hub_port_status.change);
  490. }
  491. void UHCIController::reset_port(u8 port)
  492. {
  493. // We still have to reset the port manually because UHCI does not automatically enable the port after reset.
  494. // Additionally, the USB 2.0 specification says the SetPortFeature(PORT_ENABLE) request is not specified and that the _ideal_ behaviour is to return a Request Error.
  495. // Source: USB 2.0 Specification Section 11.24.2.7.1.2
  496. // This means the hub code cannot rely on using it.
  497. // The check is done by UHCIRootHub and set_port_feature.
  498. VERIFY(port < NUMBER_OF_ROOT_PORTS);
  499. u16 port_data = port == 0 ? read_portsc1() : read_portsc2();
  500. port_data &= UCHI_PORTSC_NON_WRITE_CLEAR_BIT_MASK;
  501. port_data |= UHCI_PORTSC_PORT_RESET;
  502. if (port == 0)
  503. write_portsc1(port_data);
  504. else
  505. write_portsc2(port_data);
  506. // Wait at least 50 ms for the port to reset.
  507. // This is T DRSTR in the USB 2.0 Specification Page 186 Table 7-13.
  508. constexpr u16 reset_delay = 50 * 1000;
  509. IO::delay(reset_delay);
  510. port_data &= ~UHCI_PORTSC_PORT_RESET;
  511. if (port == 0)
  512. write_portsc1(port_data);
  513. else
  514. write_portsc2(port_data);
  515. // Wait 10 ms for the port to recover.
  516. // This is T RSTRCY in the USB 2.0 Specification Page 188 Table 7-14.
  517. constexpr u16 reset_recovery_delay = 10 * 1000;
  518. IO::delay(reset_recovery_delay);
  519. port_data = port == 0 ? read_portsc1() : read_portsc2();
  520. port_data |= UHCI_PORTSC_PORT_ENABLED;
  521. if (port == 0)
  522. write_portsc1(port_data);
  523. else
  524. write_portsc2(port_data);
  525. dbgln_if(UHCI_DEBUG, "UHCI: Port should be enabled now: {:#04x}", port == 0 ? read_portsc1() : read_portsc2());
  526. m_port_reset_change_statuses |= (1 << port);
  527. }
  528. KResult UHCIController::set_port_feature(Badge<UHCIRootHub>, u8 port, HubFeatureSelector feature_selector)
  529. {
  530. // The check is done by UHCIRootHub.
  531. VERIFY(port < NUMBER_OF_ROOT_PORTS);
  532. dbgln_if(UHCI_DEBUG, "UHCI: set_port_feature: port={} feature_selector={}", port, (u8)feature_selector);
  533. switch (feature_selector) {
  534. case HubFeatureSelector::PORT_POWER:
  535. // Ignore the request. UHCI ports are always powered.
  536. break;
  537. case HubFeatureSelector::PORT_RESET:
  538. reset_port(port);
  539. break;
  540. case HubFeatureSelector::PORT_SUSPEND: {
  541. u16 port_data = port == 0 ? read_portsc1() : read_portsc2();
  542. port_data &= UCHI_PORTSC_NON_WRITE_CLEAR_BIT_MASK;
  543. port_data |= UHCI_PORTSC_SUSPEND;
  544. if (port == 0)
  545. write_portsc1(port_data);
  546. else
  547. write_portsc2(port_data);
  548. m_port_suspend_change_statuses |= (1 << port);
  549. break;
  550. }
  551. default:
  552. dbgln("UHCI: Unknown feature selector in set_port_feature: {}", (u8)feature_selector);
  553. return EINVAL;
  554. }
  555. return KSuccess;
  556. }
  557. KResult UHCIController::clear_port_feature(Badge<UHCIRootHub>, u8 port, HubFeatureSelector feature_selector)
  558. {
  559. // The check is done by UHCIRootHub.
  560. VERIFY(port < NUMBER_OF_ROOT_PORTS);
  561. dbgln_if(UHCI_DEBUG, "UHCI: clear_port_feature: port={} feature_selector={}", port, (u8)feature_selector);
  562. u16 port_data = port == 0 ? read_portsc1() : read_portsc2();
  563. port_data &= UCHI_PORTSC_NON_WRITE_CLEAR_BIT_MASK;
  564. switch (feature_selector) {
  565. case HubFeatureSelector::PORT_ENABLE:
  566. port_data &= ~UHCI_PORTSC_PORT_ENABLED;
  567. break;
  568. case HubFeatureSelector::PORT_SUSPEND:
  569. port_data &= ~UHCI_PORTSC_SUSPEND;
  570. break;
  571. case HubFeatureSelector::PORT_POWER:
  572. // Ignore the request. UHCI ports are always powered.
  573. break;
  574. case HubFeatureSelector::C_PORT_CONNECTION:
  575. // This field is Write Clear.
  576. port_data |= UHCI_PORTSC_CONNECT_STATUS_CHANGED;
  577. break;
  578. case HubFeatureSelector::C_PORT_RESET:
  579. m_port_reset_change_statuses &= ~(1 << port);
  580. break;
  581. case HubFeatureSelector::C_PORT_ENABLE:
  582. // This field is Write Clear.
  583. port_data |= UHCI_PORTSC_PORT_ENABLE_CHANGED;
  584. break;
  585. case HubFeatureSelector::C_PORT_SUSPEND:
  586. m_port_suspend_change_statuses &= ~(1 << port);
  587. break;
  588. default:
  589. dbgln("UHCI: Unknown feature selector in clear_port_feature: {}", (u8)feature_selector);
  590. return EINVAL;
  591. }
  592. dbgln_if(UHCI_DEBUG, "UHCI: clear_port_feature: writing 0x{:04x} to portsc{}.", port_data, port + 1);
  593. if (port == 0)
  594. write_portsc1(port_data);
  595. else
  596. write_portsc2(port_data);
  597. return KSuccess;
  598. }
  599. }