UHCIController.cpp 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795
  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/JsonArraySerializer.h>
  8. #include <AK/JsonObjectSerializer.h>
  9. #include <AK/Platform.h>
  10. #include <Kernel/Bus/USB/UHCIController.h>
  11. #include <Kernel/Bus/USB/USBRequest.h>
  12. #include <Kernel/CommandLine.h>
  13. #include <Kernel/Debug.h>
  14. #include <Kernel/FileSystem/SysFS.h>
  15. #include <Kernel/KBufferBuilder.h>
  16. #include <Kernel/Process.h>
  17. #include <Kernel/Sections.h>
  18. #include <Kernel/StdLib.h>
  19. #include <Kernel/Time/TimeManagement.h>
  20. #include <Kernel/VM/AnonymousVMObject.h>
  21. #include <Kernel/VM/MemoryManager.h>
  22. static constexpr u8 MAXIMUM_NUMBER_OF_TDS = 128; // Upper pool limit. This consumes the second page we have allocated
  23. static constexpr u8 MAXIMUM_NUMBER_OF_QHS = 64;
  24. static constexpr u8 RETRY_COUNTER_RELOAD = 3;
  25. namespace Kernel::USB {
  26. static UHCIController* s_the;
  27. static constexpr u16 UHCI_USBCMD_RUN = 0x0001;
  28. static constexpr u16 UHCI_USBCMD_HOST_CONTROLLER_RESET = 0x0002;
  29. static constexpr u16 UHCI_USBCMD_GLOBAL_RESET = 0x0004;
  30. static constexpr u16 UHCI_USBCMD_ENTER_GLOBAL_SUSPEND_MODE = 0x0008;
  31. static constexpr u16 UHCI_USBCMD_FORCE_GLOBAL_RESUME = 0x0010;
  32. static constexpr u16 UHCI_USBCMD_SOFTWARE_DEBUG = 0x0020;
  33. static constexpr u16 UHCI_USBCMD_CONFIGURE_FLAG = 0x0040;
  34. static constexpr u16 UHCI_USBCMD_MAX_PACKET = 0x0080;
  35. static constexpr u16 UHCI_USBSTS_HOST_CONTROLLER_HALTED = 0x0020;
  36. static constexpr u16 UHCI_USBSTS_HOST_CONTROLLER_PROCESS_ERROR = 0x0010;
  37. static constexpr u16 UHCI_USBSTS_PCI_BUS_ERROR = 0x0008;
  38. static constexpr u16 UHCI_USBSTS_RESUME_RECEIVED = 0x0004;
  39. static constexpr u16 UHCI_USBSTS_USB_ERROR_INTERRUPT = 0x0002;
  40. static constexpr u16 UHCI_USBSTS_USB_INTERRUPT = 0x0001;
  41. static constexpr u8 UHCI_USBINTR_TIMEOUT_CRC_ENABLE = 0x01;
  42. static constexpr u8 UHCI_USBINTR_RESUME_INTR_ENABLE = 0x02;
  43. static constexpr u8 UHCI_USBINTR_IOC_ENABLE = 0x04;
  44. static constexpr u8 UHCI_USBINTR_SHORT_PACKET_INTR_ENABLE = 0x08;
  45. static constexpr u16 UHCI_FRAMELIST_FRAME_COUNT = 1024; // Each entry is 4 bytes in our allocated page
  46. static constexpr u16 UHCI_FRAMELIST_FRAME_INVALID = 0x0001;
  47. // Port stuff
  48. static constexpr u8 UHCI_ROOT_PORT_COUNT = 2;
  49. static constexpr u16 UHCI_PORTSC_CURRRENT_CONNECT_STATUS = 0x0001;
  50. static constexpr u16 UHCI_PORTSC_CONNECT_STATUS_CHANGED = 0x0002;
  51. static constexpr u16 UHCI_PORTSC_PORT_ENABLED = 0x0004;
  52. static constexpr u16 UHCI_PORTSC_PORT_ENABLE_CHANGED = 0x0008;
  53. static constexpr u16 UHCI_PORTSC_LINE_STATUS = 0x0030;
  54. static constexpr u16 UHCI_PORTSC_RESUME_DETECT = 0x40;
  55. static constexpr u16 UHCI_PORTSC_LOW_SPEED_DEVICE = 0x0100;
  56. static constexpr u16 UHCI_PORTSC_PORT_RESET = 0x0200;
  57. static constexpr u16 UHCI_PORTSC_SUSPEND = 0x1000;
  58. // *BSD and a few other drivers seem to use this number
  59. static constexpr u8 UHCI_NUMBER_OF_ISOCHRONOUS_TDS = 128;
  60. static constexpr u16 UHCI_NUMBER_OF_FRAMES = 1024;
  61. class SysFSUSBBusDirectory;
  62. static SysFSUSBBusDirectory* s_procfs_usb_bus_directory;
  63. class SysFSUSBDeviceInformation : public SysFSComponent {
  64. friend class SysFSUSBBusDirectory;
  65. public:
  66. virtual ~SysFSUSBDeviceInformation() override {};
  67. static NonnullRefPtr<SysFSUSBDeviceInformation> create(USB::Device&);
  68. RefPtr<USB::Device> device() const { return m_device; }
  69. protected:
  70. explicit SysFSUSBDeviceInformation(USB::Device& device)
  71. : SysFSComponent(String::number(device.address()))
  72. , m_device(device)
  73. {
  74. }
  75. virtual KResultOr<size_t> read_bytes(off_t offset, size_t count, UserOrKernelBuffer& buffer, FileDescription*) const override
  76. {
  77. KBufferBuilder builder;
  78. JsonArraySerializer array { builder };
  79. auto obj = array.add_object();
  80. obj.add("usb_spec_compliance_bcd", m_device->device_descriptor().usb_spec_compliance_bcd);
  81. obj.add("device_class", m_device->device_descriptor().device_class);
  82. obj.add("device_sub_class", m_device->device_descriptor().device_sub_class);
  83. obj.add("device_protocol", m_device->device_descriptor().device_protocol);
  84. obj.add("max_packet_size", m_device->device_descriptor().max_packet_size);
  85. obj.add("vendor_id", m_device->device_descriptor().vendor_id);
  86. obj.add("product_id", m_device->device_descriptor().product_id);
  87. obj.add("device_release_bcd", m_device->device_descriptor().device_release_bcd);
  88. obj.add("manufacturer_id_descriptor_index", m_device->device_descriptor().manufacturer_id_descriptor_index);
  89. obj.add("product_string_descriptor_index", m_device->device_descriptor().product_string_descriptor_index);
  90. obj.add("serial_number_descriptor_index", m_device->device_descriptor().serial_number_descriptor_index);
  91. obj.add("num_configurations", m_device->device_descriptor().num_configurations);
  92. obj.finish();
  93. array.finish();
  94. auto data = builder.build();
  95. if (!data)
  96. return ENOMEM;
  97. ssize_t nread = min(static_cast<off_t>(data->size() - offset), static_cast<off_t>(count));
  98. if (!buffer.write(data->data() + offset, nread))
  99. return EFAULT;
  100. return nread;
  101. }
  102. IntrusiveListNode<SysFSUSBDeviceInformation, RefPtr<SysFSUSBDeviceInformation>> m_list_node;
  103. NonnullRefPtr<USB::Device> m_device;
  104. };
  105. class SysFSUSBBusDirectory final : public SysFSDirectory {
  106. public:
  107. static void initialize();
  108. void plug(USB::Device&);
  109. void unplug(USB::Device&);
  110. virtual KResult traverse_as_directory(unsigned, Function<bool(FileSystem::DirectoryEntryView const&)>) const override;
  111. virtual RefPtr<SysFSComponent> lookup(StringView name) override;
  112. private:
  113. explicit SysFSUSBBusDirectory(SysFSBusDirectory&);
  114. RefPtr<SysFSUSBDeviceInformation> device_node_for(USB::Device& device);
  115. IntrusiveList<SysFSUSBDeviceInformation, RefPtr<SysFSUSBDeviceInformation>, &SysFSUSBDeviceInformation::m_list_node> m_device_nodes;
  116. mutable SpinLock<u8> m_lock;
  117. };
  118. KResult SysFSUSBBusDirectory::traverse_as_directory(unsigned fsid, Function<bool(FileSystem::DirectoryEntryView const&)> callback) const
  119. {
  120. ScopedSpinLock lock(m_lock);
  121. // Note: if the parent directory is null, it means something bad happened as this should not happen for the USB directory.
  122. VERIFY(m_parent_directory);
  123. callback({ ".", { fsid, component_index() }, 0 });
  124. callback({ "..", { fsid, m_parent_directory->component_index() }, 0 });
  125. for (auto& device_node : m_device_nodes) {
  126. InodeIdentifier identifier = { fsid, device_node.component_index() };
  127. callback({ device_node.name(), identifier, 0 });
  128. }
  129. return KSuccess;
  130. }
  131. RefPtr<SysFSComponent> SysFSUSBBusDirectory::lookup(StringView name)
  132. {
  133. ScopedSpinLock lock(m_lock);
  134. for (auto& device_node : m_device_nodes) {
  135. if (device_node.name() == name) {
  136. return device_node;
  137. }
  138. }
  139. return {};
  140. }
  141. RefPtr<SysFSUSBDeviceInformation> SysFSUSBBusDirectory::device_node_for(USB::Device& device)
  142. {
  143. RefPtr<USB::Device> checked_device = device;
  144. for (auto& device_node : m_device_nodes) {
  145. if (device_node.device().ptr() == checked_device.ptr())
  146. return device_node;
  147. }
  148. return {};
  149. }
  150. void SysFSUSBBusDirectory::plug(USB::Device& new_device)
  151. {
  152. ScopedSpinLock lock(m_lock);
  153. auto device_node = device_node_for(new_device);
  154. VERIFY(!device_node);
  155. m_device_nodes.append(SysFSUSBDeviceInformation::create(new_device));
  156. }
  157. void SysFSUSBBusDirectory::unplug(USB::Device& deleted_device)
  158. {
  159. ScopedSpinLock lock(m_lock);
  160. auto device_node = device_node_for(deleted_device);
  161. VERIFY(device_node);
  162. device_node->m_list_node.remove();
  163. }
  164. UNMAP_AFTER_INIT SysFSUSBBusDirectory::SysFSUSBBusDirectory(SysFSBusDirectory& buses_directory)
  165. : SysFSDirectory("usb"sv, buses_directory)
  166. {
  167. }
  168. UNMAP_AFTER_INIT void SysFSUSBBusDirectory::initialize()
  169. {
  170. auto directory = adopt_ref(*new SysFSUSBBusDirectory(SysFSComponentRegistry::the().buses_directory()));
  171. SysFSComponentRegistry::the().register_new_bus_directory(directory);
  172. s_procfs_usb_bus_directory = directory;
  173. }
  174. NonnullRefPtr<SysFSUSBDeviceInformation> SysFSUSBDeviceInformation::create(USB::Device& device)
  175. {
  176. return adopt_ref(*new SysFSUSBDeviceInformation(device));
  177. }
  178. UHCIController& UHCIController::the()
  179. {
  180. return *s_the;
  181. }
  182. UNMAP_AFTER_INIT void UHCIController::detect()
  183. {
  184. if (kernel_command_line().disable_uhci_controller())
  185. return;
  186. // FIXME: We create the /proc/bus/usb representation here, but it should really be handled
  187. // in a more broad singleton than this once we refactor things in USB subsystem.
  188. SysFSUSBBusDirectory::initialize();
  189. PCI::enumerate([&](const PCI::Address& address, PCI::ID id) {
  190. if (address.is_null())
  191. return;
  192. if (PCI::get_class(address) == 0xc && PCI::get_subclass(address) == 0x03 && PCI::get_programming_interface(address) == 0) {
  193. if (!s_the) {
  194. s_the = new UHCIController(address, id);
  195. s_the->spawn_port_proc();
  196. }
  197. }
  198. });
  199. }
  200. UNMAP_AFTER_INIT UHCIController::UHCIController(PCI::Address address, PCI::ID id)
  201. : PCI::Device(address)
  202. , m_io_base(PCI::get_BAR4(pci_address()) & ~1)
  203. {
  204. dmesgln("UHCI: Controller found {} @ {}", id, address);
  205. dmesgln("UHCI: I/O base {}", m_io_base);
  206. dmesgln("UHCI: Interrupt line: {}", PCI::get_interrupt_line(pci_address()));
  207. reset();
  208. start();
  209. }
  210. UNMAP_AFTER_INIT UHCIController::~UHCIController()
  211. {
  212. }
  213. RefPtr<USB::Device> const UHCIController::get_device_at_port(USB::Device::PortNumber port)
  214. {
  215. if (!m_devices.at(to_underlying(port)))
  216. return nullptr;
  217. return m_devices.at(to_underlying(port));
  218. }
  219. RefPtr<USB::Device> const UHCIController::get_device_from_address(u8 device_address)
  220. {
  221. for (auto const& device : m_devices) {
  222. if (!device)
  223. continue;
  224. if (device->address() == device_address)
  225. return device;
  226. }
  227. return nullptr;
  228. }
  229. void UHCIController::reset()
  230. {
  231. stop();
  232. write_usbcmd(UHCI_USBCMD_HOST_CONTROLLER_RESET);
  233. // FIXME: Timeout
  234. for (;;) {
  235. if (read_usbcmd() & UHCI_USBCMD_HOST_CONTROLLER_RESET)
  236. continue;
  237. break;
  238. }
  239. // Let's allocate the physical page for the Frame List (which is 4KiB aligned)
  240. auto framelist_vmobj = AnonymousVMObject::try_create_physically_contiguous_with_size(PAGE_SIZE);
  241. m_framelist = MemoryManager::the().allocate_kernel_region_with_vmobject(*framelist_vmobj, PAGE_SIZE, "UHCI Framelist", Region::Access::Write);
  242. dbgln("UHCI: Allocated framelist at physical address {}", m_framelist->physical_page(0)->paddr());
  243. dbgln("UHCI: Framelist is at virtual address {}", m_framelist->vaddr());
  244. write_sofmod(64); // 1mS frame time
  245. create_structures();
  246. setup_schedule();
  247. write_flbaseadd(m_framelist->physical_page(0)->paddr().get()); // Frame list (physical) address
  248. write_frnum(0); // Set the initial frame number
  249. // FIXME: Work out why interrupts lock up the entire system....
  250. // Disable UHCI Controller from raising an IRQ
  251. write_usbintr(0);
  252. dbgln("UHCI: Reset completed");
  253. }
  254. UNMAP_AFTER_INIT void UHCIController::create_structures()
  255. {
  256. // Let's allocate memory for both the QH and TD pools
  257. // First the QH pool and all of the Interrupt QH's
  258. auto qh_pool_vmobject = AnonymousVMObject::try_create_physically_contiguous_with_size(2 * PAGE_SIZE);
  259. m_qh_pool = MemoryManager::the().allocate_kernel_region_with_vmobject(*qh_pool_vmobject, 2 * PAGE_SIZE, "UHCI Queue Head Pool", Region::Access::Write);
  260. memset(m_qh_pool->vaddr().as_ptr(), 0, 2 * PAGE_SIZE); // Zero out both pages
  261. // Let's populate our free qh list (so we have some we can allocate later on)
  262. m_free_qh_pool.resize(MAXIMUM_NUMBER_OF_TDS);
  263. for (size_t i = 0; i < m_free_qh_pool.size(); i++) {
  264. auto placement_addr = reinterpret_cast<void*>(m_qh_pool->vaddr().get() + (i * sizeof(QueueHead)));
  265. auto paddr = static_cast<u32>(m_qh_pool->physical_page(0)->paddr().get() + (i * sizeof(QueueHead)));
  266. m_free_qh_pool.at(i) = new (placement_addr) QueueHead(paddr);
  267. }
  268. // Create the Full Speed, Low Speed Control and Bulk Queue Heads
  269. m_interrupt_transfer_queue = allocate_queue_head();
  270. m_lowspeed_control_qh = allocate_queue_head();
  271. m_fullspeed_control_qh = allocate_queue_head();
  272. m_bulk_qh = allocate_queue_head();
  273. m_dummy_qh = allocate_queue_head();
  274. // Now the Transfer Descriptor pool
  275. auto td_pool_vmobject = AnonymousVMObject::try_create_physically_contiguous_with_size(2 * PAGE_SIZE);
  276. m_td_pool = MemoryManager::the().allocate_kernel_region_with_vmobject(*td_pool_vmobject, 2 * PAGE_SIZE, "UHCI Transfer Descriptor Pool", Region::Access::Write);
  277. memset(m_td_pool->vaddr().as_ptr(), 0, 2 * PAGE_SIZE);
  278. // Set up the Isochronous Transfer Descriptor list
  279. m_iso_td_list.resize(UHCI_NUMBER_OF_ISOCHRONOUS_TDS);
  280. for (size_t i = 0; i < m_iso_td_list.size(); i++) {
  281. auto placement_addr = reinterpret_cast<void*>(m_td_pool->vaddr().get() + (i * sizeof(Kernel::USB::TransferDescriptor)));
  282. auto paddr = static_cast<u32>(m_td_pool->physical_page(0)->paddr().get() + (i * sizeof(Kernel::USB::TransferDescriptor)));
  283. // Place a new Transfer Descriptor with a 1:1 in our region
  284. // The pointer returned by `new()` lines up exactly with the value
  285. // that we store in `paddr`, meaning our member functions directly
  286. // access the raw descriptor (that we later send to the controller)
  287. m_iso_td_list.at(i) = new (placement_addr) Kernel::USB::TransferDescriptor(paddr);
  288. auto transfer_descriptor = m_iso_td_list.at(i);
  289. transfer_descriptor->set_in_use(true); // Isochronous transfers are ALWAYS marked as in use (in case we somehow get allocated one...)
  290. transfer_descriptor->set_isochronous();
  291. transfer_descriptor->link_queue_head(m_interrupt_transfer_queue->paddr());
  292. if constexpr (UHCI_VERBOSE_DEBUG)
  293. transfer_descriptor->print();
  294. }
  295. m_free_td_pool.resize(MAXIMUM_NUMBER_OF_TDS);
  296. for (size_t i = 0; i < m_free_td_pool.size(); i++) {
  297. auto placement_addr = reinterpret_cast<void*>(m_td_pool->vaddr().offset(PAGE_SIZE).get() + (i * sizeof(Kernel::USB::TransferDescriptor)));
  298. auto paddr = static_cast<u32>(m_td_pool->physical_page(1)->paddr().get() + (i * sizeof(Kernel::USB::TransferDescriptor)));
  299. // Place a new Transfer Descriptor with a 1:1 in our region
  300. // The pointer returned by `new()` lines up exactly with the value
  301. // that we store in `paddr`, meaning our member functions directly
  302. // access the raw descriptor (that we later send to the controller)
  303. m_free_td_pool.at(i) = new (placement_addr) Kernel::USB::TransferDescriptor(paddr);
  304. if constexpr (UHCI_VERBOSE_DEBUG) {
  305. auto transfer_descriptor = m_free_td_pool.at(i);
  306. transfer_descriptor->print();
  307. }
  308. }
  309. if constexpr (UHCI_DEBUG) {
  310. dbgln("UHCI: Pool information:");
  311. dbgln(" qh_pool: {}, length: {}", PhysicalAddress(m_qh_pool->physical_page(0)->paddr()), m_qh_pool->range().size());
  312. dbgln(" td_pool: {}, length: {}", PhysicalAddress(m_td_pool->physical_page(0)->paddr()), m_td_pool->range().size());
  313. }
  314. }
  315. UNMAP_AFTER_INIT void UHCIController::setup_schedule()
  316. {
  317. //
  318. // https://github.com/alkber/minix3-usbsubsystem/blob/master/usb/uhci-hcd.c
  319. //
  320. // This lad probably has the best explanation as to how this is actually done. I'll try and
  321. // explain it here to so that there's no need for anyone to go hunting for this shit again, because
  322. // the USB spec and Intel explain next to nothing.
  323. // According to the USB spec (and the UHCI datasheet), 90% of the bandwidth should be used for
  324. // Isochronous and """Interrupt""" related transfers, with the rest being used for control and bulk
  325. // transfers.
  326. // That is, most of the time, the schedule is going to be executing either an Isochronous transfer
  327. // in our framelist, or an Interrupt transfer. The allocation in `create_structures` reflects this.
  328. //
  329. // Each frame has it's own Isochronous transfer Transfer Descriptor(s) that point to each other
  330. // horizontally in the list. The end of these transfers then point to the Interrupt Queue Headers,
  331. // in which we can attach Transfer Descriptors (related to Interrupt Transfers). These are attached
  332. // to the Queue Head _vertically_. We need to ensure that these are executed every 8ms, so they are inserted
  333. // at different points in the schedule (TODO: How do we do this?!?!). After the Interrupt Transfer Queue Heads,
  334. // we attach the Control Queue Heads. We need two in total, one for Low Speed devices, and one for Full Speed
  335. // USB devices. Finally, we attach the Bulk Transfer Queue Head.
  336. // Not specified in the datasheet, however, is another Queue Head with an "inactive" Transfer Descriptor. This
  337. // is to circumvent a bug in the silicon of the PIIX4's UHCI controller.
  338. // https://github.com/openbsd/src/blob/master/sys/dev/usb/uhci.c#L390
  339. //
  340. m_interrupt_transfer_queue->link_next_queue_head(m_lowspeed_control_qh);
  341. m_interrupt_transfer_queue->terminate_element_link_ptr();
  342. m_lowspeed_control_qh->link_next_queue_head(m_fullspeed_control_qh);
  343. m_lowspeed_control_qh->terminate_element_link_ptr();
  344. m_fullspeed_control_qh->link_next_queue_head(m_bulk_qh);
  345. m_fullspeed_control_qh->terminate_element_link_ptr();
  346. m_bulk_qh->link_next_queue_head(m_dummy_qh);
  347. m_bulk_qh->terminate_element_link_ptr();
  348. auto piix4_td_hack = allocate_transfer_descriptor();
  349. piix4_td_hack->terminate();
  350. piix4_td_hack->set_max_len(0x7ff); // Null data packet
  351. piix4_td_hack->set_device_address(0x7f);
  352. piix4_td_hack->set_packet_id(PacketID::IN);
  353. m_dummy_qh->terminate_with_stray_descriptor(piix4_td_hack);
  354. m_dummy_qh->terminate_element_link_ptr();
  355. u32* framelist = reinterpret_cast<u32*>(m_framelist->vaddr().as_ptr());
  356. for (int frame = 0; frame < UHCI_NUMBER_OF_FRAMES; frame++) {
  357. // Each frame pointer points to iso_td % NUM_ISO_TDS
  358. framelist[frame] = m_iso_td_list.at(frame % UHCI_NUMBER_OF_ISOCHRONOUS_TDS)->paddr();
  359. }
  360. m_interrupt_transfer_queue->print();
  361. m_lowspeed_control_qh->print();
  362. m_fullspeed_control_qh->print();
  363. m_bulk_qh->print();
  364. m_dummy_qh->print();
  365. }
  366. QueueHead* UHCIController::allocate_queue_head() const
  367. {
  368. for (QueueHead* queue_head : m_free_qh_pool) {
  369. if (!queue_head->in_use()) {
  370. queue_head->set_in_use(true);
  371. dbgln_if(UHCI_DEBUG, "UHCI: Allocated a new Queue Head! Located @ {} ({})", VirtualAddress(queue_head), PhysicalAddress(queue_head->paddr()));
  372. return queue_head;
  373. }
  374. }
  375. return nullptr; // Huh!? We're outta queue heads!
  376. }
  377. TransferDescriptor* UHCIController::allocate_transfer_descriptor() const
  378. {
  379. for (TransferDescriptor* transfer_descriptor : m_free_td_pool) {
  380. if (!transfer_descriptor->in_use()) {
  381. transfer_descriptor->set_in_use(true);
  382. dbgln_if(UHCI_DEBUG, "UHCI: Allocated a new Transfer Descriptor! Located @ {} ({})", VirtualAddress(transfer_descriptor), PhysicalAddress(transfer_descriptor->paddr()));
  383. return transfer_descriptor;
  384. }
  385. }
  386. return nullptr; // Huh?! We're outta TDs!!
  387. }
  388. void UHCIController::stop()
  389. {
  390. write_usbcmd(read_usbcmd() & ~UHCI_USBCMD_RUN);
  391. // FIXME: Timeout
  392. for (;;) {
  393. if (read_usbsts() & UHCI_USBSTS_HOST_CONTROLLER_HALTED)
  394. break;
  395. }
  396. }
  397. void UHCIController::start()
  398. {
  399. write_usbcmd(read_usbcmd() | UHCI_USBCMD_RUN);
  400. // FIXME: Timeout
  401. for (;;) {
  402. if (!(read_usbsts() & UHCI_USBSTS_HOST_CONTROLLER_HALTED))
  403. break;
  404. }
  405. dbgln("UHCI: Started");
  406. }
  407. TransferDescriptor* UHCIController::create_transfer_descriptor(Pipe& pipe, PacketID direction, size_t data_len)
  408. {
  409. TransferDescriptor* td = allocate_transfer_descriptor();
  410. if (td == nullptr) {
  411. return nullptr;
  412. }
  413. u16 max_len = (data_len > 0) ? (data_len - 1) : 0x7ff;
  414. VERIFY(max_len <= 0x4FF || max_len == 0x7FF); // According to the datasheet, anything in the range of 0x500 to 0x7FE are illegal
  415. 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)));
  416. pipe.set_toggle(!pipe.data_toggle());
  417. if (pipe.type() == Pipe::Type::Isochronous) {
  418. td->set_isochronous();
  419. } else {
  420. if (direction == PacketID::IN) {
  421. td->set_short_packet_detect();
  422. }
  423. }
  424. // Set low-speed bit if the device connected to port is a low=speed device (probably unlikely...)
  425. if (pipe.device_speed() == Pipe::DeviceSpeed::LowSpeed) {
  426. td->set_lowspeed();
  427. }
  428. td->set_active();
  429. td->set_error_retry_counter(RETRY_COUNTER_RELOAD);
  430. return td;
  431. }
  432. 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)
  433. {
  434. // We need to create `n` transfer descriptors based on the max
  435. // size of each transfer (which we've learned from the device already by reading
  436. // its device descriptor, or 8 bytes). Each TD then has its buffer pointer
  437. // set to the initial buffer address + (max_size * index), where index is
  438. // the ID of the TD in the chain.
  439. size_t byte_count = 0;
  440. TransferDescriptor* current_td = nullptr;
  441. TransferDescriptor* prev_td = nullptr;
  442. TransferDescriptor* first_td = nullptr;
  443. // Keep creating transfer descriptors while we still have some data
  444. while (byte_count < transfer_size) {
  445. size_t packet_size = transfer_size - byte_count;
  446. if (packet_size > max_size) {
  447. packet_size = max_size;
  448. }
  449. current_td = create_transfer_descriptor(pipe, direction, packet_size);
  450. if (current_td == nullptr) {
  451. free_descriptor_chain(first_td);
  452. return ENOMEM;
  453. }
  454. if (Checked<FlatPtr>::addition_would_overflow(reinterpret_cast<FlatPtr>(&*buffer_address), byte_count))
  455. return EOVERFLOW;
  456. auto buffer_pointer = Ptr32<u8>(buffer_address + byte_count);
  457. current_td->set_buffer_address(buffer_pointer);
  458. byte_count += packet_size;
  459. if (prev_td != nullptr)
  460. prev_td->insert_next_transfer_descriptor(current_td);
  461. else
  462. first_td = current_td;
  463. prev_td = current_td;
  464. }
  465. *last_td = current_td;
  466. *td_chain = first_td;
  467. return KSuccess;
  468. }
  469. void UHCIController::free_descriptor_chain(TransferDescriptor* first_descriptor)
  470. {
  471. TransferDescriptor* descriptor = first_descriptor;
  472. while (descriptor) {
  473. descriptor->free();
  474. descriptor = descriptor->next_td();
  475. }
  476. }
  477. KResultOr<size_t> UHCIController::submit_control_transfer(Transfer& transfer)
  478. {
  479. Pipe& pipe = transfer.pipe(); // Short circuit the pipe related to this transfer
  480. bool direction_in = (transfer.request().request_type & USB_DEVICE_REQUEST_DEVICE_TO_HOST) == USB_DEVICE_REQUEST_DEVICE_TO_HOST;
  481. TransferDescriptor* setup_td = create_transfer_descriptor(pipe, PacketID::SETUP, sizeof(USBRequestData));
  482. if (!setup_td)
  483. return ENOMEM;
  484. setup_td->set_buffer_address(transfer.buffer_physical().as_ptr());
  485. // Create a new descriptor chain
  486. TransferDescriptor* last_data_descriptor;
  487. TransferDescriptor* data_descriptor_chain;
  488. auto buffer_address = Ptr32<u8>(transfer.buffer_physical().as_ptr() + sizeof(USBRequestData));
  489. auto transfer_chain_create_result = create_chain(pipe,
  490. direction_in ? PacketID::IN : PacketID::OUT,
  491. buffer_address,
  492. pipe.max_packet_size(),
  493. transfer.transfer_data_size(),
  494. &data_descriptor_chain,
  495. &last_data_descriptor);
  496. if (transfer_chain_create_result != KSuccess)
  497. return transfer_chain_create_result;
  498. // Status TD always has toggle set to 1
  499. pipe.set_toggle(true);
  500. TransferDescriptor* status_td = create_transfer_descriptor(pipe, direction_in ? PacketID::OUT : PacketID::IN, 0);
  501. if (!status_td) {
  502. free_descriptor_chain(data_descriptor_chain);
  503. return ENOMEM;
  504. }
  505. status_td->terminate();
  506. // Link transfers together
  507. if (data_descriptor_chain) {
  508. setup_td->insert_next_transfer_descriptor(data_descriptor_chain);
  509. last_data_descriptor->insert_next_transfer_descriptor(status_td);
  510. } else {
  511. setup_td->insert_next_transfer_descriptor(status_td);
  512. }
  513. // Cool, everything should be chained together now! Let's print it out
  514. if constexpr (UHCI_VERBOSE_DEBUG) {
  515. dbgln("Setup TD");
  516. setup_td->print();
  517. if (data_descriptor_chain) {
  518. dbgln("Data TD");
  519. data_descriptor_chain->print();
  520. }
  521. dbgln("Status TD");
  522. status_td->print();
  523. }
  524. QueueHead* transfer_queue = allocate_queue_head();
  525. if (!transfer_queue) {
  526. free_descriptor_chain(data_descriptor_chain);
  527. return 0;
  528. }
  529. transfer_queue->attach_transfer_descriptor_chain(setup_td);
  530. transfer_queue->set_transfer(&transfer);
  531. m_fullspeed_control_qh->attach_transfer_queue(*transfer_queue);
  532. size_t transfer_size = 0;
  533. while (!transfer.complete())
  534. transfer_size = poll_transfer_queue(*transfer_queue);
  535. free_descriptor_chain(transfer_queue->get_first_td());
  536. transfer_queue->free();
  537. return transfer_size;
  538. }
  539. size_t UHCIController::poll_transfer_queue(QueueHead& transfer_queue)
  540. {
  541. Transfer* transfer = transfer_queue.transfer();
  542. TransferDescriptor* descriptor = transfer_queue.get_first_td();
  543. bool transfer_still_in_progress = false;
  544. size_t transfer_size = 0;
  545. while (descriptor) {
  546. u32 status = descriptor->status();
  547. if (status & TransferDescriptor::StatusBits::Active) {
  548. transfer_still_in_progress = true;
  549. break;
  550. }
  551. if (status & TransferDescriptor::StatusBits::ErrorMask) {
  552. transfer->set_complete();
  553. transfer->set_error_occurred();
  554. dbgln_if(UHCI_DEBUG, "UHCIController: Transfer failed! Reason: {:08x}", status);
  555. return 0;
  556. }
  557. transfer_size += descriptor->actual_packet_length();
  558. descriptor = descriptor->next_td();
  559. }
  560. if (!transfer_still_in_progress)
  561. transfer->set_complete();
  562. return transfer_size;
  563. }
  564. void UHCIController::spawn_port_proc()
  565. {
  566. RefPtr<Thread> usb_hotplug_thread;
  567. Process::create_kernel_process(usb_hotplug_thread, "UHCIHotplug", [&] {
  568. for (;;) {
  569. for (int port = 0; port < UHCI_ROOT_PORT_COUNT; port++) {
  570. u16 port_data = 0;
  571. if (port == 1) {
  572. // Let's see what's happening on port 1
  573. // Current status
  574. port_data = read_portsc1();
  575. if (port_data & UHCI_PORTSC_CONNECT_STATUS_CHANGED) {
  576. if (port_data & UHCI_PORTSC_CURRRENT_CONNECT_STATUS) {
  577. dmesgln("UHCI: Device attach detected on Root Port 1!");
  578. // Reset the port
  579. port_data = read_portsc1();
  580. write_portsc1(port_data | UHCI_PORTSC_PORT_RESET);
  581. IO::delay(500);
  582. write_portsc1(port_data & ~UHCI_PORTSC_PORT_RESET);
  583. IO::delay(500);
  584. write_portsc1(port_data & (~UHCI_PORTSC_PORT_ENABLE_CHANGED | ~UHCI_PORTSC_CONNECT_STATUS_CHANGED));
  585. port_data = read_portsc1();
  586. write_portsc1(port_data | UHCI_PORTSC_PORT_ENABLED);
  587. dbgln("port should be enabled now: {:#04x}\n", read_portsc1());
  588. USB::Device::DeviceSpeed speed = (port_data & UHCI_PORTSC_LOW_SPEED_DEVICE) ? USB::Device::DeviceSpeed::LowSpeed : USB::Device::DeviceSpeed::FullSpeed;
  589. auto device = USB::Device::try_create(USB::Device::PortNumber::Port1, speed);
  590. if (device.is_error())
  591. dmesgln("UHCI: Device creation failed on port 1 ({})", device.error());
  592. m_devices.at(0) = device.value();
  593. VERIFY(s_procfs_usb_bus_directory);
  594. s_procfs_usb_bus_directory->plug(device.value());
  595. } else {
  596. // FIXME: Clean up (and properly) the RefPtr to the device in m_devices
  597. VERIFY(s_procfs_usb_bus_directory);
  598. VERIFY(m_devices.at(0));
  599. dmesgln("UHCI: Device detach detected on Root Port 1");
  600. s_procfs_usb_bus_directory->unplug(*m_devices.at(0));
  601. }
  602. }
  603. } else {
  604. port_data = UHCIController::the().read_portsc2();
  605. if (port_data & UHCI_PORTSC_CONNECT_STATUS_CHANGED) {
  606. if (port_data & UHCI_PORTSC_CURRRENT_CONNECT_STATUS) {
  607. dmesgln("UHCI: Device attach detected on Root Port 2");
  608. // Reset the port
  609. port_data = read_portsc2();
  610. write_portsc2(port_data | UHCI_PORTSC_PORT_RESET);
  611. for (size_t i = 0; i < 50000; ++i)
  612. IO::in8(0x80);
  613. write_portsc2(port_data & ~UHCI_PORTSC_PORT_RESET);
  614. for (size_t i = 0; i < 100000; ++i)
  615. IO::in8(0x80);
  616. write_portsc2(port_data & (~UHCI_PORTSC_PORT_ENABLE_CHANGED | ~UHCI_PORTSC_CONNECT_STATUS_CHANGED));
  617. port_data = read_portsc2();
  618. write_portsc1(port_data | UHCI_PORTSC_PORT_ENABLED);
  619. dbgln("port should be enabled now: {:#04x}\n", read_portsc1());
  620. USB::Device::DeviceSpeed speed = (port_data & UHCI_PORTSC_LOW_SPEED_DEVICE) ? USB::Device::DeviceSpeed::LowSpeed : USB::Device::DeviceSpeed::FullSpeed;
  621. auto device = USB::Device::try_create(USB::Device::PortNumber::Port2, speed);
  622. if (device.is_error())
  623. dmesgln("UHCI: Device creation failed on port 2 ({})", device.error());
  624. m_devices.at(1) = device.value();
  625. VERIFY(s_procfs_usb_bus_directory);
  626. s_procfs_usb_bus_directory->plug(device.value());
  627. } else {
  628. // FIXME: Clean up (and properly) the RefPtr to the device in m_devices
  629. VERIFY(s_procfs_usb_bus_directory);
  630. VERIFY(m_devices.at(1));
  631. dmesgln("UHCI: Device detach detected on Root Port 2");
  632. s_procfs_usb_bus_directory->unplug(*m_devices.at(1));
  633. }
  634. }
  635. }
  636. }
  637. (void)Thread::current()->sleep(Time::from_seconds(1));
  638. }
  639. });
  640. }
  641. bool UHCIController::handle_irq(const RegisterState&)
  642. {
  643. u32 status = read_usbsts();
  644. // Shared IRQ. Not ours!
  645. if (!status)
  646. return false;
  647. if constexpr (UHCI_DEBUG) {
  648. dbgln("UHCI: Interrupt happened!");
  649. dbgln("Value of USBSTS: {:#04x}", read_usbsts());
  650. }
  651. // Write back USBSTS to clear bits
  652. write_usbsts(status);
  653. return true;
  654. }
  655. }