From 195ef597f5347d29a75eacad3f674bf635e791e5 Mon Sep 17 00:00:00 2001 From: Christian Gmeiner Date: Tue, 28 Aug 2007 20:29:28 +0000 Subject: [PATCH] Add support for full and highspeed in stack and drivers. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@14492 a1c6a512-1295-4272-9138-f99709370657 --- firmware/drivers/usb/arcotg_dcd.c | 37 ++++---- firmware/drivers/usb/arcotg_dcd.h | 2 +- firmware/usbstack/controller.h | 6 +- firmware/usbstack/core/epsetup.c | 19 +---- firmware/usbstack/drivers/device/usb_serial.c | 56 ++++++++---- .../usbstack/drivers/device/usb_storage.c | 85 +++++++++++++------ .../usbstack/drivers/device/usb_storage.h | 1 + 7 files changed, 121 insertions(+), 85 deletions(-) diff --git a/firmware/drivers/usb/arcotg_dcd.c b/firmware/drivers/usb/arcotg_dcd.c index 09e71fee41..c85b4ba374 100644 --- a/firmware/drivers/usb/arcotg_dcd.c +++ b/firmware/drivers/usb/arcotg_dcd.c @@ -197,12 +197,6 @@ void usb_arcotg_dcd_start(void) { logf("start"); - if (arcotg_dcd.device_driver != NULL) { - logf("YEEEEEEESSSSSSS"); - } else { - logf("NOOOOOO"); - } - /* clear stopped bit */ dcd_controller.stopped = false; @@ -461,7 +455,7 @@ static void reset_int(void) /*-------------------------------------------------------------------------*/ /* usb controller ops */ -int usb_arcotg_dcd_enable(struct usb_ep* ep) +int usb_arcotg_dcd_enable(struct usb_ep* ep, struct usb_endpoint_descriptor* desc) { unsigned short max = 0; unsigned char mult = 0, zlt = 0; @@ -473,14 +467,12 @@ int usb_arcotg_dcd_enable(struct usb_ep* ep) return -EINVAL; } - logf("ahhh %d", ep->desc->wMaxPacketSize); - max = ep->desc->wMaxPacketSize; + max = desc->wMaxPacketSize; retval = -EINVAL; /* check the max package size validate for this endpoint */ - /* Refer to USB2.0 spec table 9-13, - */ - switch (ep->desc->bmAttributes & 0x03) { + /* Refer to USB2.0 spec table 9-13. */ + switch (desc->bmAttributes & 0x03) { case USB_ENDPOINT_XFER_BULK: zlt = 1; break; @@ -493,6 +485,7 @@ int usb_arcotg_dcd_enable(struct usb_ep* ep) break; case USB_ENDPOINT_XFER_CONTROL: + zlt = 1; break; } @@ -599,28 +592,32 @@ int usb_arcotg_dcd_enable(struct usb_ep* ep) + } #endif + /* set address of used ep in desc */ + desc->bEndpointAddress |= ep->ep_num; + /* here initialize variable of ep */ ep->maxpacket = max; + ep->desc = desc; /* hardware special operation */ /* Init EPx Queue Head (Ep Capabilites field in QH * according to max, zlt, mult) */ qh_init(ep->ep_num, - (ep->desc->bEndpointAddress & USB_DIR_IN) ? USB_RECV : USB_SEND, - (unsigned char) (ep->desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK), + (desc->bEndpointAddress & USB_DIR_IN) ? USB_RECV : USB_SEND, + (unsigned char) (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK), max, zlt, mult); /* Init endpoint x at here */ - ep_setup(ep->ep_num, - (unsigned char)((ep->desc->bEndpointAddress & USB_DIR_IN) ? USB_RECV : USB_SEND), - (unsigned char)(ep->desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)); + ep_setup(ep->ep_num, + (unsigned char)(desc->bEndpointAddress & USB_DIR_IN) ? USB_RECV : USB_SEND, + (unsigned char)(desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)); /* Now HW will be NAKing transfers to that EP, * until a buffer is queued to it. */ retval = 0; - switch (ep->desc->bmAttributes & 0x03) { + switch (desc->bmAttributes & 0x03) { case USB_ENDPOINT_XFER_BULK: val = "bulk"; break; @@ -638,8 +635,8 @@ int usb_arcotg_dcd_enable(struct usb_ep* ep) logf("ep num %d", (int)ep->ep_num); logf("enabled %s (ep%d%s-%s)", ep->name, - ep->desc->bEndpointAddress & 0x0f, - (ep->desc->bEndpointAddress & USB_DIR_IN) ? "in" : "out", val); + desc->bEndpointAddress & 0x0f, + (desc->bEndpointAddress & USB_DIR_IN) ? "in" : "out", val); logf(" maxpacket %d", max); return retval; diff --git a/firmware/drivers/usb/arcotg_dcd.h b/firmware/drivers/usb/arcotg_dcd.h index 2e6f71ef94..6c5f5739d5 100644 --- a/firmware/drivers/usb/arcotg_dcd.h +++ b/firmware/drivers/usb/arcotg_dcd.h @@ -146,7 +146,7 @@ void usb_arcotg_dcd_start(void); void usb_arcotg_dcd_stop(void); /* usb controller ops */ -int usb_arcotg_dcd_enable(struct usb_ep* ep); +int usb_arcotg_dcd_enable(struct usb_ep* ep, struct usb_endpoint_descriptor* desc); int usb_arcotg_dcd_disable(struct usb_ep* ep); int usb_arcotg_dcd_set_halt(struct usb_ep* ep, bool halt); int usb_arcotg_dcd_send(struct usb_ep* ep, struct usb_response* request); diff --git a/firmware/usbstack/controller.h b/firmware/usbstack/controller.h index d626899f70..4e742035e6 100644 --- a/firmware/usbstack/controller.h +++ b/firmware/usbstack/controller.h @@ -38,14 +38,14 @@ struct usb_controller { struct usb_dcd_controller_ops { /* endpoint management */ - int (*enable)(struct usb_ep* ep); + int (*enable)(struct usb_ep* ep, struct usb_endpoint_descriptor* desc); int (*disable)(struct usb_ep* ep); int (*set_halt)(struct usb_ep* ep, bool hald); - + /* transmitting */ int (*send)(struct usb_ep* ep, struct usb_response* req); int (*receive)(struct usb_ep* ep, struct usb_response* res); - + /* ep0 */ struct usb_ep* ep0; }; diff --git a/firmware/usbstack/core/epsetup.c b/firmware/usbstack/core/epsetup.c index 338285e8c3..702108a1cb 100644 --- a/firmware/usbstack/core/epsetup.c +++ b/firmware/usbstack/core/epsetup.c @@ -164,23 +164,6 @@ static int ep_matches(struct usb_ep* ep, struct usb_endpoint_descriptor* desc) } /* MATCH!! */ - - /* report address */ - desc->bEndpointAddress |= ep->ep_num; - - /* report (variable) full speed bulk maxpacket */ - if (type == USB_ENDPOINT_XFER_BULK) { - int size = max; - - /* min() doesn't work on bitfields with gcc-3.5 */ - if (size > 64) { - size = 64; - } - desc->wMaxPacketSize = size; - } - - /* save desc in endpoint */ - ep->desc = desc; - + return 1; } diff --git a/firmware/usbstack/drivers/device/usb_serial.c b/firmware/usbstack/drivers/device/usb_serial.c index 7750ccb8b7..7299dc6765 100644 --- a/firmware/usbstack/drivers/device/usb_serial.c +++ b/firmware/usbstack/drivers/device/usb_serial.c @@ -81,7 +81,7 @@ static struct usb_interface_descriptor serial_bulk_interface_desc = { .iInterface = GS_DATA_STR_ID, }; -static struct usb_endpoint_descriptor serial_fullspeed_in_desc = { +static struct usb_endpoint_descriptor serial_fs_in_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = USB_DIR_IN, @@ -89,7 +89,7 @@ static struct usb_endpoint_descriptor serial_fullspeed_in_desc = { .wMaxPacketSize = 8, }; -static struct usb_endpoint_descriptor serial_fullspeed_out_desc = { +static struct usb_endpoint_descriptor serial_fs_out_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = USB_DIR_OUT, @@ -110,10 +110,34 @@ static struct usb_qualifier_descriptor serial_qualifier_desc = { .bNumConfigurations = 1, }; -struct usb_descriptor_header *serial_bulk_fullspeed_function[] = { +struct usb_descriptor_header *serial_fs_function[] = { (struct usb_descriptor_header *) &serial_bulk_interface_desc, - (struct usb_descriptor_header *) &serial_fullspeed_in_desc, - (struct usb_descriptor_header *) &serial_fullspeed_out_desc, + (struct usb_descriptor_header *) &serial_fs_in_desc, + (struct usb_descriptor_header *) &serial_fs_out_desc, + NULL, +}; + +/* USB 2.0 */ +static struct usb_endpoint_descriptor serial_hs_in_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = 512, +}; + +static struct usb_endpoint_descriptor serial_hs_out_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = 512, +}; + +struct usb_descriptor_header *serial_hs_function[] = { + (struct usb_descriptor_header *) &serial_bulk_interface_desc, + (struct usb_descriptor_header *) &serial_hs_in_desc, + (struct usb_descriptor_header *) &serial_hs_out_desc, NULL, }; @@ -126,11 +150,11 @@ struct usb_response res; static int config_buf(uint8_t *buf, uint8_t type, unsigned index); static int set_config(int config); - struct device { struct usb_ep* in; struct usb_ep* out; uint32_t used_config; + struct usb_descriptor_header** descriptors; }; static struct device dev; @@ -153,14 +177,14 @@ void usb_serial_driver_bind(void* controler_ops) /* serach and asign endpoints */ usb_ep_autoconfig_reset(); - dev.in = usb_ep_autoconfig(&serial_fullspeed_in_desc); + dev.in = usb_ep_autoconfig(&serial_fs_in_desc); if (!dev.in) { goto autoconf_fail; } dev.in->claimed = true; logf("usb serial: in: %s", dev.in->name); - dev.out = usb_ep_autoconfig(&serial_fullspeed_out_desc); + dev.out = usb_ep_autoconfig(&serial_fs_out_desc); if (!dev.out) { goto autoconf_fail; } @@ -180,7 +204,7 @@ void usb_serial_driver_bind(void* controler_ops) return; autoconf_fail: - logf("failed to find endpoiunts"); + logf("failed to find endpoints"); } int usb_serial_driver_request(struct usb_ctrlrequest* request) @@ -252,15 +276,13 @@ int usb_serial_driver_request(struct usb_ctrlrequest* request) void usb_serial_driver_speed(enum usb_device_speed speed) { switch (speed) { - case USB_SPEED_LOW: - case USB_SPEED_FULL: - logf("usb serial: using fullspeed"); - break; case USB_SPEED_HIGH: logf("usb serial: using highspeed"); + dev.descriptors = serial_hs_function; break; default: - logf("speed: hmm"); + logf("usb serial: using fullspeed"); + dev.descriptors = serial_fs_function; break; } } @@ -274,7 +296,7 @@ static int config_buf(uint8_t *buf, uint8_t type, unsigned index) /* TODO check index*/ - len = usb_stack_configdesc(&serial_bulk_config_desc, buf, BUFFER_SIZE, serial_bulk_fullspeed_function); + len = usb_stack_configdesc(&serial_bulk_config_desc, buf, BUFFER_SIZE, dev.descriptors); if (len < 0) { return len; } @@ -288,9 +310,9 @@ static int set_config(int config) /* enable endpoints */ logf("setup %s", dev.in->name); - ops->enable(dev.in); + ops->enable(dev.in, (struct usb_endpoint_descriptor*)dev.descriptors[1]); logf("setup %s", dev.out->name); - ops->enable(dev.out); + ops->enable(dev.out, (struct usb_endpoint_descriptor*)dev.descriptors[2]); /* store config */ logf("using config %d", config); diff --git a/firmware/usbstack/drivers/device/usb_storage.c b/firmware/usbstack/drivers/device/usb_storage.c index 38c2b97eb0..3db379c1df 100644 --- a/firmware/usbstack/drivers/device/usb_storage.c +++ b/firmware/usbstack/drivers/device/usb_storage.c @@ -31,17 +31,9 @@ struct usb_device_driver usb_storage_driver = { .request = usb_storage_driver_request, .suspend = NULL, .resume = NULL, - .speed = NULL, + .speed = usb_storage_driver_speed, }; -struct device { - struct usb_ep* in; - struct usb_ep* out; - struct usb_ep* intr; -}; - -static struct device dev; - /*-------------------------------------------------------------------------*/ #define PROTO_BULK 0x50 // Bulk only @@ -92,8 +84,31 @@ static struct usb_interface_descriptor storage_interface_desc = { .iInterface = 0, }; -/* endpoint I -> bulk in */ -static struct usb_endpoint_descriptor storage_bulk_in_desc = { +static struct usb_endpoint_descriptor storage_fs_bulk_in_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = 64, +}; + +static struct usb_endpoint_descriptor storage_fs_bulk_out_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = USB_DIR_OUT, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = 64, +}; + +struct usb_descriptor_header *storage_fs_function[] = { + (struct usb_descriptor_header *) &storage_interface_desc, + (struct usb_descriptor_header *) &storage_fs_bulk_in_desc, + (struct usb_descriptor_header *) &storage_fs_bulk_out_desc, + NULL, +}; + +/* USB 2.0 */ +static struct usb_endpoint_descriptor storage_hs_bulk_in_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = USB_DIR_IN, @@ -101,8 +116,7 @@ static struct usb_endpoint_descriptor storage_bulk_in_desc = { .wMaxPacketSize = 512, }; -/* endpoint II -> bulk out */ -static struct usb_endpoint_descriptor storage_bulk_out_desc = { +static struct usb_endpoint_descriptor storage_hs_bulk_out_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = USB_DIR_OUT, @@ -110,10 +124,10 @@ static struct usb_endpoint_descriptor storage_bulk_out_desc = { .wMaxPacketSize = 512, }; -struct usb_descriptor_header *storage_fullspeed_function[] = { +struct usb_descriptor_header *storage_hs_function[] = { (struct usb_descriptor_header *) &storage_interface_desc, - (struct usb_descriptor_header *) &storage_bulk_in_desc, - (struct usb_descriptor_header *) &storage_bulk_out_desc, + (struct usb_descriptor_header *) &storage_hs_bulk_in_desc, + (struct usb_descriptor_header *) &storage_hs_bulk_out_desc, NULL, }; @@ -126,6 +140,15 @@ struct usb_response res; static int config_buf(uint8_t *buf, uint8_t type, unsigned index); static int set_config(int config); +struct device { + struct usb_ep* in; + struct usb_ep* out; + struct usb_ep* intr; + struct usb_descriptor_header** descriptors; +}; + +static struct device dev; + /*-------------------------------------------------------------------------*/ void usb_storage_driver_init(void) @@ -144,14 +167,14 @@ void usb_storage_driver_bind(void* controler_ops) /* serach and asign endpoints */ usb_ep_autoconfig_reset(); - dev.in = usb_ep_autoconfig(&storage_bulk_in_desc); + dev.in = usb_ep_autoconfig(&storage_fs_bulk_in_desc); if (!dev.in) { goto autoconf_fail; } dev.in->claimed = true; logf("usb storage: in: %s", dev.in->name); - dev.out = usb_ep_autoconfig(&storage_bulk_out_desc); + dev.out = usb_ep_autoconfig(&storage_fs_bulk_out_desc); if (!dev.out) { goto autoconf_fail; } @@ -234,6 +257,20 @@ int usb_storage_driver_request(struct usb_ctrlrequest* request) return ret; } +void usb_storage_driver_speed(enum usb_device_speed speed) +{ + switch (speed) { + case USB_SPEED_HIGH: + logf("usb storage: using highspeed"); + dev.descriptors = storage_hs_function; + break; + default: + logf("usb storage: using fullspeed"); + dev.descriptors = storage_fs_function; + break; + } +} + /*-------------------------------------------------------------------------*/ /* S/GET CONFIGURATION helpers */ @@ -241,12 +278,8 @@ static int config_buf(uint8_t *buf, uint8_t type, unsigned index) { int len; - /* only one configuration */ - if (index != 0) { - return -EINVAL; - } - - len = usb_stack_configdesc(&storage_config_desc, buf, BUFFER_SIZE, storage_fullspeed_function); + len = usb_stack_configdesc(&storage_config_desc, buf, BUFFER_SIZE, dev.descriptors); + logf("result %d", len); if (len < 0) { return len; } @@ -258,9 +291,9 @@ static int set_config(int config) { /* enable endpoints */ logf("setup %s", dev.in->name); - ops->enable(dev.in); + ops->enable(dev.in, (struct usb_endpoint_descriptor*)dev.descriptors[1]); logf("setup %s", dev.out->name); - ops->enable(dev.out); + ops->enable(dev.out, (struct usb_endpoint_descriptor*)dev.descriptors[2]); /* setup buffers */ diff --git a/firmware/usbstack/drivers/device/usb_storage.h b/firmware/usbstack/drivers/device/usb_storage.h index f148d4228c..ff4b187064 100644 --- a/firmware/usbstack/drivers/device/usb_storage.h +++ b/firmware/usbstack/drivers/device/usb_storage.h @@ -27,5 +27,6 @@ void usb_storage_driver_init(void); void usb_storage_driver_bind(void* controller_ops); int usb_storage_driver_request(struct usb_ctrlrequest* req); +void usb_storage_driver_speed(enum usb_device_speed speed); #endif /*_STORGAGE_H_*/