]> Zhao Yanbai Git Server - minix.git/commitdiff
Initial interrupt URBs support
authorWojciech Zajac <wzajac@jpembedded.eu>
Fri, 30 May 2014 12:58:16 +0000 (14:58 +0200)
committerLionel Sambuc <lionel@minix3.org>
Mon, 28 Jul 2014 15:05:41 +0000 (17:05 +0200)
drivers/usbd/hcd/hcd.c
drivers/usbd/hcd/musb/musb_am335x.c
drivers/usbd/hcd/musb/musb_core.c
drivers/usbd/hcd/musb/musb_core.h
drivers/usbd/include/usb/hcd_common.h
drivers/usbd/include/usb/hcd_interface.h

index bbb39dec9e7bb390807d26f8f63a6524ddbd4908..fcb2edf2456e272508b5dcbce657325a16492d9b 100755 (executable)
@@ -30,11 +30,11 @@ static int hcd_get_descriptor_tree(hcd_device_state *);
 static int hcd_set_configuration(hcd_device_state *, int);
 static int hcd_handle_urb(hcd_device_state *);
 static int hcd_control_urb(hcd_device_state *);
-static int hcd_bulk_urb(hcd_device_state *);
+static int hcd_non_control_urb(hcd_device_state *, int);
 
 /* For internal use by more general methods */
 static int hcd_setup_packet(hcd_device_state *, hcd_ctrlrequest *);
-static int hcd_bulk_transfer(hcd_device_state *, hcd_bulkrequest *, int);
+static int hcd_data_transfer(hcd_device_state *, hcd_datarequest *);
 
 
 /*===========================================================================*
@@ -460,16 +460,13 @@ hcd_handle_urb(hcd_device_state * this_device)
                        break;
 
                case USB_TRANSFER_BLK:
-                       transfer_status = hcd_bulk_urb(this_device);
-                       break;
-
                case USB_TRANSFER_INT:
-                       /* TODO: transfer */
-                       USB_MSG("Interrupt transfer not supported");
+                       transfer_status = hcd_non_control_urb(this_device,
+                                                               urb->type);
                        break;
 
                case USB_TRANSFER_ISO:
-                       /* TODO: transfer */
+                       /* TODO: ISO transfer */
                        USB_MSG("ISO transfer not supported");
                        break;
 
@@ -478,12 +475,15 @@ hcd_handle_urb(hcd_device_state * this_device)
                        break;
        }
 
-#ifndef URB_TEST
-       /* Call completion */
+       if (EXIT_SUCCESS != transfer_status)
+               USB_MSG("USB transfer failed");
+
+       /* Call completion regardless of status */
        hcd_completion_cb(urb->priv);
-#endif
 
-       /* Only critical failures should ever yield EXIT_FAILURE */
+       /* TODO: Only critical failures should ever yield EXIT_FAILURE, so
+        * return is not bound to transfer_status for now, to let device
+        * driver act accordingly */
        return EXIT_SUCCESS;
 }
 
@@ -538,13 +538,13 @@ hcd_control_urb(hcd_device_state * this_device)
 
 
 /*===========================================================================*
- *    hcd_bulk_urb                                                           *
+ *    hcd_non_control_urb                                                    *
  *===========================================================================*/
 static int
-hcd_bulk_urb(hcd_device_state * this_device)
+hcd_non_control_urb(hcd_device_state * this_device, int type)
 {
        hcd_endpoint * e;
-       hcd_bulkrequest request;
+       hcd_datarequest request;
        hcd_urb * urb;
 
        DEBUG_DUMP;
@@ -555,7 +555,7 @@ hcd_bulk_urb(hcd_device_state * this_device)
        urb->status = EINVAL;
 
        if (NULL == urb->data) {
-               USB_MSG("No data packet in URB, for bulk transfer");
+               USB_MSG("No data packet in URB");
                return EXIT_FAILURE;
        }
 
@@ -571,12 +571,28 @@ hcd_bulk_urb(hcd_device_state * this_device)
                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 bulk request structure */
+       /* Assign to data request structure */
        request.endpoint = urb->endpoint;
+       request.direction = urb->direction;
        request.size = (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);
@@ -594,7 +610,7 @@ hcd_bulk_urb(hcd_device_state * this_device)
        }
 
        /* Check if remembered type matches */
-       if (e->descriptor.bmAttributes != UE_BULK) {
+       if (UE_GET_XFERTYPE(e->descriptor.bmAttributes) != (int)request.type) {
                USB_MSG("EP type mismatch");
                return EXIT_FAILURE;
        }
@@ -605,14 +621,14 @@ hcd_bulk_urb(hcd_device_state * this_device)
        /* Let know how to configure EP for speed */
        request.speed = this_device->speed;
 
-       /* Send bulk data */
-       if (EXIT_SUCCESS != hcd_bulk_transfer(this_device, &request,
-                                               urb->direction)) {
-               USB_MSG("URB bulk transfer, failed");
+       /* Start sending data */
+       if (EXIT_SUCCESS != hcd_data_transfer(this_device, &request)) {
+               USB_MSG("URB non-control transfer, failed");
                urb->status = EPIPE;
                return EXIT_FAILURE;
        }
 
+       /* Transfer successfully completed */
        urb->status = EXIT_SUCCESS;
        return EXIT_SUCCESS;
 }
@@ -743,14 +759,13 @@ hcd_setup_packet(hcd_device_state * this_device, hcd_ctrlrequest * setup)
 
 
 /*===========================================================================*
- *    hcd_bulk_transfer                                                      *
+ *    hcd_data_transfer                                                      *
  *===========================================================================*/
 static int
-hcd_bulk_transfer(hcd_device_state * this_device, hcd_bulkrequest * request,
-               int direction)
+hcd_data_transfer(hcd_device_state * this_device, hcd_datarequest * request)
 {
        hcd_driver_state * d;
-       hcd_bulkrequest temp_req;
+       hcd_datarequest temp_req;
        int transfer_len;
 
        DEBUG_DUMP;
@@ -764,11 +779,11 @@ hcd_bulk_transfer(hcd_device_state * this_device, hcd_bulkrequest * request,
                        this_device->address);
 
        /* TODO: broken USB_IN... constants */
-       if (1 == direction) {
+       if (1 == request->direction) {
 
                do {
-                       /* Start actual bulk transfer */
-                       d->bulk_in_stage(d->private_data, request);
+                       /* Start actual data transfer */
+                       d->rx_stage(d->private_data, request);
 
                        /* Wait for response */
                        hcd_device_wait(this_device, HCD_EVENT_ENDPOINT,
@@ -776,7 +791,7 @@ hcd_bulk_transfer(hcd_device_state * this_device, hcd_bulkrequest * request,
 
                        /* Check response */
                        if (EXIT_SUCCESS != d->check_error(d->private_data,
-                                                       HCD_TRANSFER_BULK,
+                                                       request->type,
                                                        HCD_DIRECTION_IN))
                                return EXIT_FAILURE;
 
@@ -792,7 +807,8 @@ hcd_bulk_transfer(hcd_device_state * this_device, hcd_bulkrequest * request,
                        USB_ASSERT(request->size >= 0,
                                "Invalid amount of data received");
 
-                       /* TODO: REMOVEME (dumping of bulk transfer) */
+#ifdef DEBUG
+                       /* TODO: REMOVEME (dumping of data transfer) */
                        {
                                int i;
                                USB_MSG("RECEIVED: %d", transfer_len);
@@ -800,10 +816,11 @@ hcd_bulk_transfer(hcd_device_state * this_device, hcd_bulkrequest * request,
                                        USB_MSG("%c",
                                        (request->data-transfer_len)[i]);
                        }
+#endif
 
                } while (0 != request->size);
 
-       } else if (0 == direction) {
+       } else if (0 == request->direction) {
 
                do {
                        temp_req = *request;
@@ -820,8 +837,8 @@ hcd_bulk_transfer(hcd_device_state * this_device, hcd_bulkrequest * request,
                        USB_ASSERT(request->size >= 0,
                                "Invalid amount of data received");
 
-                       /* Start actual bulk transfer */
-                       d->bulk_out_stage(d->private_data, &temp_req);
+                       /* Start actual data transfer */
+                       d->tx_stage(d->private_data, &temp_req);
 
                        /* Wait for response */
                        hcd_device_wait(this_device, HCD_EVENT_ENDPOINT,
@@ -829,7 +846,7 @@ hcd_bulk_transfer(hcd_device_state * this_device, hcd_bulkrequest * request,
 
                        /* Check response */
                        if (EXIT_SUCCESS != d->check_error(d->private_data,
-                                                       HCD_TRANSFER_BULK,
+                                                       request->type,
                                                        HCD_DIRECTION_OUT))
                                return EXIT_FAILURE;
 
index f818e5f25b736f1c3d46dc63fdac3fadfbaa1673..b60848b1e5e874485bc0da6d2cabb6da20ae107e 100755 (executable)
@@ -339,8 +339,8 @@ musb_am335x_init(void)
                ctrl->driver.setup_device = musb_setup_device;
                ctrl->driver.reset_device = musb_reset_device;
                ctrl->driver.setup_stage = musb_setup_stage;
-               ctrl->driver.bulk_in_stage = musb_bulk_in_stage;
-               ctrl->driver.bulk_out_stage = musb_bulk_out_stage;
+               ctrl->driver.rx_stage = musb_rx_stage;
+               ctrl->driver.tx_stage = musb_tx_stage;
                ctrl->driver.in_data_stage = musb_in_data_stage;
                ctrl->driver.out_data_stage = musb_out_data_stage;
                ctrl->driver.in_status_stage = musb_in_status_stage;
@@ -379,8 +379,8 @@ musb_am335x_init(void)
                ctrl->driver.setup_device = musb_setup_device;
                ctrl->driver.reset_device = musb_reset_device;
                ctrl->driver.setup_stage = musb_setup_stage;
-               ctrl->driver.bulk_in_stage = musb_bulk_in_stage;
-               ctrl->driver.bulk_out_stage = musb_bulk_out_stage;
+               ctrl->driver.rx_stage = musb_rx_stage;
+               ctrl->driver.tx_stage = musb_tx_stage;
                ctrl->driver.in_data_stage = musb_in_data_stage;
                ctrl->driver.out_data_stage = musb_out_data_stage;
                ctrl->driver.in_status_stage = musb_in_status_stage;
index f17a0972e5a1a3afb38aac94d435114fbe7aae66..0c36e6ae370dd2d230fe8c814cb85c4d5d67e573 100755 (executable)
@@ -454,10 +454,10 @@ musb_setup_stage(void * cfg, hcd_ctrlrequest * setup)
 
 
 /*===========================================================================*
- *    musb_bulk_in_stage                                                     *
+ *    musb_rx_stage                                                          *
  *===========================================================================*/
 void
-musb_bulk_in_stage(void * cfg, hcd_bulkrequest * request)
+musb_rx_stage(void * cfg, hcd_datarequest * request)
 {
        musb_core_config * core;
 #if 0
@@ -472,15 +472,27 @@ musb_bulk_in_stage(void * cfg, hcd_bulkrequest * request)
        core = (musb_core_config *)cfg;
        r = core->regs;
 
-       USB_ASSERT(request->max_packet_size <= 1024, "Invalid wMaxPacketSize");
+       USB_ASSERT(request->max_packet_size <= 1024,
+                       "Invalid wMaxPacketSize");
        USB_ASSERT((core->ep <= 15) && (core->ep > 0),
-               "Invalid bulk EP supplied");
+                       "Invalid bulk EP supplied");
 
        /* Set EP and device address to be used in this command */
        musb_set_state(core);
 
        /* Evaluate RXTYPE */
-       host_rxtype = MUSB_VAL_HOST_XXTYPE_BULK | core->ep;
+       host_rxtype = core->ep;
+
+       switch (request->type) {
+               case HCD_TRANSFER_BULK:
+                       host_rxtype |= MUSB_VAL_HOST_XXTYPE_BULK;
+                       break;
+               case HCD_TRANSFER_INTERRUPT:
+                       host_rxtype |= MUSB_VAL_HOST_XXTYPE_INTERRUPT;
+                       break;
+               default:
+                       USB_ASSERT(0, "Unsupported transfer type");
+       }
 
        if (HCD_SPEED_HIGH == request->speed)
                host_rxtype |= MUSB_VAL_HOST_XXTYPE_HIGH_SPEED;
@@ -493,8 +505,12 @@ musb_bulk_in_stage(void * cfg, hcd_bulkrequest * request)
        /* Rewrite RXMAXP */
        HCD_WR2(r, MUSB_REG_RXMAXP, request->max_packet_size);
 
-       /* Rewrite HOST_RXINTERVAL */
-       HCD_WR1(r, MUSB_REG_HOST_RXINTERVAL, MUSB_VAL_HOST_XXINTERVAL_DEFAULT);
+       /* Set HOST_RXINTERVAL based on transfer type */
+       if (HCD_TRANSFER_BULK == request->type)
+               HCD_WR1(r, MUSB_REG_HOST_RXINTERVAL,
+                       MUSB_VAL_HOST_XXINTERVAL_DEFAULT);
+       else if (HCD_TRANSFER_INTERRUPT == request->type)
+               HCD_WR1(r, MUSB_REG_HOST_RXINTERVAL, request->interval);
 
        /* Not required in some MUSB implementations */
 #if 0
@@ -536,10 +552,10 @@ musb_bulk_in_stage(void * cfg, hcd_bulkrequest * request)
 
 
 /*===========================================================================*
- *    musb_bulk_out_stage                                                    *
+ *    musb_tx_stage                                                          *
  *===========================================================================*/
 void
-musb_bulk_out_stage(void * cfg, hcd_bulkrequest * request)
+musb_tx_stage(void * cfg, hcd_datarequest * request)
 {
        musb_core_config * core;
 #if 0
@@ -554,15 +570,27 @@ musb_bulk_out_stage(void * cfg, hcd_bulkrequest * request)
        core = (musb_core_config *)cfg;
        r = core->regs;
 
-       USB_ASSERT(request->max_packet_size <= 1024, "Invalid wMaxPacketSize");
+       USB_ASSERT(request->max_packet_size <= 1024,
+                       "Invalid wMaxPacketSize");
        USB_ASSERT((core->ep <= 15) && (core->ep > 0),
-               "Invalid bulk EP supplied");
+                       "Invalid bulk EP supplied");
 
        /* Set EP and device address to be used in this command */
        musb_set_state(core);
 
        /* Evaluate TXTYPE */
-       host_txtype = MUSB_VAL_HOST_XXTYPE_BULK | core->ep;
+       host_txtype = core->ep;
+
+       switch (request->type) {
+               case HCD_TRANSFER_BULK:
+                       host_txtype |= MUSB_VAL_HOST_XXTYPE_BULK;
+                       break;
+               case HCD_TRANSFER_INTERRUPT:
+                       host_txtype |= MUSB_VAL_HOST_XXTYPE_INTERRUPT;
+                       break;
+               default:
+                       USB_ASSERT(0, "Unsupported transfer type");
+       }
 
        if (HCD_SPEED_HIGH == request->speed)
                host_txtype |= MUSB_VAL_HOST_XXTYPE_HIGH_SPEED;
@@ -575,8 +603,12 @@ musb_bulk_out_stage(void * cfg, hcd_bulkrequest * request)
        /* Rewrite TXMAXP */
        HCD_WR2(r, MUSB_REG_TXMAXP, request->max_packet_size);
 
-       /* Rewrite HOST_TXINTERVAL */
-       HCD_WR1(r, MUSB_REG_HOST_TXINTERVAL, MUSB_VAL_HOST_XXINTERVAL_DEFAULT);
+       /* Set HOST_TXINTERVAL based on transfer type */
+       if (HCD_TRANSFER_BULK == request->type)
+               HCD_WR1(r, MUSB_REG_HOST_TXINTERVAL,
+                       MUSB_VAL_HOST_XXINTERVAL_DEFAULT);
+       else if (HCD_TRANSFER_INTERRUPT == request->type)
+               HCD_WR1(r, MUSB_REG_HOST_TXINTERVAL, request->interval);
 
        /* Not required in some MUSB implementations */
 #if 0
index e51f15988c8f17a81e2a9d7e8de462048e804ab5..e60713f9eff8ec1a2b0bc69d0a515c4597728f06 100755 (executable)
@@ -35,8 +35,8 @@ void musb_core_stop(void *);
 void musb_setup_device(void *, hcd_reg1, hcd_reg1);
 int musb_reset_device(void *, hcd_speed *);
 void musb_setup_stage(void *, hcd_ctrlrequest *);
-void musb_bulk_in_stage(void *, hcd_bulkrequest *);
-void musb_bulk_out_stage(void *, hcd_bulkrequest *);
+void musb_rx_stage(void *, hcd_datarequest *);
+void musb_tx_stage(void *, hcd_datarequest *);
 void musb_in_data_stage(void *);
 void musb_out_data_stage(void *);
 void musb_in_status_stage(void *);
index 6df67ae529b03472d33952b1fa2c02301f1a391f..7d3f251fbfe530c40b27adf880396df23052346f 100755 (executable)
@@ -150,22 +150,6 @@ typedef struct hcd_device_state {
 hcd_device_state;
 
 
-/*===========================================================================*
- *    HCD transfer requests                                                  *
- *===========================================================================*/
-struct hcd_bulkrequest {
-
-       char * data;
-       int size;
-       int endpoint;
-       unsigned int max_packet_size;
-       hcd_speed speed;
-};
-
-typedef struct usb_ctrlrequest         hcd_ctrlrequest;
-typedef struct hcd_bulkrequest         hcd_bulkrequest;
-
-
 /*===========================================================================*
  *    HCD event handling                                                     *
  *===========================================================================*/
@@ -203,6 +187,25 @@ hcd_event;
 #define HCD_ENDPOINT_0                 0
 
 
+/*===========================================================================*
+ *    HCD transfer requests                                                  *
+ *===========================================================================*/
+struct hcd_datarequest {
+
+       char * data;
+       int size;
+       int endpoint;
+       int direction;
+       unsigned int max_packet_size;
+       unsigned int interval;
+       hcd_speed speed;
+       hcd_transfer type;
+};
+
+typedef struct usb_ctrlrequest         hcd_ctrlrequest;
+typedef struct hcd_datarequest         hcd_datarequest;
+
+
 /*===========================================================================*
  *    Other definitions                                                      *
  *===========================================================================*/
index c59d6e62f523299eebaa05484e8c47836936c933..3d20f1c4f43f430a53deb5bc3cbd73e83e1ee0cc 100755 (executable)
@@ -26,8 +26,8 @@ struct hcd_driver_state {
        void    (*setup_device)         (void *, hcd_reg1, hcd_reg1);
        int     (*reset_device)         (void *, hcd_speed *);
        void    (*setup_stage)          (void *, hcd_ctrlrequest *);
-       void    (*bulk_in_stage)        (void *, hcd_bulkrequest *);
-       void    (*bulk_out_stage)       (void *, hcd_bulkrequest *);
+       void    (*rx_stage)             (void *, hcd_datarequest *);
+       void    (*tx_stage)             (void *, hcd_datarequest *);
        void    (*in_data_stage)        (void *);
        void    (*out_data_stage)       (void *);
        void    (*in_status_stage)      (void *);