PERFORCE change 142892 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Wed Jun 4 15:59:56 UTC 2008
http://perforce.freebsd.org/chv.cgi?CH=142892
Change 142892 by hselasky at hselasky_laptop001 on 2008/06/04 15:59:13
USB Device Side Mode: Refactor the way endpoints are
configured and reset.
Affected files ...
.. //depot/projects/usb/src/sys/dev/usb/at9100_dci.c#16 edit
.. //depot/projects/usb/src/sys/dev/usb/usb_requests.c#21 edit
.. //depot/projects/usb/src/sys/dev/usb/usb_subr.c#105 edit
.. //depot/projects/usb/src/sys/dev/usb/usb_subr.h#103 edit
.. //depot/projects/usb/src/sys/dev/usb/uss820_dci.c#11 edit
Differences ...
==== //depot/projects/usb/src/sys/dev/usb/at9100_dci.c#16 (text+ko) ====
@@ -816,6 +816,8 @@
DPRINTFN(4, "real bus interrupt 0x%08x\n", status);
if (status & AT91_UDP_INT_END_BR) {
+
+ /* set correct state */
sc->sc_flags.status_bus_reset = 1;
sc->sc_flags.status_suspend = 0;
sc->sc_flags.change_suspend = 0;
@@ -1305,20 +1307,21 @@
}
static void
-at9100_dci_reset_ep(struct usbd_device *udev, uint8_t ep_no)
+at9100_dci_clear_stall_sub(struct at9100_dci_softc *sc, uint8_t ep_no,
+ uint8_t ep_type, uint8_t ep_dir)
{
- struct at9100_dci_softc *sc;
const struct usbd_hw_ep_profile *pf;
uint32_t csr_val;
uint32_t temp;
uint8_t csr_reg;
uint8_t to;
- /* get softc */
- sc = AT9100_DCI_BUS2SC(udev->bus);
-
+ if (ep_type == UE_CONTROL) {
+ /* clearing stall is not needed */
+ return;
+ }
/* get endpoint profile */
- at9100_dci_get_hw_ep_profile(udev, &pf, ep_no);
+ at9100_dci_get_hw_ep_profile(NULL, &pf, ep_no);
/* reset FIFO */
AT91_UDP_WRITE_4(sc, AT91_UDP_RST, AT91_UDP_RST_EP(ep_no));
@@ -1362,100 +1365,55 @@
AT91_CSR_ACK(csr_val, temp);
AT91_UDP_WRITE_4(sc, csr_reg, csr_val);
}
- return;
-}
+
+ AT91_CSR_ACK(csr_val, 0);
-static void
-at9100_dci_clear_stall(struct usbd_device *udev, struct usbd_pipe *pipe)
-{
- DPRINTFN(4, "pipe=%p\n", pipe);
+ /* enable endpoint */
+ csr_val &= ~AT91_UDP_CSR_ET_MASK;
+ csr_val |= AT91_UDP_CSR_EPEDS;
- mtx_assert(&(udev->bus->mtx), MA_OWNED);
+ if (ep_type == UE_CONTROL) {
+ csr_val |= AT91_UDP_CSR_ET_CTRL;
+ } else {
+ if (ep_type == UE_BULK) {
+ csr_val |= AT91_UDP_CSR_ET_BULK;
+ } else if (ep_type == UE_INTERRUPT) {
+ csr_val |= AT91_UDP_CSR_ET_INT;
+ } else {
+ csr_val |= AT91_UDP_CSR_ET_ISO;
+ }
+ if (ep_dir & UE_DIR_IN) {
+ csr_val |= AT91_UDP_CSR_ET_DIR_IN;
+ }
+ }
- /* reset endpoint */
- at9100_dci_reset_ep(udev,
- (pipe->edesc->bEndpointAddress & UE_ADDR));
+ /* enable endpoint */
+ AT91_UDP_WRITE_4(sc, AT91_UDP_CSR(ep_no), csr_val);
return;
}
-/*------------------------------------------------------------------------*
- * at9100_dci_set_config
- *
- * NOTE: Calling this function builds on the assumtion that
- * you have a configuration that is valid !
- *------------------------------------------------------------------------*/
static void
-at9100_dci_set_config(struct usbd_device *udev,
- usb_config_descriptor_t *cd)
+at9100_dci_clear_stall(struct usbd_device *udev, struct usbd_pipe *pipe)
{
struct at9100_dci_softc *sc;
usb_endpoint_descriptor_t *ed;
- uint32_t csr_val = 0;
- uint8_t n;
- uint8_t ep_type;
- uint8_t ep_dir;
+
+ DPRINTFN(4, "pipe=%p\n", pipe);
mtx_assert(&(udev->bus->mtx), MA_OWNED);
- if (udev->flags.usb_mode == USB_MODE_HOST) {
- /* this is the Root HUB */
- return;
- }
+ /* get softc */
sc = AT9100_DCI_BUS2SC(udev->bus);
- AT91_CSR_ACK(csr_val, 0);
- /* disable everything, but the control 0 endpoint */
+ /* get endpoint descriptor */
+ ed = pipe->edesc;
- for (n = 1; n != AT91_UDP_EP_MAX; n++) {
-
- /* disable endpoint */
- AT91_UDP_WRITE_4(sc, AT91_UDP_CSR(n), csr_val);
-
- /* reset endpoint */
- at9100_dci_reset_ep(udev, n);
- }
-
- if (cd == NULL) {
- /* nothing more to do */
- return;
- }
- ed = NULL;
-
- /* enable all endpoints in the configuration */
-
- while ((ed = (void *)usbd_desc_foreach(cd, (void *)ed))) {
-
- if ((ed->bDescriptorType != UDESC_ENDPOINT) ||
- (ed->bLength < sizeof(*ed))) {
- continue;
- }
- /* enable endpoint */
- csr_val &= ~AT91_UDP_CSR_ET_MASK;
- csr_val |= AT91_UDP_CSR_EPEDS;
-
- n = (ed->bEndpointAddress & UE_ADDR);
- ep_type = (ed->bmAttributes & UE_XFERTYPE);
- ep_dir = (ed->bEndpointAddress & (UE_DIR_IN | UE_DIR_OUT));
-
- if (ep_type == UE_CONTROL) {
- csr_val |= AT91_UDP_CSR_ET_CTRL;
- } else {
- if (ep_type == UE_BULK) {
- csr_val |= AT91_UDP_CSR_ET_BULK;
- } else if (ep_type == UE_INTERRUPT) {
- csr_val |= AT91_UDP_CSR_ET_INT;
- } else {
- csr_val |= AT91_UDP_CSR_ET_ISO;
- }
- if (ep_dir & UE_DIR_IN) {
- csr_val |= AT91_UDP_CSR_ET_DIR_IN;
- }
- }
-
- /* enable endpoint */
- AT91_UDP_WRITE_4(sc, AT91_UDP_CSR(n), csr_val);
- }
+ /* reset endpoint */
+ at9100_dci_clear_stall_sub(sc,
+ (ed->bEndpointAddress & UE_ADDR),
+ (ed->bEndpointAddress & (UE_DIR_IN | UE_DIR_OUT)),
+ (ed->bmAttributes & UE_XFERTYPE));
return;
}
@@ -1482,13 +1440,16 @@
DELAY(1000);
/* disable and clear all interrupts */
+
AT91_UDP_WRITE_4(sc, AT91_UDP_IDR, 0xFFFFFFFF);
AT91_UDP_WRITE_4(sc, AT91_UDP_ICR, 0xFFFFFFFF);
+ /* compute default CSR value */
+
csr_val = 0;
AT91_CSR_ACK(csr_val, 0);
- /* disable and reset all endpoints */
+ /* disable all endpoints */
for (n = 0; n != AT91_UDP_EP_MAX; n++) {
@@ -1496,6 +1457,15 @@
AT91_UDP_WRITE_4(sc, AT91_UDP_CSR(n), csr_val);
}
+ /* enable the control endpoint */
+
+ AT91_CSR_ACK(csr_val, AT91_UDP_CSR_ET_CTRL |
+ AT91_UDP_CSR_EPEDS);
+
+ /* write to FIFO control register */
+
+ AT91_UDP_WRITE_4(sc, AT91_UDP_CSR(0), csr_val);
+
/* enable the interrupts we want */
AT91_UDP_WRITE_4(sc, AT91_UDP_IER, AT91_UDP_INT_BUS);
@@ -2283,14 +2253,6 @@
if (sc->sc_flags.status_vbus &&
sc->sc_flags.status_bus_reset) {
- uint32_t csr = 0;
-
- /* enable the control endpoint */
- AT91_CSR_ACK(csr, AT91_UDP_CSR_ET_CTRL |
- AT91_UDP_CSR_EPEDS);
- /* write to FIFO control register */
- AT91_UDP_WRITE_4(sc, AT91_UDP_CSR(0), csr);
-
/* reset endpoint flags */
bzero(sc->sc_ep_flags, sizeof(sc->sc_ep_flags));
}
@@ -2564,7 +2526,6 @@
.xfer_setup = &at9100_dci_xfer_setup,
.xfer_unsetup = &at9100_dci_xfer_unsetup,
.do_poll = &at9100_dci_do_poll,
- .set_config = &at9100_dci_set_config,
.get_hw_ep_profile = &at9100_dci_get_hw_ep_profile,
.set_stall = &at9100_dci_set_stall,
.clear_stall = &at9100_dci_clear_stall,
==== //depot/projects/usb/src/sys/dev/usb/usb_requests.c#21 (text+ko) ====
@@ -821,15 +821,6 @@
PRINTF(("setting config %d\n", conf));
- /* call "set_config" method, if any */
-
- if (udev->bus->methods->set_config) {
- mtx_lock(&(udev->bus->mtx));
- (udev->bus->methods->set_config)
- (udev, (conf == USB_UNCONFIG_NO) ?
- NULL : udev->cdesc);
- mtx_unlock(&(udev->bus->mtx));
- }
/* do "set configuration" request */
req.bmRequestType = UT_WRITE_DEVICE;
==== //depot/projects/usb/src/sys/dev/usb/usb_subr.c#105 (text+ko) ====
@@ -580,9 +580,17 @@
/* the pipe is invalid: just return */
return;
}
+ /* initialise USB pipe structure */
pipe->edesc = edesc;
pipe->iface_index = iface_index;
LIST_INIT(&pipe->list_head);
+
+ /* clear stall, if any */
+ if (udev->bus->methods->clear_stall) {
+ mtx_lock(&(udev->bus->mtx));
+ (udev->bus->methods->clear_stall) (udev, pipe);
+ mtx_unlock(&(udev->bus->mtx));
+ }
return;
}
==== //depot/projects/usb/src/sys/dev/usb/usb_subr.h#103 (text+ko) ====
@@ -205,10 +205,6 @@
void (*xfer_unsetup) (struct usbd_xfer *xfer);
void (*get_dma_delay) (struct usbd_bus *, uint32_t *pdelay);
- /* USB Device and Host mode - Optional */
-
- void (*set_config) (struct usbd_device *udev, usb_config_descriptor_t *cd);
-
/* USB Device mode only - Mandatory */
void (*get_hw_ep_profile) (struct usbd_device *udev, const struct usbd_hw_ep_profile **ppf, uint8_t ep_addr);
@@ -217,6 +213,7 @@
void (*rem_wakeup_set) (struct usbd_device *udev, uint8_t is_on);
/* USB Device mode only - Optional */
+
void (*vbus_interrupt) (struct usbd_bus *, uint8_t is_on);
};
==== //depot/projects/usb/src/sys/dev/usb/uss820_dci.c#11 (text+ko) ====
@@ -1287,27 +1287,13 @@
}
static void
-uss820_dci_clear_stall(struct usbd_device *udev, struct usbd_pipe *pipe)
+uss820_dci_clear_stall_sub(struct uss820_dci_softc *sc,
+ uint8_t ep_no, uint8_t ep_type, uint8_t ep_dir)
{
- struct uss820_dci_softc *sc;
- uint8_t ep_no;
- uint8_t ep_type;
- uint8_t ep_dir;
uint8_t temp;
- mtx_assert(&(udev->bus->mtx), MA_OWNED);
-
- DPRINTFN(4, "pipe=%p\n", pipe);
-
- /* reset pipe state */
-
- sc = USS820_DCI_BUS2SC(udev->bus);
- ep_no = (pipe->edesc->bEndpointAddress & UE_ADDR);
- ep_dir = (pipe->edesc->bEndpointAddress & (UE_DIR_IN | UE_DIR_OUT));
- ep_type = (pipe->edesc->bmAttributes & UE_XFERTYPE);
-
if (ep_type == UE_CONTROL) {
- /* should not happen */
+ /* clearing stall is not needed */
return;
}
/* select endpoint index */
@@ -1351,149 +1337,33 @@
return;
}
-/*------------------------------------------------------------------------*
- * uss820_dci_set_config
- *
- * NOTE: Calling this function builds on the assumtion that
- * you have a configuration that is valid !
- *------------------------------------------------------------------------*/
static void
-uss820_dci_set_config(struct usbd_device *udev,
- usb_config_descriptor_t *cd)
+uss820_dci_clear_stall(struct usbd_device *udev, struct usbd_pipe *pipe)
{
- const struct usbd_hw_ep_profile *pf;
struct uss820_dci_softc *sc;
usb_endpoint_descriptor_t *ed;
- uint8_t n;
- uint8_t ep_type;
- uint8_t ep_dir;
- uint8_t temp;
mtx_assert(&(udev->bus->mtx), MA_OWNED);
- if (udev->flags.usb_mode == USB_MODE_HOST) {
- /* this is the Root HUB */
- return;
- }
- sc = USS820_DCI_BUS2SC(udev->bus);
+ DPRINTFN(4, "pipe=%p\n", pipe);
- /* disable everything, but the control 0 endpoint */
+ /* reset pipe state */
- for (n = 1; n != USS820_EP_MAX; n++) {
+ sc = USS820_DCI_BUS2SC(udev->bus);
+ ed = pipe->edesc;
- /* select endpoint */
- USS820_WRITE_1(sc, USS820_EPINDEX, n);
-
- /* disable endpoint - both directions */
- uss820_dci_update_shared_1(sc, USS820_EPCON, 0, 0);
- }
-
- if (cd == NULL) {
- /* nothing more to do */
- return;
- }
- ed = NULL;
-
- /* enable all endpoints in the configuration */
-
- while ((ed = (void *)usbd_desc_foreach(cd, (void *)ed))) {
-
- if ((ed->bDescriptorType != UDESC_ENDPOINT) ||
- (ed->bLength < sizeof(*ed))) {
- continue;
- }
- n = (ed->bEndpointAddress & UE_ADDR);
- ep_type = (ed->bmAttributes & UE_XFERTYPE);
- ep_dir = (ed->bEndpointAddress & (UE_DIR_IN | UE_DIR_OUT));
-
- uss820_dci_get_hw_ep_profile(udev, &pf, n);
-
- /* configure endpoint */
-
- if (ep_type == UE_ISOCHRONOUS) {
- if (pf->max_frame_size <= 64) {
- temp = (USS820_TXCON_FFSZ_16_64 |
- USS820_TXCON_TXISO |
- USS820_TXCON_ATM);
- } else if (pf->max_frame_size <= 256) {
- temp = (USS820_TXCON_FFSZ_64_256 |
- USS820_TXCON_TXISO |
- USS820_TXCON_ATM);
- } else if (pf->max_frame_size <= 512) {
- temp = (USS820_TXCON_FFSZ_8_512 |
- USS820_TXCON_TXISO |
- USS820_TXCON_ATM);
- } else { /* 1024 bytes */
- temp = (USS820_TXCON_FFSZ_32_1024 |
- USS820_TXCON_TXISO |
- USS820_TXCON_ATM);
- }
- } else {
- if ((pf->max_frame_size <= 8) &&
- (sc->sc_flags.mcsr_feat)) {
- temp = (USS820_TXCON_FFSZ_8_512 |
- USS820_TXCON_ATM);
- } else if (pf->max_frame_size <= 16) {
- temp = (USS820_TXCON_FFSZ_16_64 |
- USS820_TXCON_ATM);
- } else if ((pf->max_frame_size <= 32) &&
- (sc->sc_flags.mcsr_feat)) {
- temp = (USS820_TXCON_FFSZ_32_1024 |
- USS820_TXCON_ATM);
- } else { /* 64 bytes */
- temp = (USS820_TXCON_FFSZ_64_256 |
- USS820_TXCON_ATM);
- }
- }
-
- USS820_WRITE_1(sc, USS820_EPINDEX, n);
-
- if ((ep_dir == UE_DIR_IN) || (ep_type == UE_CONTROL)) {
-
- if (ep_type != UE_CONTROL) {
- /* reset data toggle */
- USS820_WRITE_1(sc, USS820_TXSTAT,
- USS820_TXSTAT_TXSOVW);
- }
- /* configure endpoint */
- USS820_WRITE_1(sc, USS820_TXCON, temp |
- USS820_TXCON_TXCLR);
- USS820_WRITE_1(sc, USS820_TXCON, temp);
- }
- if ((ep_dir == UE_DIR_OUT) || (ep_type == UE_CONTROL)) {
+ uss820_dci_clear_stall_sub(sc,
+ (ed->bEndpointAddress & UE_ADDR),
+ (ed->bEndpointAddress & (UE_DIR_IN | UE_DIR_OUT)),
+ (ed->bmAttributes & UE_XFERTYPE));
- if (ep_type != UE_CONTROL) {
- /* reset data toggle */
- uss820_dci_update_shared_1(sc, USS820_RXSTAT,
- 0, USS820_RXSTAT_RXSOVW);
- }
- /* configure endpoint */
- USS820_WRITE_1(sc, USS820_RXCON, temp |
- USS820_RXCON_RXCLR);
- USS820_WRITE_1(sc, USS820_RXCON, temp);
- }
- /* enable endpoint */
- if (ep_type == UE_CONTROL) {
- temp = (USS820_EPCON_CTLEP |
- USS820_EPCON_RXSPM |
- USS820_EPCON_RXEPEN |
- USS820_EPCON_TXEPEN);
- } else {
- if (ep_dir == UE_DIR_IN) {
- temp = USS820_EPCON_TXEPEN;
- } else {
- temp = USS820_EPCON_RXEPEN;
- }
- }
-
- uss820_dci_update_shared_1(sc, USS820_EPCON, 0xFF, temp);
- }
return;
}
usbd_status_t
uss820_dci_init(struct uss820_dci_softc *sc)
{
+ const struct usbd_hw_ep_profile *pf;
uint8_t n;
uint8_t temp;
@@ -1577,6 +1447,70 @@
uss820_dci_update_shared_1(sc, USS820_EPCON, 0, 0);
}
+ /*
+ * Initialise default values for some registers that cannot be
+ * changed during operation!
+ */
+ for (n = 0; n != USS820_EP_MAX; n++) {
+
+ uss820_dci_get_hw_ep_profile(NULL, &pf, n);
+
+ if (pf->support_isochronous) {
+ if (pf->max_frame_size <= 64) {
+ temp = (USS820_TXCON_FFSZ_16_64 |
+ USS820_TXCON_TXISO |
+ USS820_TXCON_ATM);
+ } else if (pf->max_frame_size <= 256) {
+ temp = (USS820_TXCON_FFSZ_64_256 |
+ USS820_TXCON_TXISO |
+ USS820_TXCON_ATM);
+ } else if (pf->max_frame_size <= 512) {
+ temp = (USS820_TXCON_FFSZ_8_512 |
+ USS820_TXCON_TXISO |
+ USS820_TXCON_ATM);
+ } else { /* 1024 bytes */
+ temp = (USS820_TXCON_FFSZ_32_1024 |
+ USS820_TXCON_TXISO |
+ USS820_TXCON_ATM);
+ }
+ } else {
+ if ((pf->max_frame_size <= 8) &&
+ (sc->sc_flags.mcsr_feat)) {
+ temp = (USS820_TXCON_FFSZ_8_512 |
+ USS820_TXCON_ATM);
+ } else if (pf->max_frame_size <= 16) {
+ temp = (USS820_TXCON_FFSZ_16_64 |
+ USS820_TXCON_ATM);
+ } else if ((pf->max_frame_size <= 32) &&
+ (sc->sc_flags.mcsr_feat)) {
+ temp = (USS820_TXCON_FFSZ_32_1024 |
+ USS820_TXCON_ATM);
+ } else { /* 64 bytes */
+ temp = (USS820_TXCON_FFSZ_64_256 |
+ USS820_TXCON_ATM);
+ }
+ }
+
+ /* need to configure the chip early */
+
+ USS820_WRITE_1(sc, USS820_EPINDEX, n);
+ USS820_WRITE_1(sc, USS820_TXCON, temp);
+ USS820_WRITE_1(sc, USS820_RXCON, temp);
+
+ if (pf->support_control) {
+ temp = USS820_EPCON_CTLEP |
+ USS820_EPCON_RXSPM |
+ USS820_EPCON_RXIE |
+ USS820_EPCON_RXEPEN |
+ USS820_EPCON_TXOE |
+ USS820_EPCON_TXEPEN;
+ } else {
+ temp = USS820_EPCON_RXEPEN | USS820_EPCON_TXEPEN;
+ }
+
+ uss820_dci_update_shared_1(sc, USS820_EPCON, 0xFF, temp);
+ }
+
mtx_unlock(&(sc->sc_bus.mtx));
/* catch any lost interrupts */
@@ -2352,56 +2286,6 @@
if (sc->sc_flags.change_connect) {
value |= UPS_C_CONNECT_STATUS;
-
- if (sc->sc_flags.status_vbus &&
- sc->sc_flags.status_bus_reset) {
-
- const struct usbd_hw_ep_profile *pf;
- uint8_t temp;
-
- uss820_dci_get_hw_ep_profile(xfer->udev, &pf, 0);
-
- /* select endpoint */
- USS820_WRITE_1(sc, USS820_EPINDEX, 0);
-
- if ((pf->max_frame_size <= 8) &&
- (sc->sc_flags.mcsr_feat)) {
- temp = (USS820_TXCON_FFSZ_8_512 |
- USS820_TXCON_ATM);
- } else if (pf->max_frame_size <= 16) {
- temp = (USS820_TXCON_FFSZ_16_64 |
- USS820_TXCON_ATM);
- } else if ((pf->max_frame_size <= 32) &&
- (sc->sc_flags.mcsr_feat)) {
- temp = (USS820_TXCON_FFSZ_32_1024 |
- USS820_TXCON_ATM);
- } else { /* 64 bytes */
- temp = (USS820_TXCON_FFSZ_64_256 |
- USS820_TXCON_ATM);
- }
-
- /* configure endpoint */
- USS820_WRITE_1(sc, USS820_TXCON, temp |
- USS820_TXCON_TXCLR);
- USS820_WRITE_1(sc, USS820_TXCON, temp);
-
- /* configure endpoint */
- USS820_WRITE_1(sc, USS820_RXCON, temp |
- USS820_RXCON_RXCLR);
- USS820_WRITE_1(sc, USS820_RXCON, temp);
-
- /* enable control endpoint */
- uss820_dci_update_shared_1(sc, USS820_EPCON, 0,
- (USS820_EPCON_CTLEP |
- USS820_EPCON_RXSPM |
- USS820_EPCON_RXIE |
- USS820_EPCON_RXEPEN |
- USS820_EPCON_TXOE |
- USS820_EPCON_TXEPEN));
-
- /* disable all other endpoints */
- uss820_dci_set_config(xfer->udev, NULL);
- }
}
if (sc->sc_flags.change_suspend) {
value |= UPS_C_SUSPEND;
@@ -2686,7 +2570,6 @@
.xfer_setup = &uss820_dci_xfer_setup,
.xfer_unsetup = &uss820_dci_xfer_unsetup,
.do_poll = &uss820_dci_do_poll,
- .set_config = &uss820_dci_set_config,
.get_hw_ep_profile = &uss820_dci_get_hw_ep_profile,
.set_stall = &uss820_dci_set_stall,
.clear_stall = &uss820_dci_clear_stall,
More information about the p4-projects
mailing list