mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 12:17:35 +00:00
Kernel/USB: Implement UHCI Data structures
Implemented both Queue Heads and Transfer Descriptors. These are required to actually perform USB transactions. The UHCI driver sets up a pool of these that can be allocated when we need them. It seems some drivers have these statically allocated, so it might be worth looking into that, but for now, the simple way seems to be to allocate them on the fly as we need them, and then release them.
This commit is contained in:
parent
375d269b21
commit
a5f895d251
3 changed files with 529 additions and 12 deletions
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
||||
* Copyright (c) 2020-2021, Jesse Buhagiar <jooster669@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -26,14 +27,19 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <AK/NonnullOwnPtr.h>
|
||||
#include <Kernel/Devices/USB/UHCIDescriptorTypes.h>
|
||||
#include <Kernel/IO.h>
|
||||
#include <Kernel/PCI/Device.h>
|
||||
#include <Kernel/VM/ContiguousVMObject.h>
|
||||
|
||||
namespace Kernel::USB {
|
||||
|
||||
class UHCIController final : public PCI::Device {
|
||||
|
||||
public:
|
||||
static void detect();
|
||||
static UHCIController& the();
|
||||
virtual ~UHCIController() override;
|
||||
|
||||
void reset();
|
||||
|
@ -49,8 +55,6 @@ private:
|
|||
u16 read_frnum() { return m_io_base.offset(0x6).in<u16>(); }
|
||||
u32 read_flbaseadd() { return m_io_base.offset(0x8).in<u32>(); }
|
||||
u8 read_sofmod() { return m_io_base.offset(0xc).in<u8>(); }
|
||||
u16 read_portsc1() { return m_io_base.offset(0x10).in<u16>(); }
|
||||
u16 read_portsc2() { return m_io_base.offset(0x12).in<u16>(); }
|
||||
|
||||
void write_usbcmd(u16 value) { m_io_base.offset(0).out(value); }
|
||||
void write_usbsts(u16 value) { m_io_base.offset(0x2).out(value); }
|
||||
|
@ -58,13 +62,33 @@ private:
|
|||
void write_frnum(u16 value) { m_io_base.offset(0x6).out(value); }
|
||||
void write_flbaseadd(u32 value) { m_io_base.offset(0x8).out(value); }
|
||||
void write_sofmod(u8 value) { m_io_base.offset(0xc).out(value); }
|
||||
void write_portsc1(u16 value) { m_io_base.offset(0x10).out(value); }
|
||||
void write_portsc2(u16 value) { m_io_base.offset(0x12).out(value); }
|
||||
|
||||
virtual void handle_irq(const RegisterState&) override;
|
||||
|
||||
void create_structures();
|
||||
void setup_schedule();
|
||||
|
||||
QueueHead* allocate_queue_head() const;
|
||||
TransferDescriptor* allocate_transfer_descriptor() const;
|
||||
|
||||
private:
|
||||
IOAddress m_io_base;
|
||||
PhysicalAddress m_framelist;
|
||||
|
||||
Vector<QueueHead*> m_free_qh_pool;
|
||||
Vector<TransferDescriptor*> m_free_td_pool;
|
||||
Vector<TransferDescriptor*> m_iso_td_list;
|
||||
Vector<QueueHead*> m_interrupt_qh_list;
|
||||
|
||||
QueueHead* m_interrupt_transfer_queue;
|
||||
QueueHead* m_lowspeed_control_qh;
|
||||
QueueHead* m_fullspeed_control_qh;
|
||||
QueueHead* m_bulk_qh;
|
||||
QueueHead* m_dummy_qh; // Needed for PIIX4 hack
|
||||
|
||||
OwnPtr<Region> m_framelist;
|
||||
OwnPtr<Region> m_qh_pool;
|
||||
OwnPtr<Region> m_td_pool;
|
||||
OwnPtr<Region> m_td_buffer_region;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue