Index: sys/dev/usb/umcs.c =================================================================== RCS file: /cvsroot/src/sys/dev/usb/umcs.c,v retrieving revision 1.6 diff -p -u -r1.6 umcs.c --- sys/dev/usb/umcs.c 23 Mar 2014 20:20:38 -0000 1.6 +++ sys/dev/usb/umcs.c 4 May 2014 01:37:35 -0000 @@ -183,6 +183,19 @@ umcs7840_reg_dcr0(int phyport) } static int +umcs7840_port2phy(struct umcs7840_softc *sc, int port) +{ + + /* + * On four port cards, endpoints are 0/1 for first, + * 2/3 for second, ... + * On two port cards, they are 0/1 for first, 4/5 for second. + * On single port, just 0/1 will be used. + */ + return port * (sc->sc_numports == 2 ? 2 : 1); +} + +static int umcs7840_match(device_t dev, cfdata_t match, void *aux) { struct usb_attach_arg *uaa = aux; @@ -309,21 +322,15 @@ umcs7840_attach(device_t parent, device_ uca.arg = sc; for (i = 0; i < sc->sc_numports; i++) { - uca.bulkin = uca.bulkout = -1; + int phyport = umcs7840_port2phy(sc, i); - /* - * On four port cards, endpoints are 0/1 for first, - * 2/3 for second, ... - * On two port cards, they are 0/1 for first, 4/5 for second. - * On single port, just 0/1 will be used. - */ - int phyport = i * (sc->sc_numports == 2 ? 2 : 1); + uca.bulkin = uca.bulkout = -1; ed = usbd_interface2endpoint_descriptor(sc->sc_iface, phyport*2); if (ed == NULL) { aprint_error_dev(self, - "no bulk in endpoint found for %d\n", i); + "no bulk in endpoint found for %d\n", phyport); return; } uca.bulkin = ed->bEndpointAddress; @@ -332,16 +339,16 @@ umcs7840_attach(device_t parent, device_ phyport*2 + 1); if (ed == NULL) { aprint_error_dev(self, - "no bulk out endpoint found for %d\n", i); + "no bulk out endpoint found for %d\n", phyport); return; } uca.bulkout = ed->bEndpointAddress; - uca.portno = i; + uca.portno = phyport; DPRINTF(("port %d physical port %d bulk-in %d bulk-out %d\n", i, phyport, uca.bulkin, uca.bulkout)); - sc->sc_ports[i].sc_port_phys = phyport; - sc->sc_ports[i].sc_port_ucom = + sc->sc_ports[phyport].sc_port_phys = phyport; + sc->sc_ports[phyport].sc_port_ucom = config_found_sm_loc(self, "ucombus", NULL, &uca, ucomprint, ucomsubmatch); } @@ -533,8 +540,10 @@ umcs7840_detach(device_t self, int flags /* detach children */ for (i = 0; i < sc->sc_numports; i++) { - if (sc->sc_ports[i].sc_port_ucom) { - rv = config_detach(sc->sc_ports[i].sc_port_ucom, + int phyport = umcs7840_port2phy(sc, i); + + if (sc->sc_ports[phyport].sc_port_ucom) { + rv = config_detach(sc->sc_ports[phyport].sc_port_ucom, flags); if (rv) break; @@ -568,8 +577,10 @@ umcs7840_childdet(device_t self, device_ int i; for (i = 0; i < sc->sc_numports; i++) { - if (child == sc->sc_ports[i].sc_port_ucom) { - sc->sc_ports[i].sc_port_ucom = NULL; + int phyport = umcs7840_port2phy(sc, i); + + if (child == sc->sc_ports[phyport].sc_port_ucom) { + sc->sc_ports[phyport].sc_port_ucom = NULL; return; } } @@ -890,7 +901,9 @@ umcs7840_intr(usbd_xfer_handle xfer, usb uint32_t change_mask = 0; /* Check status of all ports */ for (subunit = 0; subunit < sc->sc_numports; subunit++) { - uint8_t pn = sc->sc_ports[subunit].sc_port_phys; + int phyport = umcs7840_port2phy(sc, subunit); + uint8_t pn = sc->sc_ports[phyport].sc_port_phys; + if (buf[pn] & MCS7840_UART_ISR_NOPENDING) continue; DPRINTF(("Port %d has pending interrupt: %02x " @@ -930,8 +943,10 @@ umcs7840_change_task(void *arg) change_mask = atomic_swap_32(&sc->sc_change_mask, 0); for (i = 0; i < sc->sc_numports; i++) { - if (ISSET(change_mask, (1U << i))) + int phyport = umcs7840_port2phy(sc, i); + + if (ISSET(change_mask, (1U << phyport))) ucom_status_change(device_private( - sc->sc_ports[i].sc_port_ucom)); + sc->sc_ports[phyport].sc_port_ucom)); } }