From owner-p4-projects@FreeBSD.ORG Thu Jan 22 15:17:02 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 335F41065670; Thu, 22 Jan 2009 15:17:02 +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 E5D6F106566B for ; Thu, 22 Jan 2009 15:17:01 +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 D3C048FC0C for ; Thu, 22 Jan 2009 15:17:01 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n0MFH1DG025152 for ; Thu, 22 Jan 2009 15:17:01 GMT (envelope-from hselasky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n0MFH1na025150 for perforce@freebsd.org; Thu, 22 Jan 2009 15:17:01 GMT (envelope-from hselasky@FreeBSD.org) Date: Thu, 22 Jan 2009 15:17:01 GMT Message-Id: <200901221517.n0MFH1na025150@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 156521 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: Thu, 22 Jan 2009 15:17:03 -0000 http://perforce.freebsd.org/chv.cgi?CH=156521 Change 156521 by hselasky@hselasky_laptop001 on 2009/01/22 15:16:39 U3G regression issue. Patch to support multiple modem instances per logical USB interface. Affected files ... .. //depot/projects/usb/src/sys/dev/usb2/serial/u3g2.c#7 edit Differences ... ==== //depot/projects/usb/src/sys/dev/usb2/serial/u3g2.c#7 (text+ko) ==== @@ -93,9 +93,9 @@ struct u3g_softc { struct usb2_com_super_softc sc_super_ucom; - struct usb2_com_softc sc_ucom; + struct usb2_com_softc sc_ucom[U3G_MAXPORTS]; - struct usb2_xfer *sc_xfer[U3G_N_TRANSFER]; + struct usb2_xfer *sc_xfer[U3G_MAXPORTS][U3G_N_TRANSFER]; struct usb2_device *sc_udev; uint8_t sc_iface_no; /* interface number */ @@ -382,8 +382,11 @@ static int u3g_attach(device_t dev) { + struct usb2_config u3g_config_tmp[U3G_N_TRANSFER]; struct usb2_attach_arg *uaa = device_get_ivars(dev); struct u3g_softc *sc = device_get_softc(dev); + uint8_t n; + uint8_t m; int error; DPRINTF("sc=%p\n", sc); @@ -391,6 +394,10 @@ if (sc == NULL) { return (ENOMEM); } + /* copy in USB config */ + for (n = 0; n != U3G_N_TRANSFER; n++) + u3g_config_tmp[n] = u3g_config[n]; + device_set_usb2_desc(dev); sc->sc_udev = uaa->device; @@ -398,23 +405,41 @@ sc->sc_iface_index = uaa->info.bIfaceIndex; sc->sc_speed = u3g_speeds[U3G_GET_SPEED(uaa)]; - error = usb2_transfer_setup(uaa->device, &sc->sc_iface_index, - sc->sc_xfer, u3g_config, U3G_N_TRANSFER, sc, &Giant); + for (m = 0; m != U3G_MAXPORTS; m++) { + + /* update BULK endpoint index */ + for (n = 0; n != U3G_N_TRANSFER; n++) + u3g_config_tmp[n].ep_index = m; + + /* try to allocate a set of BULK endpoints */ + error = usb2_transfer_setup(uaa->device, &sc->sc_iface_index, + sc->sc_xfer[m], u3g_config_tmp, U3G_N_TRANSFER, + &sc->sc_ucom[m], &Giant); - if (error) { - DPRINTF("could not allocate all pipes\n"); - goto detach; + if (error) { + if (m != 0) + break; /* end of endpoints */ + DPRINTF("could not allocate all pipes\n"); + goto detach; + } + /* set stall by default */ + usb2_transfer_set_stall(sc->sc_xfer[m][U3G_BULK_WR]); + usb2_transfer_set_stall(sc->sc_xfer[m][U3G_BULK_RD]); } - /* set stall by default */ - usb2_transfer_set_stall(sc->sc_xfer[U3G_BULK_WR]); - usb2_transfer_set_stall(sc->sc_xfer[U3G_BULK_RD]); + + sc->sc_numports = m; - error = usb2_com_attach(&sc->sc_super_ucom, &sc->sc_ucom, 1, sc, - &u3g_callback, &Giant); + error = usb2_com_attach(&sc->sc_super_ucom, sc->sc_ucom, + sc->sc_numports, sc, &u3g_callback, &Giant); if (error) { DPRINTF("usb2_com_attach failed\n"); goto detach; } + if (sc->sc_numports != 1) { + /* be verbose */ + device_printf(dev, "Found %u ports.\n", + (unsigned int)sc->sc_numports); + } return (0); detach: @@ -426,12 +451,15 @@ u3g_detach(device_t dev) { struct u3g_softc *sc = device_get_softc(dev); + uint8_t m; DPRINTF("sc=%p\n", sc); - usb2_com_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1); + /* NOTE: It is not dangerous to detach more ports than attached! */ + usb2_com_detach(&sc->sc_super_ucom, sc->sc_ucom, U3G_MAXPORTS); - usb2_transfer_unsetup(sc->sc_xfer, U3G_N_TRANSFER); + for (m = 0; m != U3G_MAXPORTS; m++) + usb2_transfer_unsetup(sc->sc_xfer[m], U3G_N_TRANSFER); return (0); } @@ -442,7 +470,7 @@ struct u3g_softc *sc = ucom->sc_parent; /* start read endpoint */ - usb2_transfer_start(sc->sc_xfer[U3G_BULK_RD]); + usb2_transfer_start(sc->sc_xfer[ucom->sc_local_unit][U3G_BULK_RD]); return; } @@ -452,7 +480,7 @@ struct u3g_softc *sc = ucom->sc_parent; /* stop read endpoint */ - usb2_transfer_stop(sc->sc_xfer[U3G_BULK_RD]); + usb2_transfer_stop(sc->sc_xfer[ucom->sc_local_unit][U3G_BULK_RD]); return; } @@ -461,7 +489,7 @@ { struct u3g_softc *sc = ucom->sc_parent; - usb2_transfer_start(sc->sc_xfer[U3G_BULK_WR]); + usb2_transfer_start(sc->sc_xfer[ucom->sc_local_unit][U3G_BULK_WR]); return; } @@ -470,21 +498,21 @@ { struct u3g_softc *sc = ucom->sc_parent; - usb2_transfer_stop(sc->sc_xfer[U3G_BULK_WR]); + usb2_transfer_stop(sc->sc_xfer[ucom->sc_local_unit][U3G_BULK_WR]); return; } static void u3g_write_callback(struct usb2_xfer *xfer) { - struct u3g_softc *sc = xfer->priv_sc; + struct usb2_com_softc *ucom = xfer->priv_sc; uint32_t actlen; switch (USB_GET_STATE(xfer)) { case USB_ST_TRANSFERRED: case USB_ST_SETUP: tr_setup: - if (usb2_com_get_data(&sc->sc_ucom, xfer->frbuffers, 0, + if (usb2_com_get_data(ucom, xfer->frbuffers, 0, U3G_BSIZE, &actlen)) { xfer->frlengths[0] = actlen; usb2_start_hardware(xfer); @@ -505,11 +533,11 @@ static void u3g_read_callback(struct usb2_xfer *xfer) { - struct u3g_softc *sc = xfer->priv_sc; + struct usb2_com_softc *ucom = xfer->priv_sc; switch (USB_GET_STATE(xfer)) { case USB_ST_TRANSFERRED: - usb2_com_put_data(&sc->sc_ucom, xfer->frbuffers, 0, xfer->actlen); + usb2_com_put_data(ucom, xfer->frbuffers, 0, xfer->actlen); case USB_ST_SETUP: tr_setup: