]> Zhao Yanbai Git Server - minix.git/commitdiff
Unification of various HCD types.
authorWojciech Zajac <wzajac@jpembedded.eu>
Fri, 13 Jun 2014 10:50:13 +0000 (12:50 +0200)
committerLionel Sambuc <lionel@minix3.org>
Mon, 28 Jul 2014 15:05:51 +0000 (17:05 +0200)
DDEKit URB's are no longer directly handled by HCD but rather translated and validated to avoid type conversion issues and illegal values.

drivers/usbd/base/earm/Makefile
drivers/usbd/hcd/hcd.c
drivers/usbd/hcd/hcd_common.c
drivers/usbd/hcd/hcd_ddekit.c
drivers/usbd/hcd/musb/musb_am335x.c
drivers/usbd/include/usb/hcd_common.h
drivers/usbd/include/usb/hcd_ddekit.h
drivers/usbd/include/usb/hcd_interface.h

index 11f9adf077e2a8c1b344a4ad2b5a6fb43e3cb3fa..26eb439d2fede85bae8489abdb59349f004bf18d 100755 (executable)
@@ -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=
 
index 63c2c67534fdf995de1574ba0011779ff6fddbe8..9f083be6ac3007a63a52dacae7114c9e242387f2 100755 (executable)
@@ -5,7 +5,6 @@
 #include <string.h>                            /* memcpy */
 
 #include <minix/drivers.h>                     /* errno with sign */
-#include <minix/usb.h>                         /* USB_TRANSFER_CTL...  */
 
 #include <usb/hcd_common.h>
 #include <usb/hcd_ddekit.h>
@@ -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,
index 305a2f191496015a95ac8cfa987382c86b22cae7..298d3f6dfff45dd1211822b8b28096679140cd73 100755 (executable)
@@ -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;
index 5f650d06f428a73d5bb4977f70abbd1506250a60..3ad74153088079b5f1b39c4beea382fbebe27079 100755 (executable)
@@ -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;
 }
index 61a379318cff3529577f222cf4603527b4b42c3b..04af7405100b3c6c1ba9fc84b60d863a1a33aad8 100755 (executable)
@@ -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
 }
index 7b127b151e8f3256510ecd5ef0344a0ce79bf2b1..5719d3080f4ded3c21667b01604afe39b18290bf 100755 (executable)
@@ -10,6 +10,7 @@
 #include <ddekit/semaphore.h>
 #include <ddekit/usb.h>
 
+/* TODO: usb.h is for DDEKit's IPC and should not be used here */
 #include <minix/usb.h>                         /* for setup structures */
 #include <minix/usb_ch9.h>                     /* 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_ */
index 67cb3254e0148266f0ff079c3e464782da3aace2..446e9cd5c86cf2162f95112486590f6d7bf5f8ea 100755 (executable)
@@ -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_ */
index d8a4170a5e4d2fbc48458e7cae185c6492f45579..332f2819c467bce5a0751d20bde4f30d884a12a2 100755 (executable)
@@ -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;
 };