diff options
author | Aaron Campbell <aaron@cvs.openbsd.org> | 2001-05-03 02:20:36 +0000 |
---|---|---|
committer | Aaron Campbell <aaron@cvs.openbsd.org> | 2001-05-03 02:20:36 +0000 |
commit | 5b92d7a741e1c34c9d68a85e4b9a47c24ea37b56 (patch) | |
tree | ac62c98e8633ce27c0186aaa2e0856e4093ade97 /sys | |
parent | c31dae3edb4a874106f38c4f1418182e49eda727 (diff) |
Sync with NetBSD. Tested with a USB keyboard, USB mouse, and three different
kue(4) Ethernet devices.
Diffstat (limited to 'sys')
36 files changed, 1151 insertions, 1579 deletions
diff --git a/sys/dev/usb/ezload.c b/sys/dev/usb/ezload.c index a36c7084a80..185c5b21a7e 100644 --- a/sys/dev/usb/ezload.c +++ b/sys/dev/usb/ezload.c @@ -1,5 +1,5 @@ -/* $OpenBSD: ezload.c,v 1.1 2001/01/29 00:33:13 aaron Exp $ */ -/* $NetBSD: ezload.c,v 1.1 2001/01/02 18:49:56 augustss Exp $ */ +/* $OpenBSD: ezload.c,v 1.2 2001/05/03 02:20:31 aaron Exp $ */ +/* $NetBSD: ezload.c,v 1.2 2001/01/18 20:28:23 jdolecek Exp $ */ /* * Copyright (c) 2000 The NetBSD Foundation, Inc. diff --git a/sys/dev/usb/ezload.h b/sys/dev/usb/ezload.h index 05ce8b34f8a..e62e4cb6569 100644 --- a/sys/dev/usb/ezload.h +++ b/sys/dev/usb/ezload.h @@ -1,5 +1,5 @@ -/* $OpenBSD: ezload.h,v 1.1 2001/01/29 00:33:13 aaron Exp $ */ -/* $NetBSD: ezload.h,v 1.1 2001/01/02 22:24:00 augustss Exp $ */ +/* $OpenBSD: ezload.h,v 1.2 2001/05/03 02:20:32 aaron Exp $ */ +/* $NetBSD: ezload.h,v 1.2 2001/01/18 20:28:23 jdolecek Exp $ */ /* * Copyright (c) 2000 The NetBSD Foundation, Inc. diff --git a/sys/dev/usb/if_aue.c b/sys/dev/usb/if_aue.c index 4cc0f27cdc4..0ab8eca568c 100644 --- a/sys/dev/usb/if_aue.c +++ b/sys/dev/usb/if_aue.c @@ -1,5 +1,5 @@ -/* $OpenBSD: if_aue.c,v 1.12 2001/02/20 19:39:47 mickey Exp $ */ -/* $NetBSD: if_aue.c,v 1.38 2000/04/04 20:16:19 augustss Exp $ */ +/* $OpenBSD: if_aue.c,v 1.13 2001/05/03 02:20:32 aaron Exp $ */ +/* $NetBSD: if_aue.c,v 1.55 2001/03/25 22:59:43 augustss Exp $ */ /* * Copyright (c) 1997, 1998, 1999, 2000 * Bill Paul <wpaul@ee.columbia.edu>. All rights reserved. @@ -89,42 +89,28 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/sockio.h> +#include <sys/lock.h> #include <sys/mbuf.h> #include <sys/malloc.h> #include <sys/kernel.h> +#include <sys/proc.h> #include <sys/socket.h> -#if defined(__FreeBSD__) - -#include <net/ethernet.h> -#include <machine/clock.h> /* for DELAY */ -#include <sys/bus.h> -/* "controller miibus0" required. See GENERIC if you get errors here. */ -#include "miibus_if.h" - -#elif defined(__NetBSD__) || defined(__OpenBSD__) - #include <sys/device.h> #if NRND > 0 #include <sys/rnd.h> #endif -#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ - #include <net/if.h> -#if defined(__NetBSD__) || defined(__FreeBSD__) +#if defined(__NetBSD__) #include <net/if_arp.h> #endif #include <net/if_dl.h> #include <net/if_media.h> -#if defined(__NetBSD__) || defined(__OpenBSD__) #define BPF_MTAP(ifp, m) bpf_mtap((ifp)->if_bpf, (m)) -#else -#define BPF_MTAP(ifp, m) bpf_mtap((ifp), (m)) -#endif -#if defined(__FreeBSD__) || NBPFILTER > 0 +#if NBPFILTER > 0 #include <net/bpf.h> #endif @@ -146,12 +132,10 @@ #endif #endif /* defined(__OpenBSD__) */ -#if defined(__NetBSD__) || defined(__OpenBSD__) #ifdef NS #include <netns/ns.h> #include <netns/ns_if.h> #endif -#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ #include <dev/mii/mii.h> #include <dev/mii/miivar.h> @@ -161,10 +145,6 @@ #include <dev/usb/usbdi_util.h> #include <dev/usb/usbdevs.h> -#ifdef __FreeBSD__ -#include <dev/usb/usb_ethersubr.h> -#endif - #include <dev/usb/if_auereg.h> #ifdef AUE_DEBUG @@ -185,7 +165,7 @@ struct aue_type { char aue_linksys; }; -Static struct aue_type aue_devs[] = { +Static const struct aue_type aue_devs[] = { { USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USB100, 0 }, { USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUATX1, 0 }, { USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUATX5, 0 }, @@ -205,94 +185,42 @@ Static struct aue_type aue_devs[] = { USB_DECLARE_DRIVER(aue); -Static struct aue_type *aue_lookup __P((u_int16_t, u_int16_t)); -Static int aue_tx_list_init __P((struct aue_softc *)); -Static int aue_rx_list_init __P((struct aue_softc *)); -Static int aue_newbuf __P((struct aue_softc *, struct aue_chain *, - struct mbuf *)); -Static int aue_send __P((struct aue_softc *, struct mbuf *, int)); -Static void aue_intr __P((usbd_xfer_handle, - usbd_private_handle, usbd_status)); -Static void aue_rxeof __P((usbd_xfer_handle, - usbd_private_handle, usbd_status)); -Static void aue_txeof __P((usbd_xfer_handle, - usbd_private_handle, usbd_status)); -Static void aue_tick __P((void *)); -Static void aue_start __P((struct ifnet *)); -Static int aue_ioctl __P((struct ifnet *, u_long, caddr_t)); -Static void aue_init __P((void *)); -Static void aue_stop __P((struct aue_softc *)); -Static void aue_watchdog __P((struct ifnet *)); -#ifdef __FreeBSD__ -Static void aue_shutdown __P((device_ptr_t)); -#endif -Static int aue_openpipes __P((struct aue_softc *)); -Static int aue_ifmedia_upd __P((struct ifnet *)); -Static void aue_ifmedia_sts __P((struct ifnet *, struct ifmediareq *)); - -Static int aue_eeprom_getword __P((struct aue_softc *, int)); -Static void aue_read_mac __P((struct aue_softc *, u_char *)); -Static int aue_miibus_readreg __P((device_ptr_t, int, int)); -#if defined(__FreeBSD__) -Static int aue_miibus_writereg __P((device_ptr_t, int, int, int)); -#elif defined(__NetBSD__) || defined(__OpenBSD__) -Static void aue_miibus_writereg __P((device_ptr_t, int, int, int)); -#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ -Static void aue_miibus_statchg __P((device_ptr_t)); - -Static void aue_setmulti __P((struct aue_softc *)); -Static u_int32_t aue_crc __P((caddr_t)); -Static void aue_reset __P((struct aue_softc *)); - -Static int aue_csr_read_1 __P((struct aue_softc *, int)); -Static int aue_csr_write_1 __P((struct aue_softc *, int, int)); -Static int aue_csr_read_2 __P((struct aue_softc *, int)); -Static int aue_csr_write_2 __P((struct aue_softc *, int, int)); - -#if defined(__FreeBSD__) -#if !defined(lint) -static const char rcsid[] = - "$FreeBSD: src/sys/dev/usb/if_aue.c,v 1.11 2000/01/14 01:36:14 wpaul Exp $"; -#endif - -Static void aue_rxstart __P((struct ifnet *)); - -Static struct usb_qdat aue_qdat; - -Static device_method_t aue_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, aue_match), - DEVMETHOD(device_attach, aue_attach), - DEVMETHOD(device_detach, aue_detach), - DEVMETHOD(device_shutdown, aue_shutdown), - - /* bus interface */ - DEVMETHOD(bus_print_child, bus_generic_print_child), - DEVMETHOD(bus_driver_added, bus_generic_driver_added), - - /* MII interface */ - DEVMETHOD(miibus_readreg, aue_miibus_readreg), - DEVMETHOD(miibus_writereg, aue_miibus_writereg), - DEVMETHOD(miibus_statchg, aue_miibus_statchg), - - { 0, 0 } -}; - -Static driver_t aue_driver = { - "aue", - aue_methods, - sizeof(struct aue_softc) -}; - -Static devclass_t aue_devclass; - -DRIVER_MODULE(if_aue, uhub, aue_driver, aue_devclass, usbd_driver_load, 0); -DRIVER_MODULE(miibus, aue, miibus_driver, miibus_devclass, 0, 0); - -#endif /* __FreeBSD__ */ - -#define AUE_DO_REQUEST(dev, req, data) \ - usbd_do_request_flags(dev, req, data, USBD_NO_TSLEEP, NULL) +Static const struct aue_type *aue_lookup(u_int16_t vendor, u_int16_t product); +Static int aue_tx_list_init(struct aue_softc *); +Static int aue_rx_list_init(struct aue_softc *); +Static int aue_newbuf(struct aue_softc *, struct aue_chain *, struct mbuf *); +Static int aue_send(struct aue_softc *, struct mbuf *, int); +Static void aue_intr(usbd_xfer_handle, usbd_private_handle, usbd_status); +Static void aue_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status); +Static void aue_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status); +Static void aue_tick(void *); +Static void aue_tick_task(void *); +Static void aue_start(struct ifnet *); +Static int aue_ioctl(struct ifnet *, u_long, caddr_t); +Static void aue_init(void *); +Static void aue_stop(struct aue_softc *); +Static void aue_watchdog(struct ifnet *); +Static int aue_openpipes(struct aue_softc *); +Static int aue_ifmedia_upd(struct ifnet *); +Static void aue_ifmedia_sts(struct ifnet *, struct ifmediareq *); + +Static int aue_eeprom_getword(struct aue_softc *, int); +Static void aue_read_mac(struct aue_softc *, u_char *); +Static int aue_miibus_readreg(device_ptr_t, int, int); +Static void aue_miibus_writereg(device_ptr_t, int, int, int); +Static void aue_miibus_statchg(device_ptr_t); + +Static void aue_lock_mii(struct aue_softc *); +Static void aue_unlock_mii(struct aue_softc *); + +Static void aue_setmulti(struct aue_softc *); +Static u_int32_t aue_crc(caddr_t); +Static void aue_reset(struct aue_softc *); + +Static int aue_csr_read_1(struct aue_softc *, int); +Static int aue_csr_write_1(struct aue_softc *, int, int); +Static int aue_csr_read_2(struct aue_softc *, int); +Static int aue_csr_write_2(struct aue_softc *, int, int); #define AUE_SETBIT(sc, reg, x) \ aue_csr_write_1(sc, reg, aue_csr_read_1(sc, reg) | (x)) @@ -301,14 +229,11 @@ DRIVER_MODULE(miibus, aue, miibus_driver, miibus_devclass, 0, 0); aue_csr_write_1(sc, reg, aue_csr_read_1(sc, reg) & ~(x)) Static int -aue_csr_read_1(sc, reg) - struct aue_softc *sc; - int reg; +aue_csr_read_1(struct aue_softc *sc, int reg) { usb_device_request_t req; usbd_status err; uByte val = 0; - int s; if (sc->aue_dying) return (0); @@ -319,9 +244,7 @@ aue_csr_read_1(sc, reg) USETW(req.wIndex, reg); USETW(req.wLength, 1); - s = splusb(); - err = AUE_DO_REQUEST(sc->aue_udev, &req, &val); - splx(s); + err = usbd_do_request(sc->aue_udev, &req, &val); if (err) { DPRINTF(("%s: aue_csr_read_1: reg=0x%x err=%s\n", @@ -333,14 +256,11 @@ aue_csr_read_1(sc, reg) } Static int -aue_csr_read_2(sc, reg) - struct aue_softc *sc; - int reg; +aue_csr_read_2(struct aue_softc *sc, int reg) { usb_device_request_t req; usbd_status err; uWord val; - int s; if (sc->aue_dying) return (0); @@ -351,9 +271,7 @@ aue_csr_read_2(sc, reg) USETW(req.wIndex, reg); USETW(req.wLength, 2); - s = splusb(); - err = AUE_DO_REQUEST(sc->aue_udev, &req, &val); - splx(s); + err = usbd_do_request(sc->aue_udev, &req, &val); if (err) { DPRINTF(("%s: aue_csr_read_2: reg=0x%x err=%s\n", @@ -365,13 +283,10 @@ aue_csr_read_2(sc, reg) } Static int -aue_csr_write_1(sc, reg, aval) - struct aue_softc *sc; - int reg, aval; +aue_csr_write_1(struct aue_softc *sc, int reg, int aval) { usb_device_request_t req; usbd_status err; - int s; uByte val; if (sc->aue_dying) @@ -384,9 +299,7 @@ aue_csr_write_1(sc, reg, aval) USETW(req.wIndex, reg); USETW(req.wLength, 1); - s = splusb(); - err = AUE_DO_REQUEST(sc->aue_udev, &req, &val); - splx(s); + err = usbd_do_request(sc->aue_udev, &req, &val); if (err) { DPRINTF(("%s: aue_csr_write_1: reg=0x%x err=%s\n", @@ -398,13 +311,10 @@ aue_csr_write_1(sc, reg, aval) } Static int -aue_csr_write_2(sc, reg, aval) - struct aue_softc *sc; - int reg, aval; +aue_csr_write_2(struct aue_softc *sc, int reg, int aval) { usb_device_request_t req; usbd_status err; - int s; uWord val; if (sc->aue_dying) @@ -417,9 +327,7 @@ aue_csr_write_2(sc, reg, aval) USETW(req.wIndex, reg); USETW(req.wLength, 2); - s = splusb(); - err = AUE_DO_REQUEST(sc->aue_udev, &req, &val); - splx(s); + err = usbd_do_request(sc->aue_udev, &req, &val); if (err) { DPRINTF(("%s: aue_csr_write_2: reg=0x%x err=%s\n", @@ -434,9 +342,7 @@ aue_csr_write_2(sc, reg, aval) * Read a word of data stored in the EEPROM at address 'addr.' */ Static int -aue_eeprom_getword(sc, addr) - struct aue_softc *sc; - int addr; +aue_eeprom_getword(struct aue_softc *sc, int addr) { int i; @@ -460,9 +366,7 @@ aue_eeprom_getword(sc, addr) * Read the MAC from the EEPROM. It's at offset 0. */ Static void -aue_read_mac(sc, dest) - struct aue_softc *sc; - u_char *dest; +aue_read_mac(struct aue_softc *sc, u_char *dest) { int i; int off = 0; @@ -477,15 +381,27 @@ aue_read_mac(sc, dest) } } +/* Get exclusive access to the MII registers */ +Static void +aue_lock_mii(struct aue_softc *sc) +{ + lockmgr(&sc->aue_mii_lock, LK_EXCLUSIVE, NULL, curproc); +} + +Static void +aue_unlock_mii(struct aue_softc *sc) +{ + lockmgr(&sc->aue_mii_lock, LK_RELEASE, NULL, curproc); +} + Static int -aue_miibus_readreg(dev, phy, reg) - device_ptr_t dev; - int phy, reg; +aue_miibus_readreg(device_ptr_t dev, int phy, int reg) { struct aue_softc *sc = USBGETSOFTC(dev); int i; u_int16_t val; +#if 0 /* * The Am79C901 HomePNA PHY actually contains * two transceivers: a 1Mbps HomePNA PHY and a @@ -498,10 +414,12 @@ aue_miibus_readreg(dev, phy, reg) */ if (sc->aue_vendor == USB_VENDOR_ADMTEK && sc->aue_product == USB_PRODUCT_ADMTEK_PEGASUS) { - if (phy != 1) + if (phy == 3) return (0); } +#endif + aue_lock_mii(sc); aue_csr_write_1(sc, AUE_PHY_ADDR, phy); aue_csr_write_1(sc, AUE_PHY_CTL, reg | AUE_PHYCTL_READ); @@ -511,8 +429,7 @@ aue_miibus_readreg(dev, phy, reg) } if (i == AUE_TIMEOUT) { - printf("%s: MII read timed out\n", - USBDEVNAME(sc->aue_dev)); + printf("%s: MII read timed out\n", USBDEVNAME(sc->aue_dev)); } val = aue_csr_read_2(sc, AUE_PHY_DATA); @@ -520,34 +437,28 @@ aue_miibus_readreg(dev, phy, reg) DPRINTFN(11,("%s: %s: phy=%d reg=%d => 0x%04x\n", USBDEVNAME(sc->aue_dev), __FUNCTION__, phy, reg, val)); + aue_unlock_mii(sc); return (val); } -#if defined(__FreeBSD__) -Static int -#elif defined(__NetBSD__) || defined(__OpenBSD__) Static void -#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ -aue_miibus_writereg(dev, phy, reg, data) - device_ptr_t dev; - int phy, reg, data; +aue_miibus_writereg(device_ptr_t dev, int phy, int reg, int data) { struct aue_softc *sc = USBGETSOFTC(dev); int i; +#if 0 if (sc->aue_vendor == USB_VENDOR_ADMTEK && sc->aue_product == USB_PRODUCT_ADMTEK_PEGASUS) { if (phy == 3) -#if defined(__FreeBSD__) - return (0); -#elif defined(__NetBSD__) || defined(__OpenBSD__) return; -#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ } +#endif DPRINTFN(11,("%s: %s: phy=%d reg=%d data=0x%04x\n", USBDEVNAME(sc->aue_dev), __FUNCTION__, phy, reg, data)); + aue_lock_mii(sc); aue_csr_write_2(sc, AUE_PHY_DATA, data); aue_csr_write_1(sc, AUE_PHY_ADDR, phy); aue_csr_write_1(sc, AUE_PHY_CTL, reg | AUE_PHYCTL_WRITE); @@ -561,21 +472,18 @@ aue_miibus_writereg(dev, phy, reg, data) printf("%s: MII read timed out\n", USBDEVNAME(sc->aue_dev)); } - -#if defined(__FreeBSD__) - return (0); -#endif + aue_unlock_mii(sc); } Static void -aue_miibus_statchg(dev) - device_ptr_t dev; +aue_miibus_statchg(device_ptr_t dev) { struct aue_softc *sc = USBGETSOFTC(dev); struct mii_data *mii = GET_MII(sc); DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev), __FUNCTION__)); + aue_lock_mii(sc); AUE_CLRBIT(sc, AUE_CTL0, AUE_CTL0_RX_ENB | AUE_CTL0_TX_ENB); if (IFM_SUBTYPE(mii->mii_media_active) == IFM_100_TX) { @@ -590,6 +498,7 @@ aue_miibus_statchg(dev) AUE_CLRBIT(sc, AUE_CTL1, AUE_CTL1_DUPLEX); AUE_SETBIT(sc, AUE_CTL0, AUE_CTL0_RX_ENB | AUE_CTL0_TX_ENB); + aue_unlock_mii(sc); /* * Set the LED modes on the LinkSys adapter. @@ -607,8 +516,7 @@ aue_miibus_statchg(dev) #define AUE_BITS 6 Static u_int32_t -aue_crc(addr) - caddr_t addr; +aue_crc(caddr_t addr) { u_int32_t idx, bit, data, crc; @@ -624,23 +532,20 @@ aue_crc(addr) } Static void -aue_setmulti(sc) - struct aue_softc *sc; +aue_setmulti(struct aue_softc *sc) { struct ifnet *ifp; -#if defined(__FreeBSD__) - struct ifmultiaddr *ifma; -#elif defined(__NetBSD__) || defined(__OpenBSD__) struct ether_multi *enm; struct ether_multistep step; -#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ u_int32_t h = 0, i; DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev), __FUNCTION__)); ifp = GET_IFP(sc); - if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) { + if (ifp->if_flags & IFF_PROMISC) { +allmulti: + ifp->if_flags |= IFF_ALLMULTI; AUE_SETBIT(sc, AUE_CTL0, AUE_CTL0_ALLMULTI); return; } @@ -652,39 +557,26 @@ aue_setmulti(sc) aue_csr_write_1(sc, AUE_MAR0 + i, 0); /* now program new ones */ -#if defined(__FreeBSD__) - for (ifma = ifp->if_multiaddrs.lh_first; ifma != NULL; - ifma = ifma->ifma_link.le_next) { - if (ifma->ifma_addr->sa_family != AF_LINK) - continue; - h = aue_crc(LLADDR((struct sockaddr_dl *)ifma->ifma_addr)); - AUE_SETBIT(sc, AUE_MAR + (h >> 3), 1 << (h & 0x7)); - } -#elif defined(__NetBSD__) || defined(__OpenBSD__) #if defined(__NetBSD__) ETHER_FIRST_MULTI(step, &sc->aue_ec, enm); #else ETHER_FIRST_MULTI(step, &sc->arpcom, enm); #endif while (enm != NULL) { -#if 1 if (memcmp(enm->enm_addrlo, - enm->enm_addrhi, ETHER_ADDR_LEN) != 0) { - ifp->if_flags |= IFF_ALLMULTI; - AUE_SETBIT(sc, AUE_CTL0, AUE_CTL0_ALLMULTI); - return; - } -#endif + enm->enm_addrhi, ETHER_ADDR_LEN) != 0) + goto allmulti; + h = aue_crc(enm->enm_addrlo); AUE_SETBIT(sc, AUE_MAR + (h >> 3), 1 << (h & 0x7)); ETHER_NEXT_MULTI(step, enm); } -#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ + + ifp->if_flags &= ~IFF_ALLMULTI; } Static void -aue_reset(sc) - struct aue_softc *sc; +aue_reset(struct aue_softc *sc) { int i; @@ -726,11 +618,10 @@ aue_reset(sc) delay(10000); /* XXX */ } -Static struct aue_type * -aue_lookup(vendor, product) - u_int16_t vendor, product; +Static const struct aue_type * +aue_lookup(u_int16_t vendor, u_int16_t product) { - struct aue_type *t; + const struct aue_type *t; for (t = aue_devs; t->aue_vid != 0; t++) if (vendor == t->aue_vid && product == t->aue_did) @@ -771,23 +662,23 @@ USB_ATTACH(aue) usb_endpoint_descriptor_t *ed; int i; -#ifdef __FreeBSD__ - bzero(sc, sizeof(struct aue_softc)); -#endif - DPRINTFN(5,(" : aue_attach: sc=%p", sc)); usbd_devinfo(dev, 0, devinfo); USB_ATTACH_SETUP; printf("%s: %s\n", USBDEVNAME(sc->aue_dev), devinfo); - err = usbd_set_config_no(dev, AUE_CONFIG_NO, 0); + err = usbd_set_config_no(dev, AUE_CONFIG_NO, 1); if (err) { printf("%s: setting config no failed\n", USBDEVNAME(sc->aue_dev)); USB_ATTACH_ERROR_RETURN; } + usb_init_task(&sc->aue_tick_task, aue_tick_task, sc); + usb_init_task(&sc->aue_stop_task, (void (*)(void *))aue_stop, sc); + lockinit(&sc->aue_mii_lock, PZERO, "auemii", 0, 0); + err = usbd_device2interface_handle(dev, AUE_IFACE_IDX, &iface); if (err) { printf("%s: getting interface handle failed\n", @@ -831,7 +722,7 @@ USB_ATTACH(aue) } - s = splimp(); + s = splnet(); /* Reset the adapter. */ aue_reset(sc); @@ -845,58 +736,6 @@ USB_ATTACH(aue) * A Pegasus chip was detected. Inform the world. */ ifp = GET_IFP(sc); -#if defined(__FreeBSD__) - printf("%s: Ethernet address: %6D\n", USBDEVNAME(sc->aue_dev), - eaddr, ":"); - - bcopy(eaddr, (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN); - - ifp->if_softc = sc; - ifp->if_unit = sc->aue_unit; - ifp->if_name = "aue"; - ifp->if_mtu = ETHERMTU; - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_ioctl = aue_ioctl; - ifp->if_output = ether_output; - ifp->if_start = aue_start; - ifp->if_watchdog = aue_watchdog; - ifp->if_init = aue_init; - ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; - - /* - * Do MII setup. - * NOTE: Doing this causes child devices to be attached to us, - * which we would normally disconnect at in the detach routine - * using device_delete_child(). However the USB code is set up - * such that when this driver is removed, all childred devices - * are removed as well. In effect, the USB code ends up detaching - * all of our children for us, so we don't have to do is ourselves - * in aue_detach(). It's important to point this out since if - * we *do* try to detach the child devices ourselves, we will - * end up getting the children deleted twice, which will crash - * the system. - */ - if (mii_phy_probe(self, &sc->aue_miibus, - aue_ifmedia_upd, aue_ifmedia_sts)) { - printf("%s: MII without any PHY!\n", USBDEVNAME(sc->aue_dev)); - splx(s); - USB_ATTACH_ERROR_RETURN; - } - - aue_qdat.ifp = ifp; - aue_qdat.if_rxstart = aue_rxstart; - - /* - * Call MI attach routines. - */ - if_attach(ifp); - ether_ifattach(ifp); - bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header)); - - usb_register_netisr(); - -#elif defined(__NetBSD__) || defined(__OpenBSD__) - printf("%s: Ethernet address %s\n", USBDEVNAME(sc->aue_dev), ether_sprintf(eaddr)); @@ -922,6 +761,7 @@ USB_ATTACH(aue) mii->mii_readreg = aue_miibus_readreg; mii->mii_writereg = aue_miibus_writereg; mii->mii_statchg = aue_miibus_statchg; + mii->mii_flags = MIIF_AUTOTSLEEP; ifmedia_init(&mii->mii_media, 0, aue_ifmedia_upd, aue_ifmedia_sts); mii_attach(self, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0); if (LIST_FIRST(&mii->mii_phys) == NULL) { @@ -933,14 +773,11 @@ USB_ATTACH(aue) /* Attach the interface. */ if_attach(ifp); Ether_ifattach(ifp, eaddr); - #if NRND > 0 rnd_attach_source(&sc->rnd_source, USBDEVNAME(sc->aue_dev), RND_TYPE_NET, 0); #endif -#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ - usb_callout_init(sc->aue_stat_ch); sc->aue_attached = 1; @@ -960,9 +797,15 @@ USB_DETACH(aue) DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev), __FUNCTION__)); - s = splusb(); - usb_uncallout(sc->aue_stat_ch, aue_tick, sc); + /* + * Remove any pending tasks. They cannot be executing because they run + * in the same thread as detach. + */ + usb_rem_task(sc->aue_udev, &sc->aue_tick_task); + usb_rem_task(sc->aue_udev, &sc->aue_stop_task); + + s = splusb(); if (!sc->aue_attached) { /* Detached before attached finished, so just bail out. */ @@ -986,8 +829,8 @@ USB_DETACH(aue) #if NBPFILTER > 0 bpfdetach(ifp); #endif - ether_ifdetach(ifp); #endif /* __NetBSD__ */ + ether_ifdetach(ifp); if_detach(ifp); @@ -1008,11 +851,8 @@ USB_DETACH(aue) return (0); } -#if defined(__NetBSD__) || defined(__OpenBSD__) int -aue_activate(self, act) - device_ptr_t self; - enum devact act; +aue_activate(device_ptr_t self, enum devact act) { struct aue_softc *sc = (struct aue_softc *)self; @@ -1030,16 +870,12 @@ aue_activate(self, act) } return (0); } -#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ /* * Initialize an RX descriptor and attach an MBUF cluster. */ Static int -aue_newbuf(sc, c, m) - struct aue_softc *sc; - struct aue_chain *c; - struct mbuf *m; +aue_newbuf(struct aue_softc *sc, struct aue_chain *c, struct mbuf *m) { struct mbuf *m_new = NULL; @@ -1074,8 +910,7 @@ aue_newbuf(sc, c, m) } Static int -aue_rx_list_init(sc) - struct aue_softc *sc; +aue_rx_list_init(struct aue_softc *sc) { struct aue_cdata *cd; struct aue_chain *c; @@ -1104,8 +939,7 @@ aue_rx_list_init(sc) } Static int -aue_tx_list_init(sc) - struct aue_softc *sc; +aue_tx_list_init(struct aue_softc *sc) { struct aue_cdata *cd; struct aue_chain *c; @@ -1133,10 +967,7 @@ aue_tx_list_init(sc) } Static void -aue_intr(xfer, priv, status) - usbd_xfer_handle xfer; - usbd_private_handle priv; - usbd_status status; +aue_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) { struct aue_softc *sc = priv; struct ifnet *ifp = GET_IFP(sc); @@ -1173,39 +1004,12 @@ aue_intr(xfer, priv, status) ifp->if_collisions++; } -#if defined(__FreeBSD__) -Static void -aue_rxstart(ifp) - struct ifnet *ifp; -{ - struct aue_softc *sc; - struct aue_chain *c; - - sc = ifp->if_softc; - c = &sc->aue_cdata.aue_rx_chain[sc->aue_cdata.aue_rx_prod]; - - if (aue_newbuf(sc, c, NULL) == ENOBUFS) { - ifp->if_ierrors++; - return; - } - - /* Setup new transfer. */ - usbd_setup_xfer(c->aue_xfer, sc->aue_ep[AUE_ENDPT_RX], - c, mtod(c->aue_mbuf, char *), AUE_BUFSZ, USBD_SHORT_XFER_OK, - USBD_NO_TIMEOUT, aue_rxeof); - usbd_transfer(c->aue_xfer); -} -#endif - /* * A frame has been uploaded: pass the resulting mbuf chain up to * the higher level protocols. */ Static void -aue_rxeof(xfer, priv, status) - usbd_xfer_handle xfer; - usbd_private_handle priv; - usbd_status status; +aue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) { struct aue_chain *c = priv; struct aue_softc *sc = c->aue_sc; @@ -1213,9 +1017,7 @@ aue_rxeof(xfer, priv, status) struct mbuf *m; u_int32_t total_len; struct aue_rxpkt r; -#if defined(__NetBSD__) || defined(__OpenBSD__) int s; -#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev),__FUNCTION__)); @@ -1264,17 +1066,9 @@ aue_rxeof(xfer, priv, status) m->m_pkthdr.len = m->m_len = total_len; ifp->if_ipackets++; -#if defined(__FreeBSD__) - m->m_pkthdr.rcvif = (struct ifnet *)&kue_qdat; - /* Put the packet on the special USB input queue. */ - usb_ether_input(m); - - return; - -#elif defined(__NetBSD__) || defined(__OpenBSD__) m->m_pkthdr.rcvif = ifp; - s = splimp(); + s = splnet(); /* XXX ugly */ if (aue_newbuf(sc, c, NULL) == ENOBUFS) { @@ -1289,29 +1083,15 @@ aue_rxeof(xfer, priv, status) * a broadcast packet, multicast packet, matches our ethernet * address or the interface is in promiscuous mode. */ - if (ifp->if_bpf) { -#if defined(__NetBSD__) - struct ether_header *eh = mtod(m, struct ether_header *); - BPF_MTAP(ifp, m); - if ((ifp->if_flags & IFF_PROMISC) && - memcmp(eh->ether_dhost, LLADDR(ifp->if_sadl), - ETHER_ADDR_LEN) && - !(eh->ether_dhost[0] & 1)) { - m_freem(m); - goto done1; - } -#else + if (ifp->if_bpf) BPF_MTAP(ifp, m); #endif - } -#endif DPRINTFN(10,("%s: %s: deliver %d\n", USBDEVNAME(sc->aue_dev), __FUNCTION__, m->m_len)); IF_INPUT(ifp, m); done1: splx(s); -#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ done: @@ -1332,10 +1112,7 @@ aue_rxeof(xfer, priv, status) */ Static void -aue_txeof(xfer, priv, status) - usbd_xfer_handle xfer; - usbd_private_handle priv; - usbd_status status; +aue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) { struct aue_chain *c = priv; struct aue_softc *sc = c->aue_sc; @@ -1345,7 +1122,7 @@ aue_txeof(xfer, priv, status) if (sc->aue_dying) return; - s = splimp(); + s = splnet(); DPRINTFN(10,("%s: %s: enter status=%d\n", USBDEVNAME(sc->aue_dev), __FUNCTION__, status)); @@ -1369,29 +1146,19 @@ aue_txeof(xfer, priv, status) ifp->if_opackets++; -#if defined(__FreeBSD__) - c->aue_mbuf->m_pkthdr.rcvif = ifp; - usb_tx_done(c->aue_mbuf); - c->aue_mbuf = NULL; -#elif defined(__NetBSD__) || defined(__OpenBSD__) m_freem(c->aue_mbuf); c->aue_mbuf = NULL; if (ifp->if_snd.ifq_head != NULL) aue_start(ifp); -#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ splx(s); } Static void -aue_tick(xsc) - void *xsc; +aue_tick(void *xsc) { struct aue_softc *sc = xsc; - struct ifnet *ifp; - struct mii_data *mii; - int s; DPRINTFN(15,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev),__FUNCTION__)); @@ -1401,12 +1168,29 @@ aue_tick(xsc) if (sc->aue_dying) return; + /* Perform periodic stuff in process context. */ + usb_add_task(sc->aue_udev, &sc->aue_tick_task); +} + +Static void +aue_tick_task(void *xsc) +{ + struct aue_softc *sc = xsc; + struct ifnet *ifp; + struct mii_data *mii; + int s; + + DPRINTFN(15,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev),__FUNCTION__)); + + if (sc->aue_dying) + return; + ifp = GET_IFP(sc); mii = GET_MII(sc); if (mii == NULL) return; - s = splimp(); + s = splnet(); mii_tick(mii); if (!sc->aue_link) { @@ -1427,10 +1211,7 @@ aue_tick(xsc) } Static int -aue_send(sc, m, idx) - struct aue_softc *sc; - struct mbuf *m; - int idx; +aue_send(struct aue_softc *sc, struct mbuf *m, int idx) { int total_len; struct aue_chain *c; @@ -1466,7 +1247,8 @@ aue_send(sc, m, idx) if (err != USBD_IN_PROGRESS) { printf("%s: aue_send error=%s\n", USBDEVNAME(sc->aue_dev), usbd_errstr(err)); - aue_stop(sc); + /* Stop the interface from process context. */ + usb_add_task(sc->aue_udev, &sc->aue_stop_task); return (EIO); } DPRINTFN(5,("%s: %s: send %d bytes\n", USBDEVNAME(sc->aue_dev), @@ -1478,8 +1260,7 @@ aue_send(sc, m, idx) } Static void -aue_start(ifp) - struct ifnet *ifp; +aue_start(struct ifnet *ifp) { struct aue_softc *sc = ifp->if_softc; struct mbuf *m_head = NULL; @@ -1524,8 +1305,7 @@ aue_start(ifp) } Static void -aue_init(xsc) - void *xsc; +aue_init(void *xsc) { struct aue_softc *sc = xsc; struct ifnet *ifp = GET_IFP(sc); @@ -1541,14 +1321,14 @@ aue_init(xsc) if (ifp->if_flags & IFF_RUNNING) return; - s = splimp(); + s = splnet(); /* * Cancel pending I/O and free all RX/TX buffers. */ aue_reset(sc); -#if defined(__FreeBSD__) || defined(__OpenBSD__) +#if defined(__OpenBSD__) eaddr = sc->arpcom.ac_enaddr; #elif defined(__NetBSD__) eaddr = LLADDR(ifp->if_sadl); @@ -1602,8 +1382,7 @@ aue_init(xsc) } Static int -aue_openpipes(sc) - struct aue_softc *sc; +aue_openpipes(struct aue_softc *sc) { struct aue_chain *c; usbd_status err; @@ -1653,8 +1432,7 @@ aue_openpipes(sc) * Set media options. */ Static int -aue_ifmedia_upd(ifp) - struct ifnet *ifp; +aue_ifmedia_upd(struct ifnet *ifp) { struct aue_softc *sc = ifp->if_softc; struct mii_data *mii = GET_MII(sc); @@ -1680,9 +1458,7 @@ aue_ifmedia_upd(ifp) * Report current media status. */ Static void -aue_ifmedia_sts(ifp, ifmr) - struct ifnet *ifp; - struct ifmediareq *ifmr; +aue_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) { struct aue_softc *sc = ifp->if_softc; struct mii_data *mii = GET_MII(sc); @@ -1695,15 +1471,10 @@ aue_ifmedia_sts(ifp, ifmr) } Static int -aue_ioctl(ifp, command, data) - struct ifnet *ifp; - u_long command; - caddr_t data; +aue_ioctl(struct ifnet *ifp, u_long command, caddr_t data) { struct aue_softc *sc = ifp->if_softc; -#if defined(__NetBSD__) || defined(__OpenBSD__) struct ifaddr *ifa = (struct ifaddr *)data; -#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ struct ifreq *ifr = (struct ifreq *)data; struct mii_data *mii; int s, error = 0; @@ -1711,16 +1482,9 @@ aue_ioctl(ifp, command, data) if (sc->aue_dying) return (EIO); - s = splimp(); + s = splnet(); switch(command) { -#if defined(__FreeBSD__) - case SIOCSIFADDR: - case SIOCGIFADDR: - case SIOCSIFMTU: - error = ether_ioctl(ifp, command, data); - break; -#elif defined(__NetBSD__) || defined(__OpenBSD__) case SIOCSIFADDR: ifp->if_flags |= IFF_UP; aue_init(sc); @@ -1760,7 +1524,6 @@ aue_ioctl(ifp, command, data) ifp->if_mtu = ifr->ifr_mtu; break; -#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ case SIOCSIFFLAGS: if (ifp->if_flags & IFF_UP) { if (ifp->if_flags & IFF_RUNNING && @@ -1782,6 +1545,17 @@ aue_ioctl(ifp, command, data) break; case SIOCADDMULTI: case SIOCDELMULTI: + error = (command == SIOCADDMULTI) ? +#if defined(__NetBSD__) + ether_addmulti(ifr, &sc->aue_ec) : + ether_delmulti(ifr, &sc->aue_ec); +#else + ether_addmulti(ifr, &sc->arpcom) : + ether_delmulti(ifr, &sc->arpcom); +#endif + if (error == ENETRESET) { + aue_init(sc); + } aue_setmulti(sc); error = 0; break; @@ -1801,29 +1575,26 @@ aue_ioctl(ifp, command, data) } Static void -aue_watchdog(ifp) - struct ifnet *ifp; +aue_watchdog(struct ifnet *ifp) { struct aue_softc *sc = ifp->if_softc; + struct aue_chain *c; + usbd_status stat; + int s; DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev), __FUNCTION__)); ifp->if_oerrors++; printf("%s: watchdog timeout\n", USBDEVNAME(sc->aue_dev)); - /* - * The polling business is a kludge to avoid allowing the - * USB code to call tsleep() in usbd_delay_ms(), which will - * kill us since the watchdog routine is invoked from - * interrupt context. - */ - usbd_set_polling(sc->aue_udev, 1); - aue_stop(sc); - aue_init(sc); - usbd_set_polling(sc->aue_udev, 0); + s = splusb(); + c = &sc->aue_cdata.aue_tx_chain[0]; + usbd_get_xfer_status(c->aue_xfer, NULL, NULL, NULL, &stat); + aue_txeof(c->aue_xfer, c, stat); if (ifp->if_snd.ifq_head != NULL) aue_start(ifp); + splx(s); } /* @@ -1831,8 +1602,7 @@ aue_watchdog(ifp) * RX and TX lists. */ Static void -aue_stop(sc) - struct aue_softc *sc; +aue_stop(struct aue_softc *sc) { usbd_status err; struct ifnet *ifp; @@ -1919,21 +1689,3 @@ aue_stop(sc) ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); } - -#ifdef __FreeBSD__ -/* - * Stop all chip I/O so that the kernel's probe routines don't - * get confused by errant DMAs when rebooting. - */ -Static void -aue_shutdown(dev) - device_ptr_t dev; -{ - struct aue_softc *sc = USBGETSOFTC(dev); - - DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev), __FUNCTION__)); - - aue_reset(sc); - aue_stop(sc); -} -#endif diff --git a/sys/dev/usb/if_auereg.h b/sys/dev/usb/if_auereg.h index 6b3e5bc1110..9b1b146df0c 100644 --- a/sys/dev/usb/if_auereg.h +++ b/sys/dev/usb/if_auereg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_auereg.h,v 1.3 2000/07/04 11:44:21 fgsch Exp $ */ +/* $OpenBSD: if_auereg.h,v 1.4 2001/05/03 02:20:32 aaron Exp $ */ /* $NetBSD: if_auereg.h,v 1.12 2000/04/04 20:16:19 augustss Exp $ */ /* * Copyright (c) 1997, 1998, 1999 @@ -266,6 +266,11 @@ struct aue_softc { u_int aue_rx_errs; u_int aue_intr_errs; struct timeval aue_rx_notice; + + struct usb_task aue_tick_task; + struct usb_task aue_stop_task; + + struct lock aue_mii_lock; }; #define AUE_TIMEOUT 1000 diff --git a/sys/dev/usb/if_cue.c b/sys/dev/usb/if_cue.c index 741573d5eb6..6a82299a871 100644 --- a/sys/dev/usb/if_cue.c +++ b/sys/dev/usb/if_cue.c @@ -1,5 +1,5 @@ -/* $OpenBSD: if_cue.c,v 1.7 2001/02/20 19:39:47 mickey Exp $ */ -/* $NetBSD: if_cue.c,v 1.21 2000/04/02 21:25:41 augustss Exp $ */ +/* $OpenBSD: if_cue.c,v 1.8 2001/05/03 02:20:32 aaron Exp $ */ +/* $NetBSD: if_cue.c,v 1.34 2001/04/12 23:54:56 augustss Exp $ */ /* * Copyright (c) 1997, 1998, 1999, 2000 * Bill Paul <wpaul@ee.columbia.edu>. All rights reserved. @@ -56,10 +56,6 @@ * Ported to NetBSD and somewhat rewritten by Lennart Augustsson. */ -/* - * TODO: - * proper cleanup on errors - */ #if defined(__NetBSD__) #include "opt_inet.h" #include "opt_ns.h" @@ -80,34 +76,20 @@ #include <sys/kernel.h> #include <sys/socket.h> -#if defined(__FreeBSD__) - -#include <net/ethernet.h> -#include <machine/clock.h> /* for DELAY */ -#include <sys/bus.h> - -#elif defined(__NetBSD__) || defined(__OpenBSD__) - #include <sys/device.h> #if NRND > 0 #include <sys/rnd.h> #endif -#endif - #include <net/if.h> -#if defined(__NetBSD__) || defined(__FreeBSD__) +#if defined(__NetBSD__) #include <net/if_arp.h> #endif #include <net/if_dl.h> -#if defined(__NetBSD__) || defined(__OpenBSD__) #define BPF_MTAP(ifp, m) bpf_mtap((ifp)->if_bpf, (m)) -#else -#define BPF_MTAP(ifp, m) bpf_mtap((ifp), (m)) -#endif -#if defined(__FreeBSD__) || NBPFILTER > 0 +#if NBPFILTER > 0 #include <net/bpf.h> #endif @@ -129,22 +111,16 @@ #endif #endif /* defined(__OpenBSD__) */ -#if defined(__NetBSD__) || defined(__OpenBSD__) #ifdef NS #include <netns/ns.h> #include <netns/ns_if.h> #endif -#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ #include <dev/usb/usb.h> #include <dev/usb/usbdi.h> #include <dev/usb/usbdi_util.h> #include <dev/usb/usbdevs.h> -#ifdef __FreeBSD__ -#include <dev/usb/usb_ethersubr.h> -#endif - #include <dev/usb/if_cuereg.h> #ifdef CUE_DEBUG @@ -169,72 +145,33 @@ Static struct cue_type cue_devs[] = { USB_DECLARE_DRIVER(cue); -Static int cue_open_pipes __P((struct cue_softc *)); -Static int cue_tx_list_init __P((struct cue_softc *)); -Static int cue_rx_list_init __P((struct cue_softc *)); -Static int cue_newbuf __P((struct cue_softc *, struct cue_chain *, - struct mbuf *)); -Static int cue_send __P((struct cue_softc *, struct mbuf *, int)); -Static void cue_rxeof __P((usbd_xfer_handle, - usbd_private_handle, usbd_status)); -Static void cue_txeof __P((usbd_xfer_handle, - usbd_private_handle, usbd_status)); -Static void cue_tick __P((void *)); -Static void cue_start __P((struct ifnet *)); -Static int cue_ioctl __P((struct ifnet *, u_long, caddr_t)); -Static void cue_init __P((void *)); -Static void cue_stop __P((struct cue_softc *)); -Static void cue_watchdog __P((struct ifnet *)); - -Static void cue_setmulti __P((struct cue_softc *)); -Static u_int32_t cue_crc __P((caddr_t)); -Static void cue_reset __P((struct cue_softc *)); - -Static int cue_csr_read_1 __P((struct cue_softc *, int)); -Static int cue_csr_write_1 __P((struct cue_softc *, int, int)); -Static int cue_csr_read_2 __P((struct cue_softc *, int)); -#ifdef notdef -Static int cue_csr_write_2 __P((struct cue_softc *, int, int)); -#endif -Static int cue_mem __P((struct cue_softc *, int, - int, void *, int)); -Static int cue_getmac __P((struct cue_softc *, void *)); - -#ifdef __FreeBSD__ -#ifndef lint -static const char rcsid[] = - "$FreeBSD: src/sys/dev/usb/if_cue.c,v 1.4 2000/01/16 22:45:06 wpaul Exp $"; +Static int cue_open_pipes(struct cue_softc *); +Static int cue_tx_list_init(struct cue_softc *); +Static int cue_rx_list_init(struct cue_softc *); +Static int cue_newbuf(struct cue_softc *, struct cue_chain *, struct mbuf *); +Static int cue_send(struct cue_softc *, struct mbuf *, int); +Static void cue_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status); +Static void cue_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status); +Static void cue_tick(void *); +Static void cue_tick_task(void *); +Static void cue_start(struct ifnet *); +Static int cue_ioctl(struct ifnet *, u_long, caddr_t); +Static void cue_init(void *); +Static void cue_stop(struct cue_softc *); +Static void cue_watchdog(struct ifnet *); + +Static void cue_setmulti(struct cue_softc *); +Static u_int32_t cue_crc(caddr_t); +Static void cue_reset(struct cue_softc *); + +Static int cue_csr_read_1(struct cue_softc *, int); +Static int cue_csr_write_1(struct cue_softc *, int, int); +Static int cue_csr_read_2(struct cue_softc *, int); +#if 0 +Static int cue_csr_write_2(struct cue_softc *, int, int); #endif - -Static void cue_rxstart __P((struct ifnet *)); -Static void cue_shutdown __P((device_t)); - -Static struct usb_qdat cue_qdat; - -Static device_method_t cue_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, cue_match), - DEVMETHOD(device_attach, cue_attach), - DEVMETHOD(device_detach, cue_detach), - DEVMETHOD(device_shutdown, cue_shutdown), - - { 0, 0 } -}; - -Static driver_t cue_driver = { - "cue", - cue_methods, - sizeof(struct cue_softc) -}; - -Static devclass_t cue_devclass; - -DRIVER_MODULE(if_cue, uhub, cue_driver, cue_devclass, usbd_driver_load, 0); - -#endif /* defined(__FreeBSD__) */ - -#define CUE_DO_REQUEST(dev, req, data) \ - usbd_do_request_flags(dev, req, data, USBD_NO_TSLEEP, NULL) +Static int cue_mem(struct cue_softc *, int, int, void *, int); +Static int cue_getmac(struct cue_softc *, void *); #define CUE_SETBIT(sc, reg, x) \ cue_csr_write_1(sc, reg, cue_csr_read_1(sc, reg) | (x)) @@ -243,14 +180,11 @@ DRIVER_MODULE(if_cue, uhub, cue_driver, cue_devclass, usbd_driver_load, 0); cue_csr_write_1(sc, reg, cue_csr_read_1(sc, reg) & ~(x)) Static int -cue_csr_read_1(sc, reg) - struct cue_softc *sc; - int reg; +cue_csr_read_1(struct cue_softc *sc, int reg) { usb_device_request_t req; usbd_status err; u_int8_t val = 0; - int s; if (sc->cue_dying) return (0); @@ -261,9 +195,7 @@ cue_csr_read_1(sc, reg) USETW(req.wIndex, reg); USETW(req.wLength, 1); - s = splusb(); - err = CUE_DO_REQUEST(sc->cue_udev, &req, &val); - splx(s); + err = usbd_do_request(sc->cue_udev, &req, &val); if (err) { DPRINTF(("%s: cue_csr_read_1: reg=0x%x err=%s\n", @@ -278,14 +210,11 @@ cue_csr_read_1(sc, reg) } Static int -cue_csr_read_2(sc, reg) - struct cue_softc *sc; - int reg; +cue_csr_read_2(struct cue_softc *sc, int reg) { usb_device_request_t req; usbd_status err; uWord val; - int s; if (sc->cue_dying) return (0); @@ -296,9 +225,7 @@ cue_csr_read_2(sc, reg) USETW(req.wIndex, reg); USETW(req.wLength, 2); - s = splusb(); - err = CUE_DO_REQUEST(sc->cue_udev, &req, &val); - splx(s); + err = usbd_do_request(sc->cue_udev, &req, &val); DPRINTFN(10,("%s: cue_csr_read_2 reg=0x%x val=0x%x\n", USBDEVNAME(sc->cue_dev), reg, UGETW(val))); @@ -313,13 +240,10 @@ cue_csr_read_2(sc, reg) } Static int -cue_csr_write_1(sc, reg, val) - struct cue_softc *sc; - int reg, val; +cue_csr_write_1(struct cue_softc *sc, int reg, int val) { usb_device_request_t req; usbd_status err; - int s; if (sc->cue_dying) return (0); @@ -333,9 +257,7 @@ cue_csr_write_1(sc, reg, val) USETW(req.wIndex, reg); USETW(req.wLength, 0); - s = splusb(); - err = CUE_DO_REQUEST(sc->cue_udev, &req, NULL); - splx(s); + err = usbd_do_request(sc->cue_udev, &req, NULL); if (err) { DPRINTF(("%s: cue_csr_write_1: reg=0x%x err=%s\n", @@ -349,11 +271,9 @@ cue_csr_write_1(sc, reg, val) return (0); } -#ifdef notdef +#if 0 Static int -cue_csr_write_2(sc, reg, val) - struct cue_softc *sc; - int reg, aval; +cue_csr_write_2(struct cue_softc *sc, int reg, int aval) { usb_device_request_t req; usbd_status err; @@ -373,9 +293,7 @@ cue_csr_write_2(sc, reg, val) USETW(req.wIndex, reg); USETW(req.wLength, 0); - s = splusb(); - err = CUE_DO_REQUEST(sc->cue_udev, &req, NULL); - splx(s); + err = usbd_do_request(sc->cue_udev, &req, NULL); if (err) { DPRINTF(("%s: cue_csr_write_2: reg=0x%x err=%s\n", @@ -388,16 +306,10 @@ cue_csr_write_2(sc, reg, val) #endif Static int -cue_mem(sc, cmd, addr, buf, len) - struct cue_softc *sc; - int cmd; - int addr; - void *buf; - int len; +cue_mem(struct cue_softc *sc, int cmd, int addr, void *buf, int len) { usb_device_request_t req; usbd_status err; - int s; DPRINTFN(10,("%s: cue_mem cmd=0x%x addr=0x%x len=%d\n", USBDEVNAME(sc->cue_dev), cmd, addr, len)); @@ -411,9 +323,7 @@ cue_mem(sc, cmd, addr, buf, len) USETW(req.wIndex, addr); USETW(req.wLength, len); - s = splusb(); - err = CUE_DO_REQUEST(sc->cue_udev, &req, buf); - splx(s); + err = usbd_do_request(sc->cue_udev, &req, buf); if (err) { DPRINTF(("%s: cue_csr_mem: addr=0x%x err=%s\n", @@ -425,13 +335,10 @@ cue_mem(sc, cmd, addr, buf, len) } Static int -cue_getmac(sc, buf) - struct cue_softc *sc; - void *buf; +cue_getmac(struct cue_softc *sc, void *buf) { usb_device_request_t req; usbd_status err; - int s; DPRINTFN(10,("%s: cue_getmac\n", USBDEVNAME(sc->cue_dev))); @@ -441,12 +348,11 @@ cue_getmac(sc, buf) USETW(req.wIndex, 0); USETW(req.wLength, ETHER_ADDR_LEN); - s = splusb(); - err = CUE_DO_REQUEST(sc->cue_udev, &req, buf); - splx(s); + err = usbd_do_request(sc->cue_udev, &req, buf); if (err) { - printf("%s: read MAC address failed\n", USBDEVNAME(sc->cue_dev)); + printf("%s: read MAC address failed\n", + USBDEVNAME(sc->cue_dev)); return (-1); } @@ -457,8 +363,7 @@ cue_getmac(sc, buf) #define CUE_BITS 9 Static u_int32_t -cue_crc(addr) - caddr_t addr; +cue_crc(caddr_t addr) { u_int32_t idx, bit, data, crc; @@ -474,16 +379,11 @@ cue_crc(addr) } Static void -cue_setmulti(sc) - struct cue_softc *sc; +cue_setmulti(struct cue_softc *sc) { struct ifnet *ifp; -#if defined(__FreeBSD__) - struct ifmultiaddr *ifma; -#elif defined(__NetBSD__) || defined(__OpenBSD__) struct ether_multi *enm; struct ether_multistep step; -#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ u_int32_t h, i; ifp = GET_IFP(sc); @@ -491,7 +391,9 @@ cue_setmulti(sc) DPRINTFN(2,("%s: cue_setmulti if_flags=0x%x\n", USBDEVNAME(sc->cue_dev), ifp->if_flags)); - if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) { + if (ifp->if_flags & IFF_PROMISC) { +allmulti: + ifp->if_flags |= IFF_ALLMULTI; for (i = 0; i < CUE_MCAST_TABLE_LEN; i++) sc->cue_mctab[i] = 0xFF; cue_mem(sc, CUE_CMD_WRITESRAM, CUE_MCAST_TABLE_ADDR, @@ -504,34 +406,22 @@ cue_setmulti(sc) sc->cue_mctab[i] = 0; /* now program new ones */ -#if defined(__FreeBSD__) - for (ifma = ifp->if_multiaddrs.lh_first; ifma != NULL; - ifma = ifma->ifma_link.le_next) { - if (ifma->ifma_addr->sa_family != AF_LINK) - continue; - h = cue_crc(LLADDR((struct sockaddr_dl *)ifma->ifma_addr)); - sc->cue_mctab[h >> 3] |= 1 << (h & 0x7); - } -#elif defined(__NetBSD__) || defined(__OpenBSD__) #if defined(__NetBSD__) ETHER_FIRST_MULTI(step, &sc->cue_ec, enm); #else ETHER_FIRST_MULTI(step, &sc->arpcom, enm); #endif while (enm != NULL) { -#if 0 if (memcmp(enm->enm_addrlo, - enm->enm_addrhi, ETHER_ADDR_LEN) != 0) { - ifp->if_flags |= IFF_ALLMULTI; - /* XXX what now? */ - return; - } -#endif + enm->enm_addrhi, ETHER_ADDR_LEN) != 0) + goto allmulti; + h = cue_crc(enm->enm_addrlo); sc->cue_mctab[h >> 3] |= 1 << (h & 0x7); ETHER_NEXT_MULTI(step, enm); } -#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ + + ifp->if_flags &= ~IFF_ALLMULTI; /* * Also include the broadcast address in the filter @@ -547,12 +437,10 @@ cue_setmulti(sc) } Static void -cue_reset(sc) - struct cue_softc *sc; +cue_reset(struct cue_softc *sc) { usb_device_request_t req; usbd_status err; - int s; DPRINTFN(2,("%s: cue_reset\n", USBDEVNAME(sc->cue_dev))); @@ -565,15 +453,13 @@ cue_reset(sc) USETW(req.wIndex, 0); USETW(req.wLength, 0); - s = splusb(); - err = CUE_DO_REQUEST(sc->cue_udev, &req, NULL); - splx(s); + err = usbd_do_request(sc->cue_udev, &req, NULL); if (err) printf("%s: reset failed\n", USBDEVNAME(sc->cue_dev)); /* Wait a little while for the chip to get its brains in order. */ - delay(1000); /* XXX */ + usbd_delay_ms(sc->cue_udev, 1); } /* @@ -612,17 +498,13 @@ USB_ATTACH(cue) usb_endpoint_descriptor_t *ed; int i; -#ifdef __FreeBSD__ - bzero(sc, sizeof(struct cue_softc)); -#endif - DPRINTFN(5,(" : cue_attach: sc=%p, dev=%p", sc, dev)); usbd_devinfo(dev, 0, devinfo); USB_ATTACH_SETUP; printf("%s: %s\n", USBDEVNAME(sc->cue_dev), devinfo); - err = usbd_set_config_no(dev, CUE_CONFIG_NO, 0); + err = usbd_set_config_no(dev, CUE_CONFIG_NO, 1); if (err) { printf("%s: setting config no failed\n", USBDEVNAME(sc->cue_dev)); @@ -633,6 +515,9 @@ USB_ATTACH(cue) sc->cue_product = uaa->product; sc->cue_vendor = uaa->vendor; + usb_init_task(&sc->cue_tick_task, cue_tick_task, sc); + usb_init_task(&sc->cue_stop_task, (void (*)(void *))cue_stop, sc); + err = usbd_device2interface_handle(dev, CUE_IFACE_IDX, &iface); if (err) { printf("%s: getting interface handle failed\n", @@ -672,42 +557,11 @@ USB_ATTACH(cue) */ cue_getmac(sc, &eaddr); - s = splimp(); + s = splnet(); /* * A CATC chip was detected. Inform the world. */ -#if defined(__FreeBSD__) - printf("%s: Ethernet address: %6D\n", USBDEVNAME(sc->cue_dev), eaddr, ":"); - - bcopy(eaddr, (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN); - - ifp = &sc->arpcom.ac_if; - ifp->if_softc = sc; - ifp->if_unit = USBDEVNAME(sc->cue_dev); - ifp->if_name = "cue"; - ifp->if_mtu = ETHERMTU; - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_ioctl = cue_ioctl; - ifp->if_output = ether_output; - ifp->if_start = cue_start; - ifp->if_watchdog = cue_watchdog; - ifp->if_init = cue_init; - ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; - - cue_qdat.ifp = ifp; - cue_qdat.if_rxstart = cue_rxstart; - - /* - * Call MI attach routines. - */ - if_attach(ifp); - ether_ifattach(ifp); - bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header)); - usb_register_netisr(); - -#elif defined(__NetBSD__) || defined(__OpenBSD__) - printf("%s: Ethernet address %s\n", USBDEVNAME(sc->cue_dev), ether_sprintf(eaddr)); @@ -731,14 +585,11 @@ USB_ATTACH(cue) /* Attach the interface. */ if_attach(ifp); Ether_ifattach(ifp, eaddr); - #if NRND > 0 rnd_attach_source(&sc->rnd_source, USBDEVNAME(sc->cue_dev), RND_TYPE_NET, 0); #endif -#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ - usb_callout_init(sc->cue_stat_ch); sc->cue_attached = 1; @@ -758,16 +609,21 @@ USB_DETACH(cue) DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev), __FUNCTION__)); - s = splusb(); - usb_uncallout(sc->cue_stat_ch, cue_tick, sc); + /* + * Remove any pending task. It cannot be executing because it run + * in the same thread as detach. + */ + usb_rem_task(sc->cue_udev, &sc->cue_tick_task); + usb_rem_task(sc->cue_udev, &sc->cue_stop_task); if (!sc->cue_attached) { /* Detached before attached finished, so just bail out. */ - splx(s); return (0); } + s = splusb(); + if (ifp->if_flags & IFF_RUNNING) cue_stop(sc); @@ -778,8 +634,8 @@ USB_DETACH(cue) #if NBPFILTER > 0 bpfdetach(ifp); #endif - ether_ifdetach(ifp); #endif /* __NetBSD__ */ + ether_ifdetach(ifp); if_detach(ifp); @@ -800,11 +656,8 @@ USB_DETACH(cue) return (0); } -#if defined(__NetBSD__) || defined(__OpenBSD__) int -cue_activate(self, act) - device_ptr_t self; - enum devact act; +cue_activate(device_ptr_t self, enum devact act) { struct cue_softc *sc = (struct cue_softc *)self; @@ -823,16 +676,12 @@ cue_activate(self, act) } return (0); } -#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ /* * Initialize an RX descriptor and attach an MBUF cluster. */ Static int -cue_newbuf(sc, c, m) - struct cue_softc *sc; - struct cue_chain *c; - struct mbuf *m; +cue_newbuf(struct cue_softc *sc, struct cue_chain *c, struct mbuf *m) { struct mbuf *m_new = NULL; @@ -865,8 +714,7 @@ cue_newbuf(sc, c, m) } Static int -cue_rx_list_init(sc) - struct cue_softc *sc; +cue_rx_list_init(struct cue_softc *sc) { struct cue_cdata *cd; struct cue_chain *c; @@ -895,8 +743,7 @@ cue_rx_list_init(sc) } Static int -cue_tx_list_init(sc) - struct cue_softc *sc; +cue_tx_list_init(struct cue_softc *sc) { struct cue_cdata *cd; struct cue_chain *c; @@ -923,39 +770,12 @@ cue_tx_list_init(sc) return (0); } -#ifdef __FreeBSD__ -Static void -cue_rxstart(ifp) - struct ifnet *ifp; -{ - struct cue_softc *sc; - struct cue_chain *c; - - sc = ifp->if_softc; - c = &sc->cue_cdata.cue_rx_chain[sc->cue_cdata.cue_rx_prod]; - - if (cue_newbuf(sc, c, NULL) == ENOBUFS) { - ifp->if_ierrors++; - return; - } - - /* Setup new transfer. */ - usbd_setup_xfer(c->cue_xfer, sc->cue_ep[CUE_ENDPT_RX], - c, c->cue_buf, CUE_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY, - USBD_NO_TIMEOUT, cue_rxeof); - usbd_transfer(c->cue_xfer); -} -#endif - /* * A frame has been uploaded: pass the resulting mbuf chain up to * the higher level protocols. */ Static void -cue_rxeof(xfer, priv, status) - usbd_xfer_handle xfer; - usbd_private_handle priv; - usbd_status status; +cue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) { struct cue_chain *c = priv; struct cue_softc *sc = c->cue_sc; @@ -963,9 +783,7 @@ cue_rxeof(xfer, priv, status) struct mbuf *m; int total_len = 0; u_int16_t len; -#if defined(__NetBSD__) || defined(__OpenBSD__) int s; -#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ DPRINTFN(10,("%s: %s: enter status=%d\n", USBDEVNAME(sc->cue_dev), __FUNCTION__, status)); @@ -1010,16 +828,9 @@ cue_rxeof(xfer, priv, status) m_adj(m, sizeof(u_int16_t)); m->m_pkthdr.len = m->m_len = total_len; -#if defined(__FreeBSD__) - m->m_pkthdr.rcvif = (struct ifnet *)&cue_qdat; - /* Put the packet on the special USB input queue. */ - usb_ether_input(m); - - return; -#elif defined(__NetBSD__) || defined(__OpenBSD__) m->m_pkthdr.rcvif = ifp; - s = splimp(); + s = splnet(); /* XXX ugly */ if (cue_newbuf(sc, c, NULL) == ENOBUFS) { @@ -1034,29 +845,15 @@ cue_rxeof(xfer, priv, status) * a broadcast packet, multicast packet, matches our ethernet * address or the interface is in promiscuous mode. */ - if (ifp->if_bpf) { -#if defined(__NetBSD__) - struct ether_header *eh = mtod(m, struct ether_header *); - BPF_MTAP(ifp, m); - if ((ifp->if_flags & IFF_PROMISC) && - memcmp(eh->ether_dhost, LLADDR(ifp->if_sadl), - ETHER_ADDR_LEN) && - !(eh->ether_dhost[0] & 1)) { - m_freem(m); - goto done1; - } -#else + if (ifp->if_bpf) BPF_MTAP(ifp, m); #endif - } -#endif DPRINTFN(10,("%s: %s: deliver %d\n", USBDEVNAME(sc->cue_dev), __FUNCTION__, m->m_len)); IF_INPUT(ifp, m); done1: splx(s); -#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ done: /* Setup new transfer. */ @@ -1074,10 +871,7 @@ done: * the list buffers. */ Static void -cue_txeof(xfer, priv, status) - usbd_xfer_handle xfer; - usbd_private_handle priv; - usbd_status status; +cue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) { struct cue_chain *c = priv; struct cue_softc *sc = c->cue_sc; @@ -1087,7 +881,7 @@ cue_txeof(xfer, priv, status) if (sc->cue_dying) return; - s = splimp(); + s = splnet(); DPRINTFN(10,("%s: %s: enter status=%d\n", USBDEVNAME(sc->cue_dev), __FUNCTION__, status)); @@ -1111,28 +905,19 @@ cue_txeof(xfer, priv, status) ifp->if_opackets++; -#if defined(__FreeBSD__) - c->cue_mbuf->m_pkthdr.rcvif = ifp; - usb_tx_done(c->cue_mbuf); - c->cue_mbuf = NULL; -#elif defined(__NetBSD__) || defined(__OpenBSD__) m_freem(c->cue_mbuf); c->cue_mbuf = NULL; if (ifp->if_snd.ifq_head != NULL) cue_start(ifp); -#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ splx(s); } Static void -cue_tick(xsc) - void *xsc; +cue_tick(void *xsc) { struct cue_softc *sc = xsc; - struct ifnet *ifp; - int s; if (sc == NULL) return; @@ -1142,7 +927,20 @@ cue_tick(xsc) DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev), __FUNCTION__)); - s = splimp(); + /* Perform statistics update in process context. */ + usb_add_task(sc->cue_udev, &sc->cue_tick_task); +} + +Static void +cue_tick_task(void *xsc) +{ + struct cue_softc *sc = xsc; + struct ifnet *ifp; + + if (sc->cue_dying) + return; + + DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev), __FUNCTION__)); ifp = GET_IFP(sc); @@ -1152,17 +950,10 @@ cue_tick(xsc) if (cue_csr_read_2(sc, CUE_RX_FRAMEERR)) ifp->if_ierrors++; - - usb_callout(sc->cue_stat_ch, hz, cue_tick, sc); - - splx(s); } Static int -cue_send(sc, m, idx) - struct cue_softc *sc; - struct mbuf *m; - int idx; +cue_send(struct cue_softc *sc, struct mbuf *m, int idx) { int total_len; struct cue_chain *c; @@ -1195,7 +986,8 @@ cue_send(sc, m, idx) if (err != USBD_IN_PROGRESS) { printf("%s: cue_send error=%s\n", USBDEVNAME(sc->cue_dev), usbd_errstr(err)); - cue_stop(sc); + /* Stop the interface from process context. */ + usb_add_task(sc->cue_udev, &sc->cue_stop_task); return (EIO); } @@ -1205,8 +997,7 @@ cue_send(sc, m, idx) } Static void -cue_start(ifp) - struct ifnet *ifp; +cue_start(struct ifnet *ifp) { struct cue_softc *sc = ifp->if_softc; struct mbuf *m_head = NULL; @@ -1247,8 +1038,7 @@ cue_start(ifp) } Static void -cue_init(xsc) - void *xsc; +cue_init(void *xsc) { struct cue_softc *sc = xsc; struct ifnet *ifp = GET_IFP(sc); @@ -1263,7 +1053,7 @@ cue_init(xsc) if (ifp->if_flags & IFF_RUNNING) return; - s = splimp(); + s = splnet(); /* * Cancel pending I/O and free all RX/TX buffers. @@ -1276,7 +1066,7 @@ cue_init(xsc) cue_csr_write_1(sc, CUE_ADVANCED_OPMODES, CUE_AOP_EMBED_RXLEN | 0x03); /* 1 wait state */ -#if defined(__FreeBSD__) || defined(__OpenBSD__) +#if defined(__OpenBSD__) eaddr = sc->arpcom.ac_enaddr; #elif defined(__NetBSD__) eaddr = LLADDR(ifp->if_sadl); @@ -1338,8 +1128,7 @@ cue_init(xsc) } Static int -cue_open_pipes(sc) - struct cue_softc *sc; +cue_open_pipes(struct cue_softc *sc) { struct cue_chain *c; usbd_status err; @@ -1375,31 +1164,19 @@ cue_open_pipes(sc) } Static int -cue_ioctl(ifp, command, data) - struct ifnet *ifp; - u_long command; - caddr_t data; +cue_ioctl(struct ifnet *ifp, u_long command, caddr_t data) { struct cue_softc *sc = ifp->if_softc; -#if defined(__NetBSD__) || defined(__OpenBSD__) struct ifaddr *ifa = (struct ifaddr *)data; struct ifreq *ifr = (struct ifreq *)data; -#endif int s, error = 0; if (sc->cue_dying) return (EIO); - s = splimp(); + s = splnet(); switch(command) { -#if defined(__FreeBSD__) - case SIOCSIFADDR: - case SIOCGIFADDR: - case SIOCSIFMTU: - error = ether_ioctl(ifp, command, data); - break; -#elif defined(__NetBSD__) || defined(__OpenBSD__) case SIOCSIFADDR: ifp->if_flags |= IFF_UP; cue_init(sc); @@ -1439,8 +1216,6 @@ cue_ioctl(ifp, command, data) ifp->if_mtu = ifr->ifr_mtu; break; -#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ - case SIOCSIFFLAGS: if (ifp->if_flags & IFF_UP) { if (ifp->if_flags & IFF_RUNNING && @@ -1478,10 +1253,12 @@ cue_ioctl(ifp, command, data) } Static void -cue_watchdog(ifp) - struct ifnet *ifp; +cue_watchdog(struct ifnet *ifp) { struct cue_softc *sc = ifp->if_softc; + struct cue_chain *c; + usbd_status stat; + int s; DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev),__FUNCTION__)); @@ -1491,19 +1268,14 @@ cue_watchdog(ifp) ifp->if_oerrors++; printf("%s: watchdog timeout\n", USBDEVNAME(sc->cue_dev)); - /* - * The polling business is a kludge to avoid allowing the - * USB code to call tsleep() in usbd_delay_ms(), which will - * kill us since the watchdog routine is invoked from - * interrupt context. - */ - usbd_set_polling(sc->cue_udev, 1); - cue_stop(sc); - cue_init(sc); - usbd_set_polling(sc->cue_udev, 0); + s = splusb(); + c = &sc->cue_cdata.cue_tx_chain[0]; + usbd_get_xfer_status(c->cue_xfer, NULL, NULL, NULL, &stat); + cue_txeof(c->cue_xfer, c, stat); if (ifp->if_snd.ifq_head != NULL) cue_start(ifp); + splx(s); } /* @@ -1511,8 +1283,7 @@ cue_watchdog(ifp) * RX and TX lists. */ Static void -cue_stop(sc) - struct cue_softc *sc; +cue_stop(struct cue_softc *sc) { usbd_status err; struct ifnet *ifp; @@ -1596,21 +1367,3 @@ cue_stop(sc) ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); } - -#ifdef __FreeBSD__ -/* - * Stop all chip I/O so that the kernel's probe routines don't - * get confused by errant DMAs when rebooting. - */ -Static void -cue_shutdown(dev) - device_t dev; -{ - struct cue_softc *sc; - - sc = device_get_softc(dev); - - cue_reset(sc); - cue_stop(sc); -} -#endif diff --git a/sys/dev/usb/if_cuereg.h b/sys/dev/usb/if_cuereg.h index f6977df6484..5b6a7bc77e2 100644 --- a/sys/dev/usb/if_cuereg.h +++ b/sys/dev/usb/if_cuereg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_cuereg.h,v 1.3 2000/07/04 11:44:21 fgsch Exp $ */ +/* $OpenBSD: if_cuereg.h,v 1.4 2001/05/03 02:20:32 aaron Exp $ */ /* $NetBSD: if_cuereg.h,v 1.11 2000/04/08 20:54:38 augustss Exp $ */ /* * Copyright (c) 1997, 1998, 1999, 2000 @@ -196,4 +196,7 @@ struct cue_softc { char cue_attached; u_int cue_rx_errs; struct timeval cue_rx_notice; + + struct usb_task cue_tick_task; + struct usb_task cue_stop_task; }; diff --git a/sys/dev/usb/if_kue.c b/sys/dev/usb/if_kue.c index 4d6bfea9eb7..b2f15b13942 100644 --- a/sys/dev/usb/if_kue.c +++ b/sys/dev/usb/if_kue.c @@ -1,5 +1,5 @@ -/* $OpenBSD: if_kue.c,v 1.9 2001/02/20 19:39:46 mickey Exp $ */ -/* $NetBSD: if_kue.c,v 1.28 2000/04/02 21:25:41 augustss Exp $ */ +/* $OpenBSD: if_kue.c,v 1.10 2001/05/03 02:20:32 aaron Exp $ */ +/* $NetBSD: if_kue.c,v 1.40 2001/04/08 02:10:57 augustss Exp $ */ /* * Copyright (c) 1997, 1998, 1999, 2000 * Bill Paul <wpaul@ee.columbia.edu>. All rights reserved. @@ -70,12 +70,6 @@ * Ported to NetBSD and somewhat rewritten by Lennart Augustsson. */ -/* - * TODO: - * only use kue_do_request for downloading firmware. - * more DPRINTF - * proper cleanup on errors - */ #if defined(__NetBSD__) #include "opt_inet.h" #include "opt_ns.h" @@ -92,35 +86,23 @@ #include <sys/malloc.h> #include <sys/kernel.h> #include <sys/socket.h> - -#if defined(__FreeBSD__) - -#include <net/ethernet.h> -#include <machine/clock.h> /* for DELAY */ -#include <sys/bus.h> - -#elif defined(__NetBSD__) || defined(__OpenBSD__) +#include <sys/device.h> +#include <sys/proc.h> #include <sys/device.h> #if NRND > 0 #include <sys/rnd.h> #endif -#endif - #include <net/if.h> -#if defined(__NetBSD__) || defined(__FreeBSD__) +#if defined(__NetBSD__) #include <net/if_arp.h> #endif #include <net/if_dl.h> -#if defined(__NetBSD__) || defined(__OpenBSD__) #define BPF_MTAP(ifp, m) bpf_mtap((ifp)->if_bpf, (m)) -#else -#define BPF_MTAP(ifp, m) bpf_mtap((ifp), (m)) -#endif -#if defined(__FreeBSD__) || NBPFILTER > 0 +#if NBPFILTER > 0 #include <net/bpf.h> #endif @@ -142,22 +124,16 @@ #endif #endif /* defined (__OpenBSD__) */ -#if defined(__NetBSD__) || defined(__OpenBSD__) #ifdef NS #include <netns/ns.h> #include <netns/ns_if.h> #endif -#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ #include <dev/usb/usb.h> #include <dev/usb/usbdi.h> #include <dev/usb/usbdi_util.h> #include <dev/usb/usbdevs.h> -#ifdef __FreeBSD__ -#include <dev/usb/usb_ethersubr.h> -#endif - #include <dev/usb/if_kuereg.h> #include <dev/usb/kue_fw.h> @@ -180,6 +156,7 @@ Static const struct kue_type kue_devs[] = { { USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_EA101 }, { USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_ENET }, { USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_ENET2 }, + { USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_ENET3 }, { USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_E45 }, { USB_VENDOR_3COM, USB_PRODUCT_3COM_3C19250 }, { USB_VENDOR_3COM, USB_PRODUCT_3COM_3C460 }, @@ -195,76 +172,31 @@ Static const struct kue_type kue_devs[] = { USB_DECLARE_DRIVER(kue); -Static int kue_tx_list_init __P((struct kue_softc *)); -Static int kue_rx_list_init __P((struct kue_softc *)); -Static int kue_newbuf __P((struct kue_softc *, struct kue_chain *, - struct mbuf *)); -Static int kue_send __P((struct kue_softc *, struct mbuf *, int)); -Static int kue_open_pipes __P((struct kue_softc *)); -Static void kue_rxeof __P((usbd_xfer_handle, - usbd_private_handle, usbd_status)); -Static void kue_txeof __P((usbd_xfer_handle, - usbd_private_handle, usbd_status)); -Static void kue_start __P((struct ifnet *)); -Static int kue_ioctl __P((struct ifnet *, u_long, caddr_t)); -Static void kue_init __P((void *)); -Static void kue_stop __P((struct kue_softc *)); -Static void kue_watchdog __P((struct ifnet *)); - -Static void kue_setmulti __P((struct kue_softc *)); -Static void kue_reset __P((struct kue_softc *)); - -Static usbd_status kue_ctl __P((struct kue_softc *, int, u_int8_t, - u_int16_t, void *, u_int32_t)); -Static usbd_status kue_setword __P((struct kue_softc *, u_int8_t, u_int16_t)); -Static int kue_is_warm __P((struct kue_softc *)); -Static int kue_load_fw __P((struct kue_softc *)); - -#if defined(__FreeBSD__) -#ifndef lint -static const char rcsid[] = - "$FreeBSD: src/sys/dev/usb/if_kue.c,v 1.14 2000/01/14 01:36:15 wpaul Exp $"; -#endif - -Static void kue_rxstart __P((struct ifnet *)); -Static void kue_shutdown __P((device_t)); - -Static struct usb_qdat kue_qdat; - -Static device_method_t kue_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, kue_match), - DEVMETHOD(device_attach, kue_attach), - DEVMETHOD(device_detach, kue_detach), - DEVMETHOD(device_shutdown, kue_shutdown), - - { 0, 0 } -}; - -Static driver_t kue_driver = { - "kue", - kue_methods, - sizeof(struct kue_softc) -}; - -Static devclass_t kue_devclass; - -DRIVER_MODULE(if_kue, uhub, kue_driver, kue_devclass, usbd_driver_load, 0); - -#endif /* __FreeBSD__ */ - -#define KUE_DO_REQUEST(dev, req, data) \ - usbd_do_request_flags(dev, req, data, USBD_NO_TSLEEP, NULL) +Static int kue_tx_list_init(struct kue_softc *); +Static int kue_rx_list_init(struct kue_softc *); +Static int kue_newbuf(struct kue_softc *, struct kue_chain *,struct mbuf *); +Static int kue_send(struct kue_softc *, struct mbuf *, int); +Static int kue_open_pipes(struct kue_softc *); +Static void kue_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status); +Static void kue_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status); +Static void kue_start(struct ifnet *); +Static int kue_ioctl(struct ifnet *, u_long, caddr_t); +Static void kue_init(void *); +Static void kue_stop(struct kue_softc *); +Static void kue_watchdog(struct ifnet *); + +Static void kue_setmulti(struct kue_softc *); +Static void kue_reset(struct kue_softc *); + +Static usbd_status kue_ctl(struct kue_softc *, int, u_int8_t, + u_int16_t, void *, u_int32_t); +Static usbd_status kue_setword(struct kue_softc *, u_int8_t, u_int16_t); +Static int kue_load_fw(struct kue_softc *); Static usbd_status -kue_setword(sc, breq, word) - struct kue_softc *sc; - u_int8_t breq; - u_int16_t word; +kue_setword(struct kue_softc *sc, u_int8_t breq, u_int16_t word) { usb_device_request_t req; - usbd_status err; - int s; DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->kue_dev),__FUNCTION__)); @@ -274,25 +206,14 @@ kue_setword(sc, breq, word) USETW(req.wIndex, 0); USETW(req.wLength, 0); - s = splusb(); - err = KUE_DO_REQUEST(sc->kue_udev, &req, NULL); - splx(s); - - return (err); + return (usbd_do_request(sc->kue_udev, &req, NULL)); } Static usbd_status -kue_ctl(sc, rw, breq, val, data, len) - struct kue_softc *sc; - int rw; - u_int8_t breq; - u_int16_t val; - void *data; - u_int32_t len; +kue_ctl(struct kue_softc *sc, int rw, u_int8_t breq, u_int16_t val, + void *data, u_int32_t len) { usb_device_request_t req; - usbd_status err; - int s; DPRINTFN(10,("%s: %s: enter, len=%d\n", USBDEVNAME(sc->kue_dev), __FUNCTION__, len)); @@ -307,36 +228,13 @@ kue_ctl(sc, rw, breq, val, data, len) USETW(req.wIndex, 0); USETW(req.wLength, len); - s = splusb(); - err = KUE_DO_REQUEST(sc->kue_udev, &req, (void *)data); - splx(s); - - return (err); + return (usbd_do_request(sc->kue_udev, &req, data)); } Static int -kue_is_warm(sc) - struct kue_softc *sc; -{ - usbd_status err; - usb_device_request_t req; - - /* Just issue some random command. */ - req.bmRequestType = UT_READ_VENDOR_DEVICE; - req.bRequest = KUE_CMD_GET_ETHER_DESCRIPTOR; - USETW(req.wValue, 0); - USETW(req.wIndex, 0); - USETW(req.wLength, sizeof(sc->kue_desc)); - - err = usbd_do_request(sc->kue_udev, &req, &sc->kue_desc); - - return (!err); -} - -Static int -kue_load_fw(sc) - struct kue_softc *sc; +kue_load_fw(struct kue_softc *sc) { + usb_device_descriptor_t dd; usbd_status err; DPRINTFN(1,("%s: %s: enter\n", USBDEVNAME(sc->kue_dev), __FUNCTION__)); @@ -350,10 +248,14 @@ kue_load_fw(sc) * so we have to avoid this condition if we don't want * to look stupid. * - * We can test this quickly by issuing a request that - * is only valid after firmware download. + * We can test this quickly by checking the bcdRevision + * code. The NIC will return a different revision code if + * it's probed while the firmware is still loaded and + * running. */ - if (kue_is_warm(sc)) { + if (usbd_get_device_desc(sc->kue_udev, &dd)) + return (EIO); + if (UGETW(dd.bcdDevice) == KUE_WARM_REV) { printf("%s: warm boot, no firmware download\n", USBDEVNAME(sc->kue_dev)); return (0); @@ -416,21 +318,18 @@ kue_load_fw(sc) } Static void -kue_setmulti(sc) - struct kue_softc *sc; +kue_setmulti(struct kue_softc *sc) { struct ifnet *ifp = GET_IFP(sc); -#if defined(__FreeBSD__) - struct ifmultiaddr *ifma; -#elif defined(__NetBSD__) || defined(__OpenBSD__) struct ether_multi *enm; struct ether_multistep step; -#endif int i; DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->kue_dev), __FUNCTION__)); - if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) { + if (ifp->if_flags & IFF_PROMISC) { +allmulti: + ifp->if_flags |= IFF_ALLMULTI; sc->kue_rxfilt |= KUE_RXFILT_ALLMULTI; sc->kue_rxfilt &= ~KUE_RXFILT_MULTICAST; kue_setword(sc, KUE_CMD_SET_PKT_FILTER, sc->kue_rxfilt); @@ -440,51 +339,27 @@ kue_setmulti(sc) sc->kue_rxfilt &= ~KUE_RXFILT_ALLMULTI; i = 0; -#if defined(__FreeBSD__) - for (ifma = ifp->if_multiaddrs.lh_first; ifma != NULL; - ifma = ifma->ifma_link.le_next) { - if (ifma->ifma_addr->sa_family != AF_LINK) - continue; - /* - * If there are too many addresses for the - * internal filter, switch over to allmulti mode. - */ - if (i == KUE_MCFILTCNT(sc)) - break; - bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr), - KUE_MCFILT(sc, i), ETHER_ADDR_LEN); - i++; - } -#elif defined(__NetBSD__) || defined(__OpenBSD__) #if defined (__NetBSD__) ETHER_FIRST_MULTI(step, &sc->kue_ec, enm); #else ETHER_FIRST_MULTI(step, &sc->arpcom, enm); #endif while (enm != NULL) { - if (i == KUE_MCFILTCNT(sc)) - break; -#if 0 - if (memcmp(enm->enm_addrlo, - enm->enm_addrhi, ETHER_ADDR_LEN) != 0) { - ifp->if_flags |= IFF_ALLMULTI; - /* XXX what now? */ - return; - } -#endif + if (i == KUE_MCFILTCNT(sc) || + memcmp(enm->enm_addrlo, enm->enm_addrhi, + ETHER_ADDR_LEN) != 0) + goto allmulti; + memcpy(KUE_MCFILT(sc, i), enm->enm_addrlo, ETHER_ADDR_LEN); ETHER_NEXT_MULTI(step, enm); i++; } -#endif - if (i == KUE_MCFILTCNT(sc)) - sc->kue_rxfilt |= KUE_RXFILT_ALLMULTI; - else { - sc->kue_rxfilt |= KUE_RXFILT_MULTICAST; - kue_ctl(sc, KUE_CTL_WRITE, KUE_CMD_SET_MCAST_FILTERS, - i, sc->kue_mcfilters, i * ETHER_ADDR_LEN); - } + ifp->if_flags &= ~IFF_ALLMULTI; + + sc->kue_rxfilt |= KUE_RXFILT_MULTICAST; + kue_ctl(sc, KUE_CTL_WRITE, KUE_CMD_SET_MCAST_FILTERS, + i, sc->kue_mcfilters, i * ETHER_ADDR_LEN); kue_setword(sc, KUE_CMD_SET_PKT_FILTER, sc->kue_rxfilt); } @@ -495,14 +370,13 @@ kue_setmulti(sc) * bring it into proper operation. */ Static void -kue_reset(sc) - struct kue_softc *sc; +kue_reset(struct kue_softc *sc) { usbd_status err; DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->kue_dev), __FUNCTION__)); - err = usbd_set_config_no(sc->kue_udev, KUE_CONFIG_NO, 0); + err = usbd_set_config_no(sc->kue_udev, KUE_CONFIG_NO, 1); if (err) printf("%s: reset failed\n", USBDEVNAME(sc->kue_dev)); @@ -516,7 +390,7 @@ kue_reset(sc) USB_MATCH(kue) { USB_MATCH_START(kue, uaa); - const struct kue_type *t; + const struct kue_type *t; DPRINTFN(25,("kue_match: enter\n")); @@ -547,17 +421,13 @@ USB_ATTACH(kue) usb_endpoint_descriptor_t *ed; int i; -#ifdef __FreeBSD__ - bzero(sc, sizeof(struct kue_softc)); -#endif - DPRINTFN(5,(" : kue_attach: sc=%p, dev=%p", sc, dev)); usbd_devinfo(dev, 0, devinfo); USB_ATTACH_SETUP; printf("%s: %s\n", USBDEVNAME(sc->kue_dev), devinfo); - err = usbd_set_config_no(dev, KUE_CONFIG_NO, 0); + err = usbd_set_config_no(dev, KUE_CONFIG_NO, 1); if (err) { printf("%s: setting config no failed\n", USBDEVNAME(sc->kue_dev)); @@ -627,44 +497,11 @@ USB_ATTACH(kue) USB_ATTACH_ERROR_RETURN; } - s = splimp(); + s = splnet(); /* * A KLSI chip was detected. Inform the world. */ -#if defined(__FreeBSD__) - printf("%s: Ethernet address: %6D\n", USBDEVNAME(sc->kue_dev), - sc->kue_desc.kue_macaddr, ":"); - - bcopy(sc->kue_desc.kue_macaddr, - (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN); - - ifp = GET_IFP(sc); - ifp->if_softc = sc; - ifp->if_unit = sc->kue_unit; - ifp->if_name = "kue"; - ifp->if_mtu = ETHERMTU; - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_ioctl = kue_ioctl; - ifp->if_output = ether_output; - ifp->if_start = kue_start; - ifp->if_watchdog = kue_watchdog; - ifp->if_init = kue_init; - ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; - - kue_qdat.ifp = ifp; - kue_qdat.if_rxstart = kue_rxstart; - - /* - * Call MI attach routines. - */ - if_attach(ifp); - ether_ifattach(ifp); - bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header)); - usb_register_netisr(); - -#elif defined(__NetBSD__) || defined(__OpenBSD__) - printf("%s: Ethernet address %s\n", USBDEVNAME(sc->kue_dev), ether_sprintf(sc->kue_desc.kue_macaddr)); @@ -689,13 +526,11 @@ USB_ATTACH(kue) /* Attach the interface. */ if_attach(ifp); Ether_ifattach(ifp, sc->kue_desc.kue_macaddr); - #if NRND > 0 rnd_attach_source(&sc->rnd_source, USBDEVNAME(sc->kue_dev), RND_TYPE_NET, 0); #endif -#endif /* __NetBSD__ */ sc->kue_attached = 1; splx(s); @@ -734,8 +569,8 @@ USB_DETACH(kue) #if NBPFILTER > 0 bpfdetach(ifp); #endif - ether_ifdetach(ifp); #endif /* __NetBSD__ */ + ether_ifdetach(ifp); if_detach(ifp); @@ -753,11 +588,8 @@ USB_DETACH(kue) return (0); } -#if defined(__NetBSD__) || defined(__OpenBSD__) int -kue_activate(self, act) - device_ptr_t self; - enum devact act; +kue_activate(device_ptr_t self, enum devact act) { struct kue_softc *sc = (struct kue_softc *)self; @@ -778,16 +610,12 @@ kue_activate(self, act) } return (0); } -#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ /* * Initialize an RX descriptor and attach an MBUF cluster. */ Static int -kue_newbuf(sc, c, m) - struct kue_softc *sc; - struct kue_chain *c; - struct mbuf *m; +kue_newbuf(struct kue_softc *sc, struct kue_chain *c, struct mbuf *m) { struct mbuf *m_new = NULL; @@ -821,8 +649,7 @@ kue_newbuf(sc, c, m) } Static int -kue_rx_list_init(sc) - struct kue_softc *sc; +kue_rx_list_init(struct kue_softc *sc) { struct kue_cdata *cd; struct kue_chain *c; @@ -851,8 +678,7 @@ kue_rx_list_init(sc) } Static int -kue_tx_list_init(sc) - struct kue_softc *sc; +kue_tx_list_init(struct kue_softc *sc) { struct kue_cdata *cd; struct kue_chain *c; @@ -879,48 +705,19 @@ kue_tx_list_init(sc) return (0); } -#ifdef __FreeBSD__ -Static void -kue_rxstart(ifp) - struct ifnet *ifp; -{ - struct kue_softc *sc; - struct kue_chain *c; - - sc = ifp->if_softc; - c = &sc->kue_cdata.kue_rx_chain[sc->kue_cdata.kue_rx_prod]; - - if (kue_newbuf(sc, c, NULL) == ENOBUFS) { - ifp->if_ierrors++; - return; - } - - /* Setup new transfer. */ - usbd_setup_xfer(c->kue_xfer, sc->kue_ep[KUE_ENDPT_RX], - c, c->kue_buf, KUE_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY, - USBD_NO_TIMEOUT, kue_rxeof); - usbd_transfer(c->kue_xfer); -} -#endif - /* * A frame has been uploaded: pass the resulting mbuf chain up to * the higher level protocols. */ Static void -kue_rxeof(xfer, priv, status) - usbd_xfer_handle xfer; - usbd_private_handle priv; - usbd_status status; +kue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) { struct kue_chain *c = priv; struct kue_softc *sc = c->kue_sc; struct ifnet *ifp = GET_IFP(sc); struct mbuf *m; int total_len = 0; -#if defined(__NetBSD__) || defined(__OpenBSD__) int s; -#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ DPRINTFN(10,("%s: %s: enter status=%d\n", USBDEVNAME(sc->kue_dev), __FUNCTION__, status)); @@ -971,17 +768,9 @@ kue_rxeof(xfer, priv, status) ifp->if_ipackets++; m->m_pkthdr.len = m->m_len = total_len; -#if defined(__FreeBSD__) - m->m_pkthdr.rcvif = (struct ifnet *)&kue_qdat; - /* Put the packet on the special USB input queue. */ - usb_ether_input(m); - - return; - -#elif defined(__NetBSD__) || defined(__OpenBSD__) m->m_pkthdr.rcvif = ifp; - s = splimp(); + s = splnet(); /* XXX ugly */ if (kue_newbuf(sc, c, NULL) == ENOBUFS) { @@ -996,29 +785,15 @@ kue_rxeof(xfer, priv, status) * a broadcast packet, multicast packet, matches our ethernet * address or the interface is in promiscuous mode. */ - if (ifp->if_bpf) { -#if defined(__NetBSD__) - struct ether_header *eh = mtod(m, struct ether_header *); - BPF_MTAP(ifp, m); - if ((ifp->if_flags & IFF_PROMISC) && - memcmp(eh->ether_dhost, LLADDR(ifp->if_sadl), - ETHER_ADDR_LEN) && - !(eh->ether_dhost[0] & 1)) { - m_freem(m); - goto done1; - } -#else + if (ifp->if_bpf) BPF_MTAP(ifp, m); #endif - } -#endif DPRINTFN(10,("%s: %s: deliver %d\n", USBDEVNAME(sc->kue_dev), __FUNCTION__, m->m_len)); IF_INPUT(ifp, m); done1: splx(s); -#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ done: @@ -1038,10 +813,7 @@ kue_rxeof(xfer, priv, status) */ Static void -kue_txeof(xfer, priv, status) - usbd_xfer_handle xfer; - usbd_private_handle priv; - usbd_status status; +kue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) { struct kue_chain *c = priv; struct kue_softc *sc = c->kue_sc; @@ -1051,7 +823,7 @@ kue_txeof(xfer, priv, status) if (sc->kue_dying) return; - s = splimp(); + s = splnet(); DPRINTFN(10,("%s: %s: enter status=%d\n", USBDEVNAME(sc->kue_dev), __FUNCTION__, status)); @@ -1075,26 +847,17 @@ kue_txeof(xfer, priv, status) ifp->if_opackets++; -#if defined(__FreeBSD__) - c->kue_mbuf->m_pkthdr.rcvif = ifp; - usb_tx_done(c->kue_mbuf); - c->kue_mbuf = NULL; -#elif defined(__NetBSD__) || defined(__OpenBSD__) m_freem(c->kue_mbuf); c->kue_mbuf = NULL; if (ifp->if_snd.ifq_head != NULL) kue_start(ifp); -#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ splx(s); } Static int -kue_send(sc, m, idx) - struct kue_softc *sc; - struct mbuf *m; - int idx; +kue_send(struct kue_softc *sc, struct mbuf *m, int idx) { int total_len; struct kue_chain *c; @@ -1120,7 +883,8 @@ kue_send(sc, m, idx) c->kue_buf[1] = (u_int8_t)(m->m_pkthdr.len >> 8); usbd_setup_xfer(c->kue_xfer, sc->kue_ep[KUE_ENDPT_TX], - c, c->kue_buf, total_len, USBD_NO_COPY, USBD_DEFAULT_TIMEOUT, kue_txeof); + c, c->kue_buf, total_len, USBD_NO_COPY, USBD_DEFAULT_TIMEOUT, + kue_txeof); /* Transmit */ err = usbd_transfer(c->kue_xfer); @@ -1137,8 +901,7 @@ kue_send(sc, m, idx) } Static void -kue_start(ifp) - struct ifnet *ifp; +kue_start(struct ifnet *ifp) { struct kue_softc *sc = ifp->if_softc; struct mbuf *m_head = NULL; @@ -1175,12 +938,11 @@ kue_start(ifp) /* * Set a timeout in case the chip goes out to lunch. */ - ifp->if_timer = 5; + ifp->if_timer = 6; } Static void -kue_init(xsc) - void *xsc; +kue_init(void *xsc) { struct kue_softc *sc = xsc; struct ifnet *ifp = GET_IFP(sc); @@ -1192,12 +954,12 @@ kue_init(xsc) if (ifp->if_flags & IFF_RUNNING) return; - s = splimp(); + s = splnet(); -#if defined(__FreeBSD__) || defined(__OpenBSD__) - eaddr = sc->arpcom.ac_enaddr; -#elif defined(__NetBSD__) +#if defined(__NetBSD__) eaddr = LLADDR(ifp->if_sadl); +#else + eaddr = sc->arpcom.ac_enaddr; #endif /* defined(__NetBSD__) */ /* Set MAC address */ kue_ctl(sc, KUE_CTL_WRITE, KUE_CMD_SET_MAC, 0, eaddr, ETHER_ADDR_LEN); @@ -1251,8 +1013,7 @@ kue_init(xsc) } Static int -kue_open_pipes(sc) - struct kue_softc *sc; +kue_open_pipes(struct kue_softc *sc) { usbd_status err; struct kue_chain *c; @@ -1293,16 +1054,11 @@ kue_open_pipes(sc) } Static int -kue_ioctl(ifp, command, data) - struct ifnet *ifp; - u_long command; - caddr_t data; +kue_ioctl(struct ifnet *ifp, u_long command, caddr_t data) { struct kue_softc *sc = ifp->if_softc; -#if defined(__NetBSD__) || defined(__OpenBSD__) struct ifaddr *ifa = (struct ifaddr *)data; struct ifreq *ifr = (struct ifreq *)data; -#endif int s, error = 0; DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->kue_dev),__FUNCTION__)); @@ -1310,16 +1066,16 @@ kue_ioctl(ifp, command, data) if (sc->kue_dying) return (EIO); - s = splimp(); +#ifdef DIAGNOSTIC + if (!curproc) { + printf("%s: no proc!!\n", USBDEVNAME(sc->kue_dev)); + return EIO; + } +#endif + + s = splnet(); switch(command) { -#if defined(__FreeBSD__) - case SIOCSIFADDR: - case SIOCGIFADDR: - case SIOCSIFMTU: - error = ether_ioctl(ifp, command, data); - break; -#elif defined(__NetBSD__) || defined(__OpenBSD__) case SIOCSIFADDR: ifp->if_flags |= IFF_UP; kue_init(sc); @@ -1359,8 +1115,6 @@ kue_ioctl(ifp, command, data) ifp->if_mtu = ifr->ifr_mtu; break; -#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ - case SIOCSIFFLAGS: if (ifp->if_flags & IFF_UP) { if (ifp->if_flags & IFF_RUNNING && @@ -1400,10 +1154,12 @@ kue_ioctl(ifp, command, data) } Static void -kue_watchdog(ifp) - struct ifnet *ifp; +kue_watchdog(struct ifnet *ifp) { struct kue_softc *sc = ifp->if_softc; + struct kue_chain *c; + usbd_status stat; + int s; DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->kue_dev),__FUNCTION__)); @@ -1413,19 +1169,14 @@ kue_watchdog(ifp) ifp->if_oerrors++; printf("%s: watchdog timeout\n", USBDEVNAME(sc->kue_dev)); - /* - * The polling business is a kludge to avoid allowing the - * USB code to call tsleep() in usbd_delay_ms(), which will - * kill us since the watchdog routine is invoked from - * interrupt context. - */ - usbd_set_polling(sc->kue_udev, 1); - kue_stop(sc); - kue_init(sc); - usbd_set_polling(sc->kue_udev, 0); + s = splusb(); + c = &sc->kue_cdata.kue_tx_chain[0]; + usbd_get_xfer_status(c->kue_xfer, NULL, NULL, NULL, &stat); + kue_txeof(c->kue_xfer, c, stat); if (ifp->if_snd.ifq_head != NULL) kue_start(ifp); + splx(s); } /* @@ -1433,8 +1184,7 @@ kue_watchdog(ifp) * RX and TX lists. */ Static void -kue_stop(sc) - struct kue_softc *sc; +kue_stop(struct kue_softc *sc) { usbd_status err; struct ifnet *ifp; @@ -1514,20 +1264,3 @@ kue_stop(sc) ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); } - -#ifdef __FreeBSD__ -/* - * Stop all chip I/O so that the kernel's probe routines don't - * get confused by errant DMAs when rebooting. - */ -Static void -kue_shutdown(dev) - device_t dev; -{ - struct kue_softc *sc; - - sc = device_get_softc(dev); - - kue_stop(sc); -} -#endif diff --git a/sys/dev/usb/if_kuereg.h b/sys/dev/usb/if_kuereg.h index ad5cf17b517..8e9f2b8d7b9 100644 --- a/sys/dev/usb/if_kuereg.h +++ b/sys/dev/usb/if_kuereg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_kuereg.h,v 1.2 2000/03/28 19:37:48 aaron Exp $ */ +/* $OpenBSD: if_kuereg.h,v 1.3 2001/05/03 02:20:32 aaron Exp $ */ /* $NetBSD: if_kuereg.h,v 1.9 2000/03/24 22:13:24 augustss Exp $ */ /* * Copyright (c) 1997, 1998, 1999, 2000 @@ -125,6 +125,8 @@ struct kue_ether_desc { #define KUE_CTL_READ 0x01 #define KUE_CTL_WRITE 0x02 +#define KUE_WARM_REV 0x0202 + /* * The interrupt endpoint is currently unused * by the KLSI part. diff --git a/sys/dev/usb/ohci.c b/sys/dev/usb/ohci.c index 6466674697b..79fcc8c1faa 100644 --- a/sys/dev/usb/ohci.c +++ b/sys/dev/usb/ohci.c @@ -1,5 +1,5 @@ -/* $OpenBSD: ohci.c,v 1.20 2001/03/25 07:03:26 csapuntz Exp $ */ -/* $NetBSD: ohci.c,v 1.93 2000/08/17 23:18:56 augustss Exp $ */ +/* $OpenBSD: ohci.c,v 1.21 2001/05/03 02:20:32 aaron Exp $ */ +/* $NetBSD: ohci.c,v 1.102 2001/04/01 15:00:29 augustss Exp $ */ /* $FreeBSD: src/sys/dev/usb/ohci.c,v 1.22 1999/11/17 22:33:40 n_hibma Exp $ */ /* @@ -857,6 +857,7 @@ ohci_init(ohci_softc_t *sc) sc->sc_bus.pipe_size = sizeof(struct ohci_pipe); #if defined(__NetBSD__) || defined(__OpenBSD__) + sc->sc_control = sc->sc_intre = 0; sc->sc_powerhook = powerhook_establish(ohci_power, sc); sc->sc_shutdownhook = shutdownhook_establish(ohci_shutdown, sc); #endif @@ -952,26 +953,45 @@ ohci_power(int why, void *v) ohci_dumpregs(sc); #endif - s = splusb(); + s = splhardusb(); switch (why) { case PWR_SUSPEND: case PWR_STANDBY: sc->sc_bus.use_polling++; - ctl = OREAD4(sc, OHCI_CONTROL); - ctl = (ctl & ~OHCI_HCFS_MASK) | OHCI_HCFS_SUSPEND; + ctl = OREAD4(sc, OHCI_CONTROL) & ~OHCI_HCFS_MASK; + if (sc->sc_control == 0) { + /* + * Preserve register values, in case that APM BIOS + * does not recover them. + */ + sc->sc_control = ctl; + sc->sc_intre = OREAD4(sc, OHCI_INTERRUPT_ENABLE); + } + ctl |= OHCI_HCFS_SUSPEND; OWRITE4(sc, OHCI_CONTROL, ctl); usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT); sc->sc_bus.use_polling--; break; case PWR_RESUME: sc->sc_bus.use_polling++; - ctl = OREAD4(sc, OHCI_CONTROL); - ctl = (ctl & ~OHCI_HCFS_MASK) | OHCI_HCFS_RESUME; + /* Some broken BIOSes do not recover these values */ + OWRITE4(sc, OHCI_HCCA, DMAADDR(&sc->sc_hccadma)); + OWRITE4(sc, OHCI_CONTROL_HEAD_ED, sc->sc_ctrl_head->physaddr); + OWRITE4(sc, OHCI_BULK_HEAD_ED, sc->sc_bulk_head->physaddr); + if (sc->sc_intre) + OWRITE4(sc, OHCI_INTERRUPT_ENABLE, + sc->sc_intre & (OHCI_ALL_INTRS | OHCI_MIE)); + if (sc->sc_control) + ctl = sc->sc_control; + else + ctl = OREAD4(sc, OHCI_CONTROL); + ctl |= OHCI_HCFS_RESUME; OWRITE4(sc, OHCI_CONTROL, ctl); usb_delay_ms(&sc->sc_bus, USB_RESUME_DELAY); ctl = (ctl & ~OHCI_HCFS_MASK) | OHCI_HCFS_OPERATIONAL; OWRITE4(sc, OHCI_CONTROL, ctl); usb_delay_ms(&sc->sc_bus, USB_RESUME_RECOVERY); + sc->sc_control = sc->sc_intre = 0; sc->sc_bus.use_polling--; break; #if defined(__NetBSD__) @@ -1083,7 +1103,12 @@ ohci_intr1(ohci_softc_t *sc) (u_int)eintrs)); if (eintrs & OHCI_SO) { - printf("%s: scheduling overrun\n",USBDEVNAME(sc->sc_bus.bdev)); + sc->sc_overrun_cnt++; + if (usbd_ratecheck(&sc->sc_overrun_ntc)) { + printf("%s: %u scheduling overruns\n", + USBDEVNAME(sc->sc_bus.bdev), sc->sc_overrun_cnt); + sc->sc_overrun_cnt = 0; + } /* XXX do what */ intrs &= ~OHCI_SO; } diff --git a/sys/dev/usb/ohcivar.h b/sys/dev/usb/ohcivar.h index ca2ff486a2b..7c94ff33186 100644 --- a/sys/dev/usb/ohcivar.h +++ b/sys/dev/usb/ohcivar.h @@ -1,5 +1,5 @@ -/* $OpenBSD: ohcivar.h,v 1.11 2000/11/08 18:10:37 aaron Exp $ */ -/* $NetBSD: ohcivar.h,v 1.24 2000/06/01 14:28:58 augustss Exp $ */ +/* $OpenBSD: ohcivar.h,v 1.12 2001/05/03 02:20:32 aaron Exp $ */ +/* $NetBSD: ohcivar.h,v 1.27 2001/02/21 10:19:30 minoura Exp $ */ /* $FreeBSD: src/sys/dev/usb/ohcivar.h,v 1.13 1999/11/17 22:33:41 n_hibma Exp $ */ /* @@ -125,6 +125,11 @@ typedef struct ohci_softc { void *sc_powerhook; /* cookie from power hook */ void *sc_shutdownhook; /* cookie from shutdown hook */ #endif + u_int32_t sc_control; /* Preserved during suspend/standby */ + u_int32_t sc_intre; + + u_int sc_overrun_cnt; + struct timeval sc_overrun_ntc; device_ptr_t sc_child; diff --git a/sys/dev/usb/uaudio.c b/sys/dev/usb/uaudio.c index a7ab58c6940..803b8ef2bdd 100644 --- a/sys/dev/usb/uaudio.c +++ b/sys/dev/usb/uaudio.c @@ -1,5 +1,5 @@ -/* $OpenBSD: uaudio.c,v 1.8 2001/01/28 09:43:41 aaron Exp $ */ -/* $NetBSD: uaudio.c,v 1.29 2000/10/05 01:35:07 augustss Exp $ */ +/* $OpenBSD: uaudio.c,v 1.9 2001/05/03 02:20:32 aaron Exp $ */ +/* $NetBSD: uaudio.c,v 1.41 2001/01/23 14:04:13 augustss Exp $ */ /* * Copyright (c) 1999 The NetBSD Foundation, Inc. @@ -52,6 +52,7 @@ #include <sys/ioctl.h> #include <sys/tty.h> #include <sys/file.h> +#include <sys/reboot.h> #include <sys/select.h> #include <sys/proc.h> #include <sys/vnode.h> @@ -382,13 +383,13 @@ USB_ATTACH(uaudio) for (j = 0; j < sc->sc_nalts; j++) { if (sc->sc_alts[j].ifaceh == NULL) { - printf("%s: alt %d missing AS interface(s)\n", USBDEVNAME(sc->sc_dev), j); + printf("%s: alt %d missing AS interface(s)\n", + USBDEVNAME(sc->sc_dev), j); USB_ATTACH_ERROR_RETURN; } } - printf("%s: audio rev %d.%02x\n", - USBDEVNAME(sc->sc_dev), + printf("%s: audio rev %d.%02x\n", USBDEVNAME(sc->sc_dev), sc->sc_audio_rev >> 8, sc->sc_audio_rev & 0xff); sc->sc_chan.sc = sc; @@ -396,6 +397,17 @@ USB_ATTACH(uaudio) if (usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_NO_FRAC) sc->sc_chan.nofrac = 1; +#if defined(__NetBSD__) +#ifndef UAUDIO_DEBUG + if (bootverbose) +#endif +#endif + printf("%s: %d mixer controls\n", USBDEVNAME(sc->sc_dev), + sc->sc_nctls); + + usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, + USBDEV(sc->sc_dev)); + DPRINTF(("uaudio_attach: doing audio_attach_mi\n")); #if defined(__OpenBSD__) audio_attach_mi(&uaudio_hw_if, sc, &sc->sc_dev); @@ -403,9 +415,6 @@ USB_ATTACH(uaudio) sc->sc_audiodev = audio_attach_mi(&uaudio_hw_if, sc, &sc->sc_dev); #endif - usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, - USBDEV(sc->sc_dev)); - USB_ATTACH_SUCCESS_RETURN; } @@ -421,7 +430,7 @@ uaudio_activate(device_ptr_t self, enum devact act) break; case DVACT_DEACTIVATE: - if (sc->sc_audiodev) + if (sc->sc_audiodev != NULL) rv = config_deactivate(sc->sc_audiodev); sc->sc_dying = 1; break; @@ -528,7 +537,7 @@ uaudio_find_iface(char *buf, int size, int *offsp, int subtype) d->bInterfaceSubClass == subtype) return (d); } - return (0); + return (NULL); } void @@ -1086,7 +1095,7 @@ uaudio_process_as(struct uaudio_softc *sc, char *buf, int *offsp, dir == UE_DIR_IN && type == UE_ISO_ADAPT) type = UE_ISO_ASYNC; - /* We can't handle endpoints that need a sync pipe. */ + /* We can't handle endpoints that need a sync pipe yet. */ if (dir == UE_DIR_IN ? type == UE_ISO_ADAPT : type == UE_ISO_ASYNC) { printf("%s: ignored %sput endpoint of type %s\n", USBDEVNAME(sc->sc_dev), diff --git a/sys/dev/usb/uaudioreg.h b/sys/dev/usb/uaudioreg.h index d843bca6fdd..ded7ad3d7c2 100644 --- a/sys/dev/usb/uaudioreg.h +++ b/sys/dev/usb/uaudioreg.h @@ -1,5 +1,5 @@ -/* $OpenBSD: uaudioreg.h,v 1.6 2001/01/28 09:43:41 aaron Exp $ */ -/* $NetBSD: uaudioreg.h,v 1.6 2000/05/30 10:10:17 augustss Exp $ */ +/* $OpenBSD: uaudioreg.h,v 1.7 2001/05/03 02:20:33 aaron Exp $ */ +/* $NetBSD: uaudioreg.h,v 1.7 2000/12/28 00:29:58 augustss Exp $ */ /* * Copyright (c) 1999 The NetBSD Foundation, Inc. diff --git a/sys/dev/usb/ucom.c b/sys/dev/usb/ucom.c index 00107ea2bca..cb1c97c7d74 100644 --- a/sys/dev/usb/ucom.c +++ b/sys/dev/usb/ucom.c @@ -1,5 +1,5 @@ -/* $OpenBSD: ucom.c,v 1.7 2001/01/28 09:43:41 aaron Exp $ */ -/* $NetBSD: ucom.c,v 1.30 2000/09/23 04:33:04 augustss Exp $ */ +/* $OpenBSD: ucom.c,v 1.8 2001/05/03 02:20:33 aaron Exp $ */ +/* $NetBSD: ucom.c,v 1.37 2001/04/02 13:18:31 augustss Exp $ */ /* * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc. @@ -162,6 +162,8 @@ USB_ATTACH(ucom) if (uca->portno != UCOM_UNK_PORTNO) printf(": portno %d", uca->portno); + if (uca->info != NULL) + printf(", %s", uca->info); printf("\n"); sc->sc_udev = uca->device; @@ -190,24 +192,28 @@ USB_ATTACH(ucom) USB_DETACH(ucom) { struct ucom_softc *sc = (struct ucom_softc *)self; + struct tty *tp = sc->sc_tty; int maj, mn; int s; - DPRINTF(("ucom_detach: sc=%p flags=%d tp=%p\n", - sc, flags, sc->sc_tty)); + DPRINTF(("ucom_detach: sc=%p flags=%d tp=%p, pipe=%d,%d\n", + sc, flags, tp, sc->sc_bulkin_no, sc->sc_bulkout_no)); sc->sc_dying = 1; -#ifdef DIAGNOSTIC - if (sc->sc_tty == NULL) { - DPRINTF(("ucom_detach: no tty\n")); - return (0); - } -#endif + if (sc->sc_bulkin_pipe != NULL) + usbd_abort_pipe(sc->sc_bulkin_pipe); + if (sc->sc_bulkout_pipe != NULL) + usbd_abort_pipe(sc->sc_bulkout_pipe); s = splusb(); if (--sc->sc_refcnt >= 0) { - /* Wake everyone.. how? */ + /* Wake up anyone waiting */ + if (tp != NULL) { + CLR(tp->t_state, TS_CARR_ON); + CLR(tp->t_cflag, CLOCAL | MDMBUF); + ttyflush(tp, FREAD|FWRITE); + } /* Wait for processes to go away. */ usb_detach_wait(USBDEV(sc->sc_dev)); } @@ -226,19 +232,22 @@ USB_DETACH(ucom) vdevgone(maj, mn | UCOMCALLUNIT_MASK, mn | UCOMCALLUNIT_MASK, VCHR); /* Detach and free the tty. */ - tty_detach(sc->sc_tty); - ttyfree(sc->sc_tty); - sc->sc_tty = 0; + if (tp != NULL) { + tty_detach(tp); + ttyfree(tp); + sc->sc_tty = NULL; + } return (0); } -#if defined(__NetBSD__) || defined(__OpenBSD__) int ucom_activate(device_ptr_t self, enum devact act) { struct ucom_softc *sc = (struct ucom_softc *)self; + DPRINTFN(5,("ucom_activate: %d\n", act)); + switch (act) { case DVACT_ACTIVATE: return (EOPNOTSUPP); @@ -250,7 +259,6 @@ ucom_activate(device_ptr_t self, enum devact act) } return (0); } -#endif void ucom_shutdown(struct ucom_softc *sc) @@ -443,12 +451,16 @@ ucomopen(dev_t dev, int flag, int mode, struct proc *p) fail_4: usbd_free_xfer(sc->sc_oxfer); + sc->sc_oxfer = NULL; fail_3: usbd_free_xfer(sc->sc_ixfer); + sc->sc_ixfer = NULL; fail_2: usbd_close_pipe(sc->sc_bulkout_pipe); + sc->sc_bulkout_pipe = NULL; fail_1: usbd_close_pipe(sc->sc_bulkin_pipe); + sc->sc_bulkin_pipe = NULL; fail_0: sc->sc_opening = 0; wakeup(&sc->sc_opening); @@ -955,7 +967,7 @@ ucomwritecb(usbd_xfer_handle xfer, usbd_private_handle p, usbd_status status) DPRINTFN(5,("ucomwritecb: status=%d\n", status)); - if (status == USBD_CANCELLED) + if (status == USBD_CANCELLED || sc->sc_dying) return; if (status) { @@ -1013,11 +1025,20 @@ ucomreadcb(usbd_xfer_handle xfer, usbd_private_handle p, usbd_status status) u_char *cp; int s; - if (status == USBD_CANCELLED) - return; + DPRINTFN(5,("ucomreadcb: status=%d\n", status)); + + if (status == USBD_CANCELLED || status == USBD_IOERROR || + sc->sc_dying) { + DPRINTF(("ucomreadcb: dying\n")); + /* Send something to wake upper layer */ + s = spltty(); + (*rint)('\n', tp); + ttwakeup(tp); + splx(s); + return; + } if (status) { - DPRINTF(("ucomreadcb: status=%d\n", status)); usbd_clear_endpoint_stall_async(sc->sc_bulkin_pipe); /* XXX we should restart after some delay. */ return; @@ -1058,12 +1079,24 @@ ucom_cleanup(struct ucom_softc *sc) DPRINTF(("ucom_cleanup: closing pipes\n")); ucom_shutdown(sc); - usbd_abort_pipe(sc->sc_bulkin_pipe); - usbd_close_pipe(sc->sc_bulkin_pipe); - usbd_abort_pipe(sc->sc_bulkout_pipe); - usbd_close_pipe(sc->sc_bulkout_pipe); - usbd_free_xfer(sc->sc_ixfer); - usbd_free_xfer(sc->sc_oxfer); + if (sc->sc_bulkin_pipe != NULL) { + usbd_abort_pipe(sc->sc_bulkin_pipe); + usbd_close_pipe(sc->sc_bulkin_pipe); + sc->sc_bulkin_pipe = NULL; + } + if (sc->sc_bulkout_pipe != NULL) { + usbd_abort_pipe(sc->sc_bulkout_pipe); + usbd_close_pipe(sc->sc_bulkout_pipe); + sc->sc_bulkout_pipe = NULL; + } + if (sc->sc_ixfer != NULL) { + usbd_free_xfer(sc->sc_ixfer); + sc->sc_ixfer = NULL; + } + if (sc->sc_oxfer != NULL) { + usbd_free_xfer(sc->sc_oxfer); + sc->sc_oxfer = NULL; + } } #endif /* NUCOM > 0 */ @@ -1071,9 +1104,12 @@ ucom_cleanup(struct ucom_softc *sc) int ucomprint(void *aux, const char *pnp) { + struct ucom_attach_args *uca = aux; if (pnp) - printf("ucom at %s\n", pnp); + printf("ucom at %s", pnp); + if (uca->portno != UCOM_UNK_PORTNO) + printf(" portno %d", uca->portno); return (UNCONF); } diff --git a/sys/dev/usb/ucomvar.h b/sys/dev/usb/ucomvar.h index 9fd5245d8cc..faa9719764b 100644 --- a/sys/dev/usb/ucomvar.h +++ b/sys/dev/usb/ucomvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ucomvar.h,v 1.5 2000/11/08 18:10:38 aaron Exp $ */ +/* $OpenBSD: ucomvar.h,v 1.6 2001/05/03 02:20:33 aaron Exp $ */ /* $NetBSD: ucomvar.h,v 1.8 2000/09/03 19:15:45 augustss Exp $ */ /* @@ -103,6 +103,7 @@ struct ucom_attach_args { u_int ibufsizepad; u_int obufsize; u_int opkthdrlen; + const char *info; /* attach message */ usbd_device_handle device; usbd_interface_handle iface; struct ucom_methods *methods; diff --git a/sys/dev/usb/uftdi.c b/sys/dev/usb/uftdi.c index 16ccf455e60..9a9b94784e7 100644 --- a/sys/dev/usb/uftdi.c +++ b/sys/dev/usb/uftdi.c @@ -1,5 +1,5 @@ -/* $OpenBSD: uftdi.c,v 1.2 2001/02/20 04:15:28 nate Exp $ */ -/* $NetBSD: uftdi.c,v 1.5 2001/01/23 14:04:13 augustss Exp $ */ +/* $OpenBSD: uftdi.c,v 1.3 2001/05/03 02:20:33 aaron Exp $ */ +/* $NetBSD: uftdi.c,v 1.6 2001/01/23 21:56:17 augustss Exp $ */ /* * Copyright (c) 2000 The NetBSD Foundation, Inc. @@ -217,6 +217,7 @@ USB_ATTACH(uftdi) uca.iface = iface; uca.methods = &uftdi_methods; uca.arg = sc; + uca.info = NULL; usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, USBDEV(sc->sc_dev)); diff --git a/sys/dev/usb/ugen.c b/sys/dev/usb/ugen.c index 56b28da7eb3..57a7204bb54 100644 --- a/sys/dev/usb/ugen.c +++ b/sys/dev/usb/ugen.c @@ -1,5 +1,5 @@ -/* $OpenBSD: ugen.c,v 1.14 2001/01/28 09:43:41 aaron Exp $ */ -/* $NetBSD: ugen.c,v 1.43 2000/10/24 14:53:59 augustss Exp $ */ +/* $OpenBSD: ugen.c,v 1.15 2001/05/03 02:20:33 aaron Exp $ */ +/* $NetBSD: ugen.c,v 1.45 2000/12/13 04:05:14 augustss Exp $ */ /* $FreeBSD: src/sys/dev/usb/ugen.c,v 1.26 1999/11/17 22:33:41 n_hibma Exp $ */ /* diff --git a/sys/dev/usb/uhci.c b/sys/dev/usb/uhci.c index 0c77d088058..843b1a537b2 100644 --- a/sys/dev/usb/uhci.c +++ b/sys/dev/usb/uhci.c @@ -1,5 +1,5 @@ -/* $OpenBSD: uhci.c,v 1.19 2001/03/25 04:26:58 csapuntz Exp $ */ -/* $NetBSD: uhci.c,v 1.125 2000/09/23 21:00:10 augustss Exp $ */ +/* $OpenBSD: uhci.c,v 1.20 2001/05/03 02:20:33 aaron Exp $ */ +/* $NetBSD: uhci.c,v 1.135 2001/04/01 14:59:52 augustss Exp $ */ /* $FreeBSD: src/sys/dev/usb/uhci.c,v 1.33 1999/11/17 22:33:41 n_hibma Exp $ */ /* @@ -687,7 +687,7 @@ uhci_power(int why, void *v) int cmd; int s; - s = splusb(); + s = splhardusb(); cmd = UREAD2(sc, UHCI_CMD); DPRINTF(("uhci_power: sc=%p, why=%d (was %d), cmd=0x%x\n", @@ -710,6 +710,8 @@ uhci_power(int why, void *v) sc->sc_saved_frnum = UREAD2(sc, UHCI_FRNUM); sc->sc_saved_sof = UREAD1(sc, UHCI_SOF); + UWRITE2(sc, UHCI_INTR, 0); /* disable intrs */ + UHCICMD(sc, cmd | UHCI_CMD_EGSM); /* enter global suspend */ usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT); sc->sc_suspend = why; @@ -1168,6 +1170,7 @@ uhci_intr(void *arg) if (sc->sc_suspend != PWR_RESUME) { printf("%s: interrupt while not operating ignored\n", USBDEVNAME(sc->sc_bus.bdev)); + UWRITE2(sc, UHCI_STS, status); /* acknowledge the ints */ return (0); } @@ -1208,10 +1211,9 @@ uhci_intr(void *arg) } - if (ack) /* acknowledge the ints */ - UWRITE2(sc, UHCI_STS, ack); - else /* nothing to acknowledge */ - return (0); + if (!ack) + return (0); /* nothing to acknowledge */ + UWRITE2(sc, UHCI_STS, ack); /* acknowledge the ints */ sc->sc_bus.no_intrs++; usb_schedsoftintr(&sc->sc_bus); @@ -1512,7 +1514,7 @@ uhci_run(uhci_softc_t *sc, int run) u_int16_t cmd; run = run != 0; - s = splusb(); + s = splhardusb(); DPRINTF(("uhci_run: setting run=%d\n", run)); cmd = UREAD2(sc, UHCI_CMD); if (run) diff --git a/sys/dev/usb/uhcireg.h b/sys/dev/usb/uhcireg.h index 0b98a634d91..0e09fc1e2b2 100644 --- a/sys/dev/usb/uhcireg.h +++ b/sys/dev/usb/uhcireg.h @@ -1,5 +1,5 @@ -/* $OpenBSD: uhcireg.h,v 1.7 2000/11/08 18:10:38 aaron Exp $ */ -/* $NetBSD: uhcireg.h,v 1.11.4.1 2000/08/22 04:11:56 augustss Exp $ */ +/* $OpenBSD: uhcireg.h,v 1.8 2001/05/03 02:20:33 aaron Exp $ */ +/* $NetBSD: uhcireg.h,v 1.13 2000/08/13 18:20:15 augustss Exp $ */ /* $FreeBSD: src/sys/dev/usb/uhcireg.h,v 1.12 1999/11/17 22:33:42 n_hibma Exp $ */ /* diff --git a/sys/dev/usb/uhid.c b/sys/dev/usb/uhid.c index 2730e06efd8..169f75bc534 100644 --- a/sys/dev/usb/uhid.c +++ b/sys/dev/usb/uhid.c @@ -1,5 +1,5 @@ -/* $OpenBSD: uhid.c,v 1.13 2001/01/28 09:43:42 aaron Exp $ */ -/* $NetBSD: uhid.c,v 1.40 2000/10/10 12:37:01 augustss Exp $ */ +/* $OpenBSD: uhid.c,v 1.14 2001/05/03 02:20:33 aaron Exp $ */ +/* $NetBSD: uhid.c,v 1.42 2000/12/29 01:47:49 augustss Exp $ */ /* $FreeBSD: src/sys/dev/usb/uhid.c,v 1.22 1999/11/17 22:33:43 n_hibma Exp $ */ /* diff --git a/sys/dev/usb/uhub.c b/sys/dev/usb/uhub.c index 5a60a06232b..05dfb76d3a7 100644 --- a/sys/dev/usb/uhub.c +++ b/sys/dev/usb/uhub.c @@ -1,5 +1,5 @@ -/* $OpenBSD: uhub.c,v 1.12 2001/01/28 09:43:42 aaron Exp $ */ -/* $NetBSD: uhub.c,v 1.47 2000/09/24 02:08:38 augustss Exp $ */ +/* $OpenBSD: uhub.c,v 1.13 2001/05/03 02:20:33 aaron Exp $ */ +/* $NetBSD: uhub.c,v 1.49 2001/01/21 19:00:06 augustss Exp $ */ /* $FreeBSD: src/sys/dev/usb/uhub.c,v 1.18 1999/11/17 22:33:43 n_hibma Exp $ */ /* @@ -569,7 +569,7 @@ uhub_intr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status) if (status != USBD_NORMAL_COMPLETION) usbd_clear_endpoint_stall_async(sc->sc_ipipe); - usb_needs_explore(sc->sc_hub->bus); + usb_needs_explore(sc->sc_hub); } #if defined(__FreeBSD__) diff --git a/sys/dev/usb/ukbd.c b/sys/dev/usb/ukbd.c index 931d945ed84..b8dffaa12f5 100644 --- a/sys/dev/usb/ukbd.c +++ b/sys/dev/usb/ukbd.c @@ -1,5 +1,5 @@ -/* $OpenBSD: ukbd.c,v 1.5 2001/03/07 20:42:38 maja Exp $ */ -/* $NetBSD: ukbd.c,v 1.60 2000/06/01 14:29:00 augustss Exp $ */ +/* $OpenBSD: ukbd.c,v 1.6 2001/05/03 02:20:33 aaron Exp $ */ +/* $NetBSD: ukbd.c,v 1.66 2001/04/06 22:54:15 augustss Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -113,7 +113,7 @@ struct ukbd_data { /* Translate USB bitmap to USB keycode. */ #define NMOD 8 -Static struct { +Static const struct { int mask, key; } ukbd_mods[NMOD] = { { MOD_CONTROL_L, 224 }, @@ -132,7 +132,7 @@ Static struct { * Translate USB keycodes to US keyboard XT scancodes. * Scancodes >= 128 represent EXTENDED keycodes. */ -Static u_int8_t ukbd_trtab[256] = { +Static const u_int8_t ukbd_trtab[256] = { NN, NN, NN, NN, 30, 48, 46, 32, /* 00 - 07 */ 18, 33, 34, 35, 23, 36, 37, 38, /* 08 - 0F */ 50, 49, 24, 25, 16, 19, 31, 20, /* 10 - 17 */ @@ -412,11 +412,11 @@ USB_ATTACH(ukbd) usbd_delay_ms(uaa->device, 400); ukbd_set_leds(sc, 0); - sc->sc_wskbddev = config_found(self, &a, wskbddevprint); - usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, USBDEV(sc->sc_dev)); + sc->sc_wskbddev = config_found(self, &a, wskbddevprint); + USB_ATTACH_SUCCESS_RETURN; } diff --git a/sys/dev/usb/ukbdmap.c b/sys/dev/usb/ukbdmap.c index 040b1bb984f..7d66556c3d5 100644 --- a/sys/dev/usb/ukbdmap.c +++ b/sys/dev/usb/ukbdmap.c @@ -1,5 +1,5 @@ -/* $OpenBSD: ukbdmap.c,v 1.6 2001/03/07 20:42:38 maja Exp $ */ -/* $NetBSD: ukbdmap.c,v 1.5 2000/04/27 15:26:49 augustss Exp $ */ +/* $OpenBSD: ukbdmap.c,v 1.7 2001/05/03 02:20:33 aaron Exp $ */ +/* $NetBSD: ukbdmap.c,v 1.6 2001/04/04 05:31:57 toshii Exp $ */ /* * Copyright (c) 1999 The NetBSD Foundation, Inc. @@ -157,6 +157,29 @@ Static const keysym_t ukbd_keydesc_us[] = { KC(231), KS_Meta_R, }; +Static const keysym_t ukbd_keydesc_jp[] = { +/* pos command normal shifted */ + KC(31), KS_2, KS_quotedbl, + KC(35), KS_6, KS_ampersand, + KC(36), KS_7, KS_apostrophe, + KC(37), KS_8, KS_parenleft, + KC(38), KS_9, KS_parenright, + KC(39), KS_0, + KC(45), KS_minus, KS_equal, + KC(46), KS_asciicircum, KS_asciitilde, + KC(47), KS_at, KS_grave, + KC(48), KS_bracketleft, KS_braceleft, + KC(50), KS_bracketright, KS_braceright, + KC(51), KS_semicolon, KS_plus, + KC(52), KS_colon, KS_asterisk, + KC(53), KS_Zenkaku_Hankaku, /* replace grave/tilde */ + KC(135), KS_backslash, KS_underscore, + KC(136), KS_Hiragana_Katakana, + KC(137), KS_backslash, KS_bar, + KC(138), KS_Henkan, + KC(139), KS_Muhenkan, +}; + Static const keysym_t ukbd_keydesc_swapctrlcaps[] = { /* pos command normal shifted */ KC(57), KS_Control_L, @@ -371,9 +394,13 @@ Static const keysym_t ukbd_keydesc_es[] = { const struct wscons_keydesc ukbd_keydesctab[] = { KBD_MAP(KB_US, 0, ukbd_keydesc_us), + KBD_MAP(KB_US | KB_SWAPCTRLCAPS, KB_US, ukbd_keydesc_swapctrlcaps), + KBD_MAP(KB_JP, KB_US, ukbd_keydesc_jp), + KBD_MAP(KB_JP | KB_SWAPCTRLCAPS,KB_JP, ukbd_keydesc_swapctrlcaps), KBD_MAP(KB_DE, KB_US, ukbd_keydesc_de), KBD_MAP(KB_DE | KB_NODEAD, KB_DE, ukbd_keydesc_de_nodead), KBD_MAP(KB_FR, KB_US, ukbd_keydesc_fr), + KBD_MAP(KB_FR | KB_SWAPCTRLCAPS, KB_FR, ukbd_keydesc_swapctrlcaps), KBD_MAP(KB_DK, KB_US, ukbd_keydesc_dk), KBD_MAP(KB_DK | KB_NODEAD, KB_DK, ukbd_keydesc_dk_nodead), KBD_MAP(KB_IT, KB_US, ukbd_keydesc_it), @@ -382,8 +409,6 @@ const struct wscons_keydesc ukbd_keydesctab[] = { KBD_MAP(KB_SV | KB_NODEAD, KB_SV, ukbd_keydesc_sv_nodead), KBD_MAP(KB_NO, KB_DK, ukbd_keydesc_no), KBD_MAP(KB_NO | KB_NODEAD, KB_NO, ukbd_keydesc_no_nodead), - KBD_MAP(KB_US | KB_SWAPCTRLCAPS, KB_US, ukbd_keydesc_swapctrlcaps), - KBD_MAP(KB_FR | KB_SWAPCTRLCAPS, KB_FR, ukbd_keydesc_swapctrlcaps), KBD_MAP(KB_ES , KB_US, ukbd_keydesc_es), {0, 0, 0, 0} }; diff --git a/sys/dev/usb/ulpt.c b/sys/dev/usb/ulpt.c index ede62f3d4d9..3769a2a2e29 100644 --- a/sys/dev/usb/ulpt.c +++ b/sys/dev/usb/ulpt.c @@ -1,5 +1,5 @@ -/* $OpenBSD: ulpt.c,v 1.6 2001/01/28 09:43:42 aaron Exp $ */ -/* $NetBSD: ulpt.c,v 1.38 2000/06/01 14:29:00 augustss Exp $ */ +/* $OpenBSD: ulpt.c,v 1.7 2001/05/03 02:20:34 aaron Exp $ */ +/* $NetBSD: ulpt.c,v 1.42 2001/04/16 00:18:06 augustss Exp $ */ /* $FreeBSD: src/sys/dev/usb/ulpt.c,v 1.24 1999/11/17 22:33:44 n_hibma Exp $ */ /* @@ -96,8 +96,15 @@ struct ulpt_softc { usbd_device_handle sc_udev; /* device */ usbd_interface_handle sc_iface; /* interface */ int sc_ifaceno; - usbd_pipe_handle sc_bulkpipe; /* bulk pipe */ - int sc_bulk; + + int sc_out; + usbd_pipe_handle sc_out_pipe; /* bulk out pipe */ + + int sc_in; + usbd_pipe_handle sc_in_pipe; /* bulk in pipe */ + usbd_xfer_handle sc_in_xfer1; + usbd_xfer_handle sc_in_xfer2; + u_char sc_junk[64]; /* somewhere to dump input */ u_char sc_state; #define ULPT_OPEN 0x01 /* device is open */ @@ -151,7 +158,9 @@ int ulpt_status(struct ulpt_softc *); void ulpt_reset(struct ulpt_softc *); int ulpt_statusmsg(u_char, struct ulpt_softc *); +#if 0 void ieee1284_print_id(char *); +#endif #define ULPTUNIT(s) (minor(s) & 0x1f) #define ULPTFLAGS(s) (minor(s) & 0xe0) @@ -182,41 +191,103 @@ USB_ATTACH(ulpt) USB_ATTACH_START(ulpt, sc, uaa); usbd_device_handle dev = uaa->device; usbd_interface_handle iface = uaa->iface; - usb_interface_descriptor_t *id = usbd_get_interface_descriptor(iface); + usb_interface_descriptor_t *ifcd = usbd_get_interface_descriptor(iface); + usb_interface_descriptor_t *id, *iend; + usb_config_descriptor_t *cdesc; + usbd_status err; char devinfo[1024]; usb_endpoint_descriptor_t *ed; - usbd_status err; + u_int8_t epcount; + int i, altno; DPRINTFN(10,("ulpt_attach: sc=%p\n", sc)); usbd_devinfo(dev, 0, devinfo); USB_ATTACH_SETUP; printf("%s: %s, iclass %d/%d\n", USBDEVNAME(sc->sc_dev), - devinfo, id->bInterfaceClass, id->bInterfaceSubClass); - - /* Figure out which endpoint is the bulk out endpoint. */ - ed = usbd_interface2endpoint_descriptor(iface, 0); - if (ed == NULL) - goto nobulk; - if (UE_GET_DIR(ed->bEndpointAddress) != UE_DIR_OUT || - (ed->bmAttributes & UE_XFERTYPE) != UE_BULK) { - /* In case we are using a bidir protocol... */ - ed = usbd_interface2endpoint_descriptor(iface, 1); - if (ed == NULL) - goto nobulk; - if (UE_GET_DIR(ed->bEndpointAddress) != UE_DIR_OUT || - (ed->bmAttributes & UE_XFERTYPE) != UE_BULK) - goto nobulk; + devinfo, ifcd->bInterfaceClass, ifcd->bInterfaceSubClass); + + /* XXX + * Stepping through the alternate settings needs to be abstracted out. + */ + cdesc = usbd_get_config_descriptor(dev); + if (cdesc == NULL) { + printf("%s: failed to get configuration descriptor\n", + USBDEVNAME(sc->sc_dev)); + USB_ATTACH_ERROR_RETURN; + } + iend = (usb_interface_descriptor_t *) + ((char *)cdesc + UGETW(cdesc->wTotalLength)); +#ifdef DIAGNOSTIC + if (ifcd < (usb_interface_descriptor_t *)cdesc || + ifcd >= iend) + panic("ulpt: iface desc out of range\n"); +#endif + /* Step through all the descriptors looking for bidir mode */ + for (id = ifcd, altno = 0; + id < iend; + id = (void *)((char *)id + id->bLength)) { + if (id->bDescriptorType == UDESC_INTERFACE && + id->bInterfaceNumber == ifcd->bInterfaceNumber) { + if (id->bInterfaceClass == UICLASS_PRINTER && + id->bInterfaceSubClass == UISUBCLASS_PRINTER && + id->bInterfaceProtocol == UIPROTO_PRINTER_BI) + goto found; + altno++; + } + } + id = ifcd; /* not found, use original */ + found: + if (id != ifcd) { + /* Found a new bidir setting */ + DPRINTF(("ulpt_attach: set altno = %d\n", altno)); + err = usbd_set_interface(iface, altno); + if (err) { + printf("%s: setting alternate interface failed\n", + USBDEVNAME(sc->sc_dev)); + sc->sc_dying = 1; + USB_ATTACH_ERROR_RETURN; + } } - sc->sc_bulk = ed->bEndpointAddress; - DPRINTFN(10, ("ulpt_attach: bulk=%d\n", sc->sc_bulk)); - sc->sc_iface = iface; - err = usbd_interface2device_handle(iface, &sc->sc_udev); - if (err) { + epcount = 0; + (void)usbd_endpoint_count(iface, &epcount); + + sc->sc_in = -1; + sc->sc_out = -1; + for (i = 0; i < epcount; i++) { + ed = usbd_interface2endpoint_descriptor(iface, i); + if (ed == NULL) { + printf("%s: couldn't get ep %d\n", + USBDEVNAME(sc->sc_dev), i); + USB_ATTACH_ERROR_RETURN; + } + if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && + UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { + sc->sc_in = ed->bEndpointAddress; + } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && + UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { + sc->sc_out = ed->bEndpointAddress; + } + } + if (sc->sc_out == -1) { + printf("%s: could not find bulk endpoint\n", + USBDEVNAME(sc->sc_dev)); sc->sc_dying = 1; USB_ATTACH_ERROR_RETURN; } + printf("%s: using %s-directional mode\n", USBDEVNAME(sc->sc_dev), + sc->sc_in >= 0 ? "bi" : "uni"); + + if (usbd_get_quirks(dev)->uq_flags & UQ_BROKEN_BIDIR) { + /* This device doesn't handle reading properly. */ + sc->sc_in = -1; + } + + DPRINTFN(10, ("ulpt_attach: bulk=%d\n", sc->sc_out)); + + sc->sc_iface = iface; sc->sc_ifaceno = id->bInterfaceNumber; + sc->sc_udev = dev; #if 0 /* @@ -266,11 +337,6 @@ USB_ATTACH(ulpt) USBDEV(sc->sc_dev)); USB_ATTACH_SUCCESS_RETURN; - - nobulk: - printf("%s: could not find bulk endpoint\n", USBDEVNAME(sc->sc_dev)); - sc->sc_dying = 1; - USB_ATTACH_ERROR_RETURN; } #if defined(__NetBSD__) || defined(__OpenBSD__) @@ -305,8 +371,10 @@ USB_DETACH(ulpt) #endif sc->sc_dying = 1; - if (sc->sc_bulkpipe != NULL) - usbd_abort_pipe(sc->sc_bulkpipe); + if (sc->sc_out_pipe != NULL) + usbd_abort_pipe(sc->sc_out_pipe); + if (sc->sc_in_pipe != NULL) + usbd_abort_pipe(sc->sc_in_pipe); s = splusb(); if (--sc->sc_refcnt >= 0) { @@ -345,7 +413,6 @@ ulpt_status(struct ulpt_softc *sc) usbd_status err; u_char status; - req.bmRequestType = UT_READ_CLASS_INTERFACE; req.bRequest = UR_GET_PORT_STATUS; USETW(req.wValue, 0); USETW(req.wIndex, sc->sc_ifaceno); @@ -372,16 +439,31 @@ ulpt_reset(struct ulpt_softc *sc) /* * There was a mistake in the USB printer 1.0 spec that gave the - * request type as UT_WRITE_CLASS_OTHER, it should have been + * request type as UT_WRITE_CLASS_OTHER; it should have been * UT_WRITE_CLASS_INTERFACE. Many printers use the old one, * so we try both. */ - if (usbd_do_request(sc->sc_udev, &req, 0)) { + if (usbd_do_request(sc->sc_udev, &req, 0)) { /* 1.0 */ req.bmRequestType = UT_WRITE_CLASS_INTERFACE; - (void)usbd_do_request(sc->sc_udev, &req, 0); + (void)usbd_do_request(sc->sc_udev, &req, 0); /* 1.1 */ } } +static void +ulpt_input(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) +{ + struct ulpt_softc *sc = priv; + + DPRINTFN(2,("ulpt_input: got some data\n")); + /* Do it again. */ + if (xfer == sc->sc_in_xfer1) + usbd_transfer(sc->sc_in_xfer2); + else + usbd_transfer(sc->sc_in_xfer1); +} + +int ulptusein = 1; + /* * Reset the printer, then wait until it's selected and not busy. */ @@ -420,6 +502,7 @@ ulptopen(dev_t dev, int flag, int mode, struct proc *p) ulpt_reset(sc); for (spin = 0; (ulpt_status(sc) & LPS_SELECT) == 0; spin += STEP) { + DPRINTF(("ulpt_open: waiting a while\n")); if (spin >= TIMEOUT) { error = EBUSY; sc->sc_state = 0; @@ -440,12 +523,39 @@ ulptopen(dev_t dev, int flag, int mode, struct proc *p) } } - err = usbd_open_pipe(sc->sc_iface, sc->sc_bulk, 0, &sc->sc_bulkpipe); + err = usbd_open_pipe(sc->sc_iface, sc->sc_out, 0, &sc->sc_out_pipe); if (err) { sc->sc_state = 0; error = EIO; goto done; } + if (ulptusein && sc->sc_in != -1) { + DPRINTF(("ulpt_open: open input pipe\n")); + err = usbd_open_pipe(sc->sc_iface, sc->sc_in,0,&sc->sc_in_pipe); + if (err) { + error = EIO; + usbd_close_pipe(sc->sc_out_pipe); + sc->sc_out_pipe = NULL; + sc->sc_state = 0; + goto done; + } + sc->sc_in_xfer1 = usbd_alloc_xfer(sc->sc_udev); + sc->sc_in_xfer2 = usbd_alloc_xfer(sc->sc_udev); + if (sc->sc_in_xfer1 == NULL || sc->sc_in_xfer2 == NULL) { + error = ENOMEM; + usbd_close_pipe(sc->sc_out_pipe); + sc->sc_out_pipe = NULL; + sc->sc_state = 0; + goto done; + } + usbd_setup_xfer(sc->sc_in_xfer1, sc->sc_in_pipe, sc, + sc->sc_junk, sizeof sc->sc_junk, USBD_SHORT_XFER_OK, + USBD_NO_TIMEOUT, ulpt_input); + usbd_setup_xfer(sc->sc_in_xfer2, sc->sc_in_pipe, sc, + sc->sc_junk, sizeof sc->sc_junk, USBD_SHORT_XFER_OK, + USBD_NO_TIMEOUT, ulpt_input); + usbd_transfer(sc->sc_in_xfer1); /* ignore failed start */ + } sc->sc_state = ULPT_OPEN; @@ -487,8 +597,23 @@ ulptclose(dev_t dev, int flag, int mode, struct proc *p) /* We are being forced to close before the open completed. */ return (0); - usbd_close_pipe(sc->sc_bulkpipe); - sc->sc_bulkpipe = 0; + if (sc->sc_out_pipe != NULL) { + usbd_close_pipe(sc->sc_out_pipe); + sc->sc_out_pipe = NULL; + } + if (sc->sc_in_pipe != NULL) { + usbd_abort_pipe(sc->sc_in_pipe); + usbd_close_pipe(sc->sc_in_pipe); + sc->sc_in_pipe = NULL; + if (sc->sc_in_xfer1 != NULL) { + usbd_free_xfer(sc->sc_in_xfer1); + sc->sc_in_xfer1 = NULL; + } + if (sc->sc_in_xfer2 != NULL) { + usbd_free_xfer(sc->sc_in_xfer2); + sc->sc_in_xfer2 = NULL; + } + } sc->sc_state = 0; @@ -520,7 +645,7 @@ ulpt_do_write(struct ulpt_softc *sc, struct uio *uio, int flags) if (error) break; DPRINTFN(1, ("ulptwrite: transfer %d bytes\n", n)); - err = usbd_bulk_transfer(xfer, sc->sc_bulkpipe, USBD_NO_COPY, + err = usbd_bulk_transfer(xfer, sc->sc_out_pipe, USBD_NO_COPY, USBD_NO_TIMEOUT, bufp, &n, "ulptwr"); if (err) { DPRINTF(("ulptwrite: error=%d\n", err)); diff --git a/sys/dev/usb/umodem.c b/sys/dev/usb/umodem.c index 3340bf3765a..df2c0ade0c2 100644 --- a/sys/dev/usb/umodem.c +++ b/sys/dev/usb/umodem.c @@ -1,5 +1,5 @@ -/* $OpenBSD: umodem.c,v 1.6 2001/01/28 09:43:42 aaron Exp $ */ -/* $NetBSD: umodem.c,v 1.31 2000/10/22 08:20:09 explorer Exp $ */ +/* $OpenBSD: umodem.c,v 1.7 2001/05/03 02:20:34 aaron Exp $ */ +/* $NetBSD: umodem.c,v 1.40 2001/03/25 23:02:34 augustss Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -114,6 +114,12 @@ struct umodem_softc { u_char sc_opening; /* lock during open */ u_char sc_dying; /* disconnecting */ + + int sc_ctl_notify; /* Notification endpoint */ + usbd_pipe_handle sc_notify_pipe; /* Notification pipe */ + usb_cdc_notification_t sc_notify_buf; /* Notification structure */ + u_char sc_lsr; /* Local status register */ + u_char sc_msr; /* Modem status register */ }; Static void *umodem_get_desc(usbd_device_handle dev, int type, int subtype); @@ -132,14 +138,17 @@ Static void umodem_break(struct umodem_softc *, int); Static void umodem_set_line_state(struct umodem_softc *); Static int umodem_param(void *, int, struct termios *); Static int umodem_ioctl(void *, int, u_long, caddr_t, int, struct proc *); +Static int umodem_open(void *, int portno); +Static void umodem_close(void *, int portno); +Static void umodem_intr(usbd_xfer_handle, usbd_private_handle, usbd_status); Static struct ucom_methods umodem_methods = { umodem_get_status, umodem_set, umodem_param, umodem_ioctl, - NULL, - NULL, + umodem_open, + umodem_close, NULL, NULL, }; @@ -210,7 +219,6 @@ USB_ATTACH(umodem) sc->sc_cm_cap & USB_CDC_CM_OVER_DATA ? "" : "no ", sc->sc_acm_cap & USB_CDC_ACM_HAS_BREAK ? "" : "no "); - /* Get the data interface too. */ for (i = 0; i < uaa->nifaces; i++) { if (uaa->ifaces[i] != NULL) { @@ -277,6 +285,31 @@ USB_ATTACH(umodem) sc->sc_cm_over_data = 1; } } + + /* + * The standard allows for notification messages (to indicate things + * like a modem hangup) to come in via an interrupt endpoint + * off of the control interface. Iterate over the endpoints on + * the control interface and see if there are any interrupt + * endpoints; if there are, then register it. + */ + + sc->sc_ctl_notify = -1; + sc->sc_notify_pipe = NULL; + + for (i = 0; i < id->bNumEndpoints; i++) { + ed = usbd_interface2endpoint_descriptor(sc->sc_ctl_iface, i); + if (ed == NULL) + continue; + + if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && + (ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT) { + printf("%s: status change notification available\n", + USBDEVNAME(sc->sc_dev)); + sc->sc_ctl_notify = ed->bEndpointAddress; + } + } + sc->sc_dtr = -1; uca.portno = UCOM_UNK_PORTNO; @@ -289,13 +322,14 @@ USB_ATTACH(umodem) uca.iface = sc->sc_data_iface; uca.methods = &umodem_methods; uca.arg = sc; - - DPRINTF(("umodem_attach: sc=%p\n", sc)); - sc->sc_subdev = config_found_sm(self, &uca, ucomprint, ucomsubmatch); + uca.info = NULL; usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, USBDEV(sc->sc_dev)); + DPRINTF(("umodem_attach: sc=%p\n", sc)); + sc->sc_subdev = config_found_sm(self, &uca, ucomprint, ucomsubmatch); + USB_ATTACH_SUCCESS_RETURN; bad: @@ -303,6 +337,111 @@ USB_ATTACH(umodem) USB_ATTACH_ERROR_RETURN; } +Static int +umodem_open(void *addr, int portno) +{ + struct umodem_softc *sc = addr; + int err; + + DPRINTF(("umodem_open: sc=%p\n", sc)); + + if (sc->sc_ctl_notify != -1 && sc->sc_notify_pipe == NULL) { + err = usbd_open_pipe_intr(sc->sc_ctl_iface, sc->sc_ctl_notify, + USBD_SHORT_XFER_OK, &sc->sc_notify_pipe, sc, + &sc->sc_notify_buf, sizeof(sc->sc_notify_buf), + umodem_intr, USBD_DEFAULT_INTERVAL); + + if (err) { + DPRINTF(("Failed to establish notify pipe: %s\n", + usbd_errstr(err))); + return EIO; + } + } + + return 0; +} + +Static void +umodem_close(void *addr, int portno) +{ + struct umodem_softc *sc = addr; + int err; + + DPRINTF(("umodem_close: sc=%p\n", sc)); + + if (sc->sc_notify_pipe != NULL) { + err = usbd_abort_pipe(sc->sc_notify_pipe); + if (err) + printf("%s: abort notify pipe failed: %s\n", + USBDEVNAME(sc->sc_dev), usbd_errstr(err)); + err = usbd_close_pipe(sc->sc_notify_pipe); + if (err) + printf("%s: close notify pipe failed: %s\n", + USBDEVNAME(sc->sc_dev), usbd_errstr(err)); + sc->sc_notify_pipe = NULL; + } +} + +Static void +umodem_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) +{ + struct umodem_softc *sc = priv; + u_char mstatus; + + if (sc->sc_dying) + return; + + if (status != USBD_NORMAL_COMPLETION) { + if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) + return; + printf("%s: abnormal status: %s\n", USBDEVNAME(sc->sc_dev), + usbd_errstr(status)); + return; + } + + if (sc->sc_notify_buf.bmRequestType != UCDC_NOTIFICATION) { + DPRINTF(("%s: unknown message type (%02x) on notify pipe\n", + USBDEVNAME(sc->sc_dev), + sc->sc_notify_buf.bmRequestType)); + return; + } + + switch (sc->sc_notify_buf.bNotification) { + case UCDC_N_SERIAL_STATE: + /* + * Set the serial state in ucom driver based on + * the bits from the notify message + */ + if (UGETW(sc->sc_notify_buf.wLength) != 2) { + printf("%s: Invalid notification length! (%d)\n", + USBDEVNAME(sc->sc_dev), + UGETW(sc->sc_notify_buf.wLength)); + break; + } + DPRINTF(("%s: notify bytes = %02x%02x\n", + USBDEVNAME(sc->sc_dev), + sc->sc_notify_buf.data[0], + sc->sc_notify_buf.data[1])); + /* Currently, lsr is always zero. */ + sc->sc_lsr = sc->sc_msr = 0; + mstatus = sc->sc_notify_buf.data[0]; + + if (ISSET(mstatus, UCDC_N_SERIAL_RI)) + sc->sc_msr |= UMSR_RI; + if (ISSET(mstatus, UCDC_N_SERIAL_DSR)) + sc->sc_msr |= UMSR_DSR; + if (ISSET(mstatus, UCDC_N_SERIAL_DCD)) + sc->sc_msr |= UMSR_DCD; + ucom_status_change((struct ucom_softc *)sc->sc_subdev); + break; + default: + DPRINTF(("%s: unknown notify message: %02x\n", + USBDEVNAME(sc->sc_dev), + sc->sc_notify_buf.bNotification)); + break; + } +} + void umodem_get_caps(usbd_device_handle dev, int *cm, int *acm) { @@ -329,12 +468,14 @@ umodem_get_caps(usbd_device_handle dev, int *cm, int *acm) void umodem_get_status(void *addr, int portno, u_char *lsr, u_char *msr) { + struct umodem_softc *sc = addr; + DPRINTF(("umodem_get_status:\n")); if (lsr != NULL) - *lsr = 0; /* XXX */ + *lsr = sc->sc_lsr; if (msr != NULL) - *msr = 0; /* XXX */ + *msr = sc->sc_msr; } int diff --git a/sys/dev/usb/ums.c b/sys/dev/usb/ums.c index 634bc82ba7b..5215bd98300 100644 --- a/sys/dev/usb/ums.c +++ b/sys/dev/usb/ums.c @@ -1,5 +1,5 @@ -/* $OpenBSD: ums.c,v 1.4 2001/01/28 09:43:42 aaron Exp $ */ -/* $NetBSD: ums.c,v 1.45 2000/10/08 20:52:18 augustss Exp $ */ +/* $OpenBSD: ums.c,v 1.5 2001/05/03 02:20:34 aaron Exp $ */ +/* $NetBSD: ums.c,v 1.47 2001/01/23 14:04:14 augustss Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -306,11 +306,11 @@ USB_ATTACH(ums) a.accessops = &ums_accessops; a.accesscookie = sc; - sc->sc_wsmousedev = config_found(self, &a, wsmousedevprint); - usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, USBDEV(sc->sc_dev)); + sc->sc_wsmousedev = config_found(self, &a, wsmousedevprint); + USB_ATTACH_SUCCESS_RETURN; } diff --git a/sys/dev/usb/usb.c b/sys/dev/usb/usb.c index 0683597dfab..edfbef7a301 100644 --- a/sys/dev/usb/usb.c +++ b/sys/dev/usb/usb.c @@ -1,5 +1,5 @@ -/* $OpenBSD: usb.c,v 1.14 2001/01/28 09:43:42 aaron Exp $ */ -/* $NetBSD: usb.c,v 1.47 2000/08/24 14:12:34 augustss Exp $ */ +/* $OpenBSD: usb.c,v 1.15 2001/05/03 02:20:34 aaron Exp $ */ +/* $NetBSD: usb.c,v 1.53 2001/01/23 17:04:30 augustss Exp $ */ /* $FreeBSD: src/sys/dev/usb/usb.c,v 1.20 1999/11/17 22:33:46 n_hibma Exp $ */ /* @@ -49,16 +49,9 @@ #include <sys/systm.h> #include <sys/kernel.h> #include <sys/malloc.h> -#if defined(__NetBSD__) || defined(__OpenBSD__) #include <sys/device.h> #include <sys/kthread.h> #include <sys/proc.h> -#elif defined(__FreeBSD__) -#include <sys/module.h> -#include <sys/bus.h> -#include <sys/filio.h> -#include <sys/uio.h> -#endif #include <sys/conf.h> #include <sys/poll.h> #include <sys/select.h> @@ -71,14 +64,6 @@ #define USB_DEV_MINOR 255 -#if defined(__FreeBSD__) -MALLOC_DEFINE(M_USB, "USB", "USB"); -MALLOC_DEFINE(M_USBDEV, "USBdev", "USB device"); -MALLOC_DEFINE(M_USBHC, "USBHC", "USB host controller"); - -#include "usb_if.h" -#endif /* defined(__FreeBSD__) */ - #include <machine/bus.h> #include <dev/usb/usbdivar.h> @@ -110,44 +95,17 @@ struct usb_softc { usbd_bus_handle sc_bus; /* USB controller */ struct usbd_port sc_port; /* dummy port for root hub */ -#if defined(__FreeBSD__) - /* This part should be deleted when kthreads is available */ - struct selinfo sc_consel; /* waiting for connect change */ -#else + TAILQ_HEAD(, usb_task) sc_tasks; struct proc *sc_event_thread; -#endif + + struct usb_task sc_exp_task; char sc_dying; }; -#if defined(__NetBSD__) || defined(__OpenBSD__) cdev_decl(usb); -#elif defined(__FreeBSD__) -d_open_t usbopen; -d_close_t usbclose; -d_read_t usbread; -d_ioctl_t usbioctl; -int usbpoll(dev_t, int, struct proc *); - -struct cdevsw usb_cdevsw = { - /* open */ usbopen, - /* close */ usbclose, - /* read */ noread, - /* write */ nowrite, - /* ioctl */ usbioctl, - /* poll */ usbpoll, - /* mmap */ nommap, - /* strategy */ nostrategy, - /* name */ "usb", - /* maj */ USB_CDEV_MAJOR, - /* dump */ nodump, - /* psize */ nopsize, - /* flags */ 0, - /* bmaj */ -1 -}; -#endif -Static usbd_status usb_discover(struct usb_softc *); +Static void usb_discover(void *); Static void usb_create_event_thread(void *); Static void usb_event_thread(void *); @@ -178,28 +136,21 @@ USB_MATCH(usb) USB_ATTACH(usb) { -#if defined(__NetBSD__) || defined(__OpenBSD__) struct usb_softc *sc = (struct usb_softc *)self; -#elif defined(__FreeBSD__) - struct usb_softc *sc = device_get_softc(self); - void *aux = device_get_ivars(self); -#endif usbd_device_handle dev; usbd_status err; int usbrev; struct usb_event ue; -#if defined(__FreeBSD__) - printf("%s", USBDEVNAME(sc->sc_dev)); - sc->sc_dev = self; -#endif - DPRINTF(("usbd_attach\n")); usbd_init(); sc->sc_bus = aux; sc->sc_bus->usbctl = sc; sc->sc_port.power = USB_MAX_POWER; + TAILQ_INIT(&sc->sc_tasks); + + usb_init_task(&sc->sc_exp_task, usb_discover, sc); usbrev = sc->sc_bus->usbrev; printf(": USB revision %s", usbrev_str[usbrev]); @@ -247,11 +198,6 @@ USB_ATTACH(usb) config_pending_incr(); usb_kthread_create(usb_create_event_thread, sc); -#if defined(__FreeBSD__) - make_dev(&usb_cdevsw, device_get_unit(self), UID_ROOT, GID_OPERATOR, - 0644, "usb%d", device_get_unit(self)); -#endif - USB_ATTACH_SUCCESS_RETURN; } @@ -269,36 +215,73 @@ usb_create_event_thread(void *arg) } } +/* + * Add a task to be performed by the event thread. This function can be + * called from any context and the task will be executed in a process + * context ASAP. + */ +void +usb_add_task(usbd_device_handle dev, struct usb_task *task) +{ + struct usb_softc *sc = dev->bus->usbctl; + int s; + + s = splusb(); + if (!task->onqueue) { + DPRINTFN(2,("usb_add_task: sc=%p task=%p\n", sc, task)); + TAILQ_INSERT_TAIL(&sc->sc_tasks, task, next); + task->onqueue = 1; + } else + DPRINTFN(3,("usb_add_task: sc=%p task=%p on q\n", sc, task)); + wakeup(&sc->sc_tasks); + splx(s); +} + +void +usb_rem_task(usbd_device_handle dev, struct usb_task *task) +{ + struct usb_softc *sc = dev->bus->usbctl; + int s; + + s = splusb(); + if (task->onqueue) { + TAILQ_REMOVE(&sc->sc_tasks, task, next); + task->onqueue = 0; + } + splx(s); +} + void usb_event_thread(void *arg) { struct usb_softc *sc = arg; - int first = 1; + struct usb_task *task; + int s; DPRINTF(("usb_event_thread: start\n")); /* Make sure first discover does something. */ sc->sc_bus->needs_explore = 1; + usb_discover(sc); + config_pending_decr(); while (!sc->sc_dying) { -#ifdef USB_DEBUG - if (usb_noexplore < 2) -#endif - usb_discover(sc); - if (first) { - config_pending_decr(); - first = 0; + s = splusb(); + task = TAILQ_FIRST(&sc->sc_tasks); + if (task == NULL) { + tsleep(&sc->sc_tasks, PWAIT, "usbevt", 0); + task = TAILQ_FIRST(&sc->sc_tasks); } -#ifdef USB_DEBUG - (void)tsleep(&sc->sc_bus->needs_explore, PWAIT, "usbevt", - usb_noexplore ? 0 : hz * 60); -#else - (void)tsleep(&sc->sc_bus->needs_explore, PWAIT, "usbevt", - hz * 60); -#endif - DPRINTFN(2,("usb_event_thread: woke up\n")); + DPRINTFN(2,("usb_event_thread: woke up task=%p\n", task)); + if (task != NULL && !sc->sc_dying) { + TAILQ_REMOVE(&sc->sc_tasks, task, next); + task->onqueue = 0; + splx(s); + task->fun(task->arg); + } else + splx(s); } - sc->sc_event_thread = 0; + sc->sc_event_thread = NULL; /* In case parent is waiting for us to exit. */ wakeup(sc); @@ -416,12 +399,6 @@ usbioctl(dev_t devt, u_long cmd, caddr_t data, int flag, struct proc *p) return (EIO); switch (cmd) { -#if defined(__FreeBSD__) - /* This part should be deleted when kthreads is available */ - case USB_DISCOVER: - usb_discover(sc); - break; -#endif #ifdef USB_DEBUG case USB_SETDEBUG: usbdebug = ((*(int *)data) & 0x000000ff); @@ -531,73 +508,38 @@ usbpoll(dev_t dev, int events, struct proc *p) return (revents); } else { -#if defined(__FreeBSD__) - /* This part should be deleted when kthreads is available */ - struct usb_softc *sc; - int unit = minor(dev); - - USB_GET_SC(usb, unit, sc); - - revents = 0; - mask = POLLOUT | POLLRDNORM; - - s = splusb(); - if (events & mask && sc->sc_bus->needs_explore) - revents |= events & mask; - if (revents == 0 && events & mask) - selrecord(p, &sc->sc_consel); - splx(s); - - return (revents); -#else return (ENXIO); -#endif } } /* Explore device tree from the root. */ -usbd_status -usb_discover(struct usb_softc *sc) +Static void +usb_discover(void *v) { -#if defined(__FreeBSD__) - /* The splxxx parts should be deleted when kthreads is available */ - int s; -#endif + struct usb_softc *sc = v; + DPRINTFN(2,("usb_discover\n")); +#ifdef USB_DEBUG + if (usb_noexplore > 1) + return; +#endif /* * We need mutual exclusion while traversing the device tree, * but this is guaranteed since this function is only called * from the event thread for the controller. */ -#if defined(__FreeBSD__) - s = splusb(); -#endif while (sc->sc_bus->needs_explore && !sc->sc_dying) { sc->sc_bus->needs_explore = 0; -#if defined(__FreeBSD__) - splx(s); -#endif sc->sc_bus->root_hub->hub->explore(sc->sc_bus->root_hub); -#if defined(__FreeBSD__) - s = splusb(); -#endif } -#if defined(__FreeBSD__) - splx(s); -#endif - - return (USBD_NORMAL_COMPLETION); } void -usb_needs_explore(usbd_bus_handle bus) +usb_needs_explore(usbd_device_handle dev) { - bus->needs_explore = 1; -#if defined(__FreeBSD__) - /* This part should be deleted when kthreads is available */ - selwakeup(&bus->usbctl->sc_consel); -#endif - wakeup(&bus->needs_explore); + DPRINTFN(2,("usb_needs_explore\n")); + dev->bus->needs_explore = 1; + usb_add_task(dev, &dev->bus->usbctl->sc_exp_task); } /* Called at splusb() */ @@ -670,7 +612,6 @@ usb_schedsoftintr(struct usbd_bus *bus) bus->methods->soft_intr(bus); } -#if defined(__NetBSD__) || defined(__OpenBSD__) int usb_activate(device_ptr_t self, enum devact act) { @@ -710,7 +651,7 @@ usb_detach(device_ptr_t self, int flags) /* Kill off event thread. */ if (sc->sc_event_thread) { - wakeup(&sc->sc_bus->needs_explore); + wakeup(&sc->sc_tasks); if (tsleep(sc, PWAIT, "usbdet", hz * 60)) printf("%s: event thread didn't die\n", USBDEVNAME(sc->sc_dev)); @@ -724,18 +665,3 @@ usb_detach(device_ptr_t self, int flags) return (0); } -#elif defined(__FreeBSD__) -int -usb_detach(device_t self) -{ - DPRINTF(("%s: unload, prevented\n", USBDEVNAME(self))); - - return (EINVAL); -} -#endif - - -#if defined(__FreeBSD__) -DRIVER_MODULE(usb, ohci, usb_driver, usb_devclass, 0, 0); -DRIVER_MODULE(usb, uhci, usb_driver, usb_devclass, 0, 0); -#endif diff --git a/sys/dev/usb/usb_port.h b/sys/dev/usb/usb_port.h index f5a93fcee9b..339f1341b08 100644 --- a/sys/dev/usb/usb_port.h +++ b/sys/dev/usb/usb_port.h @@ -1,5 +1,5 @@ -/* $OpenBSD: usb_port.h,v 1.24 2001/02/03 07:46:11 mickey Exp $ */ -/* $NetBSD: usb_port.h,v 1.35 2000/09/23 04:32:23 augustss Exp $ */ +/* $OpenBSD: usb_port.h,v 1.25 2001/05/03 02:20:34 aaron Exp $ */ +/* $NetBSD: usb_port.h,v 1.42 2001/03/28 19:00:39 ichiro Exp $ */ /* $FreeBSD: src/sys/dev/usb/usb_port.h,v 1.21 1999/11/17 22:33:47 n_hibma Exp $ */ /* @@ -60,12 +60,15 @@ #define UHUB_DEBUG 1 #define ULPT_DEBUG 1 #define UCOM_DEBUG 1 +#define UPLCOM_DEBUG 1 +#define UMCT_DEBUG 1 #define UMODEM_DEBUG 1 #define UAUDIO_DEBUG 1 #define AUE_DEBUG 1 #define CUE_DEBUG 1 #define KUE_DEBUG 1 #define UMASS_DEBUG 1 +#define UVISOR_DEBUG 1 #define UPL_DEBUG 1 #define UZCOM_DEBUG 1 #define URIO_DEBUG 1 diff --git a/sys/dev/usb/usb_quirks.c b/sys/dev/usb/usb_quirks.c index 2c7be8676f6..f2f599d5478 100644 --- a/sys/dev/usb/usb_quirks.c +++ b/sys/dev/usb/usb_quirks.c @@ -1,5 +1,5 @@ -/* $OpenBSD: usb_quirks.c,v 1.8 2001/01/28 09:43:42 aaron Exp $ */ -/* $NetBSD: usb_quirks.c,v 1.31 2000/10/24 14:57:35 augustss Exp $ */ +/* $OpenBSD: usb_quirks.c,v 1.9 2001/05/03 02:20:34 aaron Exp $ */ +/* $NetBSD: usb_quirks.c,v 1.38 2001/04/15 10:26:36 augustss Exp $ */ /* $FreeBSD: src/sys/dev/usb/usb_quirks.c,v 1.13 1999/11/17 22:33:47 n_hibma Exp $ */ /* @@ -51,6 +51,8 @@ extern int usbdebug; #endif +#define ANY 0xffff + Static const struct usbd_quirk_entry { u_int16_t idVendor; u_int16_t idProduct; @@ -80,6 +82,15 @@ Static const struct usbd_quirk_entry { { USB_VENDOR_TELEX, USB_PRODUCT_TELEX_MIC1, 0x009, { UQ_AU_NO_FRAC }}, { USB_VENDOR_SILICONPORTALS, USB_PRODUCT_SILICONPORTALS_YAPPHONE, 0x100, { UQ_AU_INP_ASYNC }}, + /* XXX These should have a revision number, but I don't know what they are. */ +#ifdef notyet + { USB_VENDOR_HP, USB_PRODUCT_HP_895C, ANY, { UQ_BROKEN_BIDIR }}, + { USB_VENDOR_HP, USB_PRODUCT_HP_880C, ANY, { UQ_BROKEN_BIDIR }}, + { USB_VENDOR_HP, USB_PRODUCT_HP_815C, ANY, { UQ_BROKEN_BIDIR }}, + { USB_VENDOR_HP, USB_PRODUCT_HP_810C, ANY, { UQ_BROKEN_BIDIR }}, + { USB_VENDOR_HP, USB_PRODUCT_HP_830C, ANY, { UQ_BROKEN_BIDIR }}, +#endif + { 0, 0, 0, { 0 } } }; @@ -89,11 +100,14 @@ const struct usbd_quirks * usbd_find_quirk(usb_device_descriptor_t *d) { const struct usbd_quirk_entry *t; + u_int16_t vendor = UGETW(d->idVendor); + u_int16_t product = UGETW(d->idProduct); + u_int16_t revision = UGETW(d->bcdDevice); for (t = usb_quirks; t->idVendor != 0; t++) { - if (t->idVendor == UGETW(d->idVendor) && - t->idProduct == UGETW(d->idProduct) && - t->bcdDevice == UGETW(d->bcdDevice)) + if (t->idVendor == vendor && + t->idProduct == product && + (t->bcdDevice == ANY || t->bcdDevice == revision)) break; } #ifdef USB_DEBUG diff --git a/sys/dev/usb/usb_quirks.h b/sys/dev/usb/usb_quirks.h index 7b757073082..7e347bf5779 100644 --- a/sys/dev/usb/usb_quirks.h +++ b/sys/dev/usb/usb_quirks.h @@ -1,5 +1,5 @@ -/* $OpenBSD: usb_quirks.h,v 1.7 2001/01/28 09:43:42 aaron Exp $ */ -/* $NetBSD: usb_quirks.h,v 1.15 2000/10/24 14:56:09 augustss Exp $ */ +/* $OpenBSD: usb_quirks.h,v 1.8 2001/05/03 02:20:34 aaron Exp $ */ +/* $NetBSD: usb_quirks.h,v 1.20 2001/04/15 09:38:01 augustss Exp $ */ /* $FreeBSD: src/sys/dev/usb/usb_quirks.h,v 1.9 1999/11/12 23:31:03 n_hibma Exp $ */ /* @@ -54,6 +54,7 @@ struct usbd_quirks { #define UQ_AU_NO_FRAC 0x0400 /* don't adjust for fractional samples */ #define UQ_AU_INP_ASYNC 0x0800 /* input is async despite claim of adaptive */ #define UQ_ASSUME_CM_OVER_DATA 0x1000 /* modem device breaks on cm over data */ +#define UQ_BROKEN_BIDIR 0x2000 /* printer has broken bidir mode */ }; extern const struct usbd_quirks usbd_no_quirk; diff --git a/sys/dev/usb/usbcdc.h b/sys/dev/usb/usbcdc.h index 1b877d2ea6b..5efb316796c 100644 --- a/sys/dev/usb/usbcdc.h +++ b/sys/dev/usb/usbcdc.h @@ -1,5 +1,5 @@ -/* $OpenBSD: usbcdc.h,v 1.4 2000/11/08 18:10:39 aaron Exp $ */ -/* $NetBSD: usbcdc.h,v 1.7 2000/05/30 10:10:18 augustss Exp $ */ +/* $OpenBSD: usbcdc.h,v 1.5 2001/05/03 02:20:34 aaron Exp $ */ +/* $NetBSD: usbcdc.h,v 1.8 2001/02/16 20:15:57 kenh Exp $ */ /* $FreeBSD: src/sys/dev/usb/usbcdc.h,v 1.7 1999/11/17 22:33:48 n_hibma Exp $ */ /* @@ -147,4 +147,16 @@ typedef struct { } UPACKED usb_cdc_notification_t; #define UCDC_NOTIFICATION_LENGTH 8 +/* + * Bits set in the SERIAL STATE notifcation (first byte of data) + */ + +#define UCDC_N_SERIAL_OVERRUN 0x40 +#define UCDC_N_SERIAL_PARITY 0x20 +#define UCDC_N_SERIAL_FRAMING 0x10 +#define UCDC_N_SERIAL_RI 0x08 +#define UCDC_N_SERIAL_BREAK 0x04 +#define UCDC_N_SERIAL_DSR 0x02 +#define UCDC_N_SERIAL_DCD 0x01 + #endif /* _USBCDC_H_ */ diff --git a/sys/dev/usb/usbdi.c b/sys/dev/usb/usbdi.c index d1392fa8bc8..8aa3f46afd3 100644 --- a/sys/dev/usb/usbdi.c +++ b/sys/dev/usb/usbdi.c @@ -1,5 +1,5 @@ -/* $OpenBSD: usbdi.c,v 1.13 2001/01/28 09:43:42 aaron Exp $ */ -/* $NetBSD: usbdi.c,v 1.77 2000/09/23 21:02:04 augustss Exp $ */ +/* $OpenBSD: usbdi.c,v 1.14 2001/05/03 02:20:34 aaron Exp $ */ +/* $NetBSD: usbdi.c,v 1.81 2001/04/17 00:05:33 augustss Exp $ */ /* $FreeBSD: src/sys/dev/usb/usbdi.c,v 1.28 1999/11/17 22:33:49 n_hibma Exp $ */ /* @@ -295,25 +295,7 @@ usbd_transfer(usbd_xfer_handle xfer) if (!xfer->done) { if (pipe->device->bus->use_polling) panic("usbd_transfer: not done\n"); - /* XXX Temporary hack XXX */ - if (xfer->flags & USBD_NO_TSLEEP) { - int i; - usbd_bus_handle bus = pipe->device->bus; - int to = xfer->timeout * 1000; - for (i = 0; i < to; i += 10) { - delay(10); - bus->methods->do_poll(bus); - if (xfer->done) - break; - } - /* XXX Is this right, what about the HC timeout? */ - if (!xfer->done) { - pipe->methods->abort(xfer); - xfer->status = USBD_TIMEOUT; - } - } else - /* XXX End hack XXX */ - tsleep(xfer, PRIBIO, "usbsyn", 0); + tsleep(xfer, PRIBIO, "usbsyn", 0); } splx(s); return (xfer->status); @@ -1015,6 +997,12 @@ usbd_do_request_async(usbd_device_handle dev, usb_device_request_t *req, const struct usbd_quirks * usbd_get_quirks(usbd_device_handle dev) { +#ifdef DIAGNOSTIC + if (dev == NULL) { + printf("usbd_get_quirks: dev == NULL\n"); + return 0; + } +#endif return (dev->quirks); } diff --git a/sys/dev/usb/usbdi.h b/sys/dev/usb/usbdi.h index 56767898592..9d28cff2e8b 100644 --- a/sys/dev/usb/usbdi.h +++ b/sys/dev/usb/usbdi.h @@ -1,5 +1,5 @@ -/* $OpenBSD: usbdi.h,v 1.11 2001/01/28 09:43:43 aaron Exp $ */ -/* $NetBSD: usbdi.h,v 1.44 2000/09/23 21:02:04 augustss Exp $ */ +/* $OpenBSD: usbdi.h,v 1.12 2001/05/03 02:20:34 aaron Exp $ */ +/* $NetBSD: usbdi.h,v 1.52 2001/05/01 16:43:44 lukem Exp $ */ /* $FreeBSD: src/sys/dev/usb/usbdi.h,v 1.18 1999/11/17 22:33:49 n_hibma Exp $ */ /* @@ -68,7 +68,7 @@ typedef enum { /* keep in sync with usbd_status_msgs */ USBD_STALLED, USBD_INTERRUPTED, - USBD_ERROR_MAX, /* must be last */ + USBD_ERROR_MAX /* must be last */ } usbd_status; typedef void (*usbd_callback)(usbd_xfer_handle, usbd_private_handle, @@ -86,9 +86,6 @@ typedef void (*usbd_callback)(usbd_xfer_handle, usbd_private_handle, /* in usb.h #define USBD_SHORT_XFER_OK 0x04*/ /* allow short reads */ #define USBD_FORCE_SHORT_XFER 0x08 /* force last short packet on write */ -/* XXX Temporary hack XXX */ -#define USBD_NO_TSLEEP 0x80 /* XXX use busy wait */ - #define USBD_NO_TIMEOUT 0 #define USBD_DEFAULT_TIMEOUT 5000 /* ms = 5 s */ @@ -179,6 +176,23 @@ usbd_status usbd_reload_device_desc(usbd_device_handle); int usbd_ratecheck(struct timeval *last); +/* + * The usb_task structs form a queue of things to run in the USB event + * thread. Normally this is just device discovery when a connect/disconnect + * has been detected. But it may also be used by drivers that need to + * perform (short) tasks that must have a process context. + */ +struct usb_task { + TAILQ_ENTRY(usb_task) next; + void (*fun)(void *); + void *arg; + char onqueue; +}; + +void usb_add_task(usbd_device_handle dev, struct usb_task *task); +void usb_rem_task(usbd_device_handle dev, struct usb_task *task); +#define usb_init_task(t, f, a) ((t)->fun = (f), (t)->arg = (a), (t)->onqueue = 0) + /* NetBSD attachment information */ /* Attach data */ diff --git a/sys/dev/usb/usbdivar.h b/sys/dev/usb/usbdivar.h index 524ba05ab1c..dcd3a6bc1df 100644 --- a/sys/dev/usb/usbdivar.h +++ b/sys/dev/usb/usbdivar.h @@ -1,5 +1,5 @@ -/* $OpenBSD: usbdivar.h,v 1.12 2001/01/28 09:43:43 aaron Exp $ */ -/* $NetBSD: usbdivar.h,v 1.60 2000/12/28 10:40:36 augustss Exp $ */ +/* $OpenBSD: usbdivar.h,v 1.13 2001/05/03 02:20:34 aaron Exp $ */ +/* $NetBSD: usbdivar.h,v 1.63 2001/01/21 19:00:06 augustss Exp $ */ /* $FreeBSD: src/sys/dev/usb/usbdivar.h,v 1.11 1999/11/17 22:33:51 n_hibma Exp $ */ /* @@ -241,7 +241,7 @@ void usb_transfer_complete(usbd_xfer_handle xfer); void usb_disconnect_port(struct usbd_port *up, device_ptr_t); /* Routines from usb.c */ -void usb_needs_explore(usbd_bus_handle); +void usb_needs_explore(usbd_device_handle); void usb_schedsoftintr(struct usbd_bus *); /* diff --git a/sys/dev/usb/uscanner.c b/sys/dev/usb/uscanner.c index fb5de01ddd4..d79802aba41 100644 --- a/sys/dev/usb/uscanner.c +++ b/sys/dev/usb/uscanner.c @@ -1,5 +1,5 @@ -/* $OpenBSD: uscanner.c,v 1.2 2001/01/28 09:43:43 aaron Exp $ */ -/* $NetBSD: uscanner.c,v 1.11 2001/01/07 14:46:32 augustss Exp $ */ +/* $OpenBSD: uscanner.c,v 1.3 2001/05/03 02:20:34 aaron Exp $ */ +/* $NetBSD: uscanner.c,v 1.12 2001/01/23 14:04:14 augustss Exp $ */ /* $FreeBSD$ */ /* @@ -320,6 +320,9 @@ USB_ATTACH(uscanner) UID_ROOT, GID_OPERATOR, 0644, "%s", USBDEVNAME(sc->sc_dev)); #endif + usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, + USBDEV(sc->sc_dev)); + USB_ATTACH_SUCCESS_RETURN; } @@ -634,6 +637,9 @@ USB_DETACH(uscanner) destroy_dev(dev); #endif + usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, + USBDEV(sc->sc_dev)); + return (0); } diff --git a/sys/dev/usb/usscanner.c b/sys/dev/usb/usscanner.c index 55c578fd5c1..68c1b7921f5 100644 --- a/sys/dev/usb/usscanner.c +++ b/sys/dev/usb/usscanner.c @@ -1,5 +1,5 @@ -/* $OpenBSD: usscanner.c,v 1.2 2001/02/20 13:43:29 ho Exp $ */ -/* $NetBSD$ */ +/* $OpenBSD: usscanner.c,v 1.3 2001/05/03 02:20:35 aaron Exp $ */ +/* $NetBSD: usscanner.c,v 1.6 2001/01/23 14:04:14 augustss Exp $ */ /* * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -349,11 +349,11 @@ USB_ATTACH(usscanner) sc->sc_child = config_found(&sc->sc_dev, &sc->sc_link, scsiprint); - DPRINTFN(10, ("usscanner_attach: %p\n", sc->sc_udev)); - usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, USBDEV(sc->sc_dev)); + DPRINTFN(10, ("usscanner_attach: %p\n", sc->sc_udev)); + USB_ATTACH_SUCCESS_RETURN; } diff --git a/sys/dev/usb/uvisor.c b/sys/dev/usb/uvisor.c index 7fb1480f26e..a0a45c54ddd 100644 --- a/sys/dev/usb/uvisor.c +++ b/sys/dev/usb/uvisor.c @@ -1,5 +1,5 @@ -/* $OpenBSD: uvisor.c,v 1.2 2000/11/08 18:10:39 aaron Exp $ */ -/* $NetBSD: uvisor.c,v 1.8 2000/09/03 19:15:45 augustss Exp $ */ +/* $OpenBSD: uvisor.c,v 1.3 2001/05/03 02:20:35 aaron Exp $ */ +/* $NetBSD: uvisor.c,v 1.11 2001/01/23 21:56:17 augustss Exp $ */ /* * Copyright (c) 2000 The NetBSD Foundation, Inc. @@ -94,20 +94,17 @@ int uvisordebug = 0; /* * UVISOR_GET_CONNECTION_INFORMATION returns data in the following format */ +#define UVISOR_MAX_CONN 8 struct uvisor_connection_info { uWord num_ports; struct { uByte port_function_id; uByte port; - } connections[8]; + } connections[UVISOR_MAX_CONN]; }; #define UVISOR_CONNECTION_INFO_SIZE 18 -/* struct uvisor_connection_info.connection[x].port defines: */ -#define UVISOR_ENDPOINT_1 0x01 -#define UVISOR_ENDPOINT_2 0x02 - /* struct uvisor_connection_info.connection[x].port_function_id defines: */ #define UVISOR_FUNCTION_GENERIC 0x00 #define UVISOR_FUNCTION_DEBUGGER 0x01 @@ -124,12 +121,14 @@ struct uvisor_softc { usbd_device_handle sc_udev; /* device */ usbd_interface_handle sc_iface; /* interface */ - device_ptr_t sc_subdev; + device_ptr_t sc_subdevs[UVISOR_MAX_CONN]; + int sc_numcon; u_char sc_dying; }; -Static usbd_status uvisor_init(struct uvisor_softc *); +Static usbd_status uvisor_init(struct uvisor_softc *, + struct uvisor_connection_info *); Static void uvisor_close(void *, int); @@ -170,10 +169,11 @@ USB_ATTACH(uvisor) usbd_device_handle dev = uaa->device; usbd_interface_handle iface; usb_interface_descriptor_t *id; + struct uvisor_connection_info coninfo; usb_endpoint_descriptor_t *ed; char devinfo[1024]; char *devname = USBDEVNAME(sc->sc_dev); - int i; + int i, j, hasin, hasout, port; usbd_status err; struct ucom_attach_args uca; @@ -203,41 +203,6 @@ USB_ATTACH(uvisor) sc->sc_udev = dev; sc->sc_iface = iface; - uca.bulkin = uca.bulkout = -1; - for (i = 0; i < id->bNumEndpoints; i++) { - int addr, dir, attr; - ed = usbd_interface2endpoint_descriptor(iface, i); - if (ed == NULL) { - printf("%s: could not read endpoint descriptor" - ": %s\n", devname, usbd_errstr(err)); - goto bad; - } - - addr = ed->bEndpointAddress; - dir = UE_GET_DIR(ed->bEndpointAddress); - attr = ed->bmAttributes & UE_XFERTYPE; - if (dir == UE_DIR_IN && attr == UE_BULK) - uca.bulkin = addr; - else if (dir == UE_DIR_OUT && attr == UE_BULK) - uca.bulkout = addr; - else { - printf("%s: unexpected endpoint\n", devname); - goto bad; - } - } - if (uca.bulkin == -1) { - printf("%s: Could not find data bulk in\n", - USBDEVNAME(sc->sc_dev)); - goto bad; - } - if (uca.bulkout == -1) { - printf("%s: Could not find data bulk out\n", - USBDEVNAME(sc->sc_dev)); - goto bad; - } - - uca.portno = UCOM_UNK_PORTNO; - /* bulkin, bulkout set above */ uca.ibufsize = UVISORIBUFSIZE; uca.obufsize = UVISOROBUFSIZE; uca.ibufsizepad = UVISORIBUFSIZE; @@ -247,15 +212,64 @@ USB_ATTACH(uvisor) uca.methods = &uvisor_methods; uca.arg = sc; - err = uvisor_init(sc); + err = uvisor_init(sc, &coninfo); if (err) { printf("%s: init failed, %s\n", USBDEVNAME(sc->sc_dev), usbd_errstr(err)); goto bad; } - DPRINTF(("uvisor: in=0x%x out=0x%x\n", uca.bulkin, uca.bulkout)); - sc->sc_subdev = config_found_sm(self, &uca, ucomprint, ucomsubmatch); + usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, + USBDEV(sc->sc_dev)); + + sc->sc_numcon = UGETW(coninfo.num_ports); + if (sc->sc_numcon > UVISOR_MAX_CONN) + sc->sc_numcon = UVISOR_MAX_CONN; + + /* Attach a ucom for each connection. */ + for (i = 0; i < sc->sc_numcon; ++i) { + switch (coninfo.connections[i].port_function_id) { + case UVISOR_FUNCTION_GENERIC: + uca.info = "Generic"; + break; + case UVISOR_FUNCTION_DEBUGGER: + uca.info = "Debugger"; + break; + case UVISOR_FUNCTION_HOTSYNC: + uca.info = "HotSync"; + break; + case UVISOR_FUNCTION_REMOTE_FILE_SYS: + uca.info = "Remote File System"; + break; + default: + uca.info = "unknown"; + break; + } + port = coninfo.connections[i].port; + uca.portno = port; + uca.bulkin = port | UE_DIR_IN; + uca.bulkout = port | UE_DIR_OUT; + /* Verify that endpoints exist. */ + for (hasin = hasout = j = 0; j < id->bNumEndpoints; j++) { + ed = usbd_interface2endpoint_descriptor(iface, j); + if (ed == NULL) + break; + if (UE_GET_ADDR(ed->bEndpointAddress) == port && + (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) { + if (UE_GET_DIR(ed->bEndpointAddress) + == UE_DIR_IN) + hasin++; + else + hasout++; + } + } + if (hasin == 1 && hasout == 1) + sc->sc_subdevs[i] = config_found_sm(self, &uca, + ucomprint, ucomsubmatch); + else + printf("%s: no proper endpoints for port %d (%d,%d)\n", + USBDEVNAME(sc->sc_dev), port, hasin, hasout); + } USB_ATTACH_SUCCESS_RETURN; @@ -270,6 +284,7 @@ uvisor_activate(device_ptr_t self, enum devact act) { struct uvisor_softc *sc = (struct uvisor_softc *)self; int rv = 0; + int i; switch (act) { case DVACT_ACTIVATE: @@ -277,8 +292,9 @@ uvisor_activate(device_ptr_t self, enum devact act) break; case DVACT_DEACTIVATE: - if (sc->sc_subdev != NULL) - rv = config_deactivate(sc->sc_subdev); + for (i = 0; i < sc->sc_numcon; i++) + if (sc->sc_subdevs[i] != NULL) + rv = config_deactivate(sc->sc_subdevs[i]); sc->sc_dying = 1; break; } @@ -290,22 +306,28 @@ uvisor_detach(device_ptr_t self, int flags) { struct uvisor_softc *sc = (struct uvisor_softc *)self; int rv = 0; + int i; DPRINTF(("uvisor_detach: sc=%p flags=%d\n", sc, flags)); sc->sc_dying = 1; - if (sc->sc_subdev != NULL) { - rv = config_detach(sc->sc_subdev, flags); - sc->sc_subdev = NULL; + for (i = 0; i < sc->sc_numcon; i++) { + if (sc->sc_subdevs[i] != NULL) { + rv |= config_detach(sc->sc_subdevs[i], flags); + sc->sc_subdevs[i] = NULL; + } } - return (0); + + usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, + USBDEV(sc->sc_dev)); + + return (rv); } usbd_status -uvisor_init(struct uvisor_softc *sc) +uvisor_init(struct uvisor_softc *sc, struct uvisor_connection_info *ci) { usbd_status err; usb_device_request_t req; - struct uvisor_connection_info coninfo; int actlen; uWord avail; @@ -315,43 +337,11 @@ uvisor_init(struct uvisor_softc *sc) USETW(req.wValue, 0); USETW(req.wIndex, 0); USETW(req.wLength, UVISOR_CONNECTION_INFO_SIZE); - err = usbd_do_request_flags(sc->sc_udev, &req, &coninfo, + err = usbd_do_request_flags(sc->sc_udev, &req, ci, USBD_SHORT_XFER_OK, &actlen); if (err) return (err); -#ifdef UVISOR_DEBUG - { - int i, np; - char *string; - - np = UGETW(coninfo.num_ports); - printf("%s: Number of ports: %d\n", USBDEVNAME(sc->sc_dev), np); - for (i = 0; i < np; ++i) { - switch (coninfo.connections[i].port_function_id) { - case UVISOR_FUNCTION_GENERIC: - string = "Generic"; - break; - case UVISOR_FUNCTION_DEBUGGER: - string = "Debugger"; - break; - case UVISOR_FUNCTION_HOTSYNC: - string = "HotSync"; - break; - case UVISOR_FUNCTION_REMOTE_FILE_SYS: - string = "Remote File System"; - break; - default: - string = "unknown"; - break; - } - printf("%s: port %d, is for %s\n", - USBDEVNAME(sc->sc_dev), coninfo.connections[i].port, - string); - } - } -#endif - DPRINTF(("uvisor_init: getting available bytes\n")); req.bmRequestType = UT_READ_VENDOR_ENDPOINT; req.bRequest = UVISOR_REQUEST_BYTES_AVAILABLE; |