diff --git a/src/add-ons/kernel/busses/usb/ohci.h b/src/add-ons/kernel/busses/usb/ohci.h index 9c48da1a7c..59ce46c090 100644 --- a/src/add-ons/kernel/busses/usb/ohci.h +++ b/src/add-ons/kernel/busses/usb/ohci.h @@ -48,6 +48,17 @@ typedef struct hcd_soft_itransfer #define OHCI_NUMBER_OF_ENDPOINTS (2 * OHCI_NUMBER_OF_INTERRUPTS - 1) +// Note: the controller returns only the physical +// address of the first processed descriptor of +// an heterogeneous list (isochronous + generic). Unfortunately +// we don't have a way to know whether the descriptor is +// generic or isochronous, either way to translate the address back to +// kernel address. The physical address is used as the hash value. +// (Kindly borrowed from *BSD) + +#define OHCI_HASH_SIZE 128 +#define HASH(x) (((x) >> 4) % OHCI_HASH_SIZE) + class OHCI : public BusManager { @@ -128,9 +139,21 @@ static int32 _FinishThread(void *data); iovec *vector, size_t vectorCount); - // OHCI needs this function - addr_t _LogicalAddress(addr_t physical); - bool _IsIsochronous(addr_t logical); + // Hash tables related methods + void _AddDescriptorToHash( + ohci_general_td *descriptor); + void _RemoveDescriptorFromHash( + addr_t physicalAddress); + ohci_general_td *_FindDescriptorInHash( + addr_t physicalAddress); + + void _AddIsoDescriptorToHash( + ohci_isochronous_td *descriptor); + void _RemoveIsoDescriptorFromHash( + addr_t physicalAddress); + ohci_isochronous_td *_FindIsoDescriptorInHash( + addr_t physicalAddress); + // Register functions inline void _WriteReg(uint32 reg, uint32 value); diff --git a/src/add-ons/kernel/busses/usb/ohci_hardware.h b/src/add-ons/kernel/busses/usb/ohci_hardware.h index c097f76d5d..ffd7c91e0b 100644 --- a/src/add-ons/kernel/busses/usb/ohci_hardware.h +++ b/src/add-ons/kernel/busses/usb/ohci_hardware.h @@ -335,16 +335,19 @@ typedef struct ohci_endpoint_descriptor typedef struct ohci_general_td { - // Hardware part + // Hardware part 16 bytes uint32 flags; // Flags field uint32 buffer_physical; // Physical buffer pointer uint32 next_physical_descriptor; // Physical pointer next descriptor uint32 last_physical_byte_address; // Physical pointer to buffer end // Software part - addr_t physical_address; // Physical pointer to this address + addr_t physical_address; // Physical address of this descriptor void *buffer_logical; // Logical pointer to the buffer void *next_logical_descriptor; // Logical pointer next descriptor size_t buffer_size; // Size of the buffer + void *endpoint; // Necessary when there is an error + void *transfer; // Pointer to the transfer + bool is_last; // Last descriptor of the transfer }; #define OHCI_BUFFER_ROUNDING 0x00040000 @@ -373,11 +376,14 @@ typedef struct ohci_general_td #define OHCI_ITD_NOFFSET 8 typedef struct ohci_isochronous_td { + // Hardware part 32 byte uint32 flags; uint32 buffer_page_byte_0; // Physical page number of byte 0 uint32 next_physical_descriptor; // Next isochronous transfer descriptor uint32 last_byte_address; // Physical buffer end uint16 offset[OHCI_ITD_NOFFSET]; // Buffer offsets + // Software part + addr_t physical_address; // Physical address of this descriptor }; #define OHCI_ITD_GET_STARTING_FRAME(x) ((x) & 0x0000ffff)