From owner-p4-projects@FreeBSD.ORG Wed Jun 4 15:59:56 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 3F7BD1065673; Wed, 4 Jun 2008 15:59:56 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id DC2751065671 for ; Wed, 4 Jun 2008 15:59:55 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id C20E28FC14 for ; Wed, 4 Jun 2008 15:59:55 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id m54FxtZo095315 for ; Wed, 4 Jun 2008 15:59:55 GMT (envelope-from hselasky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id m54FxtgO095313 for perforce@freebsd.org; Wed, 4 Jun 2008 15:59:55 GMT (envelope-from hselasky@FreeBSD.org) Date: Wed, 4 Jun 2008 15:59:55 GMT Message-Id: <200806041559.m54FxtgO095313@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky To: Perforce Change Reviews Cc: Subject: PERFORCE change 142892 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 04 Jun 2008 15:59:56 -0000 http://perforce.freebsd.org/chv.cgi?CH=142892 Change 142892 by hselasky@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,