forked from Bananymous/banan-os
				
			Kernel: Pass xHCI device information in structs
This makes code more readable and extendable
This commit is contained in:
		
							parent
							
								
									63b15a8855
								
							
						
					
					
						commit
						7de689055c
					
				|  | @ -46,7 +46,7 @@ namespace Kernel | ||||||
| 
 | 
 | ||||||
| 		void port_updater_task(); | 		void port_updater_task(); | ||||||
| 
 | 
 | ||||||
| 		BAN::ErrorOr<uint8_t> initialize_slot(int port_index); | 		BAN::ErrorOr<uint8_t> initialize_device(uint32_t route_string, USB::SpeedClass speed_class); | ||||||
| 		void deinitialize_slot(uint8_t slot_id); | 		void deinitialize_slot(uint8_t slot_id); | ||||||
| 
 | 
 | ||||||
| 		BAN::ErrorOr<XHCI::TRB> send_command(const XHCI::TRB&); | 		BAN::ErrorOr<XHCI::TRB> send_command(const XHCI::TRB&); | ||||||
|  |  | ||||||
|  | @ -30,8 +30,15 @@ namespace Kernel | ||||||
| 			void(XHCIDevice::*callback)(XHCI::TRB); | 			void(XHCIDevice::*callback)(XHCI::TRB); | ||||||
| 		}; | 		}; | ||||||
| 
 | 
 | ||||||
|  | 		struct Info | ||||||
|  | 		{ | ||||||
|  | 			USB::SpeedClass speed_class; | ||||||
|  | 			uint8_t slot_id; | ||||||
|  | 			uint32_t route_string; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
| 	public: | 	public: | ||||||
| 		static BAN::ErrorOr<BAN::UniqPtr<XHCIDevice>> create(XHCIController&, uint32_t port_id, uint32_t slot_id); | 		static BAN::ErrorOr<BAN::UniqPtr<XHCIDevice>> create(XHCIController&, const Info& info); | ||||||
| 
 | 
 | ||||||
| 		BAN::ErrorOr<void> configure_endpoint(const USBEndpointDescriptor&) override; | 		BAN::ErrorOr<void> configure_endpoint(const USBEndpointDescriptor&) override; | ||||||
| 		BAN::ErrorOr<size_t> send_request(const USBDeviceRequest&, paddr_t buffer) override; | 		BAN::ErrorOr<size_t> send_request(const USBDeviceRequest&, paddr_t buffer) override; | ||||||
|  | @ -43,8 +50,9 @@ namespace Kernel | ||||||
| 		BAN::ErrorOr<void> initialize_control_endpoint() override; | 		BAN::ErrorOr<void> initialize_control_endpoint() override; | ||||||
| 
 | 
 | ||||||
| 	private: | 	private: | ||||||
| 		XHCIDevice(XHCIController& controller, uint32_t port_id, uint32_t slot_id); | 		XHCIDevice(XHCIController& controller, const Info& info); | ||||||
| 		~XHCIDevice(); | 		~XHCIDevice(); | ||||||
|  | 
 | ||||||
| 		BAN::ErrorOr<void> update_actual_max_packet_size(); | 		BAN::ErrorOr<void> update_actual_max_packet_size(); | ||||||
| 
 | 
 | ||||||
| 		void on_interrupt_or_bulk_endpoint_event(XHCI::TRB); | 		void on_interrupt_or_bulk_endpoint_event(XHCI::TRB); | ||||||
|  | @ -55,8 +63,7 @@ namespace Kernel | ||||||
| 		static constexpr uint32_t m_transfer_ring_trb_count = PAGE_SIZE / sizeof(XHCI::TRB); | 		static constexpr uint32_t m_transfer_ring_trb_count = PAGE_SIZE / sizeof(XHCI::TRB); | ||||||
| 
 | 
 | ||||||
| 		XHCIController& m_controller; | 		XHCIController& m_controller; | ||||||
| 		const uint32_t m_port_id; | 		Info m_info; | ||||||
| 		const uint32_t m_slot_id; |  | ||||||
| 
 | 
 | ||||||
| 		Mutex m_mutex; | 		Mutex m_mutex; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -363,7 +363,8 @@ namespace Kernel | ||||||
| 						continue; | 						continue; | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				if (auto ret = initialize_slot(i); !ret.is_error()) | 				const uint8_t speed_id = (op_port.portsc >> XHCI::PORTSC::PORT_SPEED_SHIFT) & XHCI::PORTSC::PORT_SPEED_MASK; | ||||||
|  | 				if (auto ret = initialize_device(i + 1, speed_id_to_class(speed_id)); !ret.is_error()) | ||||||
| 					my_port.slot_id = ret.value(); | 					my_port.slot_id = ret.value(); | ||||||
| 				else | 				else | ||||||
| 				{ | 				{ | ||||||
|  | @ -377,10 +378,8 @@ namespace Kernel | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	BAN::ErrorOr<uint8_t> XHCIController::initialize_slot(int port_index) | 	BAN::ErrorOr<uint8_t> XHCIController::initialize_device(uint32_t route_string, USB::SpeedClass speed_class) | ||||||
| 	{ | 	{ | ||||||
| 		auto& my_port = m_ports[port_index]; |  | ||||||
| 
 |  | ||||||
| 		XHCI::TRB enable_slot { .enable_slot_command {} }; | 		XHCI::TRB enable_slot { .enable_slot_command {} }; | ||||||
| 		enable_slot.enable_slot_command.trb_type  = XHCI::TRBType::EnableSlotCommand; | 		enable_slot.enable_slot_command.trb_type  = XHCI::TRBType::EnableSlotCommand; | ||||||
| 		// 7.2.2.1.4: The Protocol Slot Type field of a USB3 or USB2 xHCI Supported Protocol Capability shall be set to ‘0’.
 | 		// 7.2.2.1.4: The Protocol Slot Type field of a USB3 or USB2 xHCI Supported Protocol Capability shall be set to ‘0’.
 | ||||||
|  | @ -393,9 +392,24 @@ namespace Kernel | ||||||
| 			dwarnln("EnableSlotCommand returned an invalid slot {}", slot_id); | 			dwarnln("EnableSlotCommand returned an invalid slot {}", slot_id); | ||||||
| 			return BAN::Error::from_errno(EFAULT); | 			return BAN::Error::from_errno(EFAULT); | ||||||
| 		} | 		} | ||||||
| 		dprintln_if(DEBUG_XHCI, "allocated slot {} for port {}", slot_id, port_index + 1); |  | ||||||
| 
 | 
 | ||||||
| 		m_slots[slot_id - 1] = TRY(XHCIDevice::create(*this, port_index + 1, slot_id)); | #if DEBUG_XHCI | ||||||
|  | 		const auto& root_port = m_ports[(route_string & 0x0F) - 1]; | ||||||
|  | 
 | ||||||
|  | 		dprintln("Initializing USB {H}.{H} device on slot {}", | ||||||
|  | 			root_port.revision_major, | ||||||
|  | 			root_port.revision_minor, | ||||||
|  | 			slot_id | ||||||
|  | 		); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | 		const XHCIDevice::Info info { | ||||||
|  | 			.speed_class = speed_class, | ||||||
|  | 			.slot_id = slot_id, | ||||||
|  | 			.route_string = route_string, | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		m_slots[slot_id - 1] = TRY(XHCIDevice::create(*this, info)); | ||||||
| 		if (auto ret = m_slots[slot_id - 1]->initialize(); ret.is_error()) | 		if (auto ret = m_slots[slot_id - 1]->initialize(); ret.is_error()) | ||||||
| 		{ | 		{ | ||||||
| 			dwarnln("Could not initialize device on slot {}: {}", slot_id, ret.error()); | 			dwarnln("Could not initialize device on slot {}: {}", slot_id, ret.error()); | ||||||
|  | @ -403,9 +417,13 @@ namespace Kernel | ||||||
| 			return ret.release_error(); | 			return ret.release_error(); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		my_port.slot_id = slot_id; | #if DEBUG_XHCI | ||||||
| 
 | 		dprintln("USB {H}.{H} device on slot {} initialized", | ||||||
| 		dprintln_if(DEBUG_XHCI, "device on slot {} initialized", slot_id); | 			root_port.revision_major, | ||||||
|  | 			root_port.revision_minor, | ||||||
|  | 			slot_id | ||||||
|  | 		); | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
| 		return slot_id; | 		return slot_id; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -8,35 +8,32 @@ | ||||||
| namespace Kernel | namespace Kernel | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
| 	BAN::ErrorOr<BAN::UniqPtr<XHCIDevice>> XHCIDevice::create(XHCIController& controller, uint32_t port_id, uint32_t slot_id) | 	BAN::ErrorOr<BAN::UniqPtr<XHCIDevice>> XHCIDevice::create(XHCIController& controller, const Info& info) | ||||||
| 	{ | 	{ | ||||||
| 		return TRY(BAN::UniqPtr<XHCIDevice>::create(controller, port_id, slot_id)); | 		return TRY(BAN::UniqPtr<XHCIDevice>::create(controller, info)); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	XHCIDevice::XHCIDevice(XHCIController& controller, uint32_t port_id, uint32_t slot_id) | 	XHCIDevice::XHCIDevice(XHCIController& controller, const Info& info) | ||||||
| 		: USBDevice(controller.speed_id_to_class((controller.operational_regs().ports[port_id - 1].portsc >> XHCI::PORTSC::PORT_SPEED_SHIFT) & XHCI::PORTSC::PORT_SPEED_MASK)) | 		: USBDevice(info.speed_class) | ||||||
| 		, m_controller(controller) | 		, m_controller(controller) | ||||||
| 		, m_port_id(port_id) | 		, m_info(info) | ||||||
| 		, m_slot_id(slot_id) |  | ||||||
| 	{} | 	{} | ||||||
| 
 | 
 | ||||||
| 	XHCIDevice::~XHCIDevice() | 	XHCIDevice::~XHCIDevice() | ||||||
| 	{ | 	{ | ||||||
| 		XHCI::TRB disable_slot { .disable_slot_command {} }; | 		XHCI::TRB disable_slot { .disable_slot_command {} }; | ||||||
| 		disable_slot.disable_slot_command.trb_type = XHCI::TRBType::DisableSlotCommand; | 		disable_slot.disable_slot_command.trb_type = XHCI::TRBType::DisableSlotCommand; | ||||||
| 		disable_slot.disable_slot_command.slot_id = m_slot_id; | 		disable_slot.disable_slot_command.slot_id = m_info.slot_id; | ||||||
| 		if (auto ret = m_controller.send_command(disable_slot); ret.is_error()) | 		if (auto ret = m_controller.send_command(disable_slot); ret.is_error()) | ||||||
| 			dwarnln("Could not disable slot {}: {}", m_slot_id, ret.error()); | 			dwarnln("Could not disable slot {}: {}", m_info.slot_id, ret.error()); | ||||||
| 		else | 		else | ||||||
| 			dprintln_if(DEBUG_XHCI, "Slot {} disabled", m_slot_id); | 			dprintln_if(DEBUG_XHCI, "Slot {} disabled", m_info.slot_id); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	BAN::ErrorOr<void> XHCIDevice::initialize_control_endpoint() | 	BAN::ErrorOr<void> XHCIDevice::initialize_control_endpoint() | ||||||
| 	{ | 	{ | ||||||
| 		const uint32_t context_size = m_controller.context_size_set() ? 64 : 32; | 		const uint32_t context_size = m_controller.context_size_set() ? 64 : 32; | ||||||
| 
 | 
 | ||||||
| 		const uint32_t portsc = m_controller.operational_regs().ports[m_port_id - 1].portsc; |  | ||||||
| 		const uint32_t speed_id = (portsc >> XHCI::PORTSC::PORT_SPEED_SHIFT) & XHCI::PORTSC::PORT_SPEED_MASK; |  | ||||||
| 
 | 
 | ||||||
| 		m_endpoints[0].max_packet_size = 0; | 		m_endpoints[0].max_packet_size = 0; | ||||||
| 		switch (m_speed_class) | 		switch (m_speed_class) | ||||||
|  | @ -68,25 +65,27 @@ namespace Kernel | ||||||
| 			auto& slot_context          = *reinterpret_cast<XHCI::SlotContext*>        (m_input_context->vaddr() + 1 * context_size); | 			auto& slot_context          = *reinterpret_cast<XHCI::SlotContext*>        (m_input_context->vaddr() + 1 * context_size); | ||||||
| 			auto& endpoint0_context     = *reinterpret_cast<XHCI::EndpointContext*>    (m_input_context->vaddr() + 2 * context_size); | 			auto& endpoint0_context     = *reinterpret_cast<XHCI::EndpointContext*>    (m_input_context->vaddr() + 2 * context_size); | ||||||
| 
 | 
 | ||||||
| 			memset(&input_control_context, 0, context_size); | 			input_control_context.add_context_flags = (1 << 1) | (1 << 0); | ||||||
| 			input_control_context.add_context_flags = 0b11; |  | ||||||
| 
 | 
 | ||||||
| 			memset(&slot_context, 0, context_size); | 			slot_context.route_string         = m_info.route_string >> 4; | ||||||
| 			slot_context.route_string         = 0; | 			slot_context.root_hub_port_number = m_info.route_string & 0x0F; | ||||||
| 			slot_context.root_hub_port_number = m_port_id; |  | ||||||
| 			slot_context.context_entries      = 1; | 			slot_context.context_entries      = 1; | ||||||
| 			slot_context.interrupter_target   = 0; | 			slot_context.interrupter_target   = 0; | ||||||
| 			slot_context.speed                = speed_id; | 			slot_context.speed                = m_controller.speed_class_to_id(m_info.speed_class); | ||||||
| 			// FIXME: 4.5.2 hub
 | 			// FIXME: 4.5.2 hub
 | ||||||
| 
 | 
 | ||||||
| 			memset(&endpoint0_context, 0, context_size); |  | ||||||
| 			endpoint0_context.endpoint_type       = XHCI::EndpointType::Control; | 			endpoint0_context.endpoint_type       = XHCI::EndpointType::Control; | ||||||
| 			endpoint0_context.max_packet_size     = m_endpoints[0].max_packet_size; | 			endpoint0_context.max_packet_size     = m_endpoints[0].max_packet_size; | ||||||
| 			endpoint0_context.error_count         = 3; | 			endpoint0_context.max_burst_size      = 0; // FIXME: SuperSpeed
 | ||||||
|  | 			endpoint0_context.interval            = 0; | ||||||
| 			endpoint0_context.tr_dequeue_pointer  = m_endpoints[0].transfer_ring->paddr() | 1; | 			endpoint0_context.tr_dequeue_pointer  = m_endpoints[0].transfer_ring->paddr() | 1; | ||||||
|  | 			endpoint0_context.max_primary_streams = 0; | ||||||
|  | 			endpoint0_context.error_count         = 3; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		m_controller.dcbaa_reg(m_slot_id) = m_output_context->paddr(); | 		m_controller.dcbaa_reg(m_info.slot_id) = m_output_context->paddr(); | ||||||
|  | 
 | ||||||
|  | 		dprintln_if(DEBUG_XHCI, "Addressing device on slot {}", m_info.slot_id); | ||||||
| 
 | 
 | ||||||
| 		for (int i = 0; i < 2; i++) | 		for (int i = 0; i < 2; i++) | ||||||
| 		{ | 		{ | ||||||
|  | @ -95,7 +94,7 @@ namespace Kernel | ||||||
| 			address_device.address_device_command.input_context_pointer     = m_input_context->paddr(); | 			address_device.address_device_command.input_context_pointer     = m_input_context->paddr(); | ||||||
| 			// NOTE: some legacy devices require sending request with BSR=1 before actual BSR=0
 | 			// NOTE: some legacy devices require sending request with BSR=1 before actual BSR=0
 | ||||||
| 			address_device.address_device_command.block_set_address_request = (i == 0); | 			address_device.address_device_command.block_set_address_request = (i == 0); | ||||||
| 			address_device.address_device_command.slot_id                   = m_slot_id; | 			address_device.address_device_command.slot_id                   = m_info.slot_id; | ||||||
| 			TRY(m_controller.send_command(address_device)); | 			TRY(m_controller.send_command(address_device)); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | @ -116,12 +115,12 @@ namespace Kernel | ||||||
| 		USBDeviceRequest request; | 		USBDeviceRequest request; | ||||||
| 		request.bmRequestType = USB::RequestType::DeviceToHost | USB::RequestType::Standard | USB::RequestType::Device; | 		request.bmRequestType = USB::RequestType::DeviceToHost | USB::RequestType::Standard | USB::RequestType::Device; | ||||||
| 		request.bRequest      = USB::Request::GET_DESCRIPTOR; | 		request.bRequest      = USB::Request::GET_DESCRIPTOR; | ||||||
| 		request.wValue        = 0x0100; | 		request.wValue        = USB::DescriptorType::DEVICE << 8; | ||||||
| 		request.wIndex        = 0; | 		request.wIndex        = 0; | ||||||
| 		request.wLength       = 8; | 		request.wLength       = 8; | ||||||
| 		TRY(send_request(request, kmalloc_paddr_of((vaddr_t)buffer.data()).value())); | 		TRY(send_request(request, kmalloc_paddr_of((vaddr_t)buffer.data()).value())); | ||||||
| 
 | 
 | ||||||
| 		const bool is_usb3 = m_controller.port(m_port_id).revision_major == 3; | 		const bool is_usb3 = (m_speed_class == USB::SpeedClass::SuperSpeed); | ||||||
| 		const uint32_t new_max_packet_size = is_usb3 ? 1u << buffer.back() : buffer.back(); | 		const uint32_t new_max_packet_size = is_usb3 ? 1u << buffer.back() : buffer.back(); | ||||||
| 
 | 
 | ||||||
| 		if (m_endpoints[0].max_packet_size == new_max_packet_size) | 		if (m_endpoints[0].max_packet_size == new_max_packet_size) | ||||||
|  | @ -133,31 +132,23 @@ namespace Kernel | ||||||
| 
 | 
 | ||||||
| 		{ | 		{ | ||||||
| 			auto& input_control_context = *reinterpret_cast<XHCI::InputControlContext*>(m_input_context->vaddr() + 0 * context_size); | 			auto& input_control_context = *reinterpret_cast<XHCI::InputControlContext*>(m_input_context->vaddr() + 0 * context_size); | ||||||
| 			auto& slot_context          = *reinterpret_cast<XHCI::SlotContext*>        (m_input_context->vaddr() + 1 * context_size); |  | ||||||
| 			auto& endpoint0_context     = *reinterpret_cast<XHCI::EndpointContext*>    (m_input_context->vaddr() + 2 * context_size); | 			auto& endpoint0_context     = *reinterpret_cast<XHCI::EndpointContext*>    (m_input_context->vaddr() + 2 * context_size); | ||||||
| 
 | 
 | ||||||
| 			memset(&input_control_context, 0, context_size); | 			memset(&input_control_context, 0, context_size); | ||||||
| 			input_control_context.add_context_flags = 0b11; | 			input_control_context.add_context_flags = (1 << 1); | ||||||
| 
 | 
 | ||||||
| 			memset(&slot_context, 0, context_size); | 			// Only update max packet size. Other fields should be fine from initial configuration
 | ||||||
| 			slot_context.max_exit_latency   = 0; // FIXME:
 | 			endpoint0_context.max_packet_size = new_max_packet_size; | ||||||
| 			slot_context.interrupter_target = 0; |  | ||||||
| 
 |  | ||||||
| 			memset(&endpoint0_context, 0, context_size); |  | ||||||
| 			endpoint0_context.endpoint_type       = XHCI::EndpointType::Control; |  | ||||||
| 			endpoint0_context.max_packet_size     = m_endpoints[0].max_packet_size; |  | ||||||
| 			endpoint0_context.error_count         = 3; |  | ||||||
| 			endpoint0_context.tr_dequeue_pointer  = m_endpoints[0].transfer_ring->paddr() | 1; |  | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		XHCI::TRB evaluate_context { .address_device_command = {} }; | 		XHCI::TRB evaluate_context { .address_device_command = {} }; | ||||||
| 		evaluate_context.address_device_command.trb_type                  = XHCI::TRBType::EvaluateContextCommand; | 		evaluate_context.address_device_command.trb_type                  = XHCI::TRBType::EvaluateContextCommand; | ||||||
| 		evaluate_context.address_device_command.input_context_pointer     = m_input_context->paddr(); | 		evaluate_context.address_device_command.input_context_pointer     = m_input_context->paddr(); | ||||||
| 		evaluate_context.address_device_command.block_set_address_request = 0; | 		evaluate_context.address_device_command.block_set_address_request = 0; | ||||||
| 		evaluate_context.address_device_command.slot_id                   = m_slot_id; | 		evaluate_context.address_device_command.slot_id                   = m_info.slot_id; | ||||||
| 		TRY(m_controller.send_command(evaluate_context)); | 		TRY(m_controller.send_command(evaluate_context)); | ||||||
| 
 | 
 | ||||||
| 		dprintln_if(DEBUG_XHCI, "successfully updated max packet size to {}", m_endpoints[0].max_packet_size); | 		dprintln_if(DEBUG_XHCI, "Updated max packet size to {}", new_max_packet_size); | ||||||
| 
 | 
 | ||||||
| 		return {}; | 		return {}; | ||||||
| 	} | 	} | ||||||
|  | @ -282,7 +273,7 @@ namespace Kernel | ||||||
| 		configure_endpoint.configure_endpoint_command.trb_type              = XHCI::TRBType::ConfigureEndpointCommand; | 		configure_endpoint.configure_endpoint_command.trb_type              = XHCI::TRBType::ConfigureEndpointCommand; | ||||||
| 		configure_endpoint.configure_endpoint_command.input_context_pointer = m_input_context->paddr(); | 		configure_endpoint.configure_endpoint_command.input_context_pointer = m_input_context->paddr(); | ||||||
| 		configure_endpoint.configure_endpoint_command.deconfigure           = 0; | 		configure_endpoint.configure_endpoint_command.deconfigure           = 0; | ||||||
| 		configure_endpoint.configure_endpoint_command.slot_id               = m_slot_id; | 		configure_endpoint.configure_endpoint_command.slot_id               = m_info.slot_id; | ||||||
| 		TRY(m_controller.send_command(configure_endpoint)); | 		TRY(m_controller.send_command(configure_endpoint)); | ||||||
| 
 | 
 | ||||||
| 		return {}; | 		return {}; | ||||||
|  | @ -455,7 +446,7 @@ namespace Kernel | ||||||
| 
 | 
 | ||||||
| 		endpoint.transfer_count = request.wLength; | 		endpoint.transfer_count = request.wLength; | ||||||
| 
 | 
 | ||||||
| 		m_controller.doorbell_reg(m_slot_id) = 1; | 		m_controller.doorbell_reg(m_info.slot_id) = 1; | ||||||
| 
 | 
 | ||||||
| 		const uint64_t timeout_ms = SystemTimer::get().ms_since_boot() + 1000; | 		const uint64_t timeout_ms = SystemTimer::get().ms_since_boot() + 1000; | ||||||
| 		while ((__atomic_load_n(&completion_trb.raw.dword2, __ATOMIC_SEQ_CST) >> 24) == 0) | 		while ((__atomic_load_n(&completion_trb.raw.dword2, __ATOMIC_SEQ_CST) >> 24) == 0) | ||||||
|  | @ -492,7 +483,7 @@ namespace Kernel | ||||||
| 		trb.normal.interrupt_on_short_packet = 1; | 		trb.normal.interrupt_on_short_packet = 1; | ||||||
| 		advance_endpoint_enqueue(endpoint, false); | 		advance_endpoint_enqueue(endpoint, false); | ||||||
| 
 | 
 | ||||||
| 		m_controller.doorbell_reg(m_slot_id) = endpoint_id; | 		m_controller.doorbell_reg(m_info.slot_id) = endpoint_id; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void XHCIDevice::advance_endpoint_enqueue(Endpoint& endpoint, bool chain) | 	void XHCIDevice::advance_endpoint_enqueue(Endpoint& endpoint, bool chain) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue