MFp4 //depot/projects/usb@160930
Change the roothub exec functions to take the usb request and data pointers directly rather than placing them on the parent bus struct. Submitted by: Hans Petter Selasky
This commit is contained in:
parent
c1911c1b7c
commit
459d369ee2
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=191402
@ -1744,28 +1744,32 @@ USB_MAKE_STRING_DESC(STRING_LANG, at91dci_langtab);
|
||||
USB_MAKE_STRING_DESC(STRING_VENDOR, at91dci_vendor);
|
||||
USB_MAKE_STRING_DESC(STRING_PRODUCT, at91dci_product);
|
||||
|
||||
static void
|
||||
at91dci_roothub_exec(struct usb2_bus *bus)
|
||||
static usb2_error_t
|
||||
at91dci_roothub_exec(struct usb2_device *udev,
|
||||
struct usb2_device_request *req, const void **pptr, uint16_t *plength)
|
||||
{
|
||||
struct at91dci_softc *sc = AT9100_DCI_BUS2SC(bus);
|
||||
struct usb2_sw_transfer *std = &sc->sc_bus.roothub_req;
|
||||
struct at91dci_softc *sc = AT9100_DCI_BUS2SC(udev->bus);
|
||||
const void *ptr;
|
||||
uint16_t len;
|
||||
uint16_t value;
|
||||
uint16_t index;
|
||||
usb2_error_t err;
|
||||
|
||||
USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
|
||||
|
||||
/* buffer reset */
|
||||
std->ptr = USB_ADD_BYTES(&sc->sc_hub_temp, 0);
|
||||
std->len = 0;
|
||||
ptr = (const void *)&sc->sc_hub_temp;
|
||||
len = 0;
|
||||
err = 0;
|
||||
|
||||
value = UGETW(std->req.wValue);
|
||||
index = UGETW(std->req.wIndex);
|
||||
value = UGETW(req->wValue);
|
||||
index = UGETW(req->wIndex);
|
||||
|
||||
/* demultiplex the control request */
|
||||
|
||||
switch (std->req.bmRequestType) {
|
||||
switch (req->bmRequestType) {
|
||||
case UT_READ_DEVICE:
|
||||
switch (std->req.bRequest) {
|
||||
switch (req->bRequest) {
|
||||
case UR_GET_DESCRIPTOR:
|
||||
goto tr_handle_get_descriptor;
|
||||
case UR_GET_CONFIG:
|
||||
@ -1778,7 +1782,7 @@ at91dci_roothub_exec(struct usb2_bus *bus)
|
||||
break;
|
||||
|
||||
case UT_WRITE_DEVICE:
|
||||
switch (std->req.bRequest) {
|
||||
switch (req->bRequest) {
|
||||
case UR_SET_ADDRESS:
|
||||
goto tr_handle_set_address;
|
||||
case UR_SET_CONFIG:
|
||||
@ -1794,9 +1798,9 @@ at91dci_roothub_exec(struct usb2_bus *bus)
|
||||
break;
|
||||
|
||||
case UT_WRITE_ENDPOINT:
|
||||
switch (std->req.bRequest) {
|
||||
switch (req->bRequest) {
|
||||
case UR_CLEAR_FEATURE:
|
||||
switch (UGETW(std->req.wValue)) {
|
||||
switch (UGETW(req->wValue)) {
|
||||
case UF_ENDPOINT_HALT:
|
||||
goto tr_handle_clear_halt;
|
||||
case UF_DEVICE_REMOTE_WAKEUP:
|
||||
@ -1806,7 +1810,7 @@ at91dci_roothub_exec(struct usb2_bus *bus)
|
||||
}
|
||||
break;
|
||||
case UR_SET_FEATURE:
|
||||
switch (UGETW(std->req.wValue)) {
|
||||
switch (UGETW(req->wValue)) {
|
||||
case UF_ENDPOINT_HALT:
|
||||
goto tr_handle_set_halt;
|
||||
case UF_DEVICE_REMOTE_WAKEUP:
|
||||
@ -1823,7 +1827,7 @@ at91dci_roothub_exec(struct usb2_bus *bus)
|
||||
break;
|
||||
|
||||
case UT_READ_ENDPOINT:
|
||||
switch (std->req.bRequest) {
|
||||
switch (req->bRequest) {
|
||||
case UR_GET_STATUS:
|
||||
goto tr_handle_get_ep_status;
|
||||
default:
|
||||
@ -1832,7 +1836,7 @@ at91dci_roothub_exec(struct usb2_bus *bus)
|
||||
break;
|
||||
|
||||
case UT_WRITE_INTERFACE:
|
||||
switch (std->req.bRequest) {
|
||||
switch (req->bRequest) {
|
||||
case UR_SET_INTERFACE:
|
||||
goto tr_handle_set_interface;
|
||||
case UR_CLEAR_FEATURE:
|
||||
@ -1844,7 +1848,7 @@ at91dci_roothub_exec(struct usb2_bus *bus)
|
||||
break;
|
||||
|
||||
case UT_READ_INTERFACE:
|
||||
switch (std->req.bRequest) {
|
||||
switch (req->bRequest) {
|
||||
case UR_GET_INTERFACE:
|
||||
goto tr_handle_get_interface;
|
||||
case UR_GET_STATUS:
|
||||
@ -1865,7 +1869,7 @@ at91dci_roothub_exec(struct usb2_bus *bus)
|
||||
break;
|
||||
|
||||
case UT_WRITE_CLASS_DEVICE:
|
||||
switch (std->req.bRequest) {
|
||||
switch (req->bRequest) {
|
||||
case UR_CLEAR_FEATURE:
|
||||
goto tr_valid;
|
||||
case UR_SET_DESCRIPTOR:
|
||||
@ -1877,7 +1881,7 @@ at91dci_roothub_exec(struct usb2_bus *bus)
|
||||
break;
|
||||
|
||||
case UT_WRITE_CLASS_OTHER:
|
||||
switch (std->req.bRequest) {
|
||||
switch (req->bRequest) {
|
||||
case UR_CLEAR_FEATURE:
|
||||
goto tr_handle_clear_port_feature;
|
||||
case UR_SET_FEATURE:
|
||||
@ -1893,7 +1897,7 @@ at91dci_roothub_exec(struct usb2_bus *bus)
|
||||
break;
|
||||
|
||||
case UT_READ_CLASS_OTHER:
|
||||
switch (std->req.bRequest) {
|
||||
switch (req->bRequest) {
|
||||
case UR_GET_TT_STATE:
|
||||
goto tr_handle_get_tt_state;
|
||||
case UR_GET_STATUS:
|
||||
@ -1904,7 +1908,7 @@ at91dci_roothub_exec(struct usb2_bus *bus)
|
||||
break;
|
||||
|
||||
case UT_READ_CLASS_DEVICE:
|
||||
switch (std->req.bRequest) {
|
||||
switch (req->bRequest) {
|
||||
case UR_GET_DESCRIPTOR:
|
||||
goto tr_handle_get_class_descriptor;
|
||||
case UR_GET_STATUS:
|
||||
@ -1925,31 +1929,31 @@ at91dci_roothub_exec(struct usb2_bus *bus)
|
||||
if (value & 0xff) {
|
||||
goto tr_stalled;
|
||||
}
|
||||
std->len = sizeof(at91dci_devd);
|
||||
std->ptr = USB_ADD_BYTES(&at91dci_devd, 0);
|
||||
len = sizeof(at91dci_devd);
|
||||
ptr = (const void *)&at91dci_devd;
|
||||
goto tr_valid;
|
||||
case UDESC_CONFIG:
|
||||
if (value & 0xff) {
|
||||
goto tr_stalled;
|
||||
}
|
||||
std->len = sizeof(at91dci_confd);
|
||||
std->ptr = USB_ADD_BYTES(&at91dci_confd, 0);
|
||||
len = sizeof(at91dci_confd);
|
||||
ptr = (const void *)&at91dci_confd;
|
||||
goto tr_valid;
|
||||
case UDESC_STRING:
|
||||
switch (value & 0xff) {
|
||||
case 0: /* Language table */
|
||||
std->len = sizeof(at91dci_langtab);
|
||||
std->ptr = USB_ADD_BYTES(&at91dci_langtab, 0);
|
||||
len = sizeof(at91dci_langtab);
|
||||
ptr = (const void *)&at91dci_langtab;
|
||||
goto tr_valid;
|
||||
|
||||
case 1: /* Vendor */
|
||||
std->len = sizeof(at91dci_vendor);
|
||||
std->ptr = USB_ADD_BYTES(&at91dci_vendor, 0);
|
||||
len = sizeof(at91dci_vendor);
|
||||
ptr = (const void *)&at91dci_vendor;
|
||||
goto tr_valid;
|
||||
|
||||
case 2: /* Product */
|
||||
std->len = sizeof(at91dci_product);
|
||||
std->ptr = USB_ADD_BYTES(&at91dci_product, 0);
|
||||
len = sizeof(at91dci_product);
|
||||
ptr = (const void *)&at91dci_product;
|
||||
goto tr_valid;
|
||||
default:
|
||||
break;
|
||||
@ -1961,12 +1965,12 @@ at91dci_roothub_exec(struct usb2_bus *bus)
|
||||
goto tr_stalled;
|
||||
|
||||
tr_handle_get_config:
|
||||
std->len = 1;
|
||||
len = 1;
|
||||
sc->sc_hub_temp.wValue[0] = sc->sc_conf;
|
||||
goto tr_valid;
|
||||
|
||||
tr_handle_get_status:
|
||||
std->len = 2;
|
||||
len = 2;
|
||||
USETW(sc->sc_hub_temp.wValue, UDS_SELF_POWERED);
|
||||
goto tr_valid;
|
||||
|
||||
@ -1985,7 +1989,7 @@ at91dci_roothub_exec(struct usb2_bus *bus)
|
||||
goto tr_valid;
|
||||
|
||||
tr_handle_get_interface:
|
||||
std->len = 1;
|
||||
len = 1;
|
||||
sc->sc_hub_temp.wValue[0] = 0;
|
||||
goto tr_valid;
|
||||
|
||||
@ -1993,7 +1997,7 @@ at91dci_roothub_exec(struct usb2_bus *bus)
|
||||
tr_handle_get_class_status:
|
||||
tr_handle_get_iface_status:
|
||||
tr_handle_get_ep_status:
|
||||
std->len = 2;
|
||||
len = 2;
|
||||
USETW(sc->sc_hub_temp.wValue, 0);
|
||||
goto tr_valid;
|
||||
|
||||
@ -2038,7 +2042,7 @@ at91dci_roothub_exec(struct usb2_bus *bus)
|
||||
sc->sc_flags.change_suspend = 0;
|
||||
break;
|
||||
default:
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
goto tr_valid;
|
||||
@ -2063,7 +2067,7 @@ at91dci_roothub_exec(struct usb2_bus *bus)
|
||||
sc->sc_flags.port_powered = 1;
|
||||
break;
|
||||
default:
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
goto tr_valid;
|
||||
@ -2117,22 +2121,24 @@ at91dci_roothub_exec(struct usb2_bus *bus)
|
||||
value |= UPS_C_SUSPEND;
|
||||
}
|
||||
USETW(sc->sc_hub_temp.ps.wPortChange, value);
|
||||
std->len = sizeof(sc->sc_hub_temp.ps);
|
||||
len = sizeof(sc->sc_hub_temp.ps);
|
||||
goto tr_valid;
|
||||
|
||||
tr_handle_get_class_descriptor:
|
||||
if (value & 0xFF) {
|
||||
goto tr_stalled;
|
||||
}
|
||||
std->ptr = USB_ADD_BYTES(&at91dci_hubd, 0);
|
||||
std->len = sizeof(at91dci_hubd);
|
||||
ptr = (const void *)&at91dci_hubd;
|
||||
len = sizeof(at91dci_hubd);
|
||||
goto tr_valid;
|
||||
|
||||
tr_stalled:
|
||||
std->err = USB_ERR_STALLED;
|
||||
err = USB_ERR_STALLED;
|
||||
tr_valid:
|
||||
done:
|
||||
return;
|
||||
*plength = len;
|
||||
*pptr = ptr;
|
||||
return (err);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1551,29 +1551,33 @@ USB_MAKE_STRING_DESC(STRING_LANG, atmegadci_langtab);
|
||||
USB_MAKE_STRING_DESC(STRING_VENDOR, atmegadci_vendor);
|
||||
USB_MAKE_STRING_DESC(STRING_PRODUCT, atmegadci_product);
|
||||
|
||||
static void
|
||||
atmegadci_roothub_exec(struct usb2_bus *bus)
|
||||
static usb2_error_t
|
||||
atmegadci_roothub_exec(struct usb2_device *udev,
|
||||
struct usb2_device_request *req, const void **pptr, uint16_t *plength)
|
||||
{
|
||||
struct atmegadci_softc *sc = ATMEGA_BUS2SC(bus);
|
||||
struct usb2_sw_transfer *std = &sc->sc_bus.roothub_req;
|
||||
struct atmegadci_softc *sc = ATMEGA_BUS2SC(udev->bus);
|
||||
const void *ptr;
|
||||
uint16_t len;
|
||||
uint16_t value;
|
||||
uint16_t index;
|
||||
uint8_t temp;
|
||||
usb2_error_t err;
|
||||
|
||||
USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
|
||||
|
||||
/* buffer reset */
|
||||
std->ptr = USB_ADD_BYTES(&sc->sc_hub_temp, 0);
|
||||
std->len = 0;
|
||||
ptr = (const void *)&sc->sc_hub_temp;
|
||||
len = 0;
|
||||
err = 0;
|
||||
|
||||
value = UGETW(std->req.wValue);
|
||||
index = UGETW(std->req.wIndex);
|
||||
value = UGETW(req->wValue);
|
||||
index = UGETW(req->wIndex);
|
||||
|
||||
/* demultiplex the control request */
|
||||
|
||||
switch (std->req.bmRequestType) {
|
||||
switch (req->bmRequestType) {
|
||||
case UT_READ_DEVICE:
|
||||
switch (std->req.bRequest) {
|
||||
switch (req->bRequest) {
|
||||
case UR_GET_DESCRIPTOR:
|
||||
goto tr_handle_get_descriptor;
|
||||
case UR_GET_CONFIG:
|
||||
@ -1586,7 +1590,7 @@ atmegadci_roothub_exec(struct usb2_bus *bus)
|
||||
break;
|
||||
|
||||
case UT_WRITE_DEVICE:
|
||||
switch (std->req.bRequest) {
|
||||
switch (req->bRequest) {
|
||||
case UR_SET_ADDRESS:
|
||||
goto tr_handle_set_address;
|
||||
case UR_SET_CONFIG:
|
||||
@ -1602,9 +1606,9 @@ atmegadci_roothub_exec(struct usb2_bus *bus)
|
||||
break;
|
||||
|
||||
case UT_WRITE_ENDPOINT:
|
||||
switch (std->req.bRequest) {
|
||||
switch (req->bRequest) {
|
||||
case UR_CLEAR_FEATURE:
|
||||
switch (UGETW(std->req.wValue)) {
|
||||
switch (UGETW(req->wValue)) {
|
||||
case UF_ENDPOINT_HALT:
|
||||
goto tr_handle_clear_halt;
|
||||
case UF_DEVICE_REMOTE_WAKEUP:
|
||||
@ -1614,7 +1618,7 @@ atmegadci_roothub_exec(struct usb2_bus *bus)
|
||||
}
|
||||
break;
|
||||
case UR_SET_FEATURE:
|
||||
switch (UGETW(std->req.wValue)) {
|
||||
switch (UGETW(req->wValue)) {
|
||||
case UF_ENDPOINT_HALT:
|
||||
goto tr_handle_set_halt;
|
||||
case UF_DEVICE_REMOTE_WAKEUP:
|
||||
@ -1631,7 +1635,7 @@ atmegadci_roothub_exec(struct usb2_bus *bus)
|
||||
break;
|
||||
|
||||
case UT_READ_ENDPOINT:
|
||||
switch (std->req.bRequest) {
|
||||
switch (req->bRequest) {
|
||||
case UR_GET_STATUS:
|
||||
goto tr_handle_get_ep_status;
|
||||
default:
|
||||
@ -1640,7 +1644,7 @@ atmegadci_roothub_exec(struct usb2_bus *bus)
|
||||
break;
|
||||
|
||||
case UT_WRITE_INTERFACE:
|
||||
switch (std->req.bRequest) {
|
||||
switch (req->bRequest) {
|
||||
case UR_SET_INTERFACE:
|
||||
goto tr_handle_set_interface;
|
||||
case UR_CLEAR_FEATURE:
|
||||
@ -1652,7 +1656,7 @@ atmegadci_roothub_exec(struct usb2_bus *bus)
|
||||
break;
|
||||
|
||||
case UT_READ_INTERFACE:
|
||||
switch (std->req.bRequest) {
|
||||
switch (req->bRequest) {
|
||||
case UR_GET_INTERFACE:
|
||||
goto tr_handle_get_interface;
|
||||
case UR_GET_STATUS:
|
||||
@ -1673,7 +1677,7 @@ atmegadci_roothub_exec(struct usb2_bus *bus)
|
||||
break;
|
||||
|
||||
case UT_WRITE_CLASS_DEVICE:
|
||||
switch (std->req.bRequest) {
|
||||
switch (req->bRequest) {
|
||||
case UR_CLEAR_FEATURE:
|
||||
goto tr_valid;
|
||||
case UR_SET_DESCRIPTOR:
|
||||
@ -1685,7 +1689,7 @@ atmegadci_roothub_exec(struct usb2_bus *bus)
|
||||
break;
|
||||
|
||||
case UT_WRITE_CLASS_OTHER:
|
||||
switch (std->req.bRequest) {
|
||||
switch (req->bRequest) {
|
||||
case UR_CLEAR_FEATURE:
|
||||
goto tr_handle_clear_port_feature;
|
||||
case UR_SET_FEATURE:
|
||||
@ -1701,7 +1705,7 @@ atmegadci_roothub_exec(struct usb2_bus *bus)
|
||||
break;
|
||||
|
||||
case UT_READ_CLASS_OTHER:
|
||||
switch (std->req.bRequest) {
|
||||
switch (req->bRequest) {
|
||||
case UR_GET_TT_STATE:
|
||||
goto tr_handle_get_tt_state;
|
||||
case UR_GET_STATUS:
|
||||
@ -1712,7 +1716,7 @@ atmegadci_roothub_exec(struct usb2_bus *bus)
|
||||
break;
|
||||
|
||||
case UT_READ_CLASS_DEVICE:
|
||||
switch (std->req.bRequest) {
|
||||
switch (req->bRequest) {
|
||||
case UR_GET_DESCRIPTOR:
|
||||
goto tr_handle_get_class_descriptor;
|
||||
case UR_GET_STATUS:
|
||||
@ -1733,31 +1737,31 @@ atmegadci_roothub_exec(struct usb2_bus *bus)
|
||||
if (value & 0xff) {
|
||||
goto tr_stalled;
|
||||
}
|
||||
std->len = sizeof(atmegadci_devd);
|
||||
std->ptr = USB_ADD_BYTES(&atmegadci_devd, 0);
|
||||
len = sizeof(atmegadci_devd);
|
||||
ptr = (const void *)&atmegadci_devd;
|
||||
goto tr_valid;
|
||||
case UDESC_CONFIG:
|
||||
if (value & 0xff) {
|
||||
goto tr_stalled;
|
||||
}
|
||||
std->len = sizeof(atmegadci_confd);
|
||||
std->ptr = USB_ADD_BYTES(&atmegadci_confd, 0);
|
||||
len = sizeof(atmegadci_confd);
|
||||
ptr = (const void *)&atmegadci_confd;
|
||||
goto tr_valid;
|
||||
case UDESC_STRING:
|
||||
switch (value & 0xff) {
|
||||
case 0: /* Language table */
|
||||
std->len = sizeof(atmegadci_langtab);
|
||||
std->ptr = USB_ADD_BYTES(&atmegadci_langtab, 0);
|
||||
len = sizeof(atmegadci_langtab);
|
||||
ptr = (const void *)&atmegadci_langtab;
|
||||
goto tr_valid;
|
||||
|
||||
case 1: /* Vendor */
|
||||
std->len = sizeof(atmegadci_vendor);
|
||||
std->ptr = USB_ADD_BYTES(&atmegadci_vendor, 0);
|
||||
len = sizeof(atmegadci_vendor);
|
||||
ptr = (const void *)&atmegadci_vendor;
|
||||
goto tr_valid;
|
||||
|
||||
case 2: /* Product */
|
||||
std->len = sizeof(atmegadci_product);
|
||||
std->ptr = USB_ADD_BYTES(&atmegadci_product, 0);
|
||||
len = sizeof(atmegadci_product);
|
||||
ptr = (const void *)&atmegadci_product;
|
||||
goto tr_valid;
|
||||
default:
|
||||
break;
|
||||
@ -1769,12 +1773,12 @@ atmegadci_roothub_exec(struct usb2_bus *bus)
|
||||
goto tr_stalled;
|
||||
|
||||
tr_handle_get_config:
|
||||
std->len = 1;
|
||||
len = 1;
|
||||
sc->sc_hub_temp.wValue[0] = sc->sc_conf;
|
||||
goto tr_valid;
|
||||
|
||||
tr_handle_get_status:
|
||||
std->len = 2;
|
||||
len = 2;
|
||||
USETW(sc->sc_hub_temp.wValue, UDS_SELF_POWERED);
|
||||
goto tr_valid;
|
||||
|
||||
@ -1793,7 +1797,7 @@ atmegadci_roothub_exec(struct usb2_bus *bus)
|
||||
goto tr_valid;
|
||||
|
||||
tr_handle_get_interface:
|
||||
std->len = 1;
|
||||
len = 1;
|
||||
sc->sc_hub_temp.wValue[0] = 0;
|
||||
goto tr_valid;
|
||||
|
||||
@ -1801,7 +1805,7 @@ atmegadci_roothub_exec(struct usb2_bus *bus)
|
||||
tr_handle_get_class_status:
|
||||
tr_handle_get_iface_status:
|
||||
tr_handle_get_ep_status:
|
||||
std->len = 2;
|
||||
len = 2;
|
||||
USETW(sc->sc_hub_temp.wValue, 0);
|
||||
goto tr_valid;
|
||||
|
||||
@ -1877,7 +1881,7 @@ atmegadci_roothub_exec(struct usb2_bus *bus)
|
||||
sc->sc_flags.change_suspend = 0;
|
||||
break;
|
||||
default:
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
goto tr_valid;
|
||||
@ -1902,7 +1906,7 @@ atmegadci_roothub_exec(struct usb2_bus *bus)
|
||||
sc->sc_flags.port_powered = 1;
|
||||
break;
|
||||
default:
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
goto tr_valid;
|
||||
@ -1950,22 +1954,24 @@ atmegadci_roothub_exec(struct usb2_bus *bus)
|
||||
value |= UPS_C_SUSPEND;
|
||||
}
|
||||
USETW(sc->sc_hub_temp.ps.wPortChange, value);
|
||||
std->len = sizeof(sc->sc_hub_temp.ps);
|
||||
len = sizeof(sc->sc_hub_temp.ps);
|
||||
goto tr_valid;
|
||||
|
||||
tr_handle_get_class_descriptor:
|
||||
if (value & 0xFF) {
|
||||
goto tr_stalled;
|
||||
}
|
||||
std->ptr = USB_ADD_BYTES(&atmegadci_hubd, 0);
|
||||
std->len = sizeof(atmegadci_hubd);
|
||||
ptr = (const void *)&atmegadci_hubd;
|
||||
len = sizeof(atmegadci_hubd);
|
||||
goto tr_valid;
|
||||
|
||||
tr_stalled:
|
||||
std->err = USB_ERR_STALLED;
|
||||
err = USB_ERR_STALLED;
|
||||
tr_valid:
|
||||
done:
|
||||
return;
|
||||
*plength = len;
|
||||
*pptr = ptr;
|
||||
return (err);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -2987,35 +2987,39 @@ ehci_disown(ehci_softc_t *sc, uint16_t index, uint8_t lowspeed)
|
||||
EOWRITE4(sc, port, v | EHCI_PS_PO);
|
||||
}
|
||||
|
||||
static void
|
||||
ehci_roothub_exec(struct usb2_bus *bus)
|
||||
static usb2_error_t
|
||||
ehci_roothub_exec(struct usb2_device *udev,
|
||||
struct usb2_device_request *req, const void **pptr, uint16_t *plength)
|
||||
{
|
||||
ehci_softc_t *sc = EHCI_BUS2SC(bus);
|
||||
struct usb2_sw_transfer *std = &sc->sc_bus.roothub_req;
|
||||
char *ptr;
|
||||
ehci_softc_t *sc = EHCI_BUS2SC(udev->bus);
|
||||
const char *str_ptr;
|
||||
const void *ptr;
|
||||
uint32_t port;
|
||||
uint32_t v;
|
||||
uint16_t len;
|
||||
uint16_t i;
|
||||
uint16_t value;
|
||||
uint16_t index;
|
||||
uint8_t l;
|
||||
usb2_error_t err;
|
||||
|
||||
USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
|
||||
|
||||
/* buffer reset */
|
||||
std->ptr = sc->sc_hub_desc.temp;
|
||||
std->len = 0;
|
||||
ptr = (const void *)&sc->sc_hub_desc;
|
||||
len = 0;
|
||||
err = 0;
|
||||
|
||||
value = UGETW(std->req.wValue);
|
||||
index = UGETW(std->req.wIndex);
|
||||
value = UGETW(req->wValue);
|
||||
index = UGETW(req->wIndex);
|
||||
|
||||
DPRINTFN(3, "type=0x%02x request=0x%02x wLen=0x%04x "
|
||||
"wValue=0x%04x wIndex=0x%04x\n",
|
||||
std->req.bmRequestType, std->req.bRequest,
|
||||
UGETW(std->req.wLength), value, index);
|
||||
req->bmRequestType, req->bRequest,
|
||||
UGETW(req->wLength), value, index);
|
||||
|
||||
#define C(x,y) ((x) | ((y) << 8))
|
||||
switch (C(std->req.bRequest, std->req.bmRequestType)) {
|
||||
switch (C(req->bRequest, req->bmRequestType)) {
|
||||
case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE):
|
||||
case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE):
|
||||
case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT):
|
||||
@ -3025,18 +3029,18 @@ ehci_roothub_exec(struct usb2_bus *bus)
|
||||
*/
|
||||
break;
|
||||
case C(UR_GET_CONFIG, UT_READ_DEVICE):
|
||||
std->len = 1;
|
||||
len = 1;
|
||||
sc->sc_hub_desc.temp[0] = sc->sc_conf;
|
||||
break;
|
||||
case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
|
||||
switch (value >> 8) {
|
||||
case UDESC_DEVICE:
|
||||
if ((value & 0xff) != 0) {
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
std->len = sizeof(ehci_devd);
|
||||
sc->sc_hub_desc.devd = ehci_devd;
|
||||
len = sizeof(ehci_devd);
|
||||
ptr = (const void *)&ehci_devd;
|
||||
break;
|
||||
/*
|
||||
* We can't really operate at another speed,
|
||||
@ -3045,74 +3049,74 @@ ehci_roothub_exec(struct usb2_bus *bus)
|
||||
*/
|
||||
case UDESC_DEVICE_QUALIFIER:
|
||||
if ((value & 0xff) != 0) {
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
std->len = sizeof(ehci_odevd);
|
||||
sc->sc_hub_desc.odevd = ehci_odevd;
|
||||
len = sizeof(ehci_odevd);
|
||||
ptr = (const void *)&ehci_odevd;
|
||||
break;
|
||||
|
||||
case UDESC_CONFIG:
|
||||
if ((value & 0xff) != 0) {
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
std->len = sizeof(ehci_confd);
|
||||
std->ptr = USB_ADD_BYTES(&ehci_confd, 0);
|
||||
len = sizeof(ehci_confd);
|
||||
ptr = (const void *)&ehci_confd;
|
||||
break;
|
||||
|
||||
case UDESC_STRING:
|
||||
switch (value & 0xff) {
|
||||
case 0: /* Language table */
|
||||
ptr = "\001";
|
||||
str_ptr = "\001";
|
||||
break;
|
||||
|
||||
case 1: /* Vendor */
|
||||
ptr = sc->sc_vendor;
|
||||
str_ptr = sc->sc_vendor;
|
||||
break;
|
||||
|
||||
case 2: /* Product */
|
||||
ptr = "EHCI root HUB";
|
||||
str_ptr = "EHCI root HUB";
|
||||
break;
|
||||
|
||||
default:
|
||||
ptr = "";
|
||||
str_ptr = "";
|
||||
break;
|
||||
}
|
||||
|
||||
std->len = usb2_make_str_desc
|
||||
(sc->sc_hub_desc.temp,
|
||||
len = usb2_make_str_desc(
|
||||
sc->sc_hub_desc.temp,
|
||||
sizeof(sc->sc_hub_desc.temp),
|
||||
ptr);
|
||||
str_ptr);
|
||||
break;
|
||||
default:
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
break;
|
||||
case C(UR_GET_INTERFACE, UT_READ_INTERFACE):
|
||||
std->len = 1;
|
||||
len = 1;
|
||||
sc->sc_hub_desc.temp[0] = 0;
|
||||
break;
|
||||
case C(UR_GET_STATUS, UT_READ_DEVICE):
|
||||
std->len = 2;
|
||||
len = 2;
|
||||
USETW(sc->sc_hub_desc.stat.wStatus, UDS_SELF_POWERED);
|
||||
break;
|
||||
case C(UR_GET_STATUS, UT_READ_INTERFACE):
|
||||
case C(UR_GET_STATUS, UT_READ_ENDPOINT):
|
||||
std->len = 2;
|
||||
len = 2;
|
||||
USETW(sc->sc_hub_desc.stat.wStatus, 0);
|
||||
break;
|
||||
case C(UR_SET_ADDRESS, UT_WRITE_DEVICE):
|
||||
if (value >= EHCI_MAX_DEVICES) {
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
sc->sc_addr = value;
|
||||
break;
|
||||
case C(UR_SET_CONFIG, UT_WRITE_DEVICE):
|
||||
if ((value != 0) && (value != 1)) {
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
sc->sc_conf = value;
|
||||
@ -3122,7 +3126,7 @@ ehci_roothub_exec(struct usb2_bus *bus)
|
||||
case C(UR_SET_FEATURE, UT_WRITE_DEVICE):
|
||||
case C(UR_SET_FEATURE, UT_WRITE_INTERFACE):
|
||||
case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT):
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE):
|
||||
break;
|
||||
@ -3136,7 +3140,7 @@ ehci_roothub_exec(struct usb2_bus *bus)
|
||||
|
||||
if ((index < 1) ||
|
||||
(index > sc->sc_noport)) {
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
port = EHCI_PORTSC(index);
|
||||
@ -3191,13 +3195,13 @@ ehci_roothub_exec(struct usb2_bus *bus)
|
||||
sc->sc_isreset = 0;
|
||||
break;
|
||||
default:
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
break;
|
||||
case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE):
|
||||
if ((value & 0xff) != 0) {
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
v = EOREAD4(sc, EHCI_HCSPARAMS);
|
||||
@ -3216,10 +3220,10 @@ ehci_roothub_exec(struct usb2_bus *bus)
|
||||
}
|
||||
sc->sc_hub_desc.hubd.bDescLength =
|
||||
8 + ((sc->sc_noport + 7) / 8);
|
||||
std->len = sc->sc_hub_desc.hubd.bDescLength;
|
||||
len = sc->sc_hub_desc.hubd.bDescLength;
|
||||
break;
|
||||
case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
|
||||
std->len = 16;
|
||||
len = 16;
|
||||
bzero(sc->sc_hub_desc.temp, 16);
|
||||
break;
|
||||
case C(UR_GET_STATUS, UT_READ_CLASS_OTHER):
|
||||
@ -3227,7 +3231,7 @@ ehci_roothub_exec(struct usb2_bus *bus)
|
||||
index);
|
||||
if ((index < 1) ||
|
||||
(index > sc->sc_noport)) {
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
v = EOREAD4(sc, EHCI_PORTSC(index));
|
||||
@ -3267,17 +3271,17 @@ ehci_roothub_exec(struct usb2_bus *bus)
|
||||
if (sc->sc_isreset)
|
||||
i |= UPS_C_PORT_RESET;
|
||||
USETW(sc->sc_hub_desc.ps.wPortChange, i);
|
||||
std->len = sizeof(sc->sc_hub_desc.ps);
|
||||
len = sizeof(sc->sc_hub_desc.ps);
|
||||
break;
|
||||
case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE):
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE):
|
||||
break;
|
||||
case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER):
|
||||
if ((index < 1) ||
|
||||
(index > sc->sc_noport)) {
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
port = EHCI_PORTSC(index);
|
||||
@ -3328,7 +3332,7 @@ ehci_roothub_exec(struct usb2_bus *bus)
|
||||
if (v & EHCI_PS_PR) {
|
||||
device_printf(sc->sc_bus.bdev,
|
||||
"port reset timeout\n");
|
||||
std->err = USB_ERR_TIMEOUT;
|
||||
err = USB_ERR_TIMEOUT;
|
||||
goto done;
|
||||
}
|
||||
if (!(v & EHCI_PS_PE) &&
|
||||
@ -3357,7 +3361,7 @@ ehci_roothub_exec(struct usb2_bus *bus)
|
||||
break;
|
||||
|
||||
default:
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
break;
|
||||
@ -3367,11 +3371,13 @@ ehci_roothub_exec(struct usb2_bus *bus)
|
||||
case C(UR_STOP_TT, UT_WRITE_CLASS_OTHER):
|
||||
break;
|
||||
default:
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
done:
|
||||
return;
|
||||
*plength = len;
|
||||
*pptr = ptr;
|
||||
return (err);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -446,8 +446,6 @@ struct ehci_config_desc {
|
||||
union ehci_hub_desc {
|
||||
struct usb2_status stat;
|
||||
struct usb2_port_status ps;
|
||||
struct usb2_device_descriptor devd;
|
||||
struct usb2_device_qualifier odevd;
|
||||
struct usb2_hub_descriptor hubd;
|
||||
uint8_t temp[128];
|
||||
};
|
||||
|
@ -2152,28 +2152,32 @@ USB_MAKE_STRING_DESC(STRING_LANG, musbotg_langtab);
|
||||
USB_MAKE_STRING_DESC(STRING_VENDOR, musbotg_vendor);
|
||||
USB_MAKE_STRING_DESC(STRING_PRODUCT, musbotg_product);
|
||||
|
||||
static void
|
||||
musbotg_roothub_exec(struct usb2_bus *bus)
|
||||
static usb2_error_t
|
||||
musbotg_roothub_exec(struct usb2_device *udev,
|
||||
struct usb2_device_request *req, const void **pptr, uint16_t *plength)
|
||||
{
|
||||
struct musbotg_softc *sc = MUSBOTG_BUS2SC(bus);
|
||||
struct usb2_sw_transfer *std = &sc->sc_bus.roothub_req;
|
||||
struct musbotg_softc *sc = MUSBOTG_BUS2SC(udev->bus);
|
||||
const void *ptr;
|
||||
uint16_t len;
|
||||
uint16_t value;
|
||||
uint16_t index;
|
||||
usb2_error_t err;
|
||||
|
||||
USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
|
||||
|
||||
/* buffer reset */
|
||||
std->ptr = USB_ADD_BYTES(&sc->sc_hub_temp, 0);
|
||||
std->len = 0;
|
||||
ptr = (const void *)&sc->sc_hub_temp;
|
||||
len = 0;
|
||||
err = 0;
|
||||
|
||||
value = UGETW(std->req.wValue);
|
||||
index = UGETW(std->req.wIndex);
|
||||
value = UGETW(req->wValue);
|
||||
index = UGETW(req->wIndex);
|
||||
|
||||
/* demultiplex the control request */
|
||||
|
||||
switch (std->req.bmRequestType) {
|
||||
switch (req->bmRequestType) {
|
||||
case UT_READ_DEVICE:
|
||||
switch (std->req.bRequest) {
|
||||
switch (req->bRequest) {
|
||||
case UR_GET_DESCRIPTOR:
|
||||
goto tr_handle_get_descriptor;
|
||||
case UR_GET_CONFIG:
|
||||
@ -2186,7 +2190,7 @@ musbotg_roothub_exec(struct usb2_bus *bus)
|
||||
break;
|
||||
|
||||
case UT_WRITE_DEVICE:
|
||||
switch (std->req.bRequest) {
|
||||
switch (req->bRequest) {
|
||||
case UR_SET_ADDRESS:
|
||||
goto tr_handle_set_address;
|
||||
case UR_SET_CONFIG:
|
||||
@ -2202,9 +2206,9 @@ musbotg_roothub_exec(struct usb2_bus *bus)
|
||||
break;
|
||||
|
||||
case UT_WRITE_ENDPOINT:
|
||||
switch (std->req.bRequest) {
|
||||
switch (req->bRequest) {
|
||||
case UR_CLEAR_FEATURE:
|
||||
switch (UGETW(std->req.wValue)) {
|
||||
switch (UGETW(req->wValue)) {
|
||||
case UF_ENDPOINT_HALT:
|
||||
goto tr_handle_clear_halt;
|
||||
case UF_DEVICE_REMOTE_WAKEUP:
|
||||
@ -2214,7 +2218,7 @@ musbotg_roothub_exec(struct usb2_bus *bus)
|
||||
}
|
||||
break;
|
||||
case UR_SET_FEATURE:
|
||||
switch (UGETW(std->req.wValue)) {
|
||||
switch (UGETW(req->wValue)) {
|
||||
case UF_ENDPOINT_HALT:
|
||||
goto tr_handle_set_halt;
|
||||
case UF_DEVICE_REMOTE_WAKEUP:
|
||||
@ -2231,7 +2235,7 @@ musbotg_roothub_exec(struct usb2_bus *bus)
|
||||
break;
|
||||
|
||||
case UT_READ_ENDPOINT:
|
||||
switch (std->req.bRequest) {
|
||||
switch (req->bRequest) {
|
||||
case UR_GET_STATUS:
|
||||
goto tr_handle_get_ep_status;
|
||||
default:
|
||||
@ -2240,7 +2244,7 @@ musbotg_roothub_exec(struct usb2_bus *bus)
|
||||
break;
|
||||
|
||||
case UT_WRITE_INTERFACE:
|
||||
switch (std->req.bRequest) {
|
||||
switch (req->bRequest) {
|
||||
case UR_SET_INTERFACE:
|
||||
goto tr_handle_set_interface;
|
||||
case UR_CLEAR_FEATURE:
|
||||
@ -2252,7 +2256,7 @@ musbotg_roothub_exec(struct usb2_bus *bus)
|
||||
break;
|
||||
|
||||
case UT_READ_INTERFACE:
|
||||
switch (std->req.bRequest) {
|
||||
switch (req->bRequest) {
|
||||
case UR_GET_INTERFACE:
|
||||
goto tr_handle_get_interface;
|
||||
case UR_GET_STATUS:
|
||||
@ -2273,7 +2277,7 @@ musbotg_roothub_exec(struct usb2_bus *bus)
|
||||
break;
|
||||
|
||||
case UT_WRITE_CLASS_DEVICE:
|
||||
switch (std->req.bRequest) {
|
||||
switch (req->bRequest) {
|
||||
case UR_CLEAR_FEATURE:
|
||||
goto tr_valid;
|
||||
case UR_SET_DESCRIPTOR:
|
||||
@ -2285,7 +2289,7 @@ musbotg_roothub_exec(struct usb2_bus *bus)
|
||||
break;
|
||||
|
||||
case UT_WRITE_CLASS_OTHER:
|
||||
switch (std->req.bRequest) {
|
||||
switch (req->bRequest) {
|
||||
case UR_CLEAR_FEATURE:
|
||||
goto tr_handle_clear_port_feature;
|
||||
case UR_SET_FEATURE:
|
||||
@ -2301,7 +2305,7 @@ musbotg_roothub_exec(struct usb2_bus *bus)
|
||||
break;
|
||||
|
||||
case UT_READ_CLASS_OTHER:
|
||||
switch (std->req.bRequest) {
|
||||
switch (req->bRequest) {
|
||||
case UR_GET_TT_STATE:
|
||||
goto tr_handle_get_tt_state;
|
||||
case UR_GET_STATUS:
|
||||
@ -2312,7 +2316,7 @@ musbotg_roothub_exec(struct usb2_bus *bus)
|
||||
break;
|
||||
|
||||
case UT_READ_CLASS_DEVICE:
|
||||
switch (std->req.bRequest) {
|
||||
switch (req->bRequest) {
|
||||
case UR_GET_DESCRIPTOR:
|
||||
goto tr_handle_get_class_descriptor;
|
||||
case UR_GET_STATUS:
|
||||
@ -2333,31 +2337,31 @@ musbotg_roothub_exec(struct usb2_bus *bus)
|
||||
if (value & 0xff) {
|
||||
goto tr_stalled;
|
||||
}
|
||||
std->len = sizeof(musbotg_devd);
|
||||
std->ptr = USB_ADD_BYTES(&musbotg_devd, 0);
|
||||
len = sizeof(musbotg_devd);
|
||||
ptr = (const void *)&musbotg_devd;
|
||||
goto tr_valid;
|
||||
case UDESC_CONFIG:
|
||||
if (value & 0xff) {
|
||||
goto tr_stalled;
|
||||
}
|
||||
std->len = sizeof(musbotg_confd);
|
||||
std->ptr = USB_ADD_BYTES(&musbotg_confd, 0);
|
||||
len = sizeof(musbotg_confd);
|
||||
ptr = (const void *)&musbotg_confd;
|
||||
goto tr_valid;
|
||||
case UDESC_STRING:
|
||||
switch (value & 0xff) {
|
||||
case 0: /* Language table */
|
||||
std->len = sizeof(musbotg_langtab);
|
||||
std->ptr = USB_ADD_BYTES(&musbotg_langtab, 0);
|
||||
len = sizeof(musbotg_langtab);
|
||||
ptr = (const void *)&musbotg_langtab;
|
||||
goto tr_valid;
|
||||
|
||||
case 1: /* Vendor */
|
||||
std->len = sizeof(musbotg_vendor);
|
||||
std->ptr = USB_ADD_BYTES(&musbotg_vendor, 0);
|
||||
len = sizeof(musbotg_vendor);
|
||||
ptr = (const void *)&musbotg_vendor;
|
||||
goto tr_valid;
|
||||
|
||||
case 2: /* Product */
|
||||
std->len = sizeof(musbotg_product);
|
||||
std->ptr = USB_ADD_BYTES(&musbotg_product, 0);
|
||||
len = sizeof(musbotg_product);
|
||||
ptr = (const void *)&musbotg_product;
|
||||
goto tr_valid;
|
||||
default:
|
||||
break;
|
||||
@ -2369,12 +2373,12 @@ musbotg_roothub_exec(struct usb2_bus *bus)
|
||||
goto tr_stalled;
|
||||
|
||||
tr_handle_get_config:
|
||||
std->len = 1;
|
||||
len = 1;
|
||||
sc->sc_hub_temp.wValue[0] = sc->sc_conf;
|
||||
goto tr_valid;
|
||||
|
||||
tr_handle_get_status:
|
||||
std->len = 2;
|
||||
len = 2;
|
||||
USETW(sc->sc_hub_temp.wValue, UDS_SELF_POWERED);
|
||||
goto tr_valid;
|
||||
|
||||
@ -2393,7 +2397,7 @@ musbotg_roothub_exec(struct usb2_bus *bus)
|
||||
goto tr_valid;
|
||||
|
||||
tr_handle_get_interface:
|
||||
std->len = 1;
|
||||
len = 1;
|
||||
sc->sc_hub_temp.wValue[0] = 0;
|
||||
goto tr_valid;
|
||||
|
||||
@ -2401,7 +2405,7 @@ musbotg_roothub_exec(struct usb2_bus *bus)
|
||||
tr_handle_get_class_status:
|
||||
tr_handle_get_iface_status:
|
||||
tr_handle_get_ep_status:
|
||||
std->len = 2;
|
||||
len = 2;
|
||||
USETW(sc->sc_hub_temp.wValue, 0);
|
||||
goto tr_valid;
|
||||
|
||||
@ -2446,7 +2450,7 @@ musbotg_roothub_exec(struct usb2_bus *bus)
|
||||
sc->sc_flags.change_suspend = 0;
|
||||
break;
|
||||
default:
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
goto tr_valid;
|
||||
@ -2471,7 +2475,7 @@ musbotg_roothub_exec(struct usb2_bus *bus)
|
||||
sc->sc_flags.port_powered = 1;
|
||||
break;
|
||||
default:
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
goto tr_valid;
|
||||
@ -2528,22 +2532,24 @@ musbotg_roothub_exec(struct usb2_bus *bus)
|
||||
value |= UPS_C_SUSPEND;
|
||||
}
|
||||
USETW(sc->sc_hub_temp.ps.wPortChange, value);
|
||||
std->len = sizeof(sc->sc_hub_temp.ps);
|
||||
len = sizeof(sc->sc_hub_temp.ps);
|
||||
goto tr_valid;
|
||||
|
||||
tr_handle_get_class_descriptor:
|
||||
if (value & 0xFF) {
|
||||
goto tr_stalled;
|
||||
}
|
||||
std->ptr = USB_ADD_BYTES(&musbotg_hubd, 0);
|
||||
std->len = sizeof(musbotg_hubd);
|
||||
ptr = (const void *)&musbotg_hubd;
|
||||
len = sizeof(musbotg_hubd);
|
||||
goto tr_valid;
|
||||
|
||||
tr_stalled:
|
||||
std->err = USB_ERR_STALLED;
|
||||
err = USB_ERR_STALLED;
|
||||
tr_valid:
|
||||
done:
|
||||
return;
|
||||
*plength = len;
|
||||
*pptr = ptr;
|
||||
return (err);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -2106,34 +2106,38 @@ struct usb2_hub_descriptor ohci_hubd =
|
||||
{0},
|
||||
};
|
||||
|
||||
static void
|
||||
ohci_roothub_exec(struct usb2_bus *bus)
|
||||
static usb2_error_t
|
||||
ohci_roothub_exec(struct usb2_device *udev,
|
||||
struct usb2_device_request *req, const void **pptr, uint16_t *plength)
|
||||
{
|
||||
ohci_softc_t *sc = OHCI_BUS2SC(bus);
|
||||
struct usb2_sw_transfer *std = &sc->sc_bus.roothub_req;
|
||||
char *ptr;
|
||||
ohci_softc_t *sc = OHCI_BUS2SC(udev->bus);
|
||||
const void *ptr;
|
||||
const char *str_ptr;
|
||||
uint32_t port;
|
||||
uint32_t v;
|
||||
uint16_t len;
|
||||
uint16_t value;
|
||||
uint16_t index;
|
||||
uint8_t l;
|
||||
usb2_error_t err;
|
||||
|
||||
USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
|
||||
|
||||
/* buffer reset */
|
||||
std->ptr = sc->sc_hub_desc.temp;
|
||||
std->len = 0;
|
||||
ptr = (const void *)&sc->sc_hub_desc.temp;
|
||||
len = 0;
|
||||
err = 0;
|
||||
|
||||
value = UGETW(std->req.wValue);
|
||||
index = UGETW(std->req.wIndex);
|
||||
value = UGETW(req->wValue);
|
||||
index = UGETW(req->wIndex);
|
||||
|
||||
DPRINTFN(3, "type=0x%02x request=0x%02x wLen=0x%04x "
|
||||
"wValue=0x%04x wIndex=0x%04x\n",
|
||||
std->req.bmRequestType, std->req.bRequest,
|
||||
UGETW(std->req.wLength), value, index);
|
||||
req->bmRequestType, req->bRequest,
|
||||
UGETW(req->wLength), value, index);
|
||||
|
||||
#define C(x,y) ((x) | ((y) << 8))
|
||||
switch (C(std->req.bRequest, std->req.bmRequestType)) {
|
||||
switch (C(req->bRequest, req->bmRequestType)) {
|
||||
case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE):
|
||||
case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE):
|
||||
case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT):
|
||||
@ -2143,82 +2147,82 @@ ohci_roothub_exec(struct usb2_bus *bus)
|
||||
*/
|
||||
break;
|
||||
case C(UR_GET_CONFIG, UT_READ_DEVICE):
|
||||
std->len = 1;
|
||||
len = 1;
|
||||
sc->sc_hub_desc.temp[0] = sc->sc_conf;
|
||||
break;
|
||||
case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
|
||||
switch (value >> 8) {
|
||||
case UDESC_DEVICE:
|
||||
if ((value & 0xff) != 0) {
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
std->len = sizeof(ohci_devd);
|
||||
sc->sc_hub_desc.devd = ohci_devd;
|
||||
len = sizeof(ohci_devd);
|
||||
ptr = (const void *)&ohci_devd;
|
||||
break;
|
||||
|
||||
case UDESC_CONFIG:
|
||||
if ((value & 0xff) != 0) {
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
std->len = sizeof(ohci_confd);
|
||||
std->ptr = USB_ADD_BYTES(&ohci_confd, 0);
|
||||
len = sizeof(ohci_confd);
|
||||
ptr = (const void *)&ohci_confd;
|
||||
break;
|
||||
|
||||
case UDESC_STRING:
|
||||
switch (value & 0xff) {
|
||||
case 0: /* Language table */
|
||||
ptr = "\001";
|
||||
str_ptr = "\001";
|
||||
break;
|
||||
|
||||
case 1: /* Vendor */
|
||||
ptr = sc->sc_vendor;
|
||||
str_ptr = sc->sc_vendor;
|
||||
break;
|
||||
|
||||
case 2: /* Product */
|
||||
ptr = "OHCI root HUB";
|
||||
str_ptr = "OHCI root HUB";
|
||||
break;
|
||||
|
||||
default:
|
||||
ptr = "";
|
||||
str_ptr = "";
|
||||
break;
|
||||
}
|
||||
|
||||
std->len = usb2_make_str_desc
|
||||
(sc->sc_hub_desc.temp,
|
||||
len = usb2_make_str_desc(
|
||||
sc->sc_hub_desc.temp,
|
||||
sizeof(sc->sc_hub_desc.temp),
|
||||
ptr);
|
||||
str_ptr);
|
||||
break;
|
||||
|
||||
default:
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
break;
|
||||
case C(UR_GET_INTERFACE, UT_READ_INTERFACE):
|
||||
std->len = 1;
|
||||
len = 1;
|
||||
sc->sc_hub_desc.temp[0] = 0;
|
||||
break;
|
||||
case C(UR_GET_STATUS, UT_READ_DEVICE):
|
||||
std->len = 2;
|
||||
len = 2;
|
||||
USETW(sc->sc_hub_desc.stat.wStatus, UDS_SELF_POWERED);
|
||||
break;
|
||||
case C(UR_GET_STATUS, UT_READ_INTERFACE):
|
||||
case C(UR_GET_STATUS, UT_READ_ENDPOINT):
|
||||
std->len = 2;
|
||||
len = 2;
|
||||
USETW(sc->sc_hub_desc.stat.wStatus, 0);
|
||||
break;
|
||||
case C(UR_SET_ADDRESS, UT_WRITE_DEVICE):
|
||||
if (value >= OHCI_MAX_DEVICES) {
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
sc->sc_addr = value;
|
||||
break;
|
||||
case C(UR_SET_CONFIG, UT_WRITE_DEVICE):
|
||||
if ((value != 0) && (value != 1)) {
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
sc->sc_conf = value;
|
||||
@ -2228,7 +2232,7 @@ ohci_roothub_exec(struct usb2_bus *bus)
|
||||
case C(UR_SET_FEATURE, UT_WRITE_DEVICE):
|
||||
case C(UR_SET_FEATURE, UT_WRITE_INTERFACE):
|
||||
case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT):
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE):
|
||||
break;
|
||||
@ -2243,7 +2247,7 @@ ohci_roothub_exec(struct usb2_bus *bus)
|
||||
index, value);
|
||||
if ((index < 1) ||
|
||||
(index > sc->sc_noport)) {
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
port = OHCI_RH_PORT_STATUS(index);
|
||||
@ -2274,7 +2278,7 @@ ohci_roothub_exec(struct usb2_bus *bus)
|
||||
OWRITE4(sc, port, UPS_C_PORT_RESET << 16);
|
||||
break;
|
||||
default:
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
switch (value) {
|
||||
@ -2293,7 +2297,7 @@ ohci_roothub_exec(struct usb2_bus *bus)
|
||||
break;
|
||||
case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE):
|
||||
if ((value & 0xff) != 0) {
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
v = OREAD4(sc, OHCI_RH_DESCRIPTOR_A);
|
||||
@ -2316,11 +2320,11 @@ ohci_roothub_exec(struct usb2_bus *bus)
|
||||
}
|
||||
sc->sc_hub_desc.hubd.bDescLength =
|
||||
8 + ((sc->sc_noport + 7) / 8);
|
||||
std->len = sc->sc_hub_desc.hubd.bDescLength;
|
||||
len = sc->sc_hub_desc.hubd.bDescLength;
|
||||
break;
|
||||
|
||||
case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
|
||||
std->len = 16;
|
||||
len = 16;
|
||||
bzero(sc->sc_hub_desc.temp, 16);
|
||||
break;
|
||||
case C(UR_GET_STATUS, UT_READ_CLASS_OTHER):
|
||||
@ -2328,24 +2332,24 @@ ohci_roothub_exec(struct usb2_bus *bus)
|
||||
index);
|
||||
if ((index < 1) ||
|
||||
(index > sc->sc_noport)) {
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
v = OREAD4(sc, OHCI_RH_PORT_STATUS(index));
|
||||
DPRINTFN(9, "port status=0x%04x\n", v);
|
||||
USETW(sc->sc_hub_desc.ps.wPortStatus, v);
|
||||
USETW(sc->sc_hub_desc.ps.wPortChange, v >> 16);
|
||||
std->len = sizeof(sc->sc_hub_desc.ps);
|
||||
len = sizeof(sc->sc_hub_desc.ps);
|
||||
break;
|
||||
case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE):
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE):
|
||||
break;
|
||||
case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER):
|
||||
if ((index < 1) ||
|
||||
(index > sc->sc_noport)) {
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
port = OHCI_RH_PORT_STATUS(index);
|
||||
@ -2368,7 +2372,7 @@ ohci_roothub_exec(struct usb2_bus *bus)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
std->err = USB_ERR_TIMEOUT;
|
||||
err = USB_ERR_TIMEOUT;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
@ -2380,16 +2384,18 @@ ohci_roothub_exec(struct usb2_bus *bus)
|
||||
OWRITE4(sc, port, UPS_PORT_POWER);
|
||||
break;
|
||||
default:
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
done:
|
||||
return;
|
||||
*plength = len;
|
||||
*pptr = ptr;
|
||||
return (err);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -312,7 +312,6 @@ struct ohci_config_desc {
|
||||
union ohci_hub_desc {
|
||||
struct usb2_status stat;
|
||||
struct usb2_port_status ps;
|
||||
struct usb2_device_descriptor devd;
|
||||
struct usb2_hub_descriptor hubd;
|
||||
uint8_t temp[128];
|
||||
};
|
||||
|
@ -2482,35 +2482,39 @@ uhci_portreset(uhci_softc_t *sc, uint16_t index)
|
||||
return (USB_ERR_NORMAL_COMPLETION);
|
||||
}
|
||||
|
||||
static void
|
||||
uhci_roothub_exec(struct usb2_bus *bus)
|
||||
static usb2_error_t
|
||||
uhci_roothub_exec(struct usb2_device *udev,
|
||||
struct usb2_device_request *req, const void **pptr, uint16_t *plength)
|
||||
{
|
||||
uhci_softc_t *sc = UHCI_BUS2SC(bus);
|
||||
struct usb2_sw_transfer *std = &sc->sc_bus.roothub_req;
|
||||
char *ptr;
|
||||
uhci_softc_t *sc = UHCI_BUS2SC(udev->bus);
|
||||
const void *ptr;
|
||||
const char *str_ptr;
|
||||
uint16_t x;
|
||||
uint16_t port;
|
||||
uint16_t value;
|
||||
uint16_t index;
|
||||
uint16_t status;
|
||||
uint16_t change;
|
||||
uint16_t len;
|
||||
usb2_error_t err;
|
||||
|
||||
USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
|
||||
|
||||
/* buffer reset */
|
||||
std->ptr = sc->sc_hub_desc.temp;
|
||||
std->len = 0;
|
||||
ptr = (const void *)&sc->sc_hub_desc.temp;
|
||||
len = 0;
|
||||
err = 0;
|
||||
|
||||
value = UGETW(std->req.wValue);
|
||||
index = UGETW(std->req.wIndex);
|
||||
value = UGETW(req->wValue);
|
||||
index = UGETW(req->wIndex);
|
||||
|
||||
DPRINTFN(3, "type=0x%02x request=0x%02x wLen=0x%04x "
|
||||
"wValue=0x%04x wIndex=0x%04x\n",
|
||||
std->req.bmRequestType, std->req.bRequest,
|
||||
UGETW(std->req.wLength), value, index);
|
||||
req->bmRequestType, req->bRequest,
|
||||
UGETW(req->wLength), value, index);
|
||||
|
||||
#define C(x,y) ((x) | ((y) << 8))
|
||||
switch (C(std->req.bRequest, std->req.bmRequestType)) {
|
||||
switch (C(req->bRequest, req->bmRequestType)) {
|
||||
case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE):
|
||||
case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE):
|
||||
case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT):
|
||||
@ -2520,82 +2524,82 @@ uhci_roothub_exec(struct usb2_bus *bus)
|
||||
*/
|
||||
break;
|
||||
case C(UR_GET_CONFIG, UT_READ_DEVICE):
|
||||
std->len = 1;
|
||||
len = 1;
|
||||
sc->sc_hub_desc.temp[0] = sc->sc_conf;
|
||||
break;
|
||||
case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
|
||||
switch (value >> 8) {
|
||||
case UDESC_DEVICE:
|
||||
if ((value & 0xff) != 0) {
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
std->len = sizeof(uhci_devd);
|
||||
sc->sc_hub_desc.devd = uhci_devd;
|
||||
len = sizeof(uhci_devd);
|
||||
ptr = (const void *)&uhci_devd;
|
||||
break;
|
||||
|
||||
case UDESC_CONFIG:
|
||||
if ((value & 0xff) != 0) {
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
std->len = sizeof(uhci_confd);
|
||||
std->ptr = USB_ADD_BYTES(&uhci_confd, 0);
|
||||
len = sizeof(uhci_confd);
|
||||
ptr = (const void *)&uhci_confd;
|
||||
break;
|
||||
|
||||
case UDESC_STRING:
|
||||
switch (value & 0xff) {
|
||||
case 0: /* Language table */
|
||||
ptr = "\001";
|
||||
str_ptr = "\001";
|
||||
break;
|
||||
|
||||
case 1: /* Vendor */
|
||||
ptr = sc->sc_vendor;
|
||||
str_ptr = sc->sc_vendor;
|
||||
break;
|
||||
|
||||
case 2: /* Product */
|
||||
ptr = "UHCI root HUB";
|
||||
str_ptr = "UHCI root HUB";
|
||||
break;
|
||||
|
||||
default:
|
||||
ptr = "";
|
||||
str_ptr = "";
|
||||
break;
|
||||
}
|
||||
|
||||
std->len = usb2_make_str_desc
|
||||
len = usb2_make_str_desc
|
||||
(sc->sc_hub_desc.temp,
|
||||
sizeof(sc->sc_hub_desc.temp),
|
||||
ptr);
|
||||
str_ptr);
|
||||
break;
|
||||
|
||||
default:
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
break;
|
||||
case C(UR_GET_INTERFACE, UT_READ_INTERFACE):
|
||||
std->len = 1;
|
||||
len = 1;
|
||||
sc->sc_hub_desc.temp[0] = 0;
|
||||
break;
|
||||
case C(UR_GET_STATUS, UT_READ_DEVICE):
|
||||
std->len = 2;
|
||||
len = 2;
|
||||
USETW(sc->sc_hub_desc.stat.wStatus, UDS_SELF_POWERED);
|
||||
break;
|
||||
case C(UR_GET_STATUS, UT_READ_INTERFACE):
|
||||
case C(UR_GET_STATUS, UT_READ_ENDPOINT):
|
||||
std->len = 2;
|
||||
len = 2;
|
||||
USETW(sc->sc_hub_desc.stat.wStatus, 0);
|
||||
break;
|
||||
case C(UR_SET_ADDRESS, UT_WRITE_DEVICE):
|
||||
if (value >= UHCI_MAX_DEVICES) {
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
sc->sc_addr = value;
|
||||
break;
|
||||
case C(UR_SET_CONFIG, UT_WRITE_DEVICE):
|
||||
if ((value != 0) && (value != 1)) {
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
sc->sc_conf = value;
|
||||
@ -2605,7 +2609,7 @@ uhci_roothub_exec(struct usb2_bus *bus)
|
||||
case C(UR_SET_FEATURE, UT_WRITE_DEVICE):
|
||||
case C(UR_SET_FEATURE, UT_WRITE_INTERFACE):
|
||||
case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT):
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE):
|
||||
break;
|
||||
@ -2623,7 +2627,7 @@ uhci_roothub_exec(struct usb2_bus *bus)
|
||||
else if (index == 2)
|
||||
port = UHCI_PORTSC2;
|
||||
else {
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
switch (value) {
|
||||
@ -2653,7 +2657,7 @@ uhci_roothub_exec(struct usb2_bus *bus)
|
||||
break;
|
||||
case UHF_C_PORT_RESET:
|
||||
sc->sc_isreset = 0;
|
||||
std->err = USB_ERR_NORMAL_COMPLETION;
|
||||
err = USB_ERR_NORMAL_COMPLETION;
|
||||
goto done;
|
||||
case UHF_C_PORT_SUSPEND:
|
||||
sc->sc_isresumed &= ~(1 << index);
|
||||
@ -2663,7 +2667,7 @@ uhci_roothub_exec(struct usb2_bus *bus)
|
||||
case UHF_PORT_POWER:
|
||||
case UHF_PORT_LOW_SPEED:
|
||||
default:
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
break;
|
||||
@ -2673,24 +2677,24 @@ uhci_roothub_exec(struct usb2_bus *bus)
|
||||
else if (index == 2)
|
||||
port = UHCI_PORTSC2;
|
||||
else {
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
std->len = 1;
|
||||
len = 1;
|
||||
sc->sc_hub_desc.temp[0] =
|
||||
((UREAD2(sc, port) & UHCI_PORTSC_LS) >>
|
||||
UHCI_PORTSC_LS_SHIFT);
|
||||
break;
|
||||
case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE):
|
||||
if ((value & 0xff) != 0) {
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
std->len = sizeof(uhci_hubd_piix);
|
||||
std->ptr = USB_ADD_BYTES(&uhci_hubd_piix, 0);
|
||||
len = sizeof(uhci_hubd_piix);
|
||||
ptr = (const void *)&uhci_hubd_piix;
|
||||
break;
|
||||
case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
|
||||
std->len = 16;
|
||||
len = 16;
|
||||
bzero(sc->sc_hub_desc.temp, 16);
|
||||
break;
|
||||
case C(UR_GET_STATUS, UT_READ_CLASS_OTHER):
|
||||
@ -2699,7 +2703,7 @@ uhci_roothub_exec(struct usb2_bus *bus)
|
||||
else if (index == 2)
|
||||
port = UHCI_PORTSC2;
|
||||
else {
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
x = UREAD2(sc, port);
|
||||
@ -2744,10 +2748,10 @@ uhci_roothub_exec(struct usb2_bus *bus)
|
||||
change |= UPS_C_PORT_RESET;
|
||||
USETW(sc->sc_hub_desc.ps.wPortStatus, status);
|
||||
USETW(sc->sc_hub_desc.ps.wPortChange, change);
|
||||
std->len = sizeof(sc->sc_hub_desc.ps);
|
||||
len = sizeof(sc->sc_hub_desc.ps);
|
||||
break;
|
||||
case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE):
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE):
|
||||
break;
|
||||
@ -2757,7 +2761,7 @@ uhci_roothub_exec(struct usb2_bus *bus)
|
||||
else if (index == 2)
|
||||
port = UHCI_PORTSC2;
|
||||
else {
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
switch (value) {
|
||||
@ -2770,11 +2774,11 @@ uhci_roothub_exec(struct usb2_bus *bus)
|
||||
UWRITE2(sc, port, x | UHCI_PORTSC_SUSP);
|
||||
break;
|
||||
case UHF_PORT_RESET:
|
||||
std->err = uhci_portreset(sc, index);
|
||||
err = uhci_portreset(sc, index);
|
||||
goto done;
|
||||
case UHF_PORT_POWER:
|
||||
/* pretend we turned on power */
|
||||
std->err = USB_ERR_NORMAL_COMPLETION;
|
||||
err = USB_ERR_NORMAL_COMPLETION;
|
||||
goto done;
|
||||
case UHF_C_PORT_CONNECTION:
|
||||
case UHF_C_PORT_ENABLE:
|
||||
@ -2785,16 +2789,18 @@ uhci_roothub_exec(struct usb2_bus *bus)
|
||||
case UHF_C_PORT_SUSPEND:
|
||||
case UHF_C_PORT_RESET:
|
||||
default:
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
done:
|
||||
return;
|
||||
*plength = len;
|
||||
*pptr = ptr;
|
||||
return (err);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -243,7 +243,6 @@ struct uhci_config_desc {
|
||||
union uhci_hub_desc {
|
||||
struct usb2_status stat;
|
||||
struct usb2_port_status ps;
|
||||
struct usb2_device_descriptor devd;
|
||||
uint8_t temp[128];
|
||||
};
|
||||
|
||||
|
@ -1788,28 +1788,32 @@ USB_MAKE_STRING_DESC(STRING_LANG, uss820dci_langtab);
|
||||
USB_MAKE_STRING_DESC(STRING_VENDOR, uss820dci_vendor);
|
||||
USB_MAKE_STRING_DESC(STRING_PRODUCT, uss820dci_product);
|
||||
|
||||
static void
|
||||
uss820dci_roothub_exec(struct usb2_bus *bus)
|
||||
static usb2_error_t
|
||||
uss820dci_roothub_exec(struct usb2_device *udev,
|
||||
struct usb2_device_request *req, const void **pptr, uint16_t *plength)
|
||||
{
|
||||
struct uss820dci_softc *sc = USS820_DCI_BUS2SC(bus);
|
||||
struct usb2_sw_transfer *std = &sc->sc_bus.roothub_req;
|
||||
struct uss820dci_softc *sc = USS820_DCI_BUS2SC(udev->bus);
|
||||
const void *ptr;
|
||||
uint16_t len;
|
||||
uint16_t value;
|
||||
uint16_t index;
|
||||
usb2_error_t err;
|
||||
|
||||
USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
|
||||
|
||||
/* buffer reset */
|
||||
std->ptr = USB_ADD_BYTES(&sc->sc_hub_temp, 0);
|
||||
std->len = 0;
|
||||
ptr = (const void *)&sc->sc_hub_temp;
|
||||
len = 0;
|
||||
err = 0;
|
||||
|
||||
value = UGETW(std->req.wValue);
|
||||
index = UGETW(std->req.wIndex);
|
||||
value = UGETW(req->wValue);
|
||||
index = UGETW(req->wIndex);
|
||||
|
||||
/* demultiplex the control request */
|
||||
|
||||
switch (std->req.bmRequestType) {
|
||||
switch (req->bmRequestType) {
|
||||
case UT_READ_DEVICE:
|
||||
switch (std->req.bRequest) {
|
||||
switch (req->bRequest) {
|
||||
case UR_GET_DESCRIPTOR:
|
||||
goto tr_handle_get_descriptor;
|
||||
case UR_GET_CONFIG:
|
||||
@ -1822,7 +1826,7 @@ uss820dci_roothub_exec(struct usb2_bus *bus)
|
||||
break;
|
||||
|
||||
case UT_WRITE_DEVICE:
|
||||
switch (std->req.bRequest) {
|
||||
switch (req->bRequest) {
|
||||
case UR_SET_ADDRESS:
|
||||
goto tr_handle_set_address;
|
||||
case UR_SET_CONFIG:
|
||||
@ -1838,9 +1842,9 @@ uss820dci_roothub_exec(struct usb2_bus *bus)
|
||||
break;
|
||||
|
||||
case UT_WRITE_ENDPOINT:
|
||||
switch (std->req.bRequest) {
|
||||
switch (req->bRequest) {
|
||||
case UR_CLEAR_FEATURE:
|
||||
switch (UGETW(std->req.wValue)) {
|
||||
switch (UGETW(req->wValue)) {
|
||||
case UF_ENDPOINT_HALT:
|
||||
goto tr_handle_clear_halt;
|
||||
case UF_DEVICE_REMOTE_WAKEUP:
|
||||
@ -1850,7 +1854,7 @@ uss820dci_roothub_exec(struct usb2_bus *bus)
|
||||
}
|
||||
break;
|
||||
case UR_SET_FEATURE:
|
||||
switch (UGETW(std->req.wValue)) {
|
||||
switch (UGETW(req->wValue)) {
|
||||
case UF_ENDPOINT_HALT:
|
||||
goto tr_handle_set_halt;
|
||||
case UF_DEVICE_REMOTE_WAKEUP:
|
||||
@ -1867,7 +1871,7 @@ uss820dci_roothub_exec(struct usb2_bus *bus)
|
||||
break;
|
||||
|
||||
case UT_READ_ENDPOINT:
|
||||
switch (std->req.bRequest) {
|
||||
switch (req->bRequest) {
|
||||
case UR_GET_STATUS:
|
||||
goto tr_handle_get_ep_status;
|
||||
default:
|
||||
@ -1876,7 +1880,7 @@ uss820dci_roothub_exec(struct usb2_bus *bus)
|
||||
break;
|
||||
|
||||
case UT_WRITE_INTERFACE:
|
||||
switch (std->req.bRequest) {
|
||||
switch (req->bRequest) {
|
||||
case UR_SET_INTERFACE:
|
||||
goto tr_handle_set_interface;
|
||||
case UR_CLEAR_FEATURE:
|
||||
@ -1888,7 +1892,7 @@ uss820dci_roothub_exec(struct usb2_bus *bus)
|
||||
break;
|
||||
|
||||
case UT_READ_INTERFACE:
|
||||
switch (std->req.bRequest) {
|
||||
switch (req->bRequest) {
|
||||
case UR_GET_INTERFACE:
|
||||
goto tr_handle_get_interface;
|
||||
case UR_GET_STATUS:
|
||||
@ -1909,7 +1913,7 @@ uss820dci_roothub_exec(struct usb2_bus *bus)
|
||||
break;
|
||||
|
||||
case UT_WRITE_CLASS_DEVICE:
|
||||
switch (std->req.bRequest) {
|
||||
switch (req->bRequest) {
|
||||
case UR_CLEAR_FEATURE:
|
||||
goto tr_valid;
|
||||
case UR_SET_DESCRIPTOR:
|
||||
@ -1921,7 +1925,7 @@ uss820dci_roothub_exec(struct usb2_bus *bus)
|
||||
break;
|
||||
|
||||
case UT_WRITE_CLASS_OTHER:
|
||||
switch (std->req.bRequest) {
|
||||
switch (req->bRequest) {
|
||||
case UR_CLEAR_FEATURE:
|
||||
goto tr_handle_clear_port_feature;
|
||||
case UR_SET_FEATURE:
|
||||
@ -1937,7 +1941,7 @@ uss820dci_roothub_exec(struct usb2_bus *bus)
|
||||
break;
|
||||
|
||||
case UT_READ_CLASS_OTHER:
|
||||
switch (std->req.bRequest) {
|
||||
switch (req->bRequest) {
|
||||
case UR_GET_TT_STATE:
|
||||
goto tr_handle_get_tt_state;
|
||||
case UR_GET_STATUS:
|
||||
@ -1948,7 +1952,7 @@ uss820dci_roothub_exec(struct usb2_bus *bus)
|
||||
break;
|
||||
|
||||
case UT_READ_CLASS_DEVICE:
|
||||
switch (std->req.bRequest) {
|
||||
switch (req->bRequest) {
|
||||
case UR_GET_DESCRIPTOR:
|
||||
goto tr_handle_get_class_descriptor;
|
||||
case UR_GET_STATUS:
|
||||
@ -1969,31 +1973,31 @@ uss820dci_roothub_exec(struct usb2_bus *bus)
|
||||
if (value & 0xff) {
|
||||
goto tr_stalled;
|
||||
}
|
||||
std->len = sizeof(uss820dci_devd);
|
||||
std->ptr = USB_ADD_BYTES(&uss820dci_devd, 0);
|
||||
len = sizeof(uss820dci_devd);
|
||||
ptr = (const void *)&uss820dci_devd;
|
||||
goto tr_valid;
|
||||
case UDESC_CONFIG:
|
||||
if (value & 0xff) {
|
||||
goto tr_stalled;
|
||||
}
|
||||
std->len = sizeof(uss820dci_confd);
|
||||
std->ptr = USB_ADD_BYTES(&uss820dci_confd, 0);
|
||||
len = sizeof(uss820dci_confd);
|
||||
ptr = (const void *)&uss820dci_confd;
|
||||
goto tr_valid;
|
||||
case UDESC_STRING:
|
||||
switch (value & 0xff) {
|
||||
case 0: /* Language table */
|
||||
std->len = sizeof(uss820dci_langtab);
|
||||
std->ptr = USB_ADD_BYTES(&uss820dci_langtab, 0);
|
||||
len = sizeof(uss820dci_langtab);
|
||||
ptr = (const void *)&uss820dci_langtab;
|
||||
goto tr_valid;
|
||||
|
||||
case 1: /* Vendor */
|
||||
std->len = sizeof(uss820dci_vendor);
|
||||
std->ptr = USB_ADD_BYTES(&uss820dci_vendor, 0);
|
||||
len = sizeof(uss820dci_vendor);
|
||||
ptr = (const void *)&uss820dci_vendor;
|
||||
goto tr_valid;
|
||||
|
||||
case 2: /* Product */
|
||||
std->len = sizeof(uss820dci_product);
|
||||
std->ptr = USB_ADD_BYTES(&uss820dci_product, 0);
|
||||
len = sizeof(uss820dci_product);
|
||||
ptr = (const void *)&uss820dci_product;
|
||||
goto tr_valid;
|
||||
default:
|
||||
break;
|
||||
@ -2005,12 +2009,12 @@ uss820dci_roothub_exec(struct usb2_bus *bus)
|
||||
goto tr_stalled;
|
||||
|
||||
tr_handle_get_config:
|
||||
std->len = 1;
|
||||
len = 1;
|
||||
sc->sc_hub_temp.wValue[0] = sc->sc_conf;
|
||||
goto tr_valid;
|
||||
|
||||
tr_handle_get_status:
|
||||
std->len = 2;
|
||||
len = 2;
|
||||
USETW(sc->sc_hub_temp.wValue, UDS_SELF_POWERED);
|
||||
goto tr_valid;
|
||||
|
||||
@ -2029,7 +2033,7 @@ uss820dci_roothub_exec(struct usb2_bus *bus)
|
||||
goto tr_valid;
|
||||
|
||||
tr_handle_get_interface:
|
||||
std->len = 1;
|
||||
len = 1;
|
||||
sc->sc_hub_temp.wValue[0] = 0;
|
||||
goto tr_valid;
|
||||
|
||||
@ -2037,7 +2041,7 @@ uss820dci_roothub_exec(struct usb2_bus *bus)
|
||||
tr_handle_get_class_status:
|
||||
tr_handle_get_iface_status:
|
||||
tr_handle_get_ep_status:
|
||||
std->len = 2;
|
||||
len = 2;
|
||||
USETW(sc->sc_hub_temp.wValue, 0);
|
||||
goto tr_valid;
|
||||
|
||||
@ -2081,7 +2085,7 @@ uss820dci_roothub_exec(struct usb2_bus *bus)
|
||||
sc->sc_flags.change_suspend = 0;
|
||||
break;
|
||||
default:
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
goto tr_valid;
|
||||
@ -2106,7 +2110,7 @@ uss820dci_roothub_exec(struct usb2_bus *bus)
|
||||
sc->sc_flags.port_powered = 1;
|
||||
break;
|
||||
default:
|
||||
std->err = USB_ERR_IOERROR;
|
||||
err = USB_ERR_IOERROR;
|
||||
goto done;
|
||||
}
|
||||
goto tr_valid;
|
||||
@ -2152,22 +2156,24 @@ uss820dci_roothub_exec(struct usb2_bus *bus)
|
||||
value |= UPS_C_SUSPEND;
|
||||
}
|
||||
USETW(sc->sc_hub_temp.ps.wPortChange, value);
|
||||
std->len = sizeof(sc->sc_hub_temp.ps);
|
||||
len = sizeof(sc->sc_hub_temp.ps);
|
||||
goto tr_valid;
|
||||
|
||||
tr_handle_get_class_descriptor:
|
||||
if (value & 0xFF) {
|
||||
goto tr_stalled;
|
||||
}
|
||||
std->ptr = USB_ADD_BYTES(&uss820dci_hubd, 0);
|
||||
std->len = sizeof(uss820dci_hubd);
|
||||
ptr = (const void *)&uss820dci_hubd;
|
||||
len = sizeof(uss820dci_hubd);
|
||||
goto tr_valid;
|
||||
|
||||
tr_stalled:
|
||||
std->err = USB_ERR_STALLED;
|
||||
err = USB_ERR_STALLED;
|
||||
tr_valid:
|
||||
done:
|
||||
return;
|
||||
*plength = len;
|
||||
*pptr = ptr;
|
||||
return (err);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -81,7 +81,7 @@ static const void *usb2_temp_get_string_desc(struct usb2_device *, uint16_t,
|
||||
static const void *usb2_temp_get_vendor_desc(struct usb2_device *,
|
||||
const struct usb2_device_request *);
|
||||
static const void *usb2_temp_get_hub_desc(struct usb2_device *);
|
||||
static void usb2_temp_get_desc(struct usb2_device *,
|
||||
static usb2_error_t usb2_temp_get_desc(struct usb2_device *,
|
||||
struct usb2_device_request *, const void **, uint16_t *);
|
||||
static usb2_error_t usb2_temp_setup(struct usb2_device *,
|
||||
const struct usb2_temp_device_desc *);
|
||||
@ -1072,7 +1072,7 @@ usb2_temp_get_hub_desc(struct usb2_device *udev)
|
||||
* This function is a demultiplexer for local USB device side control
|
||||
* endpoint requests.
|
||||
*------------------------------------------------------------------------*/
|
||||
static void
|
||||
static usb2_error_t
|
||||
usb2_temp_get_desc(struct usb2_device *udev, struct usb2_device_request *req,
|
||||
const void **pPtr, uint16_t *pLength)
|
||||
{
|
||||
@ -1157,11 +1157,12 @@ usb2_temp_get_desc(struct usb2_device *udev, struct usb2_device_request *req,
|
||||
}
|
||||
*pPtr = buf;
|
||||
*pLength = len;
|
||||
return;
|
||||
return (0); /* success */
|
||||
|
||||
tr_stalled:
|
||||
*pPtr = NULL;
|
||||
*pLength = 0;
|
||||
return (0); /* we ignore failures */
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
|
@ -44,17 +44,6 @@ struct usb2_bus_stat {
|
||||
uint32_t uds_requests[4];
|
||||
};
|
||||
|
||||
/*
|
||||
* The following structure is used to keep the state of a standard
|
||||
* root transfer.
|
||||
*/
|
||||
struct usb2_sw_transfer {
|
||||
struct usb2_device_request req;
|
||||
uint8_t *ptr;
|
||||
uint16_t len;
|
||||
usb2_error_t err;
|
||||
};
|
||||
|
||||
/*
|
||||
* The following structure defines an USB BUS. There is one USB BUS
|
||||
* for every Host or Device controller.
|
||||
@ -62,7 +51,6 @@ struct usb2_sw_transfer {
|
||||
struct usb2_bus {
|
||||
struct usb2_bus_stat stats_err;
|
||||
struct usb2_bus_stat stats_ok;
|
||||
struct usb2_sw_transfer roothub_req;
|
||||
struct root_hold_token *bus_roothold;
|
||||
/*
|
||||
* There are two callback processes. One for Giant locked
|
||||
|
@ -56,13 +56,16 @@ struct usb2_bus_methods {
|
||||
|
||||
/* USB Device and Host mode - Mandatory */
|
||||
|
||||
void (*pipe_init) (struct usb2_device *udev, struct usb2_endpoint_descriptor *edesc, struct usb2_pipe *pipe);
|
||||
void (*xfer_setup) (struct usb2_setup_params *parm);
|
||||
void (*xfer_unsetup) (struct usb2_xfer *xfer);
|
||||
void (*get_dma_delay) (struct usb2_bus *, uint32_t *pdelay);
|
||||
void (*device_suspend) (struct usb2_device *udev);
|
||||
void (*device_resume) (struct usb2_device *udev);
|
||||
void (*set_hw_power) (struct usb2_bus *bus);
|
||||
usb2_handle_request_t *roothub_exec;
|
||||
|
||||
void (*pipe_init) (struct usb2_device *, struct usb2_endpoint_descriptor *, struct usb2_pipe *);
|
||||
void (*xfer_setup) (struct usb2_setup_params *);
|
||||
void (*xfer_unsetup) (struct usb2_xfer *);
|
||||
void (*get_dma_delay) (struct usb2_bus *, uint32_t *);
|
||||
void (*device_suspend) (struct usb2_device *);
|
||||
void (*device_resume) (struct usb2_device *);
|
||||
void (*set_hw_power) (struct usb2_bus *);
|
||||
|
||||
/*
|
||||
* The following flag is set if one or more control transfers are
|
||||
* active:
|
||||
@ -95,9 +98,6 @@ struct usb2_bus_methods {
|
||||
void (*set_stall) (struct usb2_device *udev, struct usb2_xfer *xfer, struct usb2_pipe *pipe);
|
||||
void (*clear_stall) (struct usb2_device *udev, struct usb2_pipe *pipe);
|
||||
|
||||
/* USB Device and Host mode - Optional */
|
||||
|
||||
void (*roothub_exec) (struct usb2_bus *);
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -266,6 +266,7 @@
|
||||
struct file;
|
||||
struct usb2_bus;
|
||||
struct usb2_device;
|
||||
struct usb2_device_request;
|
||||
struct usb2_page;
|
||||
struct usb2_page_cache;
|
||||
struct usb2_xfer;
|
||||
@ -303,6 +304,9 @@ typedef uint32_t usb2_ticks_t; /* system defined */
|
||||
typedef uint16_t usb2_power_mask_t; /* see "USB_HW_POWER_XXX" */
|
||||
#endif
|
||||
|
||||
typedef usb2_error_t (usb2_handle_request_t)(struct usb2_device *,
|
||||
struct usb2_device_request *, const void **, uint16_t *);
|
||||
|
||||
/* structures */
|
||||
|
||||
/*
|
||||
|
@ -462,7 +462,8 @@ usb2_set_config_index(struct usb2_device *udev, uint8_t index)
|
||||
/* get the full config descriptor */
|
||||
if (udev->flags.usb2_mode == USB_MODE_DEVICE) {
|
||||
/* save some memory */
|
||||
err = usb2_req_get_config_desc_ptr(udev, &cdp, index);
|
||||
err = usb2_req_get_descriptor_ptr(udev, &cdp,
|
||||
(UDESC_CONFIG << 8) | index);
|
||||
} else {
|
||||
/* normal request */
|
||||
err = usb2_req_get_config_desc_full(udev,
|
||||
|
@ -34,7 +34,7 @@
|
||||
#include <dev/usb/usb_dynamic.h>
|
||||
|
||||
/* function prototypes */
|
||||
static usb2_temp_get_desc_t usb2_temp_get_desc_w;
|
||||
static usb2_handle_request_t usb2_temp_get_desc_w;
|
||||
static usb2_temp_setup_by_index_t usb2_temp_setup_by_index_w;
|
||||
static usb2_temp_unsetup_t usb2_temp_unsetup_w;
|
||||
static usb2_test_quirk_t usb2_test_quirk_w;
|
||||
@ -42,7 +42,7 @@ static usb2_test_huawei_autoinst_t usb2_test_huawei_autoinst_w;
|
||||
static usb2_quirk_ioctl_t usb2_quirk_ioctl_w;
|
||||
|
||||
/* global variables */
|
||||
usb2_temp_get_desc_t *usb2_temp_get_desc_p = &usb2_temp_get_desc_w;
|
||||
usb2_handle_request_t *usb2_temp_get_desc_p = &usb2_temp_get_desc_w;
|
||||
usb2_temp_setup_by_index_t *usb2_temp_setup_by_index_p = &usb2_temp_setup_by_index_w;
|
||||
usb2_temp_unsetup_t *usb2_temp_unsetup_p = &usb2_temp_unsetup_w;
|
||||
usb2_test_quirk_t *usb2_test_quirk_p = &usb2_test_quirk_w;
|
||||
@ -68,12 +68,11 @@ usb2_quirk_ioctl_w(unsigned long cmd, caddr_t data, int fflag, struct thread *td
|
||||
return (ENOIOCTL);
|
||||
}
|
||||
|
||||
static void
|
||||
static usb2_error_t
|
||||
usb2_temp_get_desc_w(struct usb2_device *udev, struct usb2_device_request *req, const void **pPtr, uint16_t *pLength)
|
||||
{
|
||||
/* stall */
|
||||
*pPtr = NULL;
|
||||
*pLength = 0;
|
||||
return (USB_ERR_STALLED);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -43,14 +43,11 @@ typedef uint8_t (usb2_test_quirk_t)(const struct usb2_lookup_info *info,
|
||||
uint16_t quirk);
|
||||
typedef int (usb2_quirk_ioctl_t)(unsigned long cmd, caddr_t data,
|
||||
int fflag, struct thread *td);
|
||||
typedef void (usb2_temp_get_desc_t)(struct usb2_device *udev,
|
||||
struct usb2_device_request *req, const void **pPtr,
|
||||
uint16_t *pLength);
|
||||
typedef void (usb2_temp_unsetup_t)(struct usb2_device *udev);
|
||||
|
||||
/* global function pointers */
|
||||
|
||||
extern usb2_temp_get_desc_t *usb2_temp_get_desc_p;
|
||||
extern usb2_handle_request_t *usb2_temp_get_desc_p;
|
||||
extern usb2_temp_setup_by_index_t *usb2_temp_setup_by_index_p;
|
||||
extern usb2_temp_unsetup_t *usb2_temp_unsetup_p;
|
||||
extern usb2_test_quirk_t *usb2_test_quirk_p;
|
||||
|
@ -595,10 +595,11 @@ usb2_handle_request(struct usb2_xfer *xfer)
|
||||
goto tr_valid;
|
||||
|
||||
tr_handle_get_descriptor:
|
||||
(usb2_temp_get_desc_p) (udev, &req, &src_zcopy, &max_len);
|
||||
if (src_zcopy == NULL) {
|
||||
err = (usb2_temp_get_desc_p) (udev, &req, &src_zcopy, &max_len);
|
||||
if (err)
|
||||
goto tr_stalled;
|
||||
if (src_zcopy == NULL)
|
||||
goto tr_stalled;
|
||||
}
|
||||
goto tr_valid;
|
||||
|
||||
tr_handle_get_config:
|
||||
|
@ -172,6 +172,18 @@ usb2_do_clear_stall_callback(struct usb2_xfer *xfer)
|
||||
USB_BUS_UNLOCK(udev->bus);
|
||||
}
|
||||
|
||||
static usb2_handle_request_t *
|
||||
usb2_get_hr_func(struct usb2_device *udev)
|
||||
{
|
||||
/* figure out if there is a Handle Request function */
|
||||
if (udev->flags.usb2_mode == USB_MODE_DEVICE)
|
||||
return (usb2_temp_get_desc_p);
|
||||
else if (udev->parent_hub == NULL)
|
||||
return (udev->bus->methods->roothub_exec);
|
||||
else
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* usb2_do_request_flags and usb2_do_request
|
||||
*
|
||||
@ -232,6 +244,7 @@ usb2_do_request_flags(struct usb2_device *udev, struct mtx *mtx,
|
||||
struct usb2_device_request *req, void *data, uint16_t flags,
|
||||
uint16_t *actlen, usb2_timeout_t timeout)
|
||||
{
|
||||
usb2_handle_request_t *hr_func;
|
||||
struct usb2_xfer *xfer;
|
||||
const void *desc;
|
||||
int err = 0;
|
||||
@ -269,29 +282,6 @@ usb2_do_request_flags(struct usb2_device *udev, struct mtx *mtx,
|
||||
if (flags & USB_USER_DATA_PTR)
|
||||
return (USB_ERR_INVAL);
|
||||
#endif
|
||||
if (udev->flags.usb2_mode == USB_MODE_DEVICE) {
|
||||
DPRINTF("USB device mode\n");
|
||||
(usb2_temp_get_desc_p) (udev, req, &desc, &temp);
|
||||
if (length > temp) {
|
||||
if (!(flags & USB_SHORT_XFER_OK))
|
||||
return (USB_ERR_SHORT_XFER);
|
||||
length = temp;
|
||||
}
|
||||
if (actlen)
|
||||
*actlen = length;
|
||||
|
||||
if (length > 0) {
|
||||
#if USB_HAVE_USER_IO
|
||||
if (flags & USB_USER_DATA_PTR) {
|
||||
if (copyout(desc, data, length)) {
|
||||
return (USB_ERR_INVAL);
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
bcopy(desc, data, length);
|
||||
}
|
||||
return (0); /* success */
|
||||
}
|
||||
if (mtx) {
|
||||
mtx_unlock(mtx);
|
||||
if (mtx != &Giant) {
|
||||
@ -305,57 +295,54 @@ usb2_do_request_flags(struct usb2_device *udev, struct mtx *mtx,
|
||||
|
||||
sx_xlock(udev->default_sx);
|
||||
|
||||
if (udev->parent_hub == NULL) {
|
||||
struct usb2_sw_transfer *std = &udev->bus->roothub_req;
|
||||
hr_func = usb2_get_hr_func(udev);
|
||||
|
||||
/* root HUB code - stripped down */
|
||||
if (hr_func != NULL) {
|
||||
DPRINTF("Handle Request function is set\n");
|
||||
|
||||
if (req->bmRequestType & UT_READ) {
|
||||
std->ptr = NULL;
|
||||
} else {
|
||||
desc = NULL;
|
||||
temp = 0;
|
||||
|
||||
if (!(req->bmRequestType & UT_READ)) {
|
||||
if (length != 0) {
|
||||
DPRINTFN(1, "Root HUB does not support "
|
||||
"writing data!\n");
|
||||
err = USB_ERR_INVAL;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
/* setup request */
|
||||
std->req = *req;
|
||||
std->err = 0;
|
||||
std->len = 0;
|
||||
|
||||
USB_BUS_LOCK(udev->bus);
|
||||
(udev->bus->methods->roothub_exec) (udev->bus);
|
||||
USB_BUS_UNLOCK(udev->bus);
|
||||
|
||||
err = std->err;
|
||||
if (err)
|
||||
goto done;
|
||||
|
||||
if (length > std->len) {
|
||||
length = std->len;
|
||||
if (!(flags & USB_SHORT_XFER_OK)) {
|
||||
err = USB_ERR_SHORT_XFER;
|
||||
DPRINTFN(1, "The handle request function "
|
||||
"does not support writing data!\n");
|
||||
err = USB_ERR_INVAL;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/* The root HUB code needs the BUS lock locked */
|
||||
|
||||
USB_BUS_LOCK(udev->bus);
|
||||
err = (hr_func) (udev, req, &desc, &temp);
|
||||
USB_BUS_UNLOCK(udev->bus);
|
||||
|
||||
if (err)
|
||||
goto done;
|
||||
|
||||
if (length > temp) {
|
||||
if (!(flags & USB_SHORT_XFER_OK)) {
|
||||
err = USB_ERR_SHORT_XFER;
|
||||
goto done;
|
||||
}
|
||||
length = temp;
|
||||
}
|
||||
if (actlen)
|
||||
*actlen = length;
|
||||
|
||||
if (length > 0) {
|
||||
#if USB_HAVE_USER_IO
|
||||
if (flags & USB_USER_DATA_PTR) {
|
||||
if (copyout(std->ptr, data, length)) {
|
||||
if (copyout(desc, data, length)) {
|
||||
err = USB_ERR_INVAL;
|
||||
goto done;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
bcopy(std->ptr, data, length);
|
||||
bcopy(desc, data, length);
|
||||
}
|
||||
goto done;
|
||||
goto done; /* success */
|
||||
}
|
||||
|
||||
/*
|
||||
@ -898,26 +885,42 @@ usb2_req_get_string_desc(struct usb2_device *udev, struct mtx *mtx, void *sdesc,
|
||||
* Else: Failure
|
||||
*------------------------------------------------------------------------*/
|
||||
usb2_error_t
|
||||
usb2_req_get_config_desc_ptr(struct usb2_device *udev,
|
||||
struct usb2_config_descriptor **ppcd, uint8_t config_index)
|
||||
usb2_req_get_descriptor_ptr(struct usb2_device *udev,
|
||||
struct usb2_config_descriptor **ppcd, uint16_t wValue)
|
||||
{
|
||||
uint16_t len;
|
||||
|
||||
struct usb2_device_request req;
|
||||
|
||||
if (udev->flags.usb2_mode != USB_MODE_DEVICE)
|
||||
return (USB_ERR_INVAL);
|
||||
usb2_handle_request_t *hr_func;
|
||||
const void *ptr;
|
||||
uint16_t len;
|
||||
usb2_error_t err;
|
||||
|
||||
req.bmRequestType = UT_READ_DEVICE;
|
||||
req.bRequest = UR_GET_DESCRIPTOR;
|
||||
USETW2(req.wValue, UDESC_CONFIG, config_index);
|
||||
USETW(req.wValue, wValue);
|
||||
USETW(req.wIndex, 0);
|
||||
USETW(req.wLength, 0);
|
||||
|
||||
(usb2_temp_get_desc_p) (udev, &req,
|
||||
__DECONST(const void **, ppcd), &len);
|
||||
ptr = NULL;
|
||||
len = 0;
|
||||
|
||||
return (*ppcd ? USB_ERR_NORMAL_COMPLETION : USB_ERR_INVAL);
|
||||
hr_func = usb2_get_hr_func(udev);
|
||||
|
||||
if (hr_func == NULL)
|
||||
err = USB_ERR_INVAL;
|
||||
else {
|
||||
USB_BUS_LOCK(udev->bus);
|
||||
err = (hr_func) (udev, &req, &ptr, &len);
|
||||
USB_BUS_UNLOCK(udev->bus);
|
||||
}
|
||||
|
||||
if (err)
|
||||
ptr = NULL;
|
||||
else if (ptr == NULL)
|
||||
err = USB_ERR_INVAL;
|
||||
|
||||
*ppcd = __DECONST(struct usb2_config_descriptor *, ptr);
|
||||
|
||||
return (err);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
|
@ -44,8 +44,8 @@ usb2_error_t usb2_req_get_alt_interface_no(struct usb2_device *udev,
|
||||
uint8_t iface_index);
|
||||
usb2_error_t usb2_req_get_config(struct usb2_device *udev, struct mtx *mtx,
|
||||
uint8_t *pconf);
|
||||
usb2_error_t usb2_req_get_config_desc_ptr(struct usb2_device *udev,
|
||||
struct usb2_config_descriptor **ppcd, uint8_t config_index);
|
||||
usb2_error_t usb2_req_get_descriptor_ptr(struct usb2_device *udev,
|
||||
struct usb2_config_descriptor **ppcd, uint16_t wValue);
|
||||
usb2_error_t usb2_req_get_config_desc(struct usb2_device *udev, struct mtx *mtx,
|
||||
struct usb2_config_descriptor *d, uint8_t conf_index);
|
||||
usb2_error_t usb2_req_get_config_desc_full(struct usb2_device *udev,
|
||||
|
Loading…
Reference in New Issue
Block a user