From: Wojciech Zajac Date: Fri, 13 Jun 2014 10:50:13 +0000 (+0200) Subject: Unification of various HCD types. X-Git-Tag: v3.3.0~201 X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/invmod.png?a=commitdiff_plain;h=1858789bf65b58c2d78a1952808a5e6260d6c962;p=minix.git Unification of various HCD types. DDEKit URB's are no longer directly handled by HCD but rather translated and validated to avoid type conversion issues and illegal values. --- diff --git a/drivers/usbd/base/earm/Makefile b/drivers/usbd/base/earm/Makefile index 11f9adf07..26eb439d2 100755 --- a/drivers/usbd/base/earm/Makefile +++ b/drivers/usbd/base/earm/Makefile @@ -9,9 +9,8 @@ SRCS= usbd.c usbd_earm.c hcd.c hcd_common.c hcd_ddekit.c musb_am335x.c musb_cor CPPFLAGS+= -I${.CURDIR}/../../include -DPADD+= ${LIBDDEKIT} ${LIBDDEKIT_USB_SERVER} ${LIBDEVMAN} ${LIBUSB} ${LIBMINC} ${LIBCLKCONF} -LDADD+= -lddekit -lddekit_usb_server -ldevman -lusb -lminc -lclkconf -LDADD+= -lsys -lminlib +DPADD+= ${LIBDDEKIT} ${LIBDDEKIT_USB_SERVER} ${LIBDEVMAN} ${LIBUSB} ${LIBMINC} ${LIBCLKCONF} ${LIBSYS} ${LIBMINLIB} +LDADD+= -lddekit -lddekit_usb_server -ldevman -lusb -lminc -lclkconf -lsys -lminlib MAN= diff --git a/drivers/usbd/hcd/hcd.c b/drivers/usbd/hcd/hcd.c index 63c2c6753..9f083be6a 100755 --- a/drivers/usbd/hcd/hcd.c +++ b/drivers/usbd/hcd/hcd.c @@ -5,7 +5,6 @@ #include /* memcpy */ #include /* errno with sign */ -#include /* USB_TRANSFER_CTL... */ #include #include @@ -25,12 +24,12 @@ static void hcd_device_finish(hcd_device_state *, const char *); /* Typical USD device communication procedures */ static int hcd_enumerate(hcd_device_state *); static int hcd_get_device_descriptor(hcd_device_state *); -static int hcd_set_address(hcd_device_state *, int); +static int hcd_set_address(hcd_device_state *, hcd_reg1); static int hcd_get_descriptor_tree(hcd_device_state *); static int hcd_set_configuration(hcd_device_state *, hcd_reg1); -static int hcd_handle_urb(hcd_device_state *); -static int hcd_control_urb(hcd_device_state *); -static int hcd_non_control_urb(hcd_device_state *, int); +static int hcd_handle_urb(hcd_device_state *, hcd_urb *); +static int hcd_control_urb(hcd_device_state *, hcd_urb *); +static int hcd_non_control_urb(hcd_device_state *, hcd_urb *); /* For internal use by more general methods */ static int hcd_setup_packet(hcd_device_state *, hcd_ctrlrequest *, hcd_reg1); @@ -148,13 +147,11 @@ hcd_device_thread(void * thread_args) /* Start handling URB's */ for(;;) { - /* No URB's yet */ - this_device->urb = NULL; - /* Block and wait for something like 'submit URB' */ - hcd_device_wait(this_device, HCD_EVENT_URB, HCD_NO_ENDPOINT); + hcd_device_wait(this_device, HCD_EVENT_URB, HCD_ANY_EP); - if (EXIT_SUCCESS != hcd_handle_urb(this_device)) + if (EXIT_SUCCESS != hcd_handle_urb(this_device, + &(this_device->urb))) hcd_device_finish(this_device, "URB handling failed"); } @@ -175,7 +172,7 @@ hcd_device_finish(hcd_device_state * this_device, const char * finish_msg) /* Lock forever */ for (;;) { - hcd_device_wait(this_device, HCD_EVENT_URB, HCD_NO_ENDPOINT); + hcd_device_wait(this_device, HCD_EVENT_URB, HCD_ANY_EP); USB_MSG("Failed attempt to continue finished thread"); } } @@ -308,13 +305,15 @@ hcd_get_device_descriptor(hcd_device_state * this_device) * hcd_set_address * *===========================================================================*/ static int -hcd_set_address(hcd_device_state * this_device, int address) +hcd_set_address(hcd_device_state * this_device, hcd_reg1 address) { hcd_ctrlrequest setup; DEBUG_DUMP; - USB_ASSERT((address > 0) && (address < 128), "Illegal address"); + /* Check for legal USB device address (must be non-zero as well) */ + USB_ASSERT((address > HCD_DEFAULT_ADDR) && (address <= HCD_LAST_ADDR), + "Illegal device address supplied"); /* TODO: magic numbers, no header for these */ setup.bRequestType = 0x00; /* OUT */ @@ -348,9 +347,9 @@ hcd_get_descriptor_tree(hcd_device_state * this_device) { hcd_config_descriptor config_descriptor; hcd_ctrlrequest setup; + hcd_reg4 total_length; + hcd_reg4 buffer_length; int completed; - int total_length; - int buffer_length; DEBUG_DUMP; @@ -384,19 +383,16 @@ hcd_get_descriptor_tree(hcd_device_state * this_device) sizeof(config_descriptor)); /* Continue only if there is more data */ - total_length = config_descriptor.wTotalLength[0] + - (config_descriptor.wTotalLength[1] << 8); + total_length = UGETW(config_descriptor.wTotalLength); - if (total_length < (int)sizeof(config_descriptor)) { + if (total_length < sizeof(config_descriptor)) { /* This should never happen for a fine device */ USB_MSG("Illegal wTotalLength value"); return EXIT_FAILURE; - } - else if (sizeof(config_descriptor) == total_length) { + } else if (sizeof(config_descriptor) == total_length) { /* Nothing more was in descriptor anyway */ completed = 1; - } - else { + } else { /* Read whatever is needed */ buffer_length = total_length; } @@ -453,48 +449,44 @@ hcd_set_configuration(hcd_device_state * this_device, hcd_reg1 configuration) * hcd_handle_urb * *===========================================================================*/ static int -hcd_handle_urb(hcd_device_state * this_device) +hcd_handle_urb(hcd_device_state * this_device, hcd_urb * urb) { - hcd_urb * urb; int transfer_status; DEBUG_DUMP; transfer_status = EXIT_FAILURE; - urb = this_device->urb; - USB_ASSERT(NULL != urb, "NULL URB given"); /* TODO: One device only */ - USB_ASSERT((void *)this_device == (void *)urb->dev, - "Unknown device for URB"); + USB_ASSERT(NULL != urb, "NULL URB given"); + USB_ASSERT(this_device == urb->target_device, "Unknown device for URB"); switch (urb->type) { - - case USB_TRANSFER_CTL: - transfer_status = hcd_control_urb(this_device); + case HCD_TRANSFER_CONTROL: + transfer_status = hcd_control_urb(this_device, urb); break; - case USB_TRANSFER_BLK: - case USB_TRANSFER_INT: - transfer_status = hcd_non_control_urb(this_device, - urb->type); + case HCD_TRANSFER_BULK: + case HCD_TRANSFER_INTERRUPT: + transfer_status = hcd_non_control_urb(this_device, urb); break; - case USB_TRANSFER_ISO: + case HCD_TRANSFER_ISOCHRONOUS: /* TODO: ISO transfer */ USB_MSG("ISO transfer not supported"); break; default: - USB_MSG("Invalid transfer type 0x%X", urb->type); + USB_MSG("Invalid transfer type 0x%02X", (int)urb->type); break; } + /* In case of error, only dump message */ if (EXIT_SUCCESS != transfer_status) USB_MSG("USB transfer failed"); /* Call completion regardless of status */ - hcd_completion_cb(urb->priv); + hcd_completion_cb(urb); /* TODO: Only critical failures should ever yield EXIT_FAILURE, so * return is not bound to transfer_status for now, to let device @@ -507,52 +499,44 @@ hcd_handle_urb(hcd_device_state * this_device) * hcd_control_urb * *===========================================================================*/ static int -hcd_control_urb(hcd_device_state * this_device) +hcd_control_urb(hcd_device_state * this_device, hcd_urb * urb) { - hcd_urb * urb; - hcd_ctrlrequest setup; - DEBUG_DUMP; - urb = this_device->urb; - /* Assume bad values unless something different occurs later */ - urb->status = EINVAL; + urb->inout_status = EINVAL; - /* Must have setup packet */ - if (NULL == urb->setup_packet) { + /* Must have setup packet for control transfer */ + if (NULL == urb->in_setup) { USB_MSG("No setup packet in URB, for control transfer"); return EXIT_FAILURE; } /* TODO: Only EP0 can have control transfer */ - if (0 != urb->endpoint) { + if (HCD_DEFAULT_EP != urb->endpoint) { USB_MSG("Control transfer for non zero EP"); return EXIT_FAILURE; } - /* Hold setup packet and analyze it */ - memcpy(&setup, urb->setup_packet, sizeof(setup)); - - /* TODO: broken constants for urb->direction (USB_OUT...) */ - if (((setup.bRequestType >> 7) & 0x01) != urb->direction) { + /* Setup and URB directions should match */ + if (((urb->in_setup->bRequestType >> 7) & 0x01) != urb->direction) { USB_MSG("URB Direction mismatch"); return EXIT_FAILURE; } /* Send setup packet */ - if (EXIT_SUCCESS != hcd_setup_packet(this_device, &setup, - (hcd_reg1)urb->endpoint)) { + if (EXIT_SUCCESS != hcd_setup_packet(this_device, urb->in_setup, + urb->endpoint)) { USB_MSG("Sending URB setup packet, failed"); - urb->status = EPIPE; + urb->inout_status = EPIPE; return EXIT_FAILURE; } /* TODO: Calling memcpy may be removed when writing directly to URB */ /* Put what was read back into URB */ - memcpy(urb->data, this_device->buffer, this_device->data_len); - urb->actual_length = (unsigned int)this_device->data_len; - urb->status = EXIT_SUCCESS; + memcpy(urb->inout_data, this_device->buffer, this_device->data_len); + urb->out_size = this_device->data_len; + urb->inout_status = EXIT_SUCCESS; return EXIT_SUCCESS; } @@ -562,80 +546,55 @@ hcd_control_urb(hcd_device_state * this_device) * hcd_non_control_urb * *===========================================================================*/ static int -hcd_non_control_urb(hcd_device_state * this_device, int type) +hcd_non_control_urb(hcd_device_state * this_device, hcd_urb * urb) { hcd_endpoint * e; hcd_datarequest request; - hcd_urb * urb; DEBUG_DUMP; - urb = this_device->urb; - /* Assume bad values unless something different occurs later */ - urb->status = EINVAL; + urb->inout_status = EINVAL; - if (NULL == urb->data) { + /* Must have data buffer to send/receive */ + if (NULL == urb->inout_data) { USB_MSG("No data packet in URB"); return EXIT_FAILURE; } - if ((UE_GET_ADDR(urb->endpoint) >= HCD_TOTAL_EP) || - (UE_GET_ADDR(urb->endpoint) <= HCD_DEFAULT_EP)) { - USB_MSG("Illegal EP number"); - return EXIT_FAILURE; - } - - /* TODO: broken USB_IN... constants */ - if ((1 != urb->direction) && (0 != urb->direction)) { - USB_MSG("Illegal EP direction"); + if (HCD_DEFAULT_EP == urb->endpoint) { + USB_MSG("Non-control transfer for EP0"); return EXIT_FAILURE; } - /* TODO: usb.h constants to type mapping */ - switch (type) { - case USB_TRANSFER_BLK: - request.type = HCD_TRANSFER_BULK; - break; - case USB_TRANSFER_INT: - request.type = HCD_TRANSFER_INTERRUPT; - break; - default: - /* TODO: ISO transfer */ - USB_MSG("Invalid transfer type"); - return EXIT_FAILURE; - } - - /* TODO: Any additional checks? (sane size?) */ - - /* Assign to data request structure */ - request.endpoint = urb->endpoint; - request.direction = urb->direction; - request.data_left = (int)urb->size; - request.data = urb->data; - request.interval = urb->interval; - - /* Check if EP number is valid */ - e = hcd_tree_find_ep(&(this_device->config_tree), request.endpoint); + /* Check if EP number is valid within remembered descriptor tree */ + e = hcd_tree_find_ep(&(this_device->config_tree), urb->endpoint); if (NULL == e) { - USB_MSG("Invalid EP value"); + USB_MSG("Invalid EP number for this device"); return EXIT_FAILURE; } - /* TODO: broken constants for urb->direction (USB_OUT...) */ - /* Check if remembered direction matches */ + /* Check if remembered descriptor direction, matches the one in URB */ if (((e->descriptor.bEndpointAddress >> 7) & 0x01) != urb->direction) { USB_MSG("EP direction mismatch"); return EXIT_FAILURE; } /* Check if remembered type matches */ - if (UE_GET_XFERTYPE(e->descriptor.bmAttributes) != (int)request.type) { + if (UE_GET_XFERTYPE(e->descriptor.bmAttributes) != urb->type) { USB_MSG("EP type mismatch"); return EXIT_FAILURE; } + /* Assign URB values to data request structure */ + request.type = urb->type; + request.endpoint = urb->endpoint; + request.direction = urb->direction; + request.data_left = urb->in_size; + request.data = urb->inout_data; + request.interval = urb->interval; + /* Assign to let know how much data can be transfered at a time */ request.max_packet_size = UGETW(e->descriptor.wMaxPacketSize); @@ -645,13 +604,13 @@ hcd_non_control_urb(hcd_device_state * this_device, int type) /* Start sending data */ if (EXIT_SUCCESS != hcd_data_transfer(this_device, &request)) { USB_MSG("URB non-control transfer, failed"); - urb->status = EPIPE; + urb->inout_status = EPIPE; return EXIT_FAILURE; } /* Transfer successfully completed */ - urb->actual_length = urb->size - request.data_left; - urb->status = EXIT_SUCCESS; + urb->out_size = urb->in_size - request.data_left; + urb->inout_status = EXIT_SUCCESS; return EXIT_SUCCESS; } @@ -671,10 +630,10 @@ hcd_setup_packet(hcd_device_state * this_device, hcd_ctrlrequest * setup, DEBUG_DUMP; /* Should have been set at enumeration or with default values */ - USB_ASSERT(this_device->max_packet_size > 0, - "Illegal MaxPacketSize for EP0"); - USB_ASSERT((ep <= HCD_LAST_EP), "Invalid EP number"); - USB_ASSERT((hcd_reg1)(this_device->address) <= HCD_LAST_ADDR, + USB_ASSERT(this_device->max_packet_size >= HCD_LS_MAXPACKETSIZE, + "Illegal MaxPacketSize"); + USB_ASSERT(ep <= HCD_LAST_EP, "Invalid EP number"); + USB_ASSERT(this_device->address <= HCD_LAST_ADDR, "Invalid device address"); /* Initially... */ @@ -683,13 +642,13 @@ hcd_setup_packet(hcd_device_state * this_device, hcd_ctrlrequest * setup, this_device->data_len = 0; /* Nothing read yet */ /* Set parameters for further communication */ - d->setup_device(d->private_data, ep, (hcd_reg1)this_device->address); + d->setup_device(d->private_data, ep, this_device->address); /* Send setup packet */ d->setup_stage(d->private_data, setup); /* Wait for response */ - hcd_device_wait(this_device, HCD_EVENT_ENDPOINT, HCD_ENDPOINT_0); + hcd_device_wait(this_device, HCD_EVENT_ENDPOINT, ep); /* Check response */ if (EXIT_SUCCESS != d->check_error(d->private_data, @@ -711,8 +670,7 @@ hcd_setup_packet(hcd_device_state * this_device, hcd_ctrlrequest * setup, /* Wait for response */ hcd_device_wait(this_device, - HCD_EVENT_ENDPOINT, - HCD_ENDPOINT_0); + HCD_EVENT_ENDPOINT, ep); /* Check response */ if (EXIT_SUCCESS != d->check_error( @@ -723,7 +681,7 @@ hcd_setup_packet(hcd_device_state * this_device, hcd_ctrlrequest * setup, /* Read data received as response */ rx_len = d->read_data(d->private_data, - current_byte, HCD_DEFAULT_EP); + current_byte, ep); /* Increment */ current_byte += rx_len; @@ -763,8 +721,7 @@ hcd_setup_packet(hcd_device_state * this_device, hcd_ctrlrequest * setup, d->out_status_stage(d->private_data); /* Wait for response */ - hcd_device_wait(this_device, HCD_EVENT_ENDPOINT, - HCD_ENDPOINT_0); + hcd_device_wait(this_device, HCD_EVENT_ENDPOINT, ep); /* Check response */ if (EXIT_SUCCESS != d->check_error(d->private_data, @@ -778,8 +735,7 @@ hcd_setup_packet(hcd_device_state * this_device, hcd_ctrlrequest * setup, d->in_status_stage(d->private_data); /* Wait for response */ - hcd_device_wait(this_device, HCD_EVENT_ENDPOINT, - HCD_ENDPOINT_0); + hcd_device_wait(this_device, HCD_EVENT_ENDPOINT, ep); /* Check response */ if (EXIT_SUCCESS != d->check_error(d->private_data, @@ -788,7 +744,7 @@ hcd_setup_packet(hcd_device_state * this_device, hcd_ctrlrequest * setup, return EXIT_FAILURE; /* Read zero data from response to clear registers */ - if (0 != d->read_data(d->private_data, NULL, HCD_DEFAULT_EP)) + if (0 != d->read_data(d->private_data, NULL, ep)) return EXIT_FAILURE; } @@ -810,7 +766,7 @@ hcd_data_transfer(hcd_device_state * this_device, hcd_datarequest * request) USB_ASSERT((hcd_reg1)(UE_GET_ADDR(request->endpoint)) <= HCD_LAST_EP, "Invalid EP number"); - USB_ASSERT((hcd_reg1)(this_device->address) <= HCD_LAST_ADDR, + USB_ASSERT(this_device->address <= HCD_LAST_ADDR, "Invalid device address"); /* Initially... */ @@ -819,7 +775,7 @@ hcd_data_transfer(hcd_device_state * this_device, hcd_datarequest * request) /* Set parameters for further communication */ d->setup_device(d->private_data, (hcd_reg1)request->endpoint, - (hcd_reg1)this_device->address); + this_device->address); /* TODO: broken USB_IN... constants */ if (1 == request->direction) { @@ -830,7 +786,7 @@ hcd_data_transfer(hcd_device_state * this_device, hcd_datarequest * request) /* Wait for response */ hcd_device_wait(this_device, HCD_EVENT_ENDPOINT, - request->endpoint); + (hcd_reg1)request->endpoint); /* Check response */ if (EXIT_SUCCESS != d->check_error(d->private_data, @@ -876,7 +832,7 @@ hcd_data_transfer(hcd_device_state * this_device, hcd_datarequest * request) /* Wait for response */ hcd_device_wait(this_device, HCD_EVENT_ENDPOINT, - request->endpoint); + (hcd_reg1)request->endpoint); /* Check response */ if (EXIT_SUCCESS != d->check_error(d->private_data, diff --git a/drivers/usbd/hcd/hcd_common.c b/drivers/usbd/hcd/hcd_common.c index 305a2f191..298d3f6df 100755 --- a/drivers/usbd/hcd/hcd_common.c +++ b/drivers/usbd/hcd/hcd_common.c @@ -240,7 +240,7 @@ hcd_disconnect_device(hcd_device_state * this_device) * hcd_device_wait * *===========================================================================*/ void -hcd_device_wait(hcd_device_state * this_device, hcd_event event, int ep) +hcd_device_wait(hcd_device_state * this_device, hcd_event event, hcd_reg1 ep) { hcd_driver_state * drv; @@ -401,7 +401,7 @@ hcd_tree_cleanup(hcd_configuration * c) * hcd_tree_find_ep * *===========================================================================*/ hcd_endpoint * -hcd_tree_find_ep(hcd_configuration * c, int ep) +hcd_tree_find_ep(hcd_configuration * c, hcd_reg1 ep) { hcd_interface * i; hcd_endpoint * e; diff --git a/drivers/usbd/hcd/hcd_ddekit.c b/drivers/usbd/hcd/hcd_ddekit.c index 5f650d06f..3ad741530 100755 --- a/drivers/usbd/hcd/hcd_ddekit.c +++ b/drivers/usbd/hcd/hcd_ddekit.c @@ -21,6 +21,11 @@ struct ddekit_usb_device_id; struct ddekit_usb_urb; struct ddekit_usb_dev; +/* Translates DDEKit UBR to one used by HCD */ +static void hcd_decode_urb(hcd_urb *, struct ddekit_usb_urb *); +static void hcd_encode_urb(hcd_urb *, struct ddekit_usb_urb *); + + /*===========================================================================* * Global definitions * *===========================================================================*/ @@ -147,7 +152,7 @@ ddekit_usb_dev_get_data(struct ddekit_usb_dev * dev) } -/* TODO: This was in header file but is not used anywhere */ +/* TODO: This was in 'ddekit/usb.h' header file, but is not used anywhere */ #if 0 /*===========================================================================* * ddekit_usb_get_device_id * @@ -171,20 +176,25 @@ ddekit_usb_get_device_id(struct ddekit_usb_dev * dev, int ddekit_usb_submit_urb(struct ddekit_usb_urb * d_urb) { - hcd_urb * urb; hcd_device_state * dev; hcd_driver_state * drv; DEBUG_DUMP; - urb = (hcd_urb *)d_urb; - dev = (hcd_device_state *)(urb->dev); + /* Retrieve info on device/driver state from DDEKit's USB */ + dev = (hcd_device_state *)(d_urb->dev); drv = (hcd_driver_state *)(dev->driver); - dev->urb = urb; - drv->current_event = HCD_EVENT_URB; + /* Remember original URB */ + dev->urb.original_urb = (void *)d_urb; + + /* TODO: URB's should be queued somewhere if DDEKit is not changed */ + /* Turn DDEKit URB format to one that is easier to handle by HCD, also + * check if URB is valid */ + hcd_decode_urb(&(dev->urb), d_urb); - /* TODO: URB's must be queued somewhere */ + /* Start handling URB event */ + drv->current_event = HCD_EVENT_URB; hcd_handle_event(drv); return EXIT_SUCCESS; @@ -228,13 +238,14 @@ ddekit_usb_init(struct ddekit_usb_driver * drv, /*===========================================================================* * hcd_connect_cb * *===========================================================================*/ -void hcd_connect_cb(hcd_device_state * dev) +void +hcd_connect_cb(hcd_device_state * dev) { unsigned int if_bitmask; DEBUG_DUMP; - /* TODO: magic numbers like in ddekit/devman */ + /* TODO: Magic numbers like in ddekit/devman */ /* Each bit starting from 0, represents valid interface */ if_bitmask = 0xFFFFFFFF >> (32 - dev->config_tree.num_interfaces); @@ -249,7 +260,8 @@ void hcd_connect_cb(hcd_device_state * dev) /*===========================================================================* * hcd_disconnect_cb * *===========================================================================*/ -void hcd_disconnect_cb(hcd_device_state * dev) +void +hcd_disconnect_cb(hcd_device_state * dev) { DEBUG_DUMP; @@ -260,9 +272,121 @@ void hcd_disconnect_cb(hcd_device_state * dev) /*===========================================================================* * hcd_completion_cb * *===========================================================================*/ -void hcd_completion_cb(void * priv) +void +hcd_completion_cb(hcd_urb * urb) +{ + struct ddekit_usb_urb * d_urb; + + DEBUG_DUMP; + + /* Recollect original URB */ + d_urb = (struct ddekit_usb_urb *)urb->original_urb; + + /* Turn HCD URB format to one handled by DDEKit */ + hcd_encode_urb(urb, d_urb); + + completion_cb(d_urb->priv); +} + + +/*===========================================================================* + * hcd_decode_urb * + *===========================================================================*/ +static void +hcd_decode_urb(hcd_urb * urb, struct ddekit_usb_urb * dde_urb) +{ + DEBUG_DUMP; + + /* No UBR error initially */ + urb->inout_status = EXIT_SUCCESS; + + /* Check transfer direction */ + switch (dde_urb->direction) { + case DDEKIT_USB_IN: + urb->direction = HCD_DIRECTION_IN; + break; + case DDEKIT_USB_OUT: + urb->direction = HCD_DIRECTION_OUT; + break; + default: + USB_MSG("URB direction error"); + goto URB_ERROR; + } + + /* Check transfer type */ + switch (dde_urb->type) { + case DDEKIT_USB_TRANSFER_ISO: + urb->type = HCD_TRANSFER_ISOCHRONOUS; + break; + case DDEKIT_USB_TRANSFER_INT: + urb->type = HCD_TRANSFER_INTERRUPT; + break; + case DDEKIT_USB_TRANSFER_CTL: + urb->type = HCD_TRANSFER_CONTROL; + break; + case DDEKIT_USB_TRANSFER_BLK: + urb->type = HCD_TRANSFER_BULK; + break; + default: + USB_MSG("URB type error"); + goto URB_ERROR; + } + + /* Check transfer endpoint validity */ + if ((dde_urb->endpoint <= (int)HCD_LAST_EP) && + (dde_urb->endpoint >= (int)HCD_DEFAULT_EP)) + urb->endpoint = (hcd_reg1)dde_urb->endpoint; + else { + USB_MSG("URB endpoint error"); + goto URB_ERROR; + } + + /* Check transfer interval validity */ + if ((dde_urb->interval <= (int)HCD_HIGHEST_INTERVAL) && + (dde_urb->interval >= (int)HCD_LOWEST_INTERVAL)) + urb->interval = (hcd_reg1)dde_urb->interval; + else { + USB_MSG("URB interval error"); + goto URB_ERROR; + } + + /* TODO: Alignment of setup packet. Can DDE client guarantee that? */ + /* Transfer data assignment */ + urb->inout_data = (void *)dde_urb->data; + urb->in_setup = (hcd_ctrlrequest *)dde_urb->setup_packet; + + /* TODO: Sane size check? */ + urb->in_size = (hcd_reg4)dde_urb->size; + + /* Buffer validity check */ + if ((NULL == urb->inout_data) && (NULL == urb->in_setup)) { + USB_MSG("URB buffer error"); + goto URB_ERROR; + } + + /* Remember device and check for NULL */ + if (NULL == (urb->target_device = (hcd_device_state *)dde_urb->dev)) { + USB_MSG("URB device pointer error"); + goto URB_ERROR; + } + + /* Decoding completed */ + return; + + URB_ERROR: + urb->inout_status = EXIT_FAILURE; +} + + +/*===========================================================================* + * hcd_encode_urb * + *===========================================================================*/ +static void +hcd_encode_urb(hcd_urb * urb, struct ddekit_usb_urb * dde_urb) { DEBUG_DUMP; - completion_cb(priv); + /* Rewrite output for DDEKit part */ + dde_urb->actual_length = urb->out_size; + dde_urb->status = urb->inout_status; } diff --git a/drivers/usbd/hcd/musb/musb_am335x.c b/drivers/usbd/hcd/musb/musb_am335x.c index 61a379318..04af74051 100755 --- a/drivers/usbd/hcd/musb/musb_am335x.c +++ b/drivers/usbd/hcd/musb/musb_am335x.c @@ -271,7 +271,7 @@ static void musb_am335x_internal_deinit(void); static void musb_am335x_irq_init(void *); static void musb_am335x_usbss_isr(void *); static void musb_am335x_usbx_isr(void *); -static int musb_am335x_irqstat0_to_ep(int); +static hcd_reg1 musb_am335x_irqstat0_to_ep(int); /* Configuration helpers */ static void musb_am335x_usb_reset(int); @@ -427,7 +427,7 @@ musb_am335x_internal_init(void) return EXIT_FAILURE; /* Read and dump revision register */ - USB_MSG("MUSB revision (REVREG): %08X", + USB_MSG("MUSB revision (REVREG): 0x%08X", (unsigned int)HCD_RD4(am335x.ss.regs, AM335X_REG_REVREG)); /* Allow OS to handle previously configured USBSS interrupts */ @@ -628,7 +628,7 @@ musb_am335x_usbx_isr(void * data) /*===========================================================================* * musb_am335x_irqstat0_to_ep * *===========================================================================*/ -static int +static hcd_reg1 musb_am335x_irqstat0_to_ep(int irqstat0) { hcd_reg1 ep; @@ -653,7 +653,7 @@ musb_am335x_irqstat0_to_ep(int irqstat0) "Invalid IRQSTAT0 supplied (2)"); } - return (int)ep; + return ep; } @@ -714,14 +714,6 @@ musb_am335x_otg_enable(int usb_num) HCD_WR4(r, AM335X_REG_USBXIRQENABLESET1, intreg); - /* Some MUSB implementations may not need this */ -#if 0 - /* Set EP0 interrupt to be enabled */ - intreg = HCD_RD4(r, AM335X_REG_USBXIRQENABLESET0); - HCD_SET(intreg, AM335X_VAL_USBXIRQENABLEXXX0_EP0); - HCD_WR4(r, AM335X_REG_USBXIRQENABLESET0, intreg); -#else - /* Set all EP interrupts as enabled */ intreg = AM335X_VAL_USBXIRQENABLEXXX0_EP0 | AM335X_VAL_USBXIRQENABLEXXX0_TX_EP1 | @@ -756,5 +748,4 @@ musb_am335x_otg_enable(int usb_num) AM335X_VAL_USBXIRQENABLEXXX0_RX_EP15 ; HCD_WR4(r, AM335X_REG_USBXIRQENABLESET0, intreg); -#endif } diff --git a/drivers/usbd/include/usb/hcd_common.h b/drivers/usbd/include/usb/hcd_common.h index 7b127b151..5719d3080 100755 --- a/drivers/usbd/include/usb/hcd_common.h +++ b/drivers/usbd/include/usb/hcd_common.h @@ -10,6 +10,7 @@ #include #include +/* TODO: usb.h is for DDEKit's IPC and should not be used here */ #include /* for setup structures */ #include /* for descriptor structures */ @@ -99,60 +100,7 @@ hcd_configuration; /*===========================================================================* - * HCD device helper types * - *===========================================================================*/ -typedef void (*hcd_thread_function)(void *); -typedef ddekit_thread_t hcd_thread; -typedef ddekit_sem_t hcd_lock; -typedef struct hcd_driver_state hcd_driver_state; -typedef struct ddekit_usb_urb hcd_urb; - -typedef enum { - - HCD_STATE_DISCONNECTED = 0, /* default for initialization */ - HCD_STATE_CONNECTION_PENDING, - HCD_STATE_CONNECTED -} -hcd_state; - -typedef enum { - - HCD_SPEED_LOW, - HCD_SPEED_FULL, - HCD_SPEED_HIGH, -} -hcd_speed; - -/* Largest value that can be transfered by this driver at a time - * see MAXPAYLOAD in TXMAXP/RXMAXP */ -#define MAX_WTOTALLENGTH 1024 - -typedef struct hcd_device_state { - - hcd_driver_state * driver; /* Specific HCD driver object */ - hcd_thread * thread; - hcd_lock * lock; - hcd_urb * urb; - void * data; - - hcd_device_descriptor device_desc; - hcd_configuration config_tree; - hcd_reg1 max_packet_size; - hcd_speed speed; - hcd_state state; - int address; - - /* Number of bytes received/transmitted in last transfer */ - int data_len; - - /* Word aligned buffer for each device to hold transfered data */ - hcd_reg1 buffer[MAX_WTOTALLENGTH] __aligned(sizeof(hcd_reg4)); -} -hcd_device_state; - - -/*===========================================================================* - * HCD event handling * + * HCD enumerations * *===========================================================================*/ /* Possible USB transfer types */ typedef enum { @@ -183,14 +131,44 @@ typedef enum { } hcd_event; -/* EP event constants */ -#define HCD_NO_ENDPOINT -1 -#define HCD_ENDPOINT_0 0 +/* Possible device states */ +typedef enum { + + HCD_STATE_DISCONNECTED = 0, /* default for initialization */ + HCD_STATE_CONNECTION_PENDING, + HCD_STATE_CONNECTED +} +hcd_state; + +/* USB speeds */ +typedef enum { + + HCD_SPEED_LOW, + HCD_SPEED_FULL, + HCD_SPEED_HIGH, +} +hcd_speed; /*===========================================================================* - * HCD transfer requests * + * HCD threading/device/URB types * *===========================================================================*/ +typedef void (*hcd_thread_function)(void *); +typedef ddekit_thread_t hcd_thread; +typedef ddekit_sem_t hcd_lock; +typedef struct hcd_driver_state hcd_driver_state; +typedef struct usb_ctrlrequest hcd_ctrlrequest; + +/* Largest value that can be transfered by this driver at a time + * see MAXPAYLOAD in TXMAXP/RXMAXP */ +#define MAX_WTOTALLENGTH 1024 + +/* Forward declarations */ +typedef struct hcd_datarequest hcd_datarequest; +typedef struct hcd_urb hcd_urb; +typedef struct hcd_device_state hcd_device_state; + +/* Non-control transfer request structure */ struct hcd_datarequest { char * data; @@ -203,8 +181,49 @@ struct hcd_datarequest { hcd_transfer type; }; -typedef struct usb_ctrlrequest hcd_ctrlrequest; -typedef struct hcd_datarequest hcd_datarequest; +/* HCD's URB structure */ +struct hcd_urb { + + /* Basic */ + void * original_urb; + hcd_device_state * target_device; + + /* Transfer (in/out signifies what may be overwritten by HCD) */ + hcd_ctrlrequest * in_setup; + void * inout_data; + hcd_reg4 in_size; + int out_size; + int inout_status; /* URB submission/validity status */ + + /* Transfer control */ + hcd_transfer type; + hcd_direction direction; + hcd_reg1 endpoint; + hcd_reg1 interval; +}; + +/* Current state of attached device */ +struct hcd_device_state { + + hcd_driver_state * driver; /* Specific HCD driver object */ + hcd_thread * thread; + hcd_lock * lock; + void * data; + + hcd_urb urb; + hcd_device_descriptor device_desc; + hcd_configuration config_tree; + hcd_reg1 max_packet_size; + hcd_speed speed; + hcd_state state; + hcd_reg1 address; + + /* Number of bytes received/transmitted in last transfer */ + int data_len; + + /* Word aligned buffer for each device to hold transfered data */ + hcd_reg1 buffer[MAX_WTOTALLENGTH] __aligned(sizeof(hcd_reg4)); +}; /*===========================================================================* @@ -218,22 +237,27 @@ typedef struct hcd_datarequest hcd_datarequest; #define HCD_NANOSLEEP_USEC(usec) ((usec) * HCD_MILI) /* Default USB communication parameters */ -#define HCD_DEFAULT_EP 0x00u -#define HCD_DEFAULT_ADDR 0x00u -#define HCD_DEFAULT_CONFIG 0x00u -#define HCD_LAST_ADDR 0x7Fu -#define HCD_LAST_EP 0x0Fu -#define HCD_TOTAL_EP 0x10u +#define HCD_DEFAULT_EP 0x00u +#define HCD_DEFAULT_ADDR 0x00u +#define HCD_DEFAULT_CONFIG 0x00u +#define HCD_LAST_ADDR 0x7Fu +#define HCD_LAST_EP 0x0Fu +#define HCD_TOTAL_EP 0x10u +#define HCD_ANY_EP 0xFFu + +/* Legal interval values */ +#define HCD_LOWEST_INTERVAL 0x00u +#define HCD_HIGHEST_INTERVAL 0xFFu /* TODO: One device only */ -#define HCD_ATTACHED_ADDR 0x01 +#define HCD_ATTACHED_ADDR 0x01u /* Translates configuration number for 'set configuration' */ -#define HCD_SET_CONFIG_NUM(num) ((num)+0x01u) +#define HCD_SET_CONFIG_NUM(num) ((num)+0x01u) /* Default MaxPacketSize for control transfer */ -#define HCD_LS_MAXPACKETSIZE 8u -#define HCD_HS_MAXPACKETSIZE 64u +#define HCD_LS_MAXPACKETSIZE 8u +#define HCD_HS_MAXPACKETSIZE 64u /*===========================================================================* @@ -278,7 +302,7 @@ int hcd_connect_device(hcd_device_state *, hcd_thread_function); void hcd_disconnect_device(hcd_device_state *); /* Locks device thread until 'hcd_device_continue' */ -void hcd_device_wait(hcd_device_state *, hcd_event, int); +void hcd_device_wait(hcd_device_state *, hcd_event, hcd_reg1); /* Unlocks device thread halted by 'hcd_device_wait' */ void hcd_device_continue(hcd_device_state *); @@ -294,7 +318,7 @@ int hcd_buffer_to_tree(hcd_reg1 *, int, hcd_configuration *); void hcd_tree_cleanup(hcd_configuration *); /* Find EP in a tree */ -hcd_endpoint * hcd_tree_find_ep(hcd_configuration *, int); +hcd_endpoint * hcd_tree_find_ep(hcd_configuration *, hcd_reg1); #endif /* !_HCD_COMMON_H_ */ diff --git a/drivers/usbd/include/usb/hcd_ddekit.h b/drivers/usbd/include/usb/hcd_ddekit.h index 67cb3254e..446e9cd5c 100755 --- a/drivers/usbd/include/usb/hcd_ddekit.h +++ b/drivers/usbd/include/usb/hcd_ddekit.h @@ -12,7 +12,7 @@ *===========================================================================*/ void hcd_connect_cb(hcd_device_state *); void hcd_disconnect_cb(hcd_device_state *); -void hcd_completion_cb(void *); +void hcd_completion_cb(hcd_urb *); #endif /* !_HCD_DDEKIT_H_ */ diff --git a/drivers/usbd/include/usb/hcd_interface.h b/drivers/usbd/include/usb/hcd_interface.h index d8a4170a5..332f2819c 100755 --- a/drivers/usbd/include/usb/hcd_interface.h +++ b/drivers/usbd/include/usb/hcd_interface.h @@ -40,9 +40,9 @@ struct hcd_driver_state { /* Current state to be handled by driver */ hcd_event current_event; - int current_endpoint; + hcd_reg1 current_endpoint; hcd_event expected_event; - int expected_endpoint; + hcd_reg1 expected_endpoint; };