From 8a23c526503dda921e55b8506817ee2f79e5598d Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sun, 19 Apr 2015 14:26:17 -0600 Subject: [PATCH] USB Hub: Change an the usbhost_ctrlxfer interface; move some functions around --- drivers/usbhost/usbhost_enumerate.c | 163 +++++++++++++--------------- drivers/usbhost/usbhost_hub.c | 37 +++++++ include/nuttx/usb/usbhost.h | 51 ++++----- 3 files changed, 136 insertions(+), 115 deletions(-) diff --git a/drivers/usbhost/usbhost_enumerate.c b/drivers/usbhost/usbhost_enumerate.c index 65f09dfcb1..b75a52db5e 100644 --- a/drivers/usbhost/usbhost_enumerate.c +++ b/drivers/usbhost/usbhost_enumerate.c @@ -313,25 +313,35 @@ static inline int usbhost_classbind(FAR struct usbhost_class_s *devclass, int usbhost_enumerate(FAR struct usbhost_class_s *devclass) { + FAR struct usb_ctrlreq_s *ctrlreq = NULL; struct usbhost_devinfo_s devinfo; struct usbhost_id_s id; size_t maxlen; unsigned int cfglen; uint8_t maxpacketsize; uint8_t descsize; - FAR uint8_t *buffer; + FAR uint8_t *buffer = NULL; int ret; DEBUGASSERT(devclass != NULL && devclass->drvr != NULL); - /* Allocate descriptor buffer for use in this function. */ + /* Allocate descriptor buffers for use in this function. We will need two: + * One for the request and one for the data buffer. + */ - ret = DRVR_ALLOC(devclass->drvr, &buffer, &maxlen); - if (ret != OK) - { - udbg("DRVR_ALLOC failed: %d\n", ret); - goto errout; - } + ret = DRVR_ALLOC(devclass->drvr, (FAR uint8_t **)&ctrlreq, &maxlen); + if (ret != OK) + { + udbg("DRVR_ALLOC failed: %d\n", ret); + return ret; + } + + ret = DRVR_ALLOC(devclass->drvr, &buffer, &maxlen); + if (ret != OK) + { + udbg("DRVR_ALLOC failed: %d\n", ret); + goto errout; + } /* Get information about the connected device */ @@ -376,10 +386,13 @@ int usbhost_enumerate(FAR struct usbhost_class_s *devclass) /* Read first bytes of the device descriptor */ - ret = usbhost_ctrlxfer(devclass, - (USB_REQ_DIR_IN | USB_REQ_RECIPIENT_DEVICE), - USB_REQ_GETDESCRIPTOR, (USB_DESC_TYPE_DEVICE << 8), - 0, descsize, buffer); + ctrlreq->type = USB_REQ_DIR_IN | USB_REQ_RECIPIENT_DEVICE; + ctrlreq->req = USB_REQ_GETDESCRIPTOR; + usbhost_putle16(ctrlreq->value, (USB_DESC_TYPE_DEVICE << 8)); + usbhost_putle16(ctrlreq->index, 0); + usbhost_putle16(ctrlreq->len, descsize); + + ret = usbhost_ctrlxfer(devclass, ctrlreq, buffer); if (ret != OK) { udbg("ERROR: Failed to get device descriptor, length=%d: %d\n", @@ -398,10 +411,13 @@ int usbhost_enumerate(FAR struct usbhost_class_s *devclass) /* Set the USB device address */ - ret = usbhost_ctrlxfer(devclass, - (USB_REQ_DIR_OUT | USB_REQ_RECIPIENT_DEVICE), - USB_REQ_SETADDRESS, devclass->addr, - 0, 0, NULL); + ctrlreq->type = USB_REQ_DIR_OUT | USB_REQ_RECIPIENT_DEVICE; + ctrlreq->req = USB_REQ_SETADDRESS; + usbhost_putle16(ctrlreq->value, ((uint16_t)devclass->addr << 8)); + usbhost_putle16(ctrlreq->index, 0); + usbhost_putle16(ctrlreq->len, 0); + + ret = usbhost_ctrlxfer(devclass, ctrlreq, NULL); if (ret != OK) { udbg("ERROR: Failed to set address: %d\n"); @@ -419,11 +435,13 @@ int usbhost_enumerate(FAR struct usbhost_class_s *devclass) if (descsize < USB_SIZEOF_DEVDESC) { - ret = usbhost_ctrlxfer(devclass, - (USB_REQ_DIR_IN | USB_REQ_RECIPIENT_DEVICE), - USB_REQ_GETDESCRIPTOR, - (USB_DESC_TYPE_DEVICE << 8), - 0, USB_SIZEOF_DEVDESC, buffer); + ctrlreq->type = USB_REQ_DIR_IN | USB_REQ_RECIPIENT_DEVICE; + ctrlreq->req = USB_REQ_GETDESCRIPTOR; + usbhost_putle16(ctrlreq->value, (USB_DESC_TYPE_DEVICE << 8)); + usbhost_putle16(ctrlreq->index, 0); + usbhost_putle16(ctrlreq->len, USB_SIZEOF_DEVDESC); + + ret = usbhost_ctrlxfer(devclass, ctrlreq, buffer); if (ret != OK) { udbg("ERROR: Failed to get device descriptor, length=%d: %d\n", @@ -445,10 +463,13 @@ int usbhost_enumerate(FAR struct usbhost_class_s *devclass) * multiple configurations. */ - ret = usbhost_ctrlxfer(devclass, - (USB_REQ_DIR_IN | USB_REQ_RECIPIENT_DEVICE), - USB_REQ_GETDESCRIPTOR, (USB_DESC_TYPE_CONFIG << 8), - 0, USB_SIZEOF_CFGDESC, buffer); + ctrlreq->type = USB_REQ_DIR_IN | USB_REQ_RECIPIENT_DEVICE; + ctrlreq->req = USB_REQ_GETDESCRIPTOR; + usbhost_putle16(ctrlreq->value, (USB_DESC_TYPE_CONFIG << 8)); + usbhost_putle16(ctrlreq->index, 0); + usbhost_putle16(ctrlreq->len, USB_SIZEOF_CFGDESC); + + ret = usbhost_ctrlxfer(devclass, ctrlreq, buffer); if (ret != OK) { udbg("ERROR: Failed to get configuration descriptor, length=%d: %d\n", @@ -465,10 +486,13 @@ int usbhost_enumerate(FAR struct usbhost_class_s *devclass) * hard-coded!) */ - ret = usbhost_ctrlxfer(devclass, - (USB_REQ_DIR_IN | USB_REQ_RECIPIENT_DEVICE), - USB_REQ_GETDESCRIPTOR, (USB_DESC_TYPE_CONFIG << 8), - 0, cfglen, buffer); + ctrlreq->type = USB_REQ_DIR_IN | USB_REQ_RECIPIENT_DEVICE; + ctrlreq->req = USB_REQ_GETDESCRIPTOR; + usbhost_putle16(ctrlreq->value, (USB_DESC_TYPE_CONFIG << 8)); + usbhost_putle16(ctrlreq->index, 0); + usbhost_putle16(ctrlreq->len, cfglen); + + ret = usbhost_ctrlxfer(devclass, ctrlreq, buffer); if (ret != OK) { udbg("ERROR: Failed to get configuration descriptor, length=%d: %d\n", @@ -478,18 +502,21 @@ int usbhost_enumerate(FAR struct usbhost_class_s *devclass) /* Select device configuration 1 (Should not be hard-coded!) */ - ret = usbhost_ctrlxfer(devclass, - (USB_REQ_DIR_OUT | USB_REQ_RECIPIENT_DEVICE), - USB_REQ_SETCONFIGURATION, 1, - 0, 0, NULL); + ctrlreq->type = USB_REQ_DIR_OUT | USB_REQ_RECIPIENT_DEVICE; + ctrlreq->req = USB_REQ_SETCONFIGURATION; + usbhost_putle16(ctrlreq->value, 1); + usbhost_putle16(ctrlreq->index, 0); + usbhost_putle16(ctrlreq->len, 0); + + ret = usbhost_ctrlxfer(devclass, ctrlreq, NULL); if (ret != OK) { udbg("ERROR: Failed to set configuration: %d\n", ret); goto errout; } - /* Was the class identification information provided in the device descriptor? - * Or do we need to find it in the interface descriptor(s)? + /* Was the class identification information provided in the device + * descriptor? Or do we need to find it in the interface descriptor(s)? */ if (id.base == USB_CLASS_PER_INTERFACE) @@ -528,6 +555,11 @@ errout: DRVR_FREE(devclass->drvr, buffer); } + if (ctrlreq) + { + DRVR_FREE(devclass->drvr, (FAR uint8_t *)ctrlreq); + } + return ret; } @@ -539,7 +571,7 @@ errout: * * Input Parameters: * devclass - A reference to the class instance. - * type, req, value, index, len - Describes the control transfer + * ctrlreq - Describes the control request transfer * buffer - Data accompanying the control transfer * * Returned Values: @@ -549,21 +581,15 @@ errout: ****************************************************************************/ int usbhost_ctrlxfer(FAR struct usbhost_class_s *devclass, - uint8_t type, uint8_t req, uint16_t value, - uint16_t index, uint16_t len, + FAR struct usb_ctrlreq_s *ctrlreq, FAR uint8_t *buffer) { struct usbhost_transfer_s xfer; - struct usb_ctrlreq_s cmd; struct timespec timeout; + uint16_t len; int ret; - cmd.type = type; - cmd.req = req; - usbhost_putle16(cmd.value, value); - usbhost_putle16(cmd.index, index); - usbhost_putle16(cmd.len, len); - + len = usbhost_getle16(ctrlreq->len); xfer.buffer = buffer; xfer.buflen = len; xfer.len = len; @@ -576,17 +602,17 @@ int usbhost_ctrlxfer(FAR struct usbhost_class_s *devclass, if (ROOTHUB(devclass)) { - ret = DRVR_RHCTRL(devclass->drvr, &xfer, &cmd); + ret = DRVR_RHCTRL(devclass->drvr, &xfer, ctrlreq); } else { - if (type & USB_REQ_DIR_IN) + if ((ctrlreq->type & USB_REQ_DIR_IN) != 0) { - ret = DRVR_CTRLIN(devclass->drvr, &xfer, &cmd); + ret = DRVR_CTRLIN(devclass->drvr, &xfer, ctrlreq); } else { - ret = DRVR_CTRLOUT(devclass->drvr, &xfer, &cmd); + ret = DRVR_CTRLOUT(devclass->drvr, &xfer, ctrlreq); } } @@ -609,42 +635,3 @@ out: return ret; } - -/**************************************************************************** - * Name: usbhost_intxfer - * - * Description: - * Free transfer buffer memory. - * - * Input Parameters: - * devclass - A reference to the class instance. - * xfer - Describes the transfer to be performed - * callback - The transfer complete callback - * - * Returned Values: - * On sucess, zero (OK) is returned. On failure, an negated errno value - * is returned to indicate the nature of the failure. - * - ****************************************************************************/ - -#ifdef CONFIG_USBHOST_HUB -int usbhost_intxfer(FAR struct usbhost_class_s *devclass, - FAR struct usbhost_transfer_s *xfer, - void (*callback)(FAR struct usbhost_transfer_s *)) -{ - int ret; - - xfer->callback = callback; - - if (ROOTHUB(devclass)) - { - ret = DRVR_RHSTATUS(devclass->drvr, xfer); - } - else - { - ret = DRVR_TRANSFER(devclass->drvr, xfer); - } - - return ret; -} -#endif diff --git a/drivers/usbhost/usbhost_hub.c b/drivers/usbhost/usbhost_hub.c index 4b84a8e8c8..e852654193 100644 --- a/drivers/usbhost/usbhost_hub.c +++ b/drivers/usbhost/usbhost_hub.c @@ -733,6 +733,43 @@ static inline int usbhost_hubpwr(FAR struct usbhost_class_s *hubclass, bool on) return OK; } +/**************************************************************************** + * Name: usbhost_intxfer + * + * Description: + * Free transfer buffer memory. + * + * Input Parameters: + * devclass - A reference to the class instance. + * xfer - Describes the transfer to be performed + * callback - The transfer complete callback + * + * Returned Values: + * On sucess, zero (OK) is returned. On failure, an negated errno value + * is returned to indicate the nature of the failure. + * + ****************************************************************************/ + +static int usbhost_intxfer(FAR struct usbhost_class_s *devclass, + FAR struct usbhost_transfer_s *xfer, + void (*callback)(FAR struct usbhost_transfer_s *)) +{ + int ret; + + xfer->callback = callback; + + if (ROOTHUB(devclass)) + { + ret = DRVR_RHSTATUS(devclass->drvr, xfer); + } + else + { + ret = DRVR_TRANSFER(devclass->drvr, xfer); + } + + return ret; +} + /**************************************************************************** * Name: usbhost_hubevent * diff --git a/include/nuttx/usb/usbhost.h b/include/nuttx/usb/usbhost.h index 80628002b8..b0c7b0257a 100644 --- a/include/nuttx/usb/usbhost.h +++ b/include/nuttx/usb/usbhost.h @@ -1066,7 +1066,7 @@ int usbhost_enumerate(FAR struct usbhost_class_s *devclass); * * Input Parameters: * devclass - A reference to the class instance. - * type, req, value, index, len - Describes the control transfer + * ctrlreq - Describes the control request transfer * buffer - Data accompanying the control transfer * * Returned Values: @@ -1075,32 +1075,9 @@ int usbhost_enumerate(FAR struct usbhost_class_s *devclass); * ****************************************************************************/ -int usbhost_ctrlxfer(FAR struct usbhost_class_s *devclass, uint8_t type, - uint8_t req, uint16_t value, uint16_t index, - uint16_t len, FAR uint8_t *buffer); - -#ifdef CONFIG_USBHOST_HUB -/**************************************************************************** - * Name: usbhost_intxfer - * - * Description: - * Free transfer buffer memory. - * - * Input Parameters: - * devclass - A reference to the class instance. - * xfer - Describes the transfer to be performed - * callback - The transfer complete callback - * - * Returned Values: - * On success, zero (OK) is returned. On failure, an negated errno value - * is returned to indicate the nature of the failure. - * - ****************************************************************************/ - -int usbhost_intxfer(FAR struct usbhost_class_s *devclass, - FAR struct usbhost_transfer_s *xfer, - void (*callback)(FAR struct usbhost_transfer_s *)); -#endif +int usbhost_ctrlxfer(FAR struct usbhost_class_s *devclass, + FAR struct usb_ctrlreq_s *ctrlreq, + FAR uint8_t *buffer); #ifdef CONFIG_USBHOST_HUB /******************************************************************************* @@ -1122,6 +1099,26 @@ int usbhost_intxfer(FAR struct usbhost_class_s *devclass, int usbhost_rh_connect(FAR struct usbhost_driver_s *drvr); #endif +/******************************************************************************* + * Name: usbhost_rh_disconnect + * + * Description: + * Disconnects USB host root hub + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call + * to the class create() method. + * + * Returned Value: + * + * Assumptions: + * + *******************************************************************************/ + +#ifdef CONFIG_USBHOST_HUB +int usbhost_rh_disconnect(FAR struct usbhost_driver_s *drvr); +#endif + #undef EXTERN #if defined(__cplusplus) }