usb: Start finalizing work on OHCI
This commit is contained in:
@@ -24,6 +24,33 @@ extern "C" {
|
||||
|
||||
typedef struct usb_t usb_t;
|
||||
|
||||
/* USB endpoint device struct. Incomplete and unused. */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t vendor_id;
|
||||
uint16_t device_id;
|
||||
|
||||
/* Reads from endpoint. Non-zero value indicates error. */
|
||||
uint8_t (*device_in)(void* priv, uint8_t* data, uint32_t len);
|
||||
/* Writes to endpoint. Non-zero value indicates error. */
|
||||
uint8_t (*device_out)(void* priv, uint8_t* data, uint32_t len);
|
||||
/* Process setup packets. */
|
||||
uint8_t (*device_setup)(void* priv, uint8_t* data);
|
||||
/* Device reset. */
|
||||
void (*device_reset)(void* priv);
|
||||
/* Get address. */
|
||||
uint8_t (*device_get_address)(void* priv);
|
||||
|
||||
void* priv;
|
||||
} usb_device_t;
|
||||
|
||||
enum usb_bus_types
|
||||
{
|
||||
USB_BUS_OHCI = 0,
|
||||
USB_BUS_UHCI,
|
||||
USB_BUS_MAX
|
||||
};
|
||||
|
||||
/* USB device creation parameters struct */
|
||||
typedef struct
|
||||
{
|
||||
@@ -52,6 +79,8 @@ typedef struct usb_t
|
||||
pc_timer_t ohci_frame_timer;
|
||||
pc_timer_t ohci_port_reset_timer[2];
|
||||
uint8_t ohci_interrupt_counter : 3;
|
||||
usb_device_t* ohci_devices[2];
|
||||
usb_device_t* uhci_devices[2];
|
||||
|
||||
usb_params_t* usb_params;
|
||||
} usb_t;
|
||||
@@ -79,30 +108,6 @@ typedef struct
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
/* USB endpoint device struct. Incomplete and unused. */
|
||||
typedef struct
|
||||
{
|
||||
uint16_t vendor_id;
|
||||
uint16_t device_id;
|
||||
|
||||
/* Reads from endpoint. Non-zero value indicates error. */
|
||||
uint8_t (*device_in)(void* priv, uint8_t* data, uint32_t len);
|
||||
/* Writes to endpoint. Non-zero value indicates error. */
|
||||
uint8_t (*device_out)(void* priv, uint8_t* data, uint32_t len);
|
||||
/* Process setup packets. */
|
||||
uint8_t (*device_setup)(void* priv, uint8_t* data);
|
||||
/* Device reset */
|
||||
void (*device_reset)(void* priv);
|
||||
|
||||
void* priv;
|
||||
} usb_device_t;
|
||||
|
||||
enum usb_bus_types
|
||||
{
|
||||
USB_BUS_OHCI = 0,
|
||||
USB_BUS_UHCI = 1
|
||||
};
|
||||
|
||||
/* Global variables. */
|
||||
extern const device_t usb_device;
|
||||
|
||||
|
75
src/usb.c
75
src/usb.c
@@ -371,12 +371,85 @@ ohci_set_interrupt(usb_t *dev, uint8_t bit)
|
||||
ohci_update_irq(dev);
|
||||
}
|
||||
|
||||
/* Next two functions ported over from QEMU. */
|
||||
static int ohci_copy_td_input(usb_t* dev, usb_td_t *td,
|
||||
uint8_t *buf, int len)
|
||||
{
|
||||
uint32_t ptr, n;
|
||||
|
||||
ptr = td->CBP;
|
||||
n = 0x1000 - (ptr & 0xfff);
|
||||
if (n > len) {
|
||||
n = len;
|
||||
}
|
||||
dma_bm_write(ptr, buf, n, 1);
|
||||
if (n == len) {
|
||||
return 0;
|
||||
}
|
||||
ptr = td->BE & ~0xfffu;
|
||||
buf += n;
|
||||
dma_bm_write(ptr, buf, len - n, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ohci_copy_td_output(usb_t* dev, usb_td_t *td,
|
||||
uint8_t *buf, int len)
|
||||
{
|
||||
uint32_t ptr, n;
|
||||
|
||||
ptr = td->CBP;
|
||||
n = 0x1000 - (ptr & 0xfff);
|
||||
if (n > len) {
|
||||
n = len;
|
||||
}
|
||||
dma_bm_read(ptr, buf, n, 1);
|
||||
if (n == len) {
|
||||
return 0;
|
||||
}
|
||||
ptr = td->BE & ~0xfffu;
|
||||
buf += n;
|
||||
dma_bm_read(ptr, buf, len - n, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
ohci_service_transfer_desc(usb_t* dev, usb_ed_t* endpoint_desc)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
uint8_t
|
||||
ohci_service_endpoint_desc(usb_t* dev, uint32_t head)
|
||||
{
|
||||
usb_ed_t endpoint_desc;
|
||||
uint8_t active = 0;
|
||||
uint32_t next = 0;
|
||||
uint32_t cur = 0;
|
||||
uint32_t limit_counter = 0;
|
||||
|
||||
return 0;
|
||||
if (head == 0)
|
||||
return 0;
|
||||
|
||||
for (cur = head; cur && limit_counter++ < ENDPOINT_DESC_LIMIT; cur = next) {
|
||||
dma_bm_read(cur, (uint8_t*)&endpoint_desc, sizeof(usb_ed_t), 4);
|
||||
|
||||
next = endpoint_desc.NextED & ~(0xFu);
|
||||
|
||||
if (endpoint_desc.flags.Skip || endpoint_desc.flags_2.Halted)
|
||||
continue;
|
||||
|
||||
if (endpoint_desc.flags.Format) {
|
||||
fatal("OHCI: Isochronous transfers not implemented!\n");
|
||||
}
|
||||
|
||||
while ((endpoint_desc.HeadP & ~(0xFu)) != endpoint_desc.TailP) {
|
||||
ohci_service_transfer_desc(dev, &endpoint_desc);
|
||||
}
|
||||
|
||||
dma_bm_write(cur, (uint8_t*)&endpoint_desc, sizeof(usb_ed_t), 4);
|
||||
}
|
||||
|
||||
return active;
|
||||
}
|
||||
|
||||
void
|
||||
|
Reference in New Issue
Block a user