diff --git a/payloads/libpayload/drivers/usb/generic_hub.c b/payloads/libpayload/drivers/usb/generic_hub.c index d568d4b8a4..fa95969f2a 100644 --- a/payloads/libpayload/drivers/usb/generic_hub.c +++ b/payloads/libpayload/drivers/usb/generic_hub.c @@ -200,7 +200,7 @@ generic_hub_attach_dev(usbdev_t *const dev, const int port) "disabled after 10ms\n", port); } - const int speed = hub->ops->port_speed(dev, port); + const usb_speed speed = hub->ops->port_speed(dev, port); if (speed >= 0) { usb_debug("generic_hub: Success at port %d\n", port); if (hub->ops->reset_port) diff --git a/payloads/libpayload/drivers/usb/generic_hub.h b/payloads/libpayload/drivers/usb/generic_hub.h index 7be20e8a9e..cd4ebb6616 100644 --- a/payloads/libpayload/drivers/usb/generic_hub.h +++ b/payloads/libpayload/drivers/usb/generic_hub.h @@ -46,7 +46,7 @@ typedef struct generic_hub_ops { /* returns 1 if the port is enabled */ int (*port_enabled)(usbdev_t *, int port); /* returns speed if port is enabled, negative value if not */ - int (*port_speed)(usbdev_t *, int port); + usb_speed (*port_speed)(usbdev_t *, int port); /* enables (powers up) a port (optional) */ int (*enable_port)(usbdev_t *, int port); diff --git a/payloads/libpayload/drivers/usb/ohci_rh.c b/payloads/libpayload/drivers/usb/ohci_rh.c index aa44f338ec..b3bf7ef3cb 100644 --- a/payloads/libpayload/drivers/usb/ohci_rh.c +++ b/payloads/libpayload/drivers/usb/ohci_rh.c @@ -121,7 +121,7 @@ ohci_rh_scanport (usbdev_t *dev, int port) return; } - int speed = (OHCI_INST(dev->controller)->opreg->HcRhPortStatus[port] & LowSpeedDeviceAttached) != 0; + usb_speed speed = (OHCI_INST(dev->controller)->opreg->HcRhPortStatus[port] & LowSpeedDeviceAttached) != 0; RH_INST (dev)->port[port] = usb_attach_device(dev->controller, dev->address, port, speed); } diff --git a/payloads/libpayload/drivers/usb/uhci_rh.c b/payloads/libpayload/drivers/usb/uhci_rh.c index 44ba498274..5cb18b9516 100644 --- a/payloads/libpayload/drivers/usb/uhci_rh.c +++ b/payloads/libpayload/drivers/usb/uhci_rh.c @@ -133,7 +133,7 @@ uhci_rh_scanport (usbdev_t *dev, int port) uhci_rh_disable_port (dev, port); uhci_rh_enable_port (dev, port); - int speed = ((uhci_reg_read16 (dev->controller, portsc) >> 8) & 1); + usb_speed speed = ((uhci_reg_read16 (dev->controller, portsc) >> 8) & 1); RH_INST (dev)->port[offset] = usb_attach_device(dev->controller, dev->address, portsc, speed); } diff --git a/payloads/libpayload/drivers/usb/usb.c b/payloads/libpayload/drivers/usb/usb.c index 8ee997ceca..0ec6f5c69e 100644 --- a/payloads/libpayload/drivers/usb/usb.c +++ b/payloads/libpayload/drivers/usb/usb.c @@ -243,44 +243,43 @@ get_free_address (hci_t *controller) } int -generic_set_address (hci_t *controller, int speed, int hubport, int hubaddr) +usb_decode_mps0(usb_speed speed, u8 bMaxPacketSize0) { - int adr = get_free_address (controller); // address to set - dev_req_t dr; - - memset (&dr, 0, sizeof (dr)); - dr.data_dir = host_to_device; - dr.req_type = standard_type; - dr.req_recp = dev_recp; - dr.bRequest = SET_ADDRESS; - dr.wValue = adr; - dr.wIndex = 0; - dr.wLength = 0; - - init_device_entry(controller, adr); - usbdev_t *dev = controller->devices[adr]; - // dummy values for registering the address - dev->address = 0; - dev->hub = hubaddr; - dev->port = hubport; - dev->speed = speed; - dev->endpoints[0].dev = dev; - dev->endpoints[0].endpoint = 0; - dev->endpoints[0].maxpacketsize = 8; - dev->endpoints[0].toggle = 0; - dev->endpoints[0].direction = SETUP; - mdelay (50); - if (dev->controller->control (dev, OUT, sizeof (dr), &dr, 0, 0) < 0) { - return -1; + switch (speed) { + case LOW_SPEED: + if (bMaxPacketSize0 != 8) { + usb_debug("Invalid MPS0: 0x%02x\n", bMaxPacketSize0); + bMaxPacketSize0 = 8; + } + return bMaxPacketSize0; + case FULL_SPEED: + switch (bMaxPacketSize0) { + case 8: case 16: case 32: case 64: + return bMaxPacketSize0; + default: + usb_debug("Invalid MPS0: 0x%02x\n", bMaxPacketSize0); + return 8; + } + case HIGH_SPEED: + if (bMaxPacketSize0 != 64) { + usb_debug("Invalid MPS0: 0x%02x\n", bMaxPacketSize0); + bMaxPacketSize0 = 64; + } + return bMaxPacketSize0; + case SUPER_SPEED: + if (bMaxPacketSize0 != 9) { + usb_debug("Invalid MPS0: 0x%02x\n", bMaxPacketSize0); + bMaxPacketSize0 = 9; + } + return 2 << bMaxPacketSize0; + default: /* GCC is stupid and cannot deal with enums correctly */ + return 8; } - mdelay (50); - - return adr; } /* Normalize bInterval to log2 of microframes */ static int -usb_decode_interval(const int speed, const endpoint_type type, const unsigned char bInterval) +usb_decode_interval(usb_speed speed, const endpoint_type type, const unsigned char bInterval) { #define LOG2(a) ((sizeof(unsigned) << 3) - __builtin_clz(a) - 1) switch (speed) { @@ -320,8 +319,45 @@ usb_decode_interval(const int speed, const endpoint_type type, const unsigned ch #undef LOG2 } +int +generic_set_address (hci_t *controller, usb_speed speed, + int hubport, int hubaddr) +{ + int adr = get_free_address (controller); // address to set + dev_req_t dr; + + memset (&dr, 0, sizeof (dr)); + dr.data_dir = host_to_device; + dr.req_type = standard_type; + dr.req_recp = dev_recp; + dr.bRequest = SET_ADDRESS; + dr.wValue = adr; + dr.wIndex = 0; + dr.wLength = 0; + + init_device_entry(controller, adr); + usbdev_t *dev = controller->devices[adr]; + // dummy values for registering the address + dev->address = 0; + dev->hub = hubaddr; + dev->port = hubport; + dev->speed = speed; + dev->endpoints[0].dev = dev; + dev->endpoints[0].endpoint = 0; + dev->endpoints[0].maxpacketsize = 8; + dev->endpoints[0].toggle = 0; + dev->endpoints[0].direction = SETUP; + if (dev->controller->control (dev, OUT, sizeof (dr), &dr, 0, 0) < 0) { + usb_debug ("set_address failed\n"); + return -1; + } + mdelay (SET_ADDRESS_MDELAY); + + return adr; +} + static int -set_address (hci_t *controller, int speed, int hubport, int hubaddr) +set_address (hci_t *controller, usb_speed speed, int hubport, int hubaddr) { int adr = controller->set_address(controller, speed, hubport, hubaddr); if (adr < 0 || !controller->devices[adr]) { @@ -539,22 +575,19 @@ usb_detach_device(hci_t *controller, int devno) been called yet by the usb class driver */ if (controller->devices[devno]) { controller->devices[devno]->destroy (controller->devices[devno]); - if (controller->destroy_device) - controller->destroy_device(controller, devno); - if (controller->devices[devno]->configuration) - free(controller->devices[devno]->configuration); - if (controller->devices[devno]->descriptor) - free(controller->devices[devno]->descriptor); free(controller->devices[devno]); controller->devices[devno] = NULL; + if (controller->destroy_device) + controller->destroy_device(controller, devno); } } int -usb_attach_device(hci_t *controller, int hubaddress, int port, int speed) +usb_attach_device(hci_t *controller, int hubaddress, int port, usb_speed speed) { - static const char* speeds[] = { "full", "low", "high" }; - usb_debug ("%sspeed device\n", (speed <= 2) ? speeds[speed] : "invalid value - no"); + static const char* speeds[] = { "full", "low", "high", "super" }; + usb_debug ("%sspeed device\n", (speed < sizeof(speeds) / sizeof(char*)) + ? speeds[speed] : "invalid value - no"); int newdev = set_address (controller, speed, port, hubaddress); if (newdev == -1) return -1; diff --git a/payloads/libpayload/drivers/usb/usbhub.c b/payloads/libpayload/drivers/usb/usbhub.c index ff7904cbd0..503a9a8528 100644 --- a/payloads/libpayload/drivers/usb/usbhub.c +++ b/payloads/libpayload/drivers/usb/usbhub.c @@ -77,7 +77,7 @@ usb_hub_port_enabled(usbdev_t *const dev, const int port) return (buf[0] & PORT_ENABLE) != 0; } -static int +static usb_speed usb_hub_port_speed(usbdev_t *const dev, const int port) { unsigned short buf[2] = { 0, 0 }; @@ -87,6 +87,7 @@ usb_hub_port_speed(usbdev_t *const dev, const int port) * 0 0 full speed * 0 1 low speed * 1 0 high speed + * 1 1 super speed (hack, not in spec!) */ return (buf[0] >> 9) & 0x3; } else { diff --git a/payloads/libpayload/drivers/usb/xhci_devconf.c b/payloads/libpayload/drivers/usb/xhci_devconf.c index f1064f0247..2b1de3bf9e 100644 --- a/payloads/libpayload/drivers/usb/xhci_devconf.c +++ b/payloads/libpayload/drivers/usb/xhci_devconf.c @@ -30,6 +30,7 @@ //#define XHCI_SPEW_DEBUG #include +#include #include "xhci_private.h" static u32 @@ -57,7 +58,7 @@ xhci_get_rh_port(xhci_t *const xhci, const int hubport, const int hubaddr) } static int -xhci_get_tt(xhci_t *const xhci, const int xhci_speed, +xhci_get_tt(xhci_t *const xhci, const usb_speed speed, const int hubport, const int hubaddr, int *const tt, int *const tt_port) { @@ -66,8 +67,8 @@ xhci_get_tt(xhci_t *const xhci, const int xhci_speed, const slotctx_t *const slot = xhci->dev[hubaddr].ctx.slot; if ((*tt = SC_GET(TTID, slot))) { *tt_port = SC_GET(TTPORT, slot); - } else if (xhci_speed < XHCI_HIGH_SPEED && - SC_GET(SPEED, slot) == XHCI_HIGH_SPEED) { + } else if (speed < HIGH_SPEED && + SC_GET(SPEED1, slot) - 1 == HIGH_SPEED) { *tt = hubaddr; *tt_port = hubport; } @@ -75,37 +76,7 @@ xhci_get_tt(xhci_t *const xhci, const int xhci_speed, } static long -xhci_decode_mps0(const int xhci_speed, const u8 b_mps) -{ - switch (xhci_speed) { - case XHCI_LOW_SPEED: - case XHCI_FULL_SPEED: - case XHCI_HIGH_SPEED: - switch (b_mps) { - case 8: case 16: case 32: case 64: - return b_mps; - default: - xhci_debug("Invalid MPS0: 0x%02x\n", b_mps); - return 8; - } - break; - case XHCI_SUPER_SPEED: - if (b_mps == 9) { - return 2 << b_mps; - } else { - xhci_debug("Invalid MPS0: 0x%02x\n", b_mps); - return 2 << 9; - } - break; - default: - xhci_debug("Invalid speed for MPS0: %d\n", xhci_speed); - return 8; - } -} - - -static long -xhci_get_mps0(usbdev_t *const dev, const int xhci_speed) +xhci_get_mps0(usbdev_t *const dev, const int speed) { u8 buf[8]; dev_req_t dr = { @@ -121,7 +92,7 @@ xhci_get_mps0(usbdev_t *const dev, const int xhci_speed) xhci_debug("Failed to read MPS0\n"); return COMMUNICATION_ERROR; } else { - return xhci_decode_mps0(xhci_speed, buf[7]); + return usb_decode_mps0(speed, buf[7]); } } @@ -150,10 +121,9 @@ xhci_make_inputctx(const size_t ctxsize) } int -xhci_set_address (hci_t *controller, int speed, int hubport, int hubaddr) +xhci_set_address (hci_t *controller, usb_speed speed, int hubport, int hubaddr) { xhci_t *const xhci = XHCI_INST(controller); - const int xhci_speed = speed + 1; const size_t ctxsize = CTXSIZE(xhci); devinfo_t *di = NULL; @@ -188,12 +158,12 @@ xhci_set_address (hci_t *controller, int speed, int hubport, int hubaddr) *ic->add = (1 << 0) /* Slot Context */ | (1 << 1) /* EP0 Context */ ; SC_SET(ROUTE, ic->dev.slot, xhci_gen_route(xhci, hubport, hubaddr)); - SC_SET(SPEED, ic->dev.slot, xhci_speed); + SC_SET(SPEED1, ic->dev.slot, speed + 1); SC_SET(CTXENT, ic->dev.slot, 1); /* the endpoint 0 context */ SC_SET(RHPORT, ic->dev.slot, xhci_get_rh_port(xhci, hubport, hubaddr)); int tt, tt_port; - if (xhci_get_tt(xhci, xhci_speed, hubport, hubaddr, &tt, &tt_port)) { + if (xhci_get_tt(xhci, speed, hubport, hubaddr, &tt, &tt_port)) { xhci_debug("TT for %d: %d[%d]\n", slot_id, tt, tt_port); SC_SET(MTT, ic->dev.slot, SC_GET(MTT, xhci->dev[tt].ctx.slot)); SC_SET(TTID, ic->dev.slot, tt); @@ -221,13 +191,13 @@ xhci_set_address (hci_t *controller, int speed, int hubport, int hubaddr) xhci_debug("Addressed device %d (USB: %d)\n", slot_id, SC_GET(UADDR, di->ctx.slot)); } - mdelay(2); /* SetAddress() recovery interval (usb20 spec 9.2.6.3) */ + mdelay(SET_ADDRESS_MDELAY); init_device_entry(controller, slot_id); controller->devices[slot_id]->address = slot_id; const long mps0 = xhci_get_mps0( - controller->devices[slot_id], xhci_speed); + controller->devices[slot_id], speed); if (mps0 < 0) { goto _disable_return; } else if (mps0 != 8) { diff --git a/payloads/libpayload/drivers/usb/xhci_private.h b/payloads/libpayload/drivers/usb/xhci_private.h index a851d8ec57..096ed2b8af 100644 --- a/payloads/libpayload/drivers/usb/xhci_private.h +++ b/payloads/libpayload/drivers/usb/xhci_private.h @@ -44,8 +44,6 @@ #define MASK(startbit, lenbit) (((1<<(lenbit))-1)<<(startbit)) -enum { XHCI_FULL_SPEED = 1, XHCI_LOW_SPEED = 2, XHCI_HIGH_SPEED = 3, XHCI_SUPER_SPEED = 4 }; - #define TIMEOUT -1 #define CONTROLLER_ERROR -2 #define COMMUNICATION_ERROR -3 @@ -164,9 +162,9 @@ typedef transfer_ring_t command_ring_t; #define SC_ROUTE_FIELD f1 /* ROUTE - Route String */ #define SC_ROUTE_START 0 #define SC_ROUTE_LEN 20 -#define SC_SPEED_FIELD f1 -#define SC_SPEED_START 20 -#define SC_SPEED_LEN 4 +#define SC_SPEED1_FIELD f1 /* SPEED - Port speed plus one (compared to usb_speed enum) */ +#define SC_SPEED1_START 20 +#define SC_SPEED1_LEN 4 #define SC_MTT_FIELD f1 /* MTT - Multi Transaction Translator */ #define SC_MTT_START 25 #define SC_MTT_LEN 1 @@ -472,7 +470,7 @@ typedef struct xhci { void *xhci_align(const size_t min_align, const size_t size); void xhci_init_cycle_ring(transfer_ring_t *, const size_t ring_size); -int xhci_set_address (hci_t *, int speed, int hubport, int hubaddr); +int xhci_set_address (hci_t *, usb_speed speed, int hubport, int hubaddr); int xhci_finish_device_config(usbdev_t *); void xhci_destroy_dev(hci_t *, int slot_id); diff --git a/payloads/libpayload/drivers/usb/xhci_rh.c b/payloads/libpayload/drivers/usb/xhci_rh.c index ca6131f624..c4cbeeaab8 100644 --- a/payloads/libpayload/drivers/usb/xhci_rh.c +++ b/payloads/libpayload/drivers/usb/xhci_rh.c @@ -84,7 +84,7 @@ xhci_rh_port_enabled(usbdev_t *const dev, const int port) return !!(*portsc & PORTSC_PED); } -static int +static usb_speed xhci_rh_port_speed(usbdev_t *const dev, const int port) { xhci_t *const xhci = XHCI_INST(dev->controller); diff --git a/payloads/libpayload/include/usb/usb.h b/payloads/libpayload/include/usb/usb.h index 2bf1993b82..83d4a85759 100644 --- a/payloads/libpayload/include/usb/usb.h +++ b/payloads/libpayload/include/usb/usb.h @@ -59,107 +59,8 @@ typedef enum { TEST_MODE = 2 } feature_selectors; -typedef struct { - union { - struct { - dev_req_recp req_recp:5; - dev_req_type req_type:2; - dev_req_dir data_dir:1; - } __attribute__ ((packed)); - unsigned char bmRequestType; - } __attribute__ ((packed)); - unsigned char bRequest; - unsigned short wValue; - unsigned short wIndex; - unsigned short wLength; -} __attribute__ ((packed)) dev_req_t; - -struct usbdev_hc; -typedef struct usbdev_hc hci_t; - -struct usbdev; -typedef struct usbdev usbdev_t; - -typedef enum { SETUP, IN, OUT } direction_t; -typedef enum { CONTROL = 0, ISOCHRONOUS = 1, BULK = 2, INTERRUPT = 3 -} endpoint_type; - -typedef struct { - usbdev_t *dev; - int endpoint; - direction_t direction; - int toggle; - int maxpacketsize; - endpoint_type type; - int interval; /* expressed as binary logarithm of the number - of microframes (i.e. t = 125us * 2^interval) */ -} endpoint_t; - -enum { FULL_SPEED = 0, LOW_SPEED = 1, HIGH_SPEED = 2, SUPER_SPEED = 3 }; - -struct usbdev { - hci_t *controller; - endpoint_t endpoints[32]; - int num_endp; - int address; // usb address - int hub; // hub, device is attached to - int port; // port where device is attached - int speed; // 1: lowspeed, 0: fullspeed, 2: highspeed - u32 quirks; // quirks field. got to love usb - void *data; - u8 *descriptor; - u8 *configuration; - void (*init) (usbdev_t *dev); - void (*destroy) (usbdev_t *dev); - void (*poll) (usbdev_t *dev); -}; - -typedef enum { OHCI = 0, UHCI = 1, EHCI = 2, XHCI = 3} hc_type; - -struct usbdev_hc { - hci_t *next; - u32 reg_base; - pcidev_t pcidev; // 0 if not used (eg on ARM) - hc_type type; - usbdev_t *devices[128]; // dev 0 is root hub, 127 is last addressable - - /* start(): Resume operation. */ - void (*start) (hci_t *controller); - /* stop(): Stop operation but keep controller initialized. */ - void (*stop) (hci_t *controller); - /* reset(): Perform a controller reset. The controller needs to - be (re)initialized afterwards to work (again). */ - void (*reset) (hci_t *controller); - /* init(): Initialize a (previously reset) controller - to a working state. */ - void (*init) (hci_t *controller); - /* shutdown(): Stop operation, detach host controller and shutdown - this driver instance. After calling shutdown() any - other usage of this hci_t* is invalid. */ - void (*shutdown) (hci_t *controller); - - int (*bulk) (endpoint_t *ep, int size, u8 *data, int finalize); - int (*control) (usbdev_t *dev, direction_t pid, int dr_length, - void *devreq, int data_length, u8 *data); - void* (*create_intr_queue) (endpoint_t *ep, int reqsize, int reqcount, int reqtiming); - void (*destroy_intr_queue) (endpoint_t *ep, void *queue); - u8* (*poll_intr_queue) (void *queue); - void *instance; - - /* set_address(): Tell the usb device its address and - return it. xHCI controllers want to - do this by themself. Also, the usbdev - structure has to be allocated and - initialized. */ - int (*set_address) (hci_t *controller, int speed, int hubport, int hubaddr); - /* finish_device_config(): Another hook for xHCI, - returns 0 on success. */ - int (*finish_device_config) (usbdev_t *dev); - /* destroy_device(): Finally, destroy all structures that - were allocated during set_address() - and finish_device_config(). */ - void (*destroy_device) (hci_t *controller, int devaddr); -}; +/* SetAddress() recovery interval (USB 2.0 specification 9.2.6.3 */ +#define SET_ADDRESS_MDELAY 2 typedef struct { unsigned char bDescLength; @@ -240,12 +141,118 @@ typedef struct { unsigned short wReportDescriptorLength; } __attribute__ ((packed)) hid_descriptor_t; +typedef struct { + union { + struct { + dev_req_recp req_recp:5; + dev_req_type req_type:2; + dev_req_dir data_dir:1; + } __attribute__ ((packed)); + unsigned char bmRequestType; + } __attribute__ ((packed)); + unsigned char bRequest; + unsigned short wValue; + unsigned short wIndex; + unsigned short wLength; +} __attribute__ ((packed)) dev_req_t; + +struct usbdev_hc; +typedef struct usbdev_hc hci_t; + +struct usbdev; +typedef struct usbdev usbdev_t; + +typedef enum { SETUP, IN, OUT } direction_t; +typedef enum { CONTROL = 0, ISOCHRONOUS = 1, BULK = 2, INTERRUPT = 3 +} endpoint_type; + +typedef struct { + usbdev_t *dev; + int endpoint; + direction_t direction; + int toggle; + int maxpacketsize; + endpoint_type type; + int interval; /* expressed as binary logarithm of the number + of microframes (i.e. t = 125us * 2^interval) */ +} endpoint_t; + +typedef enum { + FULL_SPEED = 0, LOW_SPEED = 1, HIGH_SPEED = 2, SUPER_SPEED = 3, +} usb_speed; + +struct usbdev { + hci_t *controller; + endpoint_t endpoints[32]; + int num_endp; + int address; // usb address + int hub; // hub, device is attached to + int port; // port where device is attached + usb_speed speed; + u32 quirks; // quirks field. got to love usb + void *data; + u8 *descriptor; + u8 *configuration; + void (*init) (usbdev_t *dev); + void (*destroy) (usbdev_t *dev); + void (*poll) (usbdev_t *dev); +}; + +typedef enum { OHCI = 0, UHCI = 1, EHCI = 2, XHCI = 3} hc_type; + +struct usbdev_hc { + hci_t *next; + u32 reg_base; + pcidev_t pcidev; // 0 if not used (eg on ARM) + hc_type type; + usbdev_t *devices[128]; // dev 0 is root hub, 127 is last addressable + + /* start(): Resume operation. */ + void (*start) (hci_t *controller); + /* stop(): Stop operation but keep controller initialized. */ + void (*stop) (hci_t *controller); + /* reset(): Perform a controller reset. The controller needs to + be (re)initialized afterwards to work (again). */ + void (*reset) (hci_t *controller); + /* init(): Initialize a (previously reset) controller + to a working state. */ + void (*init) (hci_t *controller); + /* shutdown(): Stop operation, detach host controller and shutdown + this driver instance. After calling shutdown() any + other usage of this hci_t* is invalid. */ + void (*shutdown) (hci_t *controller); + + int (*bulk) (endpoint_t *ep, int size, u8 *data, int finalize); + int (*control) (usbdev_t *dev, direction_t pid, int dr_length, + void *devreq, int data_length, u8 *data); + void* (*create_intr_queue) (endpoint_t *ep, int reqsize, int reqcount, int reqtiming); + void (*destroy_intr_queue) (endpoint_t *ep, void *queue); + u8* (*poll_intr_queue) (void *queue); + void *instance; + + /* set_address(): Tell the usb device its address and + return it. xHCI controllers want to + do this by themself. Also, the usbdev + structure has to be allocated and + initialized. */ + int (*set_address) (hci_t *controller, usb_speed speed, + int hubport, int hubaddr); + /* finish_device_config(): Another hook for xHCI, + returns 0 on success. */ + int (*finish_device_config) (usbdev_t *dev); + /* destroy_device(): Finally, destroy all structures that + were allocated during set_address() + and finish_device_config(). */ + void (*destroy_device) (hci_t *controller, int devaddr); +}; + hci_t *usb_add_mmio_hc(hc_type type, void *bar); hci_t *new_controller (void); void detach_controller (hci_t *controller); void usb_poll (void); void init_device_entry (hci_t *controller, int num); +int usb_decode_mps0 (usb_speed speed, u8 bMaxPacketSize0); void set_feature (usbdev_t *dev, int endp, int feature, int rtype); void get_status (usbdev_t *dev, int endp, int rtype, int len, void *data); void set_configuration (usbdev_t *dev); @@ -268,10 +275,12 @@ gen_bmRequestType (dev_req_dir dir, dev_req_type type, dev_req_recp recp) } /* default "set address" handler */ -int generic_set_address (hci_t *controller, int speed, int hubport, int hubaddr); +int generic_set_address (hci_t *controller, usb_speed speed, + int hubport, int hubaddr); void usb_detach_device(hci_t *controller, int devno); -int usb_attach_device(hci_t *controller, int hubaddress, int port, int speed); +int usb_attach_device(hci_t *controller, int hubaddress, int port, + usb_speed speed); u32 usb_quirk_check(u16 vendor, u16 device); int usb_interface_check(u16 vendor, u16 device);