1
0
Fork 0
forked from len0rd/rockbox

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
This commit is contained in:
Christian Gmeiner 2007-08-28 20:29:28 +00:00
parent 53b183f600
commit 195ef597f5
7 changed files with 121 additions and 85 deletions

View file

@ -197,12 +197,6 @@ void usb_arcotg_dcd_start(void)
{ {
logf("start"); logf("start");
if (arcotg_dcd.device_driver != NULL) {
logf("YEEEEEEESSSSSSS");
} else {
logf("NOOOOOO");
}
/* clear stopped bit */ /* clear stopped bit */
dcd_controller.stopped = false; dcd_controller.stopped = false;
@ -461,7 +455,7 @@ static void reset_int(void)
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
/* usb controller ops */ /* 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 short max = 0;
unsigned char mult = 0, zlt = 0; unsigned char mult = 0, zlt = 0;
@ -473,14 +467,12 @@ int usb_arcotg_dcd_enable(struct usb_ep* ep)
return -EINVAL; return -EINVAL;
} }
logf("ahhh %d", ep->desc->wMaxPacketSize); max = desc->wMaxPacketSize;
max = ep->desc->wMaxPacketSize;
retval = -EINVAL; retval = -EINVAL;
/* check the max package size validate for this endpoint */ /* check the max package size validate for this endpoint */
/* Refer to USB2.0 spec table 9-13, /* Refer to USB2.0 spec table 9-13. */
*/ switch (desc->bmAttributes & 0x03) {
switch (ep->desc->bmAttributes & 0x03) {
case USB_ENDPOINT_XFER_BULK: case USB_ENDPOINT_XFER_BULK:
zlt = 1; zlt = 1;
break; break;
@ -493,6 +485,7 @@ int usb_arcotg_dcd_enable(struct usb_ep* ep)
break; break;
case USB_ENDPOINT_XFER_CONTROL: case USB_ENDPOINT_XFER_CONTROL:
zlt = 1;
break; break;
} }
@ -599,28 +592,32 @@ int usb_arcotg_dcd_enable(struct usb_ep* ep)
+ } + }
#endif #endif
/* set address of used ep in desc */
desc->bEndpointAddress |= ep->ep_num;
/* here initialize variable of ep */ /* here initialize variable of ep */
ep->maxpacket = max; ep->maxpacket = max;
ep->desc = desc;
/* hardware special operation */ /* hardware special operation */
/* Init EPx Queue Head (Ep Capabilites field in QH /* Init EPx Queue Head (Ep Capabilites field in QH
* according to max, zlt, mult) */ * according to max, zlt, mult) */
qh_init(ep->ep_num, qh_init(ep->ep_num,
(ep->desc->bEndpointAddress & USB_DIR_IN) ? USB_RECV : USB_SEND, (desc->bEndpointAddress & USB_DIR_IN) ? USB_RECV : USB_SEND,
(unsigned char) (ep->desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK), (unsigned char) (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK),
max, zlt, mult); max, zlt, mult);
/* Init endpoint x at here */ /* Init endpoint x at here */
ep_setup(ep->ep_num, ep_setup(ep->ep_num,
(unsigned char)((ep->desc->bEndpointAddress & USB_DIR_IN) ? USB_RECV : USB_SEND), (unsigned char)(desc->bEndpointAddress & USB_DIR_IN) ? USB_RECV : USB_SEND,
(unsigned char)(ep->desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)); (unsigned char)(desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK));
/* Now HW will be NAKing transfers to that EP, /* Now HW will be NAKing transfers to that EP,
* until a buffer is queued to it. */ * until a buffer is queued to it. */
retval = 0; retval = 0;
switch (ep->desc->bmAttributes & 0x03) { switch (desc->bmAttributes & 0x03) {
case USB_ENDPOINT_XFER_BULK: case USB_ENDPOINT_XFER_BULK:
val = "bulk"; val = "bulk";
break; break;
@ -638,8 +635,8 @@ int usb_arcotg_dcd_enable(struct usb_ep* ep)
logf("ep num %d", (int)ep->ep_num); logf("ep num %d", (int)ep->ep_num);
logf("enabled %s (ep%d%s-%s)", ep->name, logf("enabled %s (ep%d%s-%s)", ep->name,
ep->desc->bEndpointAddress & 0x0f, desc->bEndpointAddress & 0x0f,
(ep->desc->bEndpointAddress & USB_DIR_IN) ? "in" : "out", val); (desc->bEndpointAddress & USB_DIR_IN) ? "in" : "out", val);
logf(" maxpacket %d", max); logf(" maxpacket %d", max);
return retval; return retval;

View file

@ -146,7 +146,7 @@ void usb_arcotg_dcd_start(void);
void usb_arcotg_dcd_stop(void); void usb_arcotg_dcd_stop(void);
/* usb controller ops */ /* 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_disable(struct usb_ep* ep);
int usb_arcotg_dcd_set_halt(struct usb_ep* ep, bool halt); 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); int usb_arcotg_dcd_send(struct usb_ep* ep, struct usb_response* request);

View file

@ -38,7 +38,7 @@ struct usb_controller {
struct usb_dcd_controller_ops { struct usb_dcd_controller_ops {
/* endpoint management */ /* 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 (*disable)(struct usb_ep* ep);
int (*set_halt)(struct usb_ep* ep, bool hald); int (*set_halt)(struct usb_ep* ep, bool hald);

View file

@ -165,22 +165,5 @@ static int ep_matches(struct usb_ep* ep, struct usb_endpoint_descriptor* desc)
/* MATCH!! */ /* 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; return 1;
} }

View file

@ -81,7 +81,7 @@ static struct usb_interface_descriptor serial_bulk_interface_desc = {
.iInterface = GS_DATA_STR_ID, .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, .bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT, .bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_IN, .bEndpointAddress = USB_DIR_IN,
@ -89,7 +89,7 @@ static struct usb_endpoint_descriptor serial_fullspeed_in_desc = {
.wMaxPacketSize = 8, .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, .bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT, .bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_OUT, .bEndpointAddress = USB_DIR_OUT,
@ -110,10 +110,34 @@ static struct usb_qualifier_descriptor serial_qualifier_desc = {
.bNumConfigurations = 1, .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_bulk_interface_desc,
(struct usb_descriptor_header *) &serial_fullspeed_in_desc, (struct usb_descriptor_header *) &serial_fs_in_desc,
(struct usb_descriptor_header *) &serial_fullspeed_out_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, NULL,
}; };
@ -126,11 +150,11 @@ struct usb_response res;
static int config_buf(uint8_t *buf, uint8_t type, unsigned index); static int config_buf(uint8_t *buf, uint8_t type, unsigned index);
static int set_config(int config); static int set_config(int config);
struct device { struct device {
struct usb_ep* in; struct usb_ep* in;
struct usb_ep* out; struct usb_ep* out;
uint32_t used_config; uint32_t used_config;
struct usb_descriptor_header** descriptors;
}; };
static struct device dev; static struct device dev;
@ -153,14 +177,14 @@ void usb_serial_driver_bind(void* controler_ops)
/* serach and asign endpoints */ /* serach and asign endpoints */
usb_ep_autoconfig_reset(); 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) { if (!dev.in) {
goto autoconf_fail; goto autoconf_fail;
} }
dev.in->claimed = true; dev.in->claimed = true;
logf("usb serial: in: %s", dev.in->name); 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) { if (!dev.out) {
goto autoconf_fail; goto autoconf_fail;
} }
@ -180,7 +204,7 @@ void usb_serial_driver_bind(void* controler_ops)
return; return;
autoconf_fail: autoconf_fail:
logf("failed to find endpoiunts"); logf("failed to find endpoints");
} }
int usb_serial_driver_request(struct usb_ctrlrequest* request) 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) void usb_serial_driver_speed(enum usb_device_speed speed)
{ {
switch (speed) { switch (speed) {
case USB_SPEED_LOW:
case USB_SPEED_FULL:
logf("usb serial: using fullspeed");
break;
case USB_SPEED_HIGH: case USB_SPEED_HIGH:
logf("usb serial: using highspeed"); logf("usb serial: using highspeed");
dev.descriptors = serial_hs_function;
break; break;
default: default:
logf("speed: hmm"); logf("usb serial: using fullspeed");
dev.descriptors = serial_fs_function;
break; break;
} }
} }
@ -274,7 +296,7 @@ static int config_buf(uint8_t *buf, uint8_t type, unsigned index)
/* TODO check 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) { if (len < 0) {
return len; return len;
} }
@ -288,9 +310,9 @@ static int set_config(int config)
/* enable endpoints */ /* enable endpoints */
logf("setup %s", dev.in->name); 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); logf("setup %s", dev.out->name);
ops->enable(dev.out); ops->enable(dev.out, (struct usb_endpoint_descriptor*)dev.descriptors[2]);
/* store config */ /* store config */
logf("using config %d", config); logf("using config %d", config);

View file

@ -31,17 +31,9 @@ struct usb_device_driver usb_storage_driver = {
.request = usb_storage_driver_request, .request = usb_storage_driver_request,
.suspend = NULL, .suspend = NULL,
.resume = 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 #define PROTO_BULK 0x50 // Bulk only
@ -92,8 +84,31 @@ static struct usb_interface_descriptor storage_interface_desc = {
.iInterface = 0, .iInterface = 0,
}; };
/* endpoint I -> bulk in */ static struct usb_endpoint_descriptor storage_fs_bulk_in_desc = {
static struct usb_endpoint_descriptor storage_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, .bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT, .bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_IN, .bEndpointAddress = USB_DIR_IN,
@ -101,8 +116,7 @@ static struct usb_endpoint_descriptor storage_bulk_in_desc = {
.wMaxPacketSize = 512, .wMaxPacketSize = 512,
}; };
/* endpoint II -> bulk out */ static struct usb_endpoint_descriptor storage_hs_bulk_out_desc = {
static struct usb_endpoint_descriptor storage_bulk_out_desc = {
.bLength = USB_DT_ENDPOINT_SIZE, .bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT, .bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_OUT, .bEndpointAddress = USB_DIR_OUT,
@ -110,10 +124,10 @@ static struct usb_endpoint_descriptor storage_bulk_out_desc = {
.wMaxPacketSize = 512, .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_interface_desc,
(struct usb_descriptor_header *) &storage_bulk_in_desc, (struct usb_descriptor_header *) &storage_hs_bulk_in_desc,
(struct usb_descriptor_header *) &storage_bulk_out_desc, (struct usb_descriptor_header *) &storage_hs_bulk_out_desc,
NULL, NULL,
}; };
@ -126,6 +140,15 @@ struct usb_response res;
static int config_buf(uint8_t *buf, uint8_t type, unsigned index); static int config_buf(uint8_t *buf, uint8_t type, unsigned index);
static int set_config(int config); 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) void usb_storage_driver_init(void)
@ -144,14 +167,14 @@ void usb_storage_driver_bind(void* controler_ops)
/* serach and asign endpoints */ /* serach and asign endpoints */
usb_ep_autoconfig_reset(); 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) { if (!dev.in) {
goto autoconf_fail; goto autoconf_fail;
} }
dev.in->claimed = true; dev.in->claimed = true;
logf("usb storage: in: %s", dev.in->name); 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) { if (!dev.out) {
goto autoconf_fail; goto autoconf_fail;
} }
@ -234,6 +257,20 @@ int usb_storage_driver_request(struct usb_ctrlrequest* request)
return ret; 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 */ /* S/GET CONFIGURATION helpers */
@ -241,12 +278,8 @@ static int config_buf(uint8_t *buf, uint8_t type, unsigned index)
{ {
int len; int len;
/* only one configuration */ len = usb_stack_configdesc(&storage_config_desc, buf, BUFFER_SIZE, dev.descriptors);
if (index != 0) { logf("result %d", len);
return -EINVAL;
}
len = usb_stack_configdesc(&storage_config_desc, buf, BUFFER_SIZE, storage_fullspeed_function);
if (len < 0) { if (len < 0) {
return len; return len;
} }
@ -258,9 +291,9 @@ static int set_config(int config)
{ {
/* enable endpoints */ /* enable endpoints */
logf("setup %s", dev.in->name); 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); logf("setup %s", dev.out->name);
ops->enable(dev.out); ops->enable(dev.out, (struct usb_endpoint_descriptor*)dev.descriptors[2]);
/* setup buffers */ /* setup buffers */

View file

@ -27,5 +27,6 @@ void usb_storage_driver_init(void);
void usb_storage_driver_bind(void* controller_ops); void usb_storage_driver_bind(void* controller_ops);
int usb_storage_driver_request(struct usb_ctrlrequest* req); int usb_storage_driver_request(struct usb_ctrlrequest* req);
void usb_storage_driver_speed(enum usb_device_speed speed);
#endif /*_STORGAGE_H_*/ #endif /*_STORGAGE_H_*/