From: aaron Date: Tue, 28 Mar 2000 19:37:45 +0000 (+0000) Subject: Much cleaner sync with NetBSD. Some #if defined() magic has been sent in the X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=5deafb7594bc2d24e68201bcf855d5fd81782e73;p=openbsd Much cleaner sync with NetBSD. Some #if defined() magic has been sent in the form of a diff to augustss@netbsd.org so that future syncs will be very easy. This commit also adds support for ADMtek AN986 "Pegasus" based USB Ethernet, CATC USB-EL1210A based USB Ethernet, and USB Printers (all untested). --- diff --git a/sys/arch/i386/conf/GENERIC b/sys/arch/i386/conf/GENERIC index 430bcba190d..23aea71090a 100644 --- a/sys/arch/i386/conf/GENERIC +++ b/sys/arch/i386/conf/GENERIC @@ -1,4 +1,4 @@ -# $OpenBSD: GENERIC,v 1.165 2000/03/28 04:28:59 mickey Exp $ +# $OpenBSD: GENERIC,v 1.166 2000/03/28 19:37:45 aaron Exp $ # $NetBSD: GENERIC,v 1.48 1996/05/20 18:17:23 mrg Exp $ # # GENERIC -- everything that's currently supported @@ -79,10 +79,15 @@ pcmcia* at pcic? controller ? socket ? # USB Generic HID devices #uhid* at uhub? port ? configuration ? interface ? -# USB audio +# USB Printer +#ulpt* at uhub? port ? configuration ? interface ? + +# USB Audio #uaudio* at uhub? port ? configuration ? # USB Ethernet adapters +#aue* at uhub? port ? # ADMtek AN986 Pegasus based adapters +#cue* at uhub? port ? # CATC USB-EL1201A based adapters #kue* at uhub? port ? # Kawasaki KL5KUSB101B based adapters # USB Generic driver diff --git a/sys/dev/usb/FILES b/sys/dev/usb/FILES index 3b2f0790b9a..170b931889b 100644 --- a/sys/dev/usb/FILES +++ b/sys/dev/usb/FILES @@ -5,7 +5,7 @@ Makefile to install .h files Makefile.usbdevs to run devlist2h.awk TODO just a list of things to do devlist2h.awk script to generate usbdevs*.h -files.usb config inclued file +files.usb config include file hid.c subroutines to parse and access HID data hid.h API for hid.c ohci.c Host controller driver for OHCI @@ -23,6 +23,7 @@ ukbd.c USB keyboard driver ukbdmap.c wscons key mapping for ukbd ukbdvar.h API for ukbd.c ulpt.c USB printer class driver +umass.c USB mass storage driver (bulk only for now) umodem.c USB modem (CDC ACM) driver ums.c USB mouse driver usb.c usb (bus) device driver diff --git a/sys/dev/usb/TODO b/sys/dev/usb/TODO index 4d578b946dd..acc8feccf51 100644 --- a/sys/dev/usb/TODO +++ b/sys/dev/usb/TODO @@ -1,8 +1,14 @@ Some things that need to be done in no particular order: -------------------------------------------------------- -Find race condition in UHCI driver. Rarely (under heavy USB load) you get a -"uhci_idone: ii=0x%x is done!". This "cannot happen". +Before 1.5: +----------- + +Add isoc to OHCI driver. + +Port FreeBSD umass driver. + +----------- Add lots of bus_dmamap_sync(). @@ -28,11 +34,7 @@ Rotate the QHs for bulk transport to get fairer scheduling. Change HC drivers to queue multiple request for an endpoint to get better performance. -Add generic ucom layer for serial adapters. - -Add isoc to OHCI driver. - -Do memory deallocation when HC driver is deactivated. +Do memory deallocation when HC driver is detached. uaudio problems: mixer names are awful, use some heuristics. @@ -48,4 +50,15 @@ Document device driver API. Document HC driver API. -Handle CLEAR_ENPOINT_STALL centrally. +Handle CLEAR_ENDPOINT_STALL centrally. + +Use splsoftusb() or a thread to deliver callbacks. + +Add threads to the Ethernet drivers. + +Change what's done at watchdog timeout inb if_{a,c,k}ue.c; what we have +now doesn't work because it's done in an interrupt context. + +Rewrite HID driver to handle report IDs properly. Perhaps there should +be a hiddev to which hid with different IDs can attach? + diff --git a/sys/dev/usb/files.usb b/sys/dev/usb/files.usb index cf1d7ae6923..f6f0443b3c8 100644 --- a/sys/dev/usb/files.usb +++ b/sys/dev/usb/files.usb @@ -1,5 +1,5 @@ -# $OpenBSD: files.usb,v 1.6 2000/03/26 18:49:44 aaron Exp $ -# $NetBSD: files.usb,v 1.8 1999/06/30 06:44:22 augustss Exp $ +# $OpenBSD: files.usb,v 1.7 2000/03/28 19:37:46 aaron Exp $ +# $NetBSD: files.usb,v 1.16 2000/02/14 20:29:54 augustss Exp $ # # Config file and device description for machine-independent USB code. # Included by ports that need it. Ports that use it must provide @@ -38,42 +38,21 @@ device uhid attach uhid at uhub file dev/usb/uhid.c uhid needs-flag -# Keyboards -#device ukbd: wskbddev -#attach ukbd at uhub -#file dev/usb/ukbd.c ukbd needs-flag -#file dev/usb/ukbdmap.c ukbd - # Printers -#device ulpt -#attach ulpt at uhub -#file dev/usb/ulpt.c ulpt needs-flag - -# Mass storage -device umass: scsi -attach umass at uhub -file dev/usb/umass.c umass - -# Modems -device umodem -attach umodem at uhub -file dev/usb/umodem.c umodem needs-flag - -# Mice -#device ums: wsmousedev -#attach ums at uhub -#file dev/usb/ums.c ums needs-flag +device ulpt +attach ulpt at uhub +file dev/usb/ulpt.c ulpt needs-flag # Ethernet adapters # ADMtek AN986 Pegasus -#device aue: ether, ifnet, mii, ifmedia -#attach aue at uhub -#file dev/usb/if_aue.c aue +device aue: ether, ifnet, mii, ifmedia +attach aue at uhub +file dev/usb/if_aue.c aue # CATC USB-EL1201A -#device cue: ether, ifnet, ifmedia -#attach cue at uhub -#file dev/usb_if_cue.c cue +device cue: ether, ifnet, ifmedia +attach cue at uhub +file dev/usb/if_cue.c cue # Kawasaki LSI KL5KUSB101B device kue: ether, ifnet, ifmedia diff --git a/sys/dev/usb/hid.c b/sys/dev/usb/hid.c index 58db47c6ba5..207ead12211 100644 --- a/sys/dev/usb/hid.c +++ b/sys/dev/usb/hid.c @@ -1,5 +1,6 @@ -/* $OpenBSD: hid.c,v 1.4 2000/03/26 08:39:45 aaron Exp $ */ +/* $OpenBSD: hid.c,v 1.5 2000/03/28 19:37:46 aaron Exp $ */ /* $NetBSD: hid.c,v 1.12 2000/03/17 18:16:18 augustss Exp $ */ +/* $FreeBSD: src/sys/dev/usb/hid.c,v 1.11 1999/11/17 22:33:39 n_hibma Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -40,7 +41,7 @@ #include #include -#if defined(__NetBSD__) || defined(__OpenBSD__) +#if defined(__NetBSD__) #include #endif #include @@ -370,7 +371,7 @@ hid_get_item(s, h) } } -int +int hid_report_size(buf, len, k, idp) void *buf; int len; diff --git a/sys/dev/usb/hid.h b/sys/dev/usb/hid.h index 777500bde3d..bf12b0406b7 100644 --- a/sys/dev/usb/hid.h +++ b/sys/dev/usb/hid.h @@ -1,5 +1,6 @@ -/* $OpenBSD: hid.h,v 1.1 1999/08/13 05:28:03 fgsch Exp $ */ -/* $NetBSD: hid.h,v 1.3 1998/11/25 22:32:04 augustss Exp $ */ +/* $OpenBSD: hid.h,v 1.2 2000/03/28 19:37:46 aaron Exp $ */ +/* $NetBSD: hid.h,v 1.4 1999/11/18 23:32:26 augustss Exp $ */ +/* $FreeBSD: src/sys/dev/usb/hid.h,v 1.7 1999/11/17 22:33:40 n_hibma Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. diff --git a/sys/dev/usb/if_aue.c b/sys/dev/usb/if_aue.c new file mode 100644 index 00000000000..4ff18e9ec3c --- /dev/null +++ b/sys/dev/usb/if_aue.c @@ -0,0 +1,1933 @@ +/* $OpenBSD: if_aue.c,v 1.1 2000/03/28 19:37:47 aaron Exp $ */ +/* $NetBSD: if_aue.c,v 1.33 2000/03/24 22:03:28 augustss Exp $ */ +/* + * Copyright (c) 1997, 1998, 1999, 2000 + * Bill Paul . All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Bill Paul. + * 4. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD: src/sys/dev/usb/if_aue.c,v 1.11 2000/01/14 01:36:14 wpaul Exp $ + */ + +/* + * ADMtek AN986 Pegasus USB to ethernet driver. Datasheet is available + * from http://www.admtek.com.tw. + * + * Written by Bill Paul + * Electrical Engineering Department + * Columbia University, New York City + */ + +/* + * The Pegasus chip uses four USB "endpoints" to provide 10/100 ethernet + * support: the control endpoint for reading/writing registers, burst + * read endpoint for packet reception, burst write for packet transmission + * and one for "interrupts." The chip uses the same RX filter scheme + * as the other ADMtek ethernet parts: one perfect filter entry for the + * the station address and a 64-bit multicast hash table. The chip supports + * both MII and HomePNA attachments. + * + * Since the maximum data transfer speed of USB is supposed to be 12Mbps, + * you're never really going to get 100Mbps speeds from this device. I + * think the idea is to allow the device to connect to 10 or 100Mbps + * networks, not necessarily to provide 100Mbps performance. Also, since + * the controller uses an external PHY chip, it's possible that board + * designers might simply choose a 10Mbps PHY. + * + * Registers are accessed using usbd_do_request(). Packet transfers are + * done using usbd_transfer() and friends. + */ + +/* + * Ported to NetBSD and somewhat rewritten by Lennart Augustsson. + */ + +/* + * TODO: + * better error messages from rxstat + * split out if_auevar.h + * add thread to avoid register reads from interrupt context + * more error checks + * investigate short rx problem + * proper cleanup on errors + */ + +#if defined(__NetBSD__) +#include "opt_inet.h" +#include "opt_ns.h" +#include "bpfilter.h" +#include "rnd.h" +#elif defined(__OpenBSD__) +#include "bpfilter.h" +#endif + +#include +#include +#include +#include +#include +#include +#include + +#if defined(__FreeBSD__) + +#include +#include /* for DELAY */ +#include +/* "controller miibus0" required. See GENERIC if you get errors here. */ +#include "miibus_if.h" + +#elif defined(__NetBSD__) || defined(__OpenBSD__) + +#include +#if NRND > 0 +#include +#endif + +#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ + +#include +#if defined(__NetBSD__) || defined(__FreeBSD__) +#include +#endif +#include +#include + +#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 +#include +#endif + +#if defined(__NetBSD__) +#include +#ifdef INET +#include +#include +#endif +#endif /* defined(__NetBSD__) */ + +#if defined(__OpenBSD__) +#ifdef INET +#include +#include +#include +#include +#include +#endif +#endif /* defined(__OpenBSD__) */ + +#if defined(__NetBSD__) || defined(__OpenBSD__) +#ifdef NS +#include +#include +#endif +#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ + +#include +#include + +#include +#include +#include +#include + +#ifdef __FreeBSD__ +#include +#endif + +#include + +#ifdef AUE_DEBUG +#define DPRINTF(x) if (auedebug) logprintf x +#define DPRINTFN(n,x) if (auedebug >= (n)) logprintf x +int auedebug = 0; +#else +#define DPRINTF(x) +#define DPRINTFN(n,x) +#endif + +/* + * Various supported device vendors/products. + */ +static struct aue_type aue_devs[] = { + { USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USB100 }, + { USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUATX }, + { USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB100TX }, + { USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUS }, + { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX }, + { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX_PNA }, + { USB_VENDOR_SMC, USB_PRODUCT_SMC_2202USB }, + { USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB_TX }, + { USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBETTX }, + { 0, 0 } +}; + +USB_DECLARE_DRIVER(aue); + +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) + +#define AUE_SETBIT(sc, reg, x) \ + aue_csr_write_1(sc, reg, aue_csr_read_1(sc, reg) | (x)) + +#define AUE_CLRBIT(sc, reg, x) \ + 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; +{ + usb_device_request_t req; + usbd_status err; + uByte val = 0; + int s; + + if (sc->aue_dying) + return (0); + + req.bmRequestType = UT_READ_VENDOR_DEVICE; + req.bRequest = AUE_UR_READREG; + USETW(req.wValue, 0); + USETW(req.wIndex, reg); + USETW(req.wLength, 1); + + s = splusb(); + err = AUE_DO_REQUEST(sc->aue_udev, &req, &val); + splx(s); + + if (err) { + DPRINTF(("%s: aue_csr_read_1: reg=0x%x err=%s\n", + USBDEVNAME(sc->aue_dev), reg, usbd_errstr(err))); + return (0); + } + + return (val); +} + +static int +aue_csr_read_2(sc, reg) + struct aue_softc *sc; + int reg; +{ + usb_device_request_t req; + usbd_status err; + uWord val; + int s; + + if (sc->aue_dying) + return (0); + + req.bmRequestType = UT_READ_VENDOR_DEVICE; + req.bRequest = AUE_UR_READREG; + USETW(req.wValue, 0); + USETW(req.wIndex, reg); + USETW(req.wLength, 2); + + s = splusb(); + err = AUE_DO_REQUEST(sc->aue_udev, &req, &val); + splx(s); + + if (err) { + DPRINTF(("%s: aue_csr_read_2: reg=0x%x err=%s\n", + USBDEVNAME(sc->aue_dev), reg, usbd_errstr(err))); + return (0); + } + + return (UGETW(val)); +} + +static int +aue_csr_write_1(sc, reg, aval) + struct aue_softc *sc; + int reg, aval; +{ + usb_device_request_t req; + usbd_status err; + int s; + uByte val; + + if (sc->aue_dying) + return (0); + + val = aval; + req.bmRequestType = UT_WRITE_VENDOR_DEVICE; + req.bRequest = AUE_UR_WRITEREG; + USETW(req.wValue, val); + USETW(req.wIndex, reg); + USETW(req.wLength, 1); + + s = splusb(); + err = AUE_DO_REQUEST(sc->aue_udev, &req, &val); + splx(s); + + if (err) { + DPRINTF(("%s: aue_csr_write_1: reg=0x%x err=%s\n", + USBDEVNAME(sc->aue_dev), reg, usbd_errstr(err))); + return (-1); + } + + return (0); +} + +static int +aue_csr_write_2(sc, reg, aval) + struct aue_softc *sc; + int reg, aval; +{ + usb_device_request_t req; + usbd_status err; + int s; + uWord val; + + if (sc->aue_dying) + return (0); + + USETW(val, aval); + req.bmRequestType = UT_WRITE_VENDOR_DEVICE; + req.bRequest = AUE_UR_WRITEREG; + USETW(req.wValue, aval); + USETW(req.wIndex, reg); + USETW(req.wLength, 2); + + s = splusb(); + err = AUE_DO_REQUEST(sc->aue_udev, &req, &val); + splx(s); + + if (err) { + DPRINTF(("%s: aue_csr_write_2: reg=0x%x err=%s\n", + USBDEVNAME(sc->aue_dev), reg, usbd_errstr(err))); + return (-1); + } + + return (0); +} + +/* + * 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; +{ + int i; + + aue_csr_write_1(sc, AUE_EE_REG, addr); + aue_csr_write_1(sc, AUE_EE_CTL, AUE_EECTL_READ); + + for (i = 0; i < AUE_TIMEOUT; i++) { + if (aue_csr_read_1(sc, AUE_EE_CTL) & AUE_EECTL_DONE) + break; + } + + if (i == AUE_TIMEOUT) { + printf("%s: EEPROM read timed out\n", + USBDEVNAME(sc->aue_dev)); + } + + return (aue_csr_read_2(sc, AUE_EE_DATA)); +} + +/* + * 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; +{ + int i; + int off = 0; + int word; + + DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev), __FUNCTION__)); + + for (i = 0; i < 3; i++) { + word = aue_eeprom_getword(sc, off + i); + dest[2 * i] = (u_char)word; + dest[2 * i + 1] = (u_char)(word >> 8); + } +} + +static int +aue_miibus_readreg(dev, phy, reg) + device_ptr_t dev; + int phy, reg; +{ + struct aue_softc *sc = USBGETSOFTC(dev); + int i; + u_int16_t val; + + /* + * The Am79C901 HomePNA PHY actually contains + * two transceivers: a 1Mbps HomePNA PHY and a + * 10Mbps full/half duplex ethernet PHY with + * NWAY autoneg. However in the ADMtek adapter, + * only the 1Mbps PHY is actually connected to + * anything, so we ignore the 10Mbps one. It + * happens to be configured for MII address 3, + * so we filter that out. + */ + if (sc->aue_vendor == USB_VENDOR_ADMTEK && + sc->aue_product == USB_PRODUCT_ADMTEK_PEGASUS) { + if (phy != 1) + return (0); + } + + aue_csr_write_1(sc, AUE_PHY_ADDR, phy); + aue_csr_write_1(sc, AUE_PHY_CTL, reg | AUE_PHYCTL_READ); + + for (i = 0; i < AUE_TIMEOUT; i++) { + if (aue_csr_read_1(sc, AUE_PHY_CTL) & AUE_PHYCTL_DONE) + break; + } + + if (i == AUE_TIMEOUT) { + printf("%s: MII read timed out\n", + USBDEVNAME(sc->aue_dev)); + } + + val = aue_csr_read_2(sc, AUE_PHY_DATA); + + DPRINTFN(11,("%s: %s: phy=%d reg=%d => 0x%04x\n", + USBDEVNAME(sc->aue_dev), __FUNCTION__, phy, reg, val)); + + 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; +{ + struct aue_softc *sc = USBGETSOFTC(dev); + int i; + + 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__) */ + } + + DPRINTFN(11,("%s: %s: phy=%d reg=%d data=0x%04x\n", + USBDEVNAME(sc->aue_dev), __FUNCTION__, phy, reg, data)); + + 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); + + for (i = 0; i < AUE_TIMEOUT; i++) { + if (aue_csr_read_1(sc, AUE_PHY_CTL) & AUE_PHYCTL_DONE) + break; + } + + if (i == AUE_TIMEOUT) { + printf("%s: MII read timed out\n", + USBDEVNAME(sc->aue_dev)); + } + +#if defined(__FreeBSD__) + return (0); +#endif +} + +static void +aue_miibus_statchg(dev) + 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_CLRBIT(sc, AUE_CTL0, AUE_CTL0_RX_ENB | AUE_CTL0_TX_ENB); + + if (IFM_SUBTYPE(mii->mii_media_active) == IFM_100_TX) { + AUE_SETBIT(sc, AUE_CTL1, AUE_CTL1_SPEEDSEL); + } else { + AUE_CLRBIT(sc, AUE_CTL1, AUE_CTL1_SPEEDSEL); + } + + if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX) + AUE_SETBIT(sc, AUE_CTL1, AUE_CTL1_DUPLEX); + else + AUE_CLRBIT(sc, AUE_CTL1, AUE_CTL1_DUPLEX); + + AUE_SETBIT(sc, AUE_CTL0, AUE_CTL0_RX_ENB | AUE_CTL0_TX_ENB); + + /* + * Set the LED modes on the LinkSys adapter. + * This turns on the 'dual link LED' bin in the auxmode + * register of the Broadcom PHY. + */ + if ((sc->aue_vendor == USB_VENDOR_LINKSYS && + sc->aue_product == USB_PRODUCT_LINKSYS_USB100TX) || + (sc->aue_vendor == USB_VENDOR_DLINK && + sc->aue_product == USB_PRODUCT_DLINK_DSB650TX)) { + u_int16_t auxmode; + auxmode = aue_miibus_readreg(dev, 0, 0x1b); + aue_miibus_writereg(dev, 0, 0x1b, auxmode | 0x04); + } +} + +#define AUE_POLY 0xEDB88320 +#define AUE_BITS 6 + +static u_int32_t +aue_crc(addr) + caddr_t addr; +{ + u_int32_t idx, bit, data, crc; + + /* Compute CRC for the address value. */ + crc = 0xFFFFFFFF; /* initial value */ + + for (idx = 0; idx < 6; idx++) { + for (data = *addr++, bit = 0; bit < 8; bit++, data >>= 1) + crc = (crc >> 1) ^ (((crc ^ data) & 1) ? AUE_POLY : 0); + } + + return (crc & ((1 << AUE_BITS) - 1)); +} + +static void +aue_setmulti(sc) + 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) { + AUE_SETBIT(sc, AUE_CTL0, AUE_CTL0_ALLMULTI); + return; + } + + AUE_CLRBIT(sc, AUE_CTL0, AUE_CTL0_ALLMULTI); + + /* first, zot all the existing hash bits */ + for (i = 0; i < 8; i++) + 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 & 0xF)); + } +#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 + h = aue_crc(enm->enm_addrlo); + AUE_SETBIT(sc, AUE_MAR + (h >> 3), 1 << (h & 0xF)); + ETHER_NEXT_MULTI(step, enm); + } +#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ +} + +static void +aue_reset(sc) + struct aue_softc *sc; +{ + int i; + + DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev), __FUNCTION__)); + + AUE_SETBIT(sc, AUE_CTL1, AUE_CTL1_RESETMAC); + + for (i = 0; i < AUE_TIMEOUT; i++) { + if (!(aue_csr_read_1(sc, AUE_CTL1) & AUE_CTL1_RESETMAC)) + break; + } + + if (i == AUE_TIMEOUT) + printf("%s: reset failed\n", USBDEVNAME(sc->aue_dev)); + + /* + * The PHY(s) attached to the Pegasus chip may be held + * in reset until we flip on the GPIO outputs. Make sure + * to set the GPIO pins high so that the PHY(s) will + * be enabled. + * + * Note: We force all of the GPIO pins low first, *then* + * enable the ones we want. + */ + aue_csr_write_1(sc, AUE_GPIO0, + AUE_GPIO_OUT0 | AUE_GPIO_SEL0); + aue_csr_write_1(sc, AUE_GPIO0, + AUE_GPIO_OUT0 | AUE_GPIO_SEL0 | AUE_GPIO_SEL1); + + /* Grrr. LinkSys has to be different from everyone else. */ + if ((sc->aue_vendor == USB_VENDOR_LINKSYS && + sc->aue_product == USB_PRODUCT_LINKSYS_USB100TX) || + (sc->aue_vendor == USB_VENDOR_DLINK && + sc->aue_product == USB_PRODUCT_DLINK_DSB650TX)) { + aue_csr_write_1(sc, AUE_GPIO0, + AUE_GPIO_SEL0 | AUE_GPIO_SEL1); + aue_csr_write_1(sc, AUE_GPIO0, + AUE_GPIO_SEL0 | AUE_GPIO_SEL1 | AUE_GPIO_OUT0); + } + + /* Wait a little while for the chip to get its brains in order. */ + delay(10000); /* XXX */ +} + +/* + * Probe for a Pegasus chip. + */ +USB_MATCH(aue) +{ + USB_MATCH_START(aue, uaa); + struct aue_type *t; + + if (uaa->iface != NULL) + return (UMATCH_NONE); + + for (t = aue_devs; t->aue_vid != 0; t++) + if (uaa->vendor == t->aue_vid && uaa->product == t->aue_did) + return (UMATCH_VENDOR_PRODUCT); + + return (UMATCH_NONE); +} + +/* + * Attach the interface. Allocate softc structures, do ifmedia + * setup and ethernet/BPF attach. + */ +USB_ATTACH(aue) +{ + USB_ATTACH_START(aue, sc, uaa); + char devinfo[1024]; + int s; + u_char eaddr[ETHER_ADDR_LEN]; + struct ifnet *ifp; + struct mii_data *mii; + usbd_device_handle dev = uaa->device; + usbd_interface_handle iface; + usbd_status err; + usb_interface_descriptor_t *id; + 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); + if (err) { + printf("%s: setting config no failed\n", + USBDEVNAME(sc->aue_dev)); + USB_ATTACH_ERROR_RETURN; + } + + err = usbd_device2interface_handle(dev, AUE_IFACE_IDX, &iface); + if (err) { + printf("%s: getting interface handle failed\n", + USBDEVNAME(sc->aue_dev)); + USB_ATTACH_ERROR_RETURN; + } + + sc->aue_udev = dev; + sc->aue_iface = iface; + sc->aue_product = uaa->product; + sc->aue_vendor = uaa->vendor; + + id = usbd_get_interface_descriptor(iface); + + /* Find endpoints. */ + for (i = 0; i < id->bNumEndpoints; i++) { + ed = usbd_interface2endpoint_descriptor(iface, i); + if (ed == NULL) { + printf("%s: couldn't get endpoint descriptor %d\n", + USBDEVNAME(sc->aue_dev), i); + USB_ATTACH_ERROR_RETURN; + } + if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && + UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { + sc->aue_ed[AUE_ENDPT_RX] = ed->bEndpointAddress; + } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && + UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { + sc->aue_ed[AUE_ENDPT_TX] = ed->bEndpointAddress; + } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && + UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { + sc->aue_ed[AUE_ENDPT_INTR] = ed->bEndpointAddress; + } + } + + if (sc->aue_ed[AUE_ENDPT_RX] == 0 || sc->aue_ed[AUE_ENDPT_TX] == 0 || + sc->aue_ed[AUE_ENDPT_INTR] == 0) { + printf("%s: missing endpoint\n", USBDEVNAME(sc->aue_dev)); + USB_ATTACH_ERROR_RETURN; + } + + + s = splimp(); + + /* Reset the adapter. */ + aue_reset(sc); + + /* + * Get station address from the EEPROM. + */ + aue_read_mac(sc, eaddr); + + /* + * A Pegasus chip was detected. Inform the world. + */ +#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 = &sc->arpcom.ac_if; + 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)); + + /* Initialize interface info.*/ + ifp = GET_IFP(sc); + ifp->if_softc = sc; + ifp->if_mtu = ETHERMTU; + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; + ifp->if_ioctl = aue_ioctl; + ifp->if_start = aue_start; + ifp->if_watchdog = aue_watchdog; + strncpy(ifp->if_xname, USBDEVNAME(sc->aue_dev), IFNAMSIZ); + + /* Initialize MII/media info. */ + mii = &sc->aue_mii; + mii->mii_ifp = ifp; + mii->mii_readreg = aue_miibus_readreg; + mii->mii_writereg = aue_miibus_writereg; + mii->mii_statchg = aue_miibus_statchg; + ifmedia_init(&mii->mii_media, 0, aue_ifmedia_upd, aue_ifmedia_sts); +#if defined(__NetBSD__) + mii_attach(self, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0); +#else + mii_phy_probe(self, mii, 0xffffffff); +#endif + if (LIST_FIRST(&mii->mii_phys) == NULL) { + ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE, 0, NULL); + ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_NONE); + } else + ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_AUTO); + + /* Attach the interface. */ + if_attach(ifp); +#if defined (__NetBSD__) + ether_ifattach(ifp, eaddr); +#else + ether_ifattach(ifp); +#endif + +#if NBPFILTER > 0 + bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, + sizeof(struct ether_header)); +#endif +#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; + splx(s); + + usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->aue_udev, + USBDEV(sc->aue_dev)); + + USB_ATTACH_SUCCESS_RETURN; +} + +USB_DETACH(aue) +{ + USB_DETACH_START(aue, sc); + struct ifnet *ifp = GET_IFP(sc); + int s; + + DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev), __FUNCTION__)); + + s = splusb(); + + usb_uncallout(sc->aue_stat_ch, aue_tick, sc); + + if (!sc->aue_attached) { + /* Detached before attached finished, so just bail out. */ + splx(s); + return (0); + } + + if (ifp->if_flags & IFF_RUNNING) + aue_stop(sc); + +#if defined(__NetBSD__) +#if NRND > 0 + rnd_detach_source(&sc->rnd_source); +#endif + mii_detach(&sc->aue_mii, MII_PHY_ANY, MII_OFFSET_ANY); + ifmedia_delete_instance(&sc->aue_mii.mii_media, IFM_INST_ANY); +#if NBPFILTER > 0 + bpfdetach(ifp); +#endif + ether_ifdetach(ifp); +#endif /* __NetBSD__ */ + + if_detach(ifp); + +#ifdef DIAGNOSTIC + if (sc->aue_ep[AUE_ENDPT_TX] != NULL || + sc->aue_ep[AUE_ENDPT_RX] != NULL || + sc->aue_ep[AUE_ENDPT_INTR] != NULL) + printf("%s: detach has active endpoints\n", + USBDEVNAME(sc->aue_dev)); +#endif + + sc->aue_attached = 0; + splx(s); + + usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->aue_udev, + USBDEV(sc->aue_dev)); + + return (0); +} + +#if defined(__NetBSD__) || defined(__OpenBSD__) +int +aue_activate(self, act) + device_ptr_t self; + enum devact act; +{ + struct aue_softc *sc = (struct aue_softc *)self; + + DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev), __FUNCTION__)); + + switch (act) { + case DVACT_ACTIVATE: + return (EOPNOTSUPP); + break; + + case DVACT_DEACTIVATE: +#if defined(__NetBSD__) + if_deactivate(&sc->aue_ec.ec_if); +#endif + sc->aue_dying = 1; + break; + } + 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; +{ + struct mbuf *m_new = NULL; + + DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev),__FUNCTION__)); + + if (m == NULL) { + MGETHDR(m_new, M_DONTWAIT, MT_DATA); + if (m_new == NULL) { + printf("%s: no memory for rx list " + "-- packet dropped!\n", USBDEVNAME(sc->aue_dev)); + return (ENOBUFS); + } + + MCLGET(m_new, M_DONTWAIT); + if (!(m_new->m_flags & M_EXT)) { + printf("%s: no memory for rx list " + "-- packet dropped!\n", USBDEVNAME(sc->aue_dev)); + m_freem(m_new); + return (ENOBUFS); + } + m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; + } else { + m_new = m; + m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; + m_new->m_data = m_new->m_ext.ext_buf; + } + + m_adj(m_new, ETHER_ALIGN); + c->aue_mbuf = m_new; + + return (0); +} + +static int +aue_rx_list_init(sc) + struct aue_softc *sc; +{ + struct aue_cdata *cd; + struct aue_chain *c; + int i; + + DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev), __FUNCTION__)); + + cd = &sc->aue_cdata; + for (i = 0; i < AUE_RX_LIST_CNT; i++) { + c = &cd->aue_rx_chain[i]; + c->aue_sc = sc; + c->aue_idx = i; + if (aue_newbuf(sc, c, NULL) == ENOBUFS) + return (ENOBUFS); + if (c->aue_xfer == NULL) { + c->aue_xfer = usbd_alloc_xfer(sc->aue_udev); + if (c->aue_xfer == NULL) + return (ENOBUFS); + c->aue_buf = usbd_alloc_buffer(c->aue_xfer, AUE_BUFSZ); + if (c->aue_buf == NULL) + return (ENOBUFS); /* XXX free xfer */ + } + } + + return (0); +} + +static int +aue_tx_list_init(sc) + struct aue_softc *sc; +{ + struct aue_cdata *cd; + struct aue_chain *c; + int i; + + DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev), __FUNCTION__)); + + cd = &sc->aue_cdata; + for (i = 0; i < AUE_TX_LIST_CNT; i++) { + c = &cd->aue_tx_chain[i]; + c->aue_sc = sc; + c->aue_idx = i; + c->aue_mbuf = NULL; + if (c->aue_xfer == NULL) { + c->aue_xfer = usbd_alloc_xfer(sc->aue_udev); + if (c->aue_xfer == NULL) + return (ENOBUFS); + c->aue_buf = usbd_alloc_buffer(c->aue_xfer, AUE_BUFSZ); + if (c->aue_buf == NULL) + return (ENOBUFS); + } + } + + return (0); +} + +static void +aue_intr(xfer, priv, status) + usbd_xfer_handle xfer; + usbd_private_handle priv; + usbd_status status; +{ + struct aue_softc *sc = priv; + struct ifnet *ifp = GET_IFP(sc); + struct aue_intrpkt *p = &sc->aue_cdata.aue_ibuf; + + DPRINTFN(15,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev),__FUNCTION__)); + + if (sc->aue_dying) + return; + + if (!(ifp->if_flags & IFF_RUNNING)) + return; + + if (status != USBD_NORMAL_COMPLETION) { + if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { + return; + } + printf("%s: usb error on intr: %s\n", USBDEVNAME(sc->aue_dev), + usbd_errstr(status)); + if (status == USBD_STALLED) + usbd_clear_endpoint_stall(sc->aue_ep[AUE_ENDPT_RX]); + return; + } + + if (p->aue_txstat0) + ifp->if_oerrors++; + + if (p->aue_txstat0 & (AUE_TXSTAT0_LATECOLL | AUE_TXSTAT0_EXCESSCOLL)) + 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. + * + * Grrr. Receiving transfers larger than about 1152 bytes sometimes + * doesn't work. We get an incomplete frame. In order to avoid + * this, we queue up RX transfers that are shorter than a full sized + * frame. If the received frame is larger than our transfer size, + * we snag the rest of the data using a second transfer. Does this + * hurt performance? Yes. But after fighting with this stupid thing + * for three days, I'm willing to settle. I'd rather have reliable + * receive performance that fast but spotty performance. + */ +static void +aue_rxeof(xfer, priv, status) + usbd_xfer_handle xfer; + usbd_private_handle priv; + usbd_status status; +{ + struct aue_chain *c = priv; + struct aue_softc *sc = c->aue_sc; + struct ifnet *ifp = GET_IFP(sc); + struct mbuf *m; + u_int32_t total_len; + struct aue_rxpkt r; +#if defined(__NetBSD__) || defined(__OpenBSD__) + int s; + struct ether_header *eh; +#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ + + DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev),__FUNCTION__)); + + if (sc->aue_dying) + return; + + if (!(ifp->if_flags & IFF_RUNNING)) + return; + + if (status != USBD_NORMAL_COMPLETION) { + if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) + return; + sc->aue_rx_errs++; + if (usbd_ratecheck(&sc->aue_rx_notice)) { + printf("%s: %u usb errors on rx: %s\n", + USBDEVNAME(sc->aue_dev), sc->aue_rx_errs, + usbd_errstr(status)); + sc->aue_rx_errs = 0; + } + if (status == USBD_STALLED) + usbd_clear_endpoint_stall(sc->aue_ep[AUE_ENDPT_RX]); + goto done; + } + + usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL); + + memcpy(mtod(c->aue_mbuf, char*), c->aue_buf, total_len); + + if (total_len <= 4 + ETHER_CRC_LEN) { + ifp->if_ierrors++; + goto done; + } + + memcpy(&r, c->aue_buf + total_len - 4, sizeof(r)); + + /* Turn off all the non-error bits in the rx status word. */ + r.aue_rxstat &= AUE_RXSTAT_MASK; + if (r.aue_rxstat) { + ifp->if_ierrors++; + goto done; + } + + /* No errors; receive the packet. */ + m = c->aue_mbuf; + total_len -= ETHER_CRC_LEN + 4; + 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(); + + /* XXX ugly */ + if (aue_newbuf(sc, c, NULL) == ENOBUFS) { + ifp->if_ierrors++; + goto done1; + } + + eh = mtod(m, struct ether_header *); + +#if NBPFILTER > 0 + /* + * Handle BPF listeners. Let the BPF user see the packet, but + * don't pass it up to the ether_input() layer unless it's + * a broadcast packet, multicast packet, matches our ethernet + * address or the interface is in promiscuous mode. + */ + if (ifp->if_bpf) { + BPF_MTAP(ifp, m); +#if defined(__NetBSD__) + 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; + } +#endif + } +#endif + + DPRINTFN(10,("%s: %s: deliver %d\n", USBDEVNAME(sc->aue_dev), + __FUNCTION__, m->m_len)); +#if defined(__NetBSD__) + (*ifp->if_input)(ifp, m); +#else + ether_input(ifp, eh, m); +#endif + done1: + splx(s); +#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ + + done: + + /* Setup new transfer. */ + usbd_setup_xfer(xfer, sc->aue_ep[AUE_ENDPT_RX], + c, c->aue_buf, AUE_BUFSZ, + USBD_SHORT_XFER_OK | USBD_NO_COPY, + USBD_NO_TIMEOUT, aue_rxeof); + usbd_transfer(xfer); + + DPRINTFN(10,("%s: %s: start rx\n", USBDEVNAME(sc->aue_dev), + __FUNCTION__)); +} + +/* + * A frame was downloaded to the chip. It's safe for us to clean up + * the list buffers. + */ + +static void +aue_txeof(xfer, priv, status) + usbd_xfer_handle xfer; + usbd_private_handle priv; + usbd_status status; +{ + struct aue_chain *c = priv; + struct aue_softc *sc = c->aue_sc; + struct ifnet *ifp = GET_IFP(sc); + int s; + + if (sc->aue_dying) + return; + + s = splimp(); + + DPRINTFN(10,("%s: %s: enter status=%d\n", USBDEVNAME(sc->aue_dev), + __FUNCTION__, status)); + + ifp->if_timer = 0; + ifp->if_flags &= ~IFF_OACTIVE; + + if (status != USBD_NORMAL_COMPLETION) { + if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { + splx(s); + return; + } + ifp->if_oerrors++; + printf("%s: usb error on tx: %s\n", USBDEVNAME(sc->aue_dev), + usbd_errstr(status)); + if (status == USBD_STALLED) + usbd_clear_endpoint_stall(sc->aue_ep[AUE_ENDPT_TX]); + splx(s); + return; + } + + 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; +{ + 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 == NULL) + return; + + if (sc->aue_dying) + return; + + ifp = GET_IFP(sc); + mii = GET_MII(sc); + if (mii == NULL) + return; + + s = splimp(); + + mii_tick(mii); + if (!sc->aue_link) { + mii_pollstat(mii); + if (mii->mii_media_status & IFM_ACTIVE && + IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) { + DPRINTFN(2,("%s: %s: got link\n", + USBDEVNAME(sc->aue_dev),__FUNCTION__)); + sc->aue_link++; + if (ifp->if_snd.ifq_head != NULL) + aue_start(ifp); + } + } + + usb_callout(sc->aue_stat_ch, hz, aue_tick, sc); + + splx(s); +} + +static int +aue_send(sc, m, idx) + struct aue_softc *sc; + struct mbuf *m; + int idx; +{ + int total_len; + struct aue_chain *c; + usbd_status err; + + DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev),__FUNCTION__)); + + c = &sc->aue_cdata.aue_tx_chain[idx]; + + /* + * Copy the mbuf data into a contiguous buffer, leaving two + * bytes at the beginning to hold the frame length. + */ + m_copydata(m, 0, m->m_pkthdr.len, c->aue_buf + 2); + c->aue_mbuf = m; + + /* + * The ADMtek documentation says that the packet length is + * supposed to be specified in the first two bytes of the + * transfer, however it actually seems to ignore this info + * and base the frame size on the bulk transfer length. + */ + c->aue_buf[0] = (u_int8_t)m->m_pkthdr.len; + c->aue_buf[1] = (u_int8_t)(m->m_pkthdr.len >> 8); + total_len = m->m_pkthdr.len + 2; + + usbd_setup_xfer(c->aue_xfer, sc->aue_ep[AUE_ENDPT_TX], + c, c->aue_buf, total_len, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, + AUE_TX_TIMEOUT, aue_txeof); + + /* Transmit */ + err = usbd_transfer(c->aue_xfer); + if (err != USBD_IN_PROGRESS) { + aue_stop(sc); + return (EIO); + } + DPRINTFN(5,("%s: %s: send %d bytes\n", USBDEVNAME(sc->aue_dev), + __FUNCTION__, total_len)); + + sc->aue_cdata.aue_tx_cnt++; + + return (0); +} + +static void +aue_start(ifp) + struct ifnet *ifp; +{ + struct aue_softc *sc = ifp->if_softc; + struct mbuf *m_head = NULL; + + DPRINTFN(5,("%s: %s: enter, link=%d\n", USBDEVNAME(sc->aue_dev), + __FUNCTION__, sc->aue_link)); + + if (sc->aue_dying) + return; + + if (!sc->aue_link) + return; + + if (ifp->if_flags & IFF_OACTIVE) + return; + + IF_DEQUEUE(&ifp->if_snd, m_head); + if (m_head == NULL) + return; + + if (aue_send(sc, m_head, 0)) { + IF_PREPEND(&ifp->if_snd, m_head); + ifp->if_flags |= IFF_OACTIVE; + return; + } + +#if NBPFILTER > 0 + /* + * If there's a BPF listener, bounce a copy of this frame + * to him. + */ + if (ifp->if_bpf) + BPF_MTAP(ifp, m_head); +#endif + + ifp->if_flags |= IFF_OACTIVE; + + /* + * Set a timeout in case the chip goes out to lunch. + */ + ifp->if_timer = 5; +} + +static void +aue_init(xsc) + void *xsc; +{ + struct aue_softc *sc = xsc; + struct ifnet *ifp = GET_IFP(sc); + struct mii_data *mii = GET_MII(sc); + int i, s; + u_char *eaddr; + + DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev), __FUNCTION__)); + + if (sc->aue_dying) + return; + + if (ifp->if_flags & IFF_RUNNING) + return; + + s = splimp(); + + /* + * Cancel pending I/O and free all RX/TX buffers. + */ + aue_reset(sc); + +#if defined(__FreeBSD__) || defined(__OpenBSD__) + eaddr = sc->arpcom.ac_enaddr; +#elif defined(__NetBSD__) + eaddr = LLADDR(ifp->if_sadl); +#endif /* defined(__NetBSD__) */ + for (i = 0; i < ETHER_ADDR_LEN; i++) + aue_csr_write_1(sc, AUE_PAR0 + i, eaddr[i]); + + /* If we want promiscuous mode, set the allframes bit. */ + if (ifp->if_flags & IFF_PROMISC) + AUE_SETBIT(sc, AUE_CTL2, AUE_CTL2_RX_PROMISC); + else + AUE_CLRBIT(sc, AUE_CTL2, AUE_CTL2_RX_PROMISC); + + /* Init TX ring. */ + if (aue_tx_list_init(sc) == ENOBUFS) { + printf("%s: tx list init failed\n", USBDEVNAME(sc->aue_dev)); + splx(s); + return; + } + + /* Init RX ring. */ + if (aue_rx_list_init(sc) == ENOBUFS) { + printf("%s: rx list init failed\n", USBDEVNAME(sc->aue_dev)); + splx(s); + return; + } + + /* Load the multicast filter. */ + aue_setmulti(sc); + + /* Enable RX and TX */ + aue_csr_write_1(sc, AUE_CTL0, AUE_CTL0_RXSTAT_APPEND | AUE_CTL0_RX_ENB); + AUE_SETBIT(sc, AUE_CTL0, AUE_CTL0_TX_ENB); + AUE_SETBIT(sc, AUE_CTL2, AUE_CTL2_EP3_CLR); + + mii_mediachg(mii); + + if (sc->aue_ep[AUE_ENDPT_RX] == NULL) { + if (aue_openpipes(sc)) { + splx(s); + return; + } + } + + ifp->if_flags |= IFF_RUNNING; + ifp->if_flags &= ~IFF_OACTIVE; + + splx(s); + + usb_callout(sc->aue_stat_ch, hz, aue_tick, sc); +} + +static int +aue_openpipes(sc) + struct aue_softc *sc; +{ + struct aue_chain *c; + usbd_status err; + int i; + + /* Open RX and TX pipes. */ + err = usbd_open_pipe(sc->aue_iface, sc->aue_ed[AUE_ENDPT_RX], + USBD_EXCLUSIVE_USE, &sc->aue_ep[AUE_ENDPT_RX]); + if (err) { + printf("%s: open rx pipe failed: %s\n", + USBDEVNAME(sc->aue_dev), usbd_errstr(err)); + return (EIO); + } + usbd_open_pipe(sc->aue_iface, sc->aue_ed[AUE_ENDPT_TX], + USBD_EXCLUSIVE_USE, &sc->aue_ep[AUE_ENDPT_TX]); + if (err) { + printf("%s: open tx pipe failed: %s\n", + USBDEVNAME(sc->aue_dev), usbd_errstr(err)); + return (EIO); + } + err = usbd_open_pipe_intr(sc->aue_iface, sc->aue_ed[AUE_ENDPT_INTR], + USBD_EXCLUSIVE_USE, &sc->aue_ep[AUE_ENDPT_INTR], sc, + &sc->aue_cdata.aue_ibuf, AUE_INTR_PKTLEN, aue_intr, + AUE_INTR_INTERVAL); + if (err) { + printf("%s: open intr pipe failed: %s\n", + USBDEVNAME(sc->aue_dev), usbd_errstr(err)); + return (EIO); + } + + /* Start up the receive pipe. */ + for (i = 0; i < AUE_RX_LIST_CNT; i++) { + c = &sc->aue_cdata.aue_rx_chain[i]; + usbd_setup_xfer(c->aue_xfer, sc->aue_ep[AUE_ENDPT_RX], + c, c->aue_buf, AUE_BUFSZ, + USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT, + aue_rxeof); + (void)usbd_transfer(c->aue_xfer); /* XXX */ + DPRINTFN(5,("%s: %s: start read\n", USBDEVNAME(sc->aue_dev), + __FUNCTION__)); + + } + return (0); +} + +/* + * Set media options. + */ +static int +aue_ifmedia_upd(ifp) + struct ifnet *ifp; +{ + struct aue_softc *sc = ifp->if_softc; + struct mii_data *mii = GET_MII(sc); + + DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev), __FUNCTION__)); + + if (sc->aue_dying) + return (0); + + sc->aue_link = 0; + if (mii->mii_instance) { + struct mii_softc *miisc; + for (miisc = LIST_FIRST(&mii->mii_phys); miisc != NULL; + miisc = LIST_NEXT(miisc, mii_list)) + mii_phy_reset(miisc); + } + mii_mediachg(mii); + + return (0); +} + +/* + * Report current media status. + */ +static void +aue_ifmedia_sts(ifp, ifmr) + struct ifnet *ifp; + struct ifmediareq *ifmr; +{ + struct aue_softc *sc = ifp->if_softc; + struct mii_data *mii = GET_MII(sc); + + DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev), __FUNCTION__)); + + mii_pollstat(mii); + ifmr->ifm_active = mii->mii_media_active; + ifmr->ifm_status = mii->mii_media_status; +} + +static int +aue_ioctl(ifp, command, data) + 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; + + if (sc->aue_dying) + return (EIO); + + s = splimp(); + + 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); + + switch (ifa->ifa_addr->sa_family) { +#ifdef INET + case AF_INET: +#if defined(__NetBSD__) + arp_ifinit(ifp, ifa); +#else + arp_ifinit(&sc->arpcom, ifa); +#endif + break; +#endif /* INET */ +#ifdef NS + case AF_NS: + { + struct ns_addr *ina = &IA_SNS(ifa)->sns_addr; + + if (ns_nullhost(*ina)) + ina->x_host = *(union ns_host *) + LLADDR(ifp->if_sadl); + else + memcpy(LLADDR(ifp->if_sadl), + ina->x_host.c_host, + ifp->if_addrlen); + break; + } +#endif /* NS */ + } + break; + + case SIOCSIFMTU: + if (ifr->ifr_mtu > ETHERMTU) + error = EINVAL; + else + 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 && + ifp->if_flags & IFF_PROMISC && + !(sc->aue_if_flags & IFF_PROMISC)) { + AUE_SETBIT(sc, AUE_CTL2, AUE_CTL2_RX_PROMISC); + } else if (ifp->if_flags & IFF_RUNNING && + !(ifp->if_flags & IFF_PROMISC) && + sc->aue_if_flags & IFF_PROMISC) { + AUE_CLRBIT(sc, AUE_CTL2, AUE_CTL2_RX_PROMISC); + } else if (!(ifp->if_flags & IFF_RUNNING)) + aue_init(sc); + } else { + if (ifp->if_flags & IFF_RUNNING) + aue_stop(sc); + } + sc->aue_if_flags = ifp->if_flags; + error = 0; + break; + case SIOCADDMULTI: + case SIOCDELMULTI: + aue_setmulti(sc); + error = 0; + break; + case SIOCGIFMEDIA: + case SIOCSIFMEDIA: + mii = GET_MII(sc); + error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command); + break; + default: + error = EINVAL; + break; + } + + splx(s); + + return (error); +} + +static void +aue_watchdog(ifp) + struct ifnet *ifp; +{ + struct aue_softc *sc = ifp->if_softc; + + 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); + + if (ifp->if_snd.ifq_head != NULL) + aue_start(ifp); +} + +/* + * Stop the adapter and free any mbufs allocated to the + * RX and TX lists. + */ +static void +aue_stop(sc) + struct aue_softc *sc; +{ + usbd_status err; + struct ifnet *ifp; + int i; + + DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->aue_dev), __FUNCTION__)); + + ifp = GET_IFP(sc); + ifp->if_timer = 0; + + aue_csr_write_1(sc, AUE_CTL0, 0); + aue_csr_write_1(sc, AUE_CTL1, 0); + aue_reset(sc); + usb_uncallout(sc->aue_stat_ch, aue_tick, sc); + + /* Stop transfers. */ + if (sc->aue_ep[AUE_ENDPT_RX] != NULL) { + err = usbd_abort_pipe(sc->aue_ep[AUE_ENDPT_RX]); + if (err) { + printf("%s: abort rx pipe failed: %s\n", + USBDEVNAME(sc->aue_dev), usbd_errstr(err)); + } + err = usbd_close_pipe(sc->aue_ep[AUE_ENDPT_RX]); + if (err) { + printf("%s: close rx pipe failed: %s\n", + USBDEVNAME(sc->aue_dev), usbd_errstr(err)); + } + sc->aue_ep[AUE_ENDPT_RX] = NULL; + } + + if (sc->aue_ep[AUE_ENDPT_TX] != NULL) { + err = usbd_abort_pipe(sc->aue_ep[AUE_ENDPT_TX]); + if (err) { + printf("%s: abort tx pipe failed: %s\n", + USBDEVNAME(sc->aue_dev), usbd_errstr(err)); + } + err = usbd_close_pipe(sc->aue_ep[AUE_ENDPT_TX]); + if (err) { + printf("%s: close tx pipe failed: %s\n", + USBDEVNAME(sc->aue_dev), usbd_errstr(err)); + } + sc->aue_ep[AUE_ENDPT_TX] = NULL; + } + + if (sc->aue_ep[AUE_ENDPT_INTR] != NULL) { + err = usbd_abort_pipe(sc->aue_ep[AUE_ENDPT_INTR]); + if (err) { + printf("%s: abort intr pipe failed: %s\n", + USBDEVNAME(sc->aue_dev), usbd_errstr(err)); + } + err = usbd_close_pipe(sc->aue_ep[AUE_ENDPT_INTR]); + if (err) { + printf("%s: close intr pipe failed: %s\n", + USBDEVNAME(sc->aue_dev), usbd_errstr(err)); + } + sc->aue_ep[AUE_ENDPT_INTR] = NULL; + } + + /* Free RX resources. */ + for (i = 0; i < AUE_RX_LIST_CNT; i++) { + if (sc->aue_cdata.aue_rx_chain[i].aue_mbuf != NULL) { + m_freem(sc->aue_cdata.aue_rx_chain[i].aue_mbuf); + sc->aue_cdata.aue_rx_chain[i].aue_mbuf = NULL; + } + if (sc->aue_cdata.aue_rx_chain[i].aue_xfer != NULL) { + usbd_free_xfer(sc->aue_cdata.aue_rx_chain[i].aue_xfer); + sc->aue_cdata.aue_rx_chain[i].aue_xfer = NULL; + } + } + + /* Free TX resources. */ + for (i = 0; i < AUE_TX_LIST_CNT; i++) { + if (sc->aue_cdata.aue_tx_chain[i].aue_mbuf != NULL) { + m_freem(sc->aue_cdata.aue_tx_chain[i].aue_mbuf); + sc->aue_cdata.aue_tx_chain[i].aue_mbuf = NULL; + } + if (sc->aue_cdata.aue_tx_chain[i].aue_xfer != NULL) { + usbd_free_xfer(sc->aue_cdata.aue_tx_chain[i].aue_xfer); + sc->aue_cdata.aue_tx_chain[i].aue_xfer = NULL; + } + } + + sc->aue_link = 0; + + 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 new file mode 100644 index 00000000000..00d7ef2ae5d --- /dev/null +++ b/sys/dev/usb/if_auereg.h @@ -0,0 +1,278 @@ +/* $OpenBSD: if_auereg.h,v 1.1 2000/03/28 19:37:47 aaron Exp $ */ +/* $NetBSD: if_auereg.h,v 1.9 2000/03/24 22:13:23 augustss Exp $ */ +/* + * Copyright (c) 1997, 1998, 1999 + * Bill Paul . All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Bill Paul. + * 4. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD: src/sys/dev/usb/if_auereg.h,v 1.2 2000/01/08 06:52:36 wpaul Exp $ + */ + +/* + * Register definitions for ADMtek Pegasus AN986 USB to Ethernet + * chip. The Pegasus uses a total of four USB endpoints: the control + * endpoint (0), a bulk read endpoint for receiving packets (1), + * a bulk write endpoint for sending packets (2) and an interrupt + * endpoint for passing RX and TX status (3). Endpoint 0 is used + * to read and write the ethernet module's registers. All registers + * are 8 bits wide. + * + * Packet transfer is done in 64 byte chunks. The last chunk in a + * transfer is denoted by having a length less that 64 bytes. For + * the RX case, the data includes an optional RX status word. + */ + +#define AUE_UR_READREG 0xF0 +#define AUE_UR_WRITEREG 0xF1 + +#define AUE_CONFIG_NO 1 +#define AUE_IFACE_IDX 0 + +/* + * Note that while the ADMtek technically has four + * endpoints, the control endpoint (endpoint 0) is + * regarded as special by the USB code and drivers + * don't have direct access to it. (We access it + * using usbd_do_request() when reading/writing + * registers.) Consequently, our endpoint indexes + * don't match those in the ADMtek Pegasus manual: + * we consider the RX data endpoint to be index 0 + * and work up from there. + */ +#define AUE_ENDPT_RX 0x0 +#define AUE_ENDPT_TX 0x1 +#define AUE_ENDPT_INTR 0x2 +#define AUE_ENDPT_MAX 0x3 + +#define AUE_CTL0 0x00 +#define AUE_CTL1 0x01 +#define AUE_CTL2 0x02 +#define AUE_MAR0 0x08 +#define AUE_MAR1 0x09 +#define AUE_MAR2 0x0A +#define AUE_MAR3 0x0B +#define AUE_MAR4 0x0C +#define AUE_MAR5 0x0D +#define AUE_MAR6 0x0E +#define AUE_MAR7 0x0F +#define AUE_MAR AUE_MAR0 +#define AUE_PAR0 0x10 +#define AUE_PAR1 0x11 +#define AUE_PAR2 0x12 +#define AUE_PAR3 0x13 +#define AUE_PAR4 0x14 +#define AUE_PAR5 0x15 +#define AUE_PAR AUE_PAR0 +#define AUE_PAUSE0 0x18 +#define AUE_PAUSE1 0x19 +#define AUE_PAUSE AUE_PAUSE0 +#define AUE_RX_FLOWCTL_CNT 0x1A +#define AUE_RX_FLOWCTL_FIFO 0x1B +#define AUE_EE_REG 0x20 +#define AUE_EE_DATA0 0x21 +#define AUE_EE_DATA1 0x22 +#define AUE_EE_DATA AUE_EE_DATA0 +#define AUE_EE_CTL 0x23 +#define AUE_PHY_ADDR 0x25 +#define AUE_PHY_DATA0 0x26 +#define AUE_PHY_DATA1 0x27 +#define AUE_PHY_DATA AUE_PHY_DATA0 +#define AUE_PHY_CTL 0x28 +#define AUE_USB_STS 0x2A +#define AUE_TXSTAT0 0x2B +#define AUE_TXSTAT1 0x2C +#define AUE_TXSTAT AUE_TXSTAT0 +#define AUE_RXSTAT 0x2D +#define AUE_PKTLOST0 0x2E +#define AUE_PKTLOST1 0x2F +#define AUE_PKTLOST AUE_PKTLOST0 + +#define AUE_GPIO0 0x7E +#define AUE_GPIO1 0x7F + +#define AUE_CTL0_INCLUDE_RXCRC 0x01 +#define AUE_CTL0_ALLMULTI 0x02 +#define AUE_CTL0_STOP_BACKOFF 0x04 +#define AUE_CTL0_RXSTAT_APPEND 0x08 +#define AUE_CTL0_WAKEON_ENB 0x10 +#define AUE_CTL0_RXPAUSE_ENB 0x20 +#define AUE_CTL0_RX_ENB 0x40 +#define AUE_CTL0_TX_ENB 0x80 + +#define AUE_CTL1_HOMELAN 0x04 +#define AUE_CTL1_RESETMAC 0x08 +#define AUE_CTL1_SPEEDSEL 0x10 /* 0 = 10mbps, 1 = 100mbps */ +#define AUE_CTL1_DUPLEX 0x20 /* 0 = half, 1 = full */ +#define AUE_CTL1_DELAYHOME 0x40 + +#define AUE_CTL2_EP3_CLR 0x01 /* reading EP3 clrs status regs */ +#define AUE_CTL2_RX_BADFRAMES 0x02 +#define AUE_CTL2_RX_PROMISC 0x04 +#define AUE_CTL2_LOOPBACK 0x08 +#define AUE_CTL2_EEPROMWR_ENB 0x10 +#define AUE_CTL2_EEPROM_LOAD 0x20 + +#define AUE_EECTL_WRITE 0x01 +#define AUE_EECTL_READ 0x02 +#define AUE_EECTL_DONE 0x04 + +#define AUE_PHYCTL_PHYREG 0x1F +#define AUE_PHYCTL_WRITE 0x20 +#define AUE_PHYCTL_READ 0x40 +#define AUE_PHYCTL_DONE 0x80 + +#define AUE_USBSTS_SUSPEND 0x01 +#define AUE_USBSTS_RESUME 0x02 + +#define AUE_TXSTAT0_JABTIMO 0x04 +#define AUE_TXSTAT0_CARLOSS 0x08 +#define AUE_TXSTAT0_NOCARRIER 0x10 +#define AUE_TXSTAT0_LATECOLL 0x20 +#define AUE_TXSTAT0_EXCESSCOLL 0x40 +#define AUE_TXSTAT0_UNDERRUN 0x80 + +#define AUE_TXSTAT1_PKTCNT 0x0F +#define AUE_TXSTAT1_FIFO_EMPTY 0x40 +#define AUE_TXSTAT1_FIFO_FULL 0x80 + +#define AUE_RXSTAT_OVERRUN 0x01 +#define AUE_RXSTAT_PAUSE 0x02 + +#define AUE_GPIO_IN0 0x01 +#define AUE_GPIO_OUT0 0x02 +#define AUE_GPIO_SEL0 0x04 +#define AUE_GPIO_IN1 0x08 +#define AUE_GPIO_OUT1 0x10 +#define AUE_GPIO_SEL1 0x20 + +struct aue_intrpkt { + u_int8_t aue_txstat0; + u_int8_t aue_txstat1; + u_int8_t aue_rxstat; + u_int8_t aue_rxlostpkt0; + u_int8_t aue_rxlostpkt1; + u_int8_t aue_wakeupstat; + u_int8_t aue_rsvd; + u_int8_t _pad; +}; +#define AUE_INTR_PKTLEN 8 + +struct aue_rxpkt { + uWord aue_pktlen; + uByte aue_rxstat; +}; + +#define AUE_RXSTAT_MCAST 0x01 +#define AUE_RXSTAT_GIANT 0x02 +#define AUE_RXSTAT_RUNT 0x04 +#define AUE_RXSTAT_CRCERR 0x08 +#define AUE_RXSTAT_DRIBBLE 0x10 +#define AUE_RXSTAT_MASK 0x1E + + +/*************** The rest belongs in if_auevar.h *************/ + +struct aue_type { + u_int16_t aue_vid; + u_int16_t aue_did; +}; + +#define AUE_TX_LIST_CNT 1 +#define AUE_RX_LIST_CNT 1 + +struct aue_softc; + +struct aue_chain { + struct aue_softc *aue_sc; + usbd_xfer_handle aue_xfer; + char *aue_buf; + struct mbuf *aue_mbuf; + int aue_idx; +}; + +struct aue_cdata { + struct aue_chain aue_tx_chain[AUE_TX_LIST_CNT]; + struct aue_chain aue_rx_chain[AUE_RX_LIST_CNT]; + struct aue_intrpkt aue_ibuf; + int aue_tx_prod; + int aue_tx_cons; + int aue_tx_cnt; + int aue_rx_prod; +}; + +struct aue_softc { + USBBASEDEVICE aue_dev; + +#if defined(__FreeBSD__) + struct arpcom arpcom; + device_t aue_miibus; +#define GET_IFP(sc) (&(sc)->arpcom.ac_if) +#define GET_MII(sc) (device_get_softc((sc)->aue_miibus)) +#elif defined(__NetBSD__) + struct ethercom aue_ec; + struct mii_data aue_mii; +#if NRND > 0 + rndsource_element_t rnd_source; +#endif +#define GET_IFP(sc) (&(sc)->aue_ec.ec_if) +#define GET_MII(sc) (&(sc)->aue_mii) +#elif defined(__OpenBSD__) + struct arpcom arpcom; + struct mii_data aue_mii; +#if NRND > 0 + rndsource_element_t rnd_source; +#endif +#define GET_IFP(sc) (&(sc)->arpcom.ac_if) +#define GET_MII(sc) (&(sc)->aue_mii) +#endif + + usb_callout_t aue_stat_ch; + + usbd_device_handle aue_udev; + usbd_interface_handle aue_iface; + u_int16_t aue_vendor; + u_int16_t aue_product; + int aue_ed[AUE_ENDPT_MAX]; + usbd_pipe_handle aue_ep[AUE_ENDPT_MAX]; + u_int8_t aue_link; + int aue_if_flags; + struct aue_cdata aue_cdata; + + char aue_dying; + char aue_attached; + u_int aue_rx_errs; + struct timeval aue_rx_notice; +}; + +#define AUE_TIMEOUT 1000 +#define ETHER_ALIGN 2 +#define AUE_BUFSZ 1536 +#define AUE_MIN_FRAMELEN 60 +#define AUE_TX_TIMEOUT 10000 /* ms */ +#define AUE_INTR_INTERVAL 100 /* ms */ diff --git a/sys/dev/usb/if_cue.c b/sys/dev/usb/if_cue.c new file mode 100644 index 00000000000..2483a266f70 --- /dev/null +++ b/sys/dev/usb/if_cue.c @@ -0,0 +1,1622 @@ +/* $OpenBSD: if_cue.c,v 1.1 2000/03/28 19:37:47 aaron Exp $ */ +/* $NetBSD: if_cue.c,v 1.16 2000/03/24 22:03:29 augustss Exp $ */ +/* + * Copyright (c) 1997, 1998, 1999, 2000 + * Bill Paul . All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Bill Paul. + * 4. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD: src/sys/dev/usb/if_cue.c,v 1.4 2000/01/16 22:45:06 wpaul Exp $ + */ + +/* + * CATC USB-EL1210A USB to ethernet driver. Used in the CATC Netmate + * adapters and others. + * + * Written by Bill Paul + * Electrical Engineering Department + * Columbia University, New York City + */ + +/* + * The CATC USB-EL1210A provides USB ethernet support at 10Mbps. The + * RX filter uses a 512-bit multicast hash table, single perfect entry + * for the station address, and promiscuous mode. Unlike the ADMtek + * and KLSI chips, the CATC ASIC supports read and write combining + * mode where multiple packets can be transfered using a single bulk + * transaction, which helps performance a great deal. + */ + +/* + * 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" +#include "bpfilter.h" +#include "rnd.h" +#elif defined(__OpenBSD__) +#include "bpfilter.h" +#endif + +#include +#include +#if !defined(__OpenBSD__) +#include +#endif +#include +#include +#include +#include +#include + +#if defined(__FreeBSD__) + +#include +#include /* for DELAY */ +#include + +#elif defined(__NetBSD__) || defined(__OpenBSD__) + +#include +#if NRND > 0 +#include +#endif + +#endif + +#include +#if defined(__NetBSD__) || defined(__FreeBSD__) +#include +#endif +#include + +#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 +#include +#endif + +#if defined(__NetBSD__) +#include +#ifdef INET +#include +#include +#endif +#endif /* defined(__NetBSD__) */ + +#if defined(__OpenBSD__) +#ifdef INET +#include +#include +#include +#include +#include +#endif +#endif /* defined(__OpenBSD__) */ + +#if defined(__NetBSD__) || defined(__OpenBSD__) +#ifdef NS +#include +#include +#endif +#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ + +#include +#include +#include +#include + +#ifdef __FreeBSD__ +#include +#endif + +#include + +#ifdef CUE_DEBUG +#define DPRINTF(x) if (cuedebug) logprintf x +#define DPRINTFN(n,x) if (cuedebug >= (n)) logprintf x +int cuedebug = 0; +#else +#define DPRINTF(x) +#define DPRINTFN(n,x) +#endif + +/* + * Various supported device vendors/products. + */ +static struct cue_type cue_devs[] = { + { USB_VENDOR_CATC, USB_PRODUCT_CATC_NETMATE }, + { USB_VENDOR_CATC, USB_PRODUCT_CATC_NETMATE2 }, + /* Belkin F5U111 adapter covered by NETMATE entry */ + { 0, 0 } +}; + +USB_DECLARE_DRIVER(cue); + +#define static + +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 $"; +#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) + +#define CUE_SETBIT(sc, reg, x) \ + cue_csr_write_1(sc, reg, cue_csr_read_1(sc, reg) | (x)) + +#define CUE_CLRBIT(sc, reg, x) \ + 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; +{ + usb_device_request_t req; + usbd_status err; + u_int8_t val = 0; + int s; + + if (sc->cue_dying) + return (0); + + req.bmRequestType = UT_READ_VENDOR_DEVICE; + req.bRequest = CUE_CMD_READREG; + USETW(req.wValue, 0); + USETW(req.wIndex, reg); + USETW(req.wLength, 1); + + s = splusb(); + err = CUE_DO_REQUEST(sc->cue_udev, &req, &val); + splx(s); + + if (err) { + DPRINTF(("%s: cue_csr_read_1: reg=0x%x err=%s\n", + USBDEVNAME(sc->cue_dev), reg, usbd_errstr(err))); + return (0); + } + + DPRINTFN(10,("%s: cue_csr_read_1 reg=0x%x val=0x%x\n", + USBDEVNAME(sc->cue_dev), reg, val)); + + return (val); +} + +static int +cue_csr_read_2(sc, reg) + struct cue_softc *sc; + int reg; +{ + usb_device_request_t req; + usbd_status err; + uWord val; + int s; + + if (sc->cue_dying) + return (0); + + req.bmRequestType = UT_READ_VENDOR_DEVICE; + req.bRequest = CUE_CMD_READREG; + USETW(req.wValue, 0); + USETW(req.wIndex, reg); + USETW(req.wLength, 2); + + s = splusb(); + err = CUE_DO_REQUEST(sc->cue_udev, &req, &val); + splx(s); + + DPRINTFN(10,("%s: cue_csr_read_2 reg=0x%x val=0x%x\n", + USBDEVNAME(sc->cue_dev), reg, UGETW(val))); + + if (err) { + DPRINTF(("%s: cue_csr_read_2: reg=0x%x err=%s\n", + USBDEVNAME(sc->cue_dev), reg, usbd_errstr(err))); + return (0); + } + + return (UGETW(val)); +} + +static int +cue_csr_write_1(sc, reg, val) + struct cue_softc *sc; + int reg, val; +{ + usb_device_request_t req; + usbd_status err; + int s; + + if (sc->cue_dying) + return (0); + + DPRINTFN(10,("%s: cue_csr_write_1 reg=0x%x val=0x%x\n", + USBDEVNAME(sc->cue_dev), reg, val)); + + req.bmRequestType = UT_WRITE_VENDOR_DEVICE; + req.bRequest = CUE_CMD_WRITEREG; + USETW(req.wValue, val); + USETW(req.wIndex, reg); + USETW(req.wLength, 0); + + s = splusb(); + err = CUE_DO_REQUEST(sc->cue_udev, &req, NULL); + splx(s); + + if (err) { + DPRINTF(("%s: cue_csr_write_1: reg=0x%x err=%s\n", + USBDEVNAME(sc->cue_dev), reg, usbd_errstr(err))); + return (-1); + } + + DPRINTFN(20,("%s: cue_csr_write_1, after reg=0x%x val=0x%x\n", + USBDEVNAME(sc->cue_dev), reg, cue_csr_read_1(sc, reg))); + + return (0); +} + +#ifdef notdef +static int +cue_csr_write_2(sc, reg, val) + struct cue_softc *sc; + int reg, aval; +{ + usb_device_request_t req; + usbd_status err; + uWord val; + int s; + + if (sc->cue_dying) + return (0); + + DPRINTFN(10,("%s: cue_csr_write_2 reg=0x%x val=0x%x\n", + USBDEVNAME(sc->cue_dev), reg, aval)); + + USETW(val, aval); + req.bmRequestType = UT_WRITE_VENDOR_DEVICE; + req.bRequest = CUE_CMD_WRITEREG; + USETW(req.wValue, val); + USETW(req.wIndex, reg); + USETW(req.wLength, 0); + + s = splusb(); + err = CUE_DO_REQUEST(sc->cue_udev, &req, NULL); + splx(s); + + if (err) { + DPRINTF(("%s: cue_csr_write_2: reg=0x%x err=%s\n", + USBDEVNAME(sc->cue_dev), reg, usbd_errstr(err))); + return (-1); + } + + return (0); +} +#endif + +static int +cue_mem(sc, cmd, addr, buf, len) + 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)); + + if (cmd == CUE_CMD_READSRAM) + req.bmRequestType = UT_READ_VENDOR_DEVICE; + else + req.bmRequestType = UT_WRITE_VENDOR_DEVICE; + req.bRequest = cmd; + USETW(req.wValue, 0); + USETW(req.wIndex, addr); + USETW(req.wLength, len); + + s = splusb(); + err = CUE_DO_REQUEST(sc->cue_udev, &req, buf); + splx(s); + + if (err) { + DPRINTF(("%s: cue_csr_mem: addr=0x%x err=%s\n", + USBDEVNAME(sc->cue_dev), addr, usbd_errstr(err))); + return (-1); + } + + return (0); +} + +static int +cue_getmac(sc, buf) + 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))); + + req.bmRequestType = UT_READ_VENDOR_DEVICE; + req.bRequest = CUE_CMD_GET_MACADDR; + USETW(req.wValue, 0); + USETW(req.wIndex, 0); + USETW(req.wLength, ETHER_ADDR_LEN); + + s = splusb(); + err = CUE_DO_REQUEST(sc->cue_udev, &req, buf); + splx(s); + + if (err) { + printf("%s: read MAC address failed\n", USBDEVNAME(sc->cue_dev)); + return (-1); + } + + return (0); +} + +#define CUE_POLY 0xEDB88320 +#define CUE_BITS 9 + +static u_int32_t +cue_crc(addr) + caddr_t addr; +{ + u_int32_t idx, bit, data, crc; + + /* Compute CRC for the address value. */ + crc = 0xFFFFFFFF; /* initial value */ + + for (idx = 0; idx < 6; idx++) { + for (data = *addr++, bit = 0; bit < 8; bit++, data >>= 1) + crc = (crc >> 1) ^ (((crc ^ data) & 1) ? CUE_POLY : 0); + } + + return (crc & ((1 << CUE_BITS) - 1)); +} + +static void +cue_setmulti(sc) + 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); + + 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) { + for (i = 0; i < CUE_MCAST_TABLE_LEN; i++) + sc->cue_mctab[i] = 0xFF; + cue_mem(sc, CUE_CMD_WRITESRAM, CUE_MCAST_TABLE_ADDR, + &sc->cue_mctab, CUE_MCAST_TABLE_LEN); + return; + } + + /* first, zot all the existing hash bits */ + for (i = 0; i < CUE_MCAST_TABLE_LEN; i++) + 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 + h = cue_crc(enm->enm_addrlo); + sc->cue_mctab[h >> 3] |= 1 << (h & 0x7); + ETHER_NEXT_MULTI(step, enm); + } +#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ + + /* + * Also include the broadcast address in the filter + * so we can receive broadcast frames. + */ + if (ifp->if_flags & IFF_BROADCAST) { + h = cue_crc(etherbroadcastaddr); + sc->cue_mctab[h >> 3] |= 1 << (h & 0x7); + } + + cue_mem(sc, CUE_CMD_WRITESRAM, CUE_MCAST_TABLE_ADDR, + &sc->cue_mctab, CUE_MCAST_TABLE_LEN); +} + +static void +cue_reset(sc) + struct cue_softc *sc; +{ + usb_device_request_t req; + usbd_status err; + int s; + + DPRINTFN(2,("%s: cue_reset\n", USBDEVNAME(sc->cue_dev))); + + if (sc->cue_dying) + return; + + req.bmRequestType = UT_WRITE_VENDOR_DEVICE; + req.bRequest = CUE_CMD_RESET; + USETW(req.wValue, 0); + USETW(req.wIndex, 0); + USETW(req.wLength, 0); + + s = splusb(); + err = CUE_DO_REQUEST(sc->cue_udev, &req, NULL); + splx(s); + + 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 */ +} + +/* + * Probe for a CATC chip. + */ +USB_MATCH(cue) +{ + USB_MATCH_START(cue, uaa); + struct cue_type *t; + + if (uaa->iface != NULL) + return (UMATCH_NONE); + + for (t = cue_devs; t->cue_vid != 0; t++) + if (uaa->vendor == t->cue_vid && uaa->product == t->cue_did) + return (UMATCH_VENDOR_PRODUCT); + + return (UMATCH_NONE); +} + +/* + * Attach the interface. Allocate softc structures, do ifmedia + * setup and ethernet/BPF attach. + */ +USB_ATTACH(cue) +{ + USB_ATTACH_START(cue, sc, uaa); + char devinfo[1024]; + int s; + u_char eaddr[ETHER_ADDR_LEN]; + usbd_device_handle dev = uaa->device; + usbd_interface_handle iface; + usbd_status err; + struct ifnet *ifp; + usb_interface_descriptor_t *id; + 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); + if (err) { + printf("%s: setting config no failed\n", + USBDEVNAME(sc->cue_dev)); + USB_ATTACH_ERROR_RETURN; + } + + sc->cue_udev = dev; + sc->cue_product = uaa->product; + sc->cue_vendor = uaa->vendor; + + err = usbd_device2interface_handle(dev, CUE_IFACE_IDX, &iface); + if (err) { + printf("%s: getting interface handle failed\n", + USBDEVNAME(sc->cue_dev)); + USB_ATTACH_ERROR_RETURN; + } + + sc->cue_iface = iface; + id = usbd_get_interface_descriptor(iface); + + /* Find endpoints. */ + for (i = 0; i < id->bNumEndpoints; i++) { + ed = usbd_interface2endpoint_descriptor(iface, i); + if (ed == NULL) { + printf("%s: couldn't get ep %d\n", + USBDEVNAME(sc->cue_dev), i); + USB_ATTACH_ERROR_RETURN; + } + if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && + UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { + sc->cue_ed[CUE_ENDPT_RX] = ed->bEndpointAddress; + } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && + UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { + sc->cue_ed[CUE_ENDPT_TX] = ed->bEndpointAddress; + } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && + UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { + sc->cue_ed[CUE_ENDPT_INTR] = ed->bEndpointAddress; + } + } + +#if 0 + /* Reset the adapter. */ + cue_reset(sc); +#endif + /* + * Get station address. + */ + cue_getmac(sc, &eaddr); + + s = splimp(); + + /* + * 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)); + + /* Initialize interface info.*/ + ifp = GET_IFP(sc); + ifp->if_softc = sc; + ifp->if_mtu = ETHERMTU; + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; + ifp->if_ioctl = cue_ioctl; + ifp->if_start = cue_start; + ifp->if_watchdog = cue_watchdog; + strncpy(ifp->if_xname, USBDEVNAME(sc->cue_dev), IFNAMSIZ); + + /* Attach the interface. */ + if_attach(ifp); +#if defined(__NetBSD__) + ether_ifattach(ifp, eaddr); +#else + ether_ifattach(ifp); +#endif + +#if NBPFILTER > 0 + bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, + sizeof(struct ether_header)); +#endif +#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; + splx(s); + + usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->cue_udev, + USBDEV(sc->cue_dev)); + + USB_ATTACH_SUCCESS_RETURN; +} + +USB_DETACH(cue) +{ + USB_DETACH_START(cue, sc); + struct ifnet *ifp = GET_IFP(sc); + int s; + + DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev), __FUNCTION__)); + + s = splusb(); + + usb_uncallout(sc->cue_stat_ch, cue_tick, sc); + + if (!sc->cue_attached) { + /* Detached before attached finished, so just bail out. */ + splx(s); + return (0); + } + + if (ifp->if_flags & IFF_RUNNING) + cue_stop(sc); + +#if defined(__NetBSD__) +#if NRND > 0 + rnd_detach_source(&sc->rnd_source); +#endif +#if NBPFILTER > 0 + bpfdetach(ifp); +#endif + ether_ifdetach(ifp); +#endif /* __NetBSD__ */ + + if_detach(ifp); + +#ifdef DIAGNOSTIC + if (sc->cue_ep[CUE_ENDPT_TX] != NULL || + sc->cue_ep[CUE_ENDPT_RX] != NULL || + sc->cue_ep[CUE_ENDPT_INTR] != NULL) + printf("%s: detach has active endpoints\n", + USBDEVNAME(sc->cue_dev)); +#endif + + sc->cue_attached = 0; + splx(s); + + usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->cue_udev, + USBDEV(sc->cue_dev)); + + return (0); +} + +#if defined(__NetBSD__) || defined(__OpenBSD__) +int +cue_activate(self, act) + device_ptr_t self; + enum devact act; +{ + struct cue_softc *sc = (struct cue_softc *)self; + + DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev), __FUNCTION__)); + + switch (act) { + case DVACT_ACTIVATE: + return (EOPNOTSUPP); + break; + + case DVACT_DEACTIVATE: +#if defined(__NetBSD__) + /* Deactivate the interface. */ + if_deactivate(&sc->cue_ec.ec_if); +#endif + sc->cue_dying = 1; + break; + } + 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; +{ + struct mbuf *m_new = NULL; + + if (m == NULL) { + MGETHDR(m_new, M_DONTWAIT, MT_DATA); + if (m_new == NULL) { + printf("%s: no memory for rx list " + "-- packet dropped!\n", USBDEVNAME(sc->cue_dev)); + return (ENOBUFS); + } + + MCLGET(m_new, M_DONTWAIT); + if (!(m_new->m_flags & M_EXT)) { + printf("%s: no memory for rx list " + "-- packet dropped!\n", USBDEVNAME(sc->cue_dev)); + m_freem(m_new); + return (ENOBUFS); + } + m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; + } else { + m_new = m; + m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; + m_new->m_data = m_new->m_ext.ext_buf; + } + + m_adj(m_new, ETHER_ALIGN); + c->cue_mbuf = m_new; + + return (0); +} + +static int +cue_rx_list_init(sc) + struct cue_softc *sc; +{ + struct cue_cdata *cd; + struct cue_chain *c; + int i; + + cd = &sc->cue_cdata; + for (i = 0; i < CUE_RX_LIST_CNT; i++) { + c = &cd->cue_rx_chain[i]; + c->cue_sc = sc; + c->cue_idx = i; + if (cue_newbuf(sc, c, NULL) == ENOBUFS) + return (ENOBUFS); + if (c->cue_xfer == NULL) { + c->cue_xfer = usbd_alloc_xfer(sc->cue_udev); + if (c->cue_xfer == NULL) + return (ENOBUFS); + c->cue_buf = usbd_alloc_buffer(c->cue_xfer, CUE_BUFSZ); + if (c->cue_buf == NULL) { + usbd_free_xfer(c->cue_xfer); + return (ENOBUFS); + } + } + } + + return (0); +} + +static int +cue_tx_list_init(sc) + struct cue_softc *sc; +{ + struct cue_cdata *cd; + struct cue_chain *c; + int i; + + cd = &sc->cue_cdata; + for (i = 0; i < CUE_TX_LIST_CNT; i++) { + c = &cd->cue_tx_chain[i]; + c->cue_sc = sc; + c->cue_idx = i; + c->cue_mbuf = NULL; + if (c->cue_xfer == NULL) { + c->cue_xfer = usbd_alloc_xfer(sc->cue_udev); + if (c->cue_xfer == NULL) + return (ENOBUFS); + c->cue_buf = usbd_alloc_buffer(c->cue_xfer, CUE_BUFSZ); + if (c->cue_buf == NULL) { + usbd_free_xfer(c->cue_xfer); + return (ENOBUFS); + } + } + } + + 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; +{ + struct cue_chain *c = priv; + struct cue_softc *sc = c->cue_sc; + struct ifnet *ifp = GET_IFP(sc); + struct mbuf *m; + int total_len = 0; + u_int16_t len; +#if defined(__NetBSD__) || defined(__OpenBSD__) + int s; + struct ether_header *eh; +#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ + + DPRINTFN(10,("%s: %s: enter status=%d\n", USBDEVNAME(sc->cue_dev), + __FUNCTION__, status)); + + if (sc->cue_dying) + return; + + if (!(ifp->if_flags & IFF_RUNNING)) + return; + + if (status != USBD_NORMAL_COMPLETION) { + if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) + return; + sc->cue_rx_errs++; + if (usbd_ratecheck(&sc->cue_rx_notice)) { + printf("%s: %u usb errors on rx: %s\n", + USBDEVNAME(sc->cue_dev), sc->cue_rx_errs, + usbd_errstr(status)); + sc->cue_rx_errs = 0; + } + if (status == USBD_STALLED) + usbd_clear_endpoint_stall(sc->cue_ep[CUE_ENDPT_RX]); + goto done; + } + + usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL); + + memcpy(mtod(c->cue_mbuf, char *), c->cue_buf, total_len); + + m = c->cue_mbuf; + len = UGETW(mtod(m, u_int8_t *)); + + /* No errors; receive the packet. */ + total_len = len; + + if (len < sizeof(struct ether_header)) { + ifp->if_ierrors++; + goto done; + } + + ifp->if_ipackets++; + 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(); + + /* XXX ugly */ + if (cue_newbuf(sc, c, NULL) == ENOBUFS) { + ifp->if_ierrors++; + goto done1; + } + + eh = mtod(m, struct ether_header *); + +#if NBPFILTER > 0 + /* + * Handle BPF listeners. Let the BPF user see the packet, but + * don't pass it up to the ether_input() layer unless it's + * a broadcast packet, multicast packet, matches our ethernet + * address or the interface is in promiscuous mode. + */ + if (ifp->if_bpf) { + BPF_MTAP(ifp, m); +#if defined(__NetBSD__) + 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; + } +#endif + } +#endif + + DPRINTFN(10,("%s: %s: deliver %d\n", USBDEVNAME(sc->cue_dev), + __FUNCTION__, m->m_len)); +#if defined(__NetBSD__) + (*ifp->if_input)(ifp, m); +#else + ether_input(ifp, eh, m); +#endif + done1: + splx(s); +#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ + +done: + /* 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); + + DPRINTFN(10,("%s: %s: start rx\n", USBDEVNAME(sc->cue_dev), + __FUNCTION__)); +} + +/* + * A frame was downloaded to the chip. It's safe for us to clean up + * the list buffers. + */ +static void +cue_txeof(xfer, priv, status) + usbd_xfer_handle xfer; + usbd_private_handle priv; + usbd_status status; +{ + struct cue_chain *c = priv; + struct cue_softc *sc = c->cue_sc; + struct ifnet *ifp = GET_IFP(sc); + int s; + + if (sc->cue_dying) + return; + + s = splimp(); + + DPRINTFN(10,("%s: %s: enter status=%d\n", USBDEVNAME(sc->cue_dev), + __FUNCTION__, status)); + + ifp->if_timer = 0; + ifp->if_flags &= ~IFF_OACTIVE; + + if (status != USBD_NORMAL_COMPLETION) { + if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { + splx(s); + return; + } + ifp->if_oerrors++; + printf("%s: usb error on tx: %s\n", USBDEVNAME(sc->cue_dev), + usbd_errstr(status)); + if (status == USBD_STALLED) + usbd_clear_endpoint_stall(sc->cue_ep[CUE_ENDPT_TX]); + splx(s); + return; + } + + 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; +{ + struct cue_softc *sc = xsc; + struct ifnet *ifp; + int s; + + if (sc == NULL) + return; + + if (sc->cue_dying) + return; + + DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev), __FUNCTION__)); + + s = splimp(); + + ifp = GET_IFP(sc); + + ifp->if_collisions += cue_csr_read_2(sc, CUE_TX_SINGLECOLL); + ifp->if_collisions += cue_csr_read_2(sc, CUE_TX_MULTICOLL); + ifp->if_collisions += cue_csr_read_2(sc, CUE_TX_EXCESSCOLL); + + 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; +{ + int total_len; + struct cue_chain *c; + usbd_status err; + + c = &sc->cue_cdata.cue_tx_chain[idx]; + + /* + * Copy the mbuf data into a contiguous buffer, leaving two + * bytes at the beginning to hold the frame length. + */ + m_copydata(m, 0, m->m_pkthdr.len, c->cue_buf + 2); + c->cue_mbuf = m; + + total_len = m->m_pkthdr.len + 2; + + DPRINTFN(10,("%s: %s: total_len=%d\n", + USBDEVNAME(sc->cue_dev), __FUNCTION__, total_len)); + + /* The first two bytes are the frame length */ + c->cue_buf[0] = (u_int8_t)m->m_pkthdr.len; + c->cue_buf[1] = (u_int8_t)(m->m_pkthdr.len >> 8); + + /* XXX 10000 */ + usbd_setup_xfer(c->cue_xfer, sc->cue_ep[CUE_ENDPT_TX], + c, c->cue_buf, total_len, USBD_NO_COPY, 10000, cue_txeof); + + /* Transmit */ + err = usbd_transfer(c->cue_xfer); + if (err != USBD_IN_PROGRESS) { + cue_stop(sc); + return (EIO); + } + + sc->cue_cdata.cue_tx_cnt++; + + return (0); +} + +static void +cue_start(ifp) + struct ifnet *ifp; +{ + struct cue_softc *sc = ifp->if_softc; + struct mbuf *m_head = NULL; + + if (sc->cue_dying) + return; + + DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev),__FUNCTION__)); + + if (ifp->if_flags & IFF_OACTIVE) + return; + + IF_DEQUEUE(&ifp->if_snd, m_head); + if (m_head == NULL) + return; + + if (cue_send(sc, m_head, 0)) { + IF_PREPEND(&ifp->if_snd, m_head); + ifp->if_flags |= IFF_OACTIVE; + return; + } + +#if NBPFILTER > 0 + /* + * If there's a BPF listener, bounce a copy of this frame + * to him. + */ + if (ifp->if_bpf) + BPF_MTAP(ifp, m_head); +#endif + + ifp->if_flags |= IFF_OACTIVE; + + /* + * Set a timeout in case the chip goes out to lunch. + */ + ifp->if_timer = 5; +} + +static void +cue_init(xsc) + void *xsc; +{ + struct cue_softc *sc = xsc; + struct ifnet *ifp = GET_IFP(sc); + int i, s, ctl; + u_char *eaddr; + + if (sc->cue_dying) + return; + + DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev),__FUNCTION__)); + + if (ifp->if_flags & IFF_RUNNING) + return; + + s = splimp(); + + /* + * Cancel pending I/O and free all RX/TX buffers. + */ +#if 1 + cue_reset(sc); +#endif + + /* Set advanced operation modes. */ + cue_csr_write_1(sc, CUE_ADVANCED_OPMODES, + CUE_AOP_EMBED_RXLEN | 0x03); /* 1 wait state */ + +#if defined(__FreeBSD__) || defined(__OpenBSD__) + eaddr = sc->arpcom.ac_enaddr; +#elif defined(__NetBSD__) + eaddr = LLADDR(ifp->if_sadl); +#endif /* defined(__NetBSD__) */ + /* Set MAC address */ + for (i = 0; i < ETHER_ADDR_LEN; i++) + cue_csr_write_1(sc, CUE_PAR0 - i, eaddr[i]); + + /* Enable RX logic. */ + ctl = CUE_ETHCTL_RX_ON | CUE_ETHCTL_MCAST_ON; + if (ifp->if_flags & IFF_PROMISC) + ctl |= CUE_ETHCTL_PROMISC; + cue_csr_write_1(sc, CUE_ETHCTL, ctl); + + /* Init TX ring. */ + if (cue_tx_list_init(sc) == ENOBUFS) { + printf("%s: tx list init failed\n", USBDEVNAME(sc->cue_dev)); + splx(s); + return; + } + + /* Init RX ring. */ + if (cue_rx_list_init(sc) == ENOBUFS) { + printf("%s: rx list init failed\n", USBDEVNAME(sc->cue_dev)); + splx(s); + return; + } + + /* Load the multicast filter. */ + cue_setmulti(sc); + + /* + * Set the number of RX and TX buffers that we want + * to reserve inside the ASIC. + */ + cue_csr_write_1(sc, CUE_RX_BUFPKTS, CUE_RX_FRAMES); + cue_csr_write_1(sc, CUE_TX_BUFPKTS, CUE_TX_FRAMES); + + /* Set advanced operation modes. */ + cue_csr_write_1(sc, CUE_ADVANCED_OPMODES, + CUE_AOP_EMBED_RXLEN | 0x01); /* 1 wait state */ + + /* Program the LED operation. */ + cue_csr_write_1(sc, CUE_LEDCTL, CUE_LEDCTL_FOLLOW_LINK); + + if (sc->cue_ep[CUE_ENDPT_RX] == NULL) { + if (cue_open_pipes(sc)) { + splx(s); + return; + } + } + + ifp->if_flags |= IFF_RUNNING; + ifp->if_flags &= ~IFF_OACTIVE; + + splx(s); + + usb_callout(sc->cue_stat_ch, hz, cue_tick, sc); +} + +static int +cue_open_pipes(sc) + struct cue_softc *sc; +{ + struct cue_chain *c; + usbd_status err; + int i; + + /* Open RX and TX pipes. */ + err = usbd_open_pipe(sc->cue_iface, sc->cue_ed[CUE_ENDPT_RX], + USBD_EXCLUSIVE_USE, &sc->cue_ep[CUE_ENDPT_RX]); + if (err) { + printf("%s: open rx pipe failed: %s\n", + USBDEVNAME(sc->cue_dev), usbd_errstr(err)); + return (EIO); + } + err = usbd_open_pipe(sc->cue_iface, sc->cue_ed[CUE_ENDPT_TX], + USBD_EXCLUSIVE_USE, &sc->cue_ep[CUE_ENDPT_TX]); + if (err) { + printf("%s: open tx pipe failed: %s\n", + USBDEVNAME(sc->cue_dev), usbd_errstr(err)); + return (EIO); + } + + /* Start up the receive pipe. */ + for (i = 0; i < CUE_RX_LIST_CNT; i++) { + c = &sc->cue_cdata.cue_rx_chain[i]; + 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); + } + + return (0); +} + +static int +cue_ioctl(ifp, command, data) + 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(); + + 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); + + switch (ifa->ifa_addr->sa_family) { +#ifdef INET + case AF_INET: +#if defined(__NetBSD__) + arp_ifinit(ifp, ifa); +#else + arp_ifinit(&sc->arpcom, ifa); +#endif + break; +#endif /* INET */ +#ifdef NS + case AF_NS: + { + struct ns_addr *ina = &IA_SNS(ifa)->sns_addr; + + if (ns_nullhost(*ina)) + ina->x_host = *(union ns_host *) + LLADDR(ifp->if_sadl); + else + memcpy(LLADDR(ifp->if_sadl), + ina->x_host.c_host, + ifp->if_addrlen); + break; + } +#endif /* NS */ + } + break; + + case SIOCSIFMTU: + if (ifr->ifr_mtu > ETHERMTU) + error = EINVAL; + else + 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 && + ifp->if_flags & IFF_PROMISC && + !(sc->cue_if_flags & IFF_PROMISC)) { + CUE_SETBIT(sc, CUE_ETHCTL, CUE_ETHCTL_PROMISC); + cue_setmulti(sc); + } else if (ifp->if_flags & IFF_RUNNING && + !(ifp->if_flags & IFF_PROMISC) && + sc->cue_if_flags & IFF_PROMISC) { + CUE_CLRBIT(sc, CUE_ETHCTL, CUE_ETHCTL_PROMISC); + cue_setmulti(sc); + } else if (!(ifp->if_flags & IFF_RUNNING)) + cue_init(sc); + } else { + if (ifp->if_flags & IFF_RUNNING) + cue_stop(sc); + } + sc->cue_if_flags = ifp->if_flags; + error = 0; + break; + case SIOCADDMULTI: + case SIOCDELMULTI: + cue_setmulti(sc); + error = 0; + break; + default: + error = EINVAL; + break; + } + + splx(s); + + return (error); +} + +static void +cue_watchdog(ifp) + struct ifnet *ifp; +{ + struct cue_softc *sc = ifp->if_softc; + + DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev),__FUNCTION__)); + + if (sc->cue_dying) + return; + + 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); + + if (ifp->if_snd.ifq_head != NULL) + cue_start(ifp); +} + +/* + * Stop the adapter and free any mbufs allocated to the + * RX and TX lists. + */ +static void +cue_stop(sc) + struct cue_softc *sc; +{ + usbd_status err; + struct ifnet *ifp; + int i; + + DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev),__FUNCTION__)); + + ifp = GET_IFP(sc); + ifp->if_timer = 0; + + cue_csr_write_1(sc, CUE_ETHCTL, 0); + cue_reset(sc); + usb_uncallout(sc->cue_stat_ch, cue_tick, sc); + + /* Stop transfers. */ + if (sc->cue_ep[CUE_ENDPT_RX] != NULL) { + err = usbd_abort_pipe(sc->cue_ep[CUE_ENDPT_RX]); + if (err) { + printf("%s: abort rx pipe failed: %s\n", + USBDEVNAME(sc->cue_dev), usbd_errstr(err)); + } + err = usbd_close_pipe(sc->cue_ep[CUE_ENDPT_RX]); + if (err) { + printf("%s: close rx pipe failed: %s\n", + USBDEVNAME(sc->cue_dev), usbd_errstr(err)); + } + sc->cue_ep[CUE_ENDPT_RX] = NULL; + } + + if (sc->cue_ep[CUE_ENDPT_TX] != NULL) { + err = usbd_abort_pipe(sc->cue_ep[CUE_ENDPT_TX]); + if (err) { + printf("%s: abort tx pipe failed: %s\n", + USBDEVNAME(sc->cue_dev), usbd_errstr(err)); + } + err = usbd_close_pipe(sc->cue_ep[CUE_ENDPT_TX]); + if (err) { + printf("%s: close tx pipe failed: %s\n", + USBDEVNAME(sc->cue_dev), usbd_errstr(err)); + } + sc->cue_ep[CUE_ENDPT_TX] = NULL; + } + + if (sc->cue_ep[CUE_ENDPT_INTR] != NULL) { + err = usbd_abort_pipe(sc->cue_ep[CUE_ENDPT_INTR]); + if (err) { + printf("%s: abort intr pipe failed: %s\n", + USBDEVNAME(sc->cue_dev), usbd_errstr(err)); + } + err = usbd_close_pipe(sc->cue_ep[CUE_ENDPT_INTR]); + if (err) { + printf("%s: close intr pipe failed: %s\n", + USBDEVNAME(sc->cue_dev), usbd_errstr(err)); + } + sc->cue_ep[CUE_ENDPT_INTR] = NULL; + } + + /* Free RX resources. */ + for (i = 0; i < CUE_RX_LIST_CNT; i++) { + if (sc->cue_cdata.cue_rx_chain[i].cue_mbuf != NULL) { + m_freem(sc->cue_cdata.cue_rx_chain[i].cue_mbuf); + sc->cue_cdata.cue_rx_chain[i].cue_mbuf = NULL; + } + if (sc->cue_cdata.cue_rx_chain[i].cue_xfer != NULL) { + usbd_free_xfer(sc->cue_cdata.cue_rx_chain[i].cue_xfer); + sc->cue_cdata.cue_rx_chain[i].cue_xfer = NULL; + } + } + + /* Free TX resources. */ + for (i = 0; i < CUE_TX_LIST_CNT; i++) { + if (sc->cue_cdata.cue_tx_chain[i].cue_mbuf != NULL) { + m_freem(sc->cue_cdata.cue_tx_chain[i].cue_mbuf); + sc->cue_cdata.cue_tx_chain[i].cue_mbuf = NULL; + } + if (sc->cue_cdata.cue_tx_chain[i].cue_xfer != NULL) { + usbd_free_xfer(sc->cue_cdata.cue_tx_chain[i].cue_xfer); + sc->cue_cdata.cue_tx_chain[i].cue_xfer = NULL; + } + } + + 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 new file mode 100644 index 00000000000..d9bdb8b1348 --- /dev/null +++ b/sys/dev/usb/if_cuereg.h @@ -0,0 +1,200 @@ +/* $OpenBSD: if_cuereg.h,v 1.1 2000/03/28 19:37:47 aaron Exp $ */ +/* $NetBSD: if_cuereg.h,v 1.9 2000/03/24 22:13:24 augustss Exp $ */ +/* + * Copyright (c) 1997, 1998, 1999, 2000 + * Bill Paul . All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Bill Paul. + * 4. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD: src/sys/dev/usb/if_cuereg.h,v 1.3 2000/01/16 22:45:06 wpaul Exp $ + */ + +/* + * Definitions for the CATC Netmate II USB to ethernet controller. + */ + + +/* + * Vendor specific control commands. + */ +#define CUE_CMD_RESET 0xF4 +#define CUE_CMD_GET_MACADDR 0xF2 +#define CUE_CMD_WRITEREG 0xFA +#define CUE_CMD_READREG 0xFB +#define CUE_CMD_READSRAM 0xF1 +#define CUE_CMD_WRITESRAM 0xFC + +/* + * Internal registers + */ +#define CUE_TX_BUFCNT 0x20 +#define CUE_RX_BUFCNT 0x21 +#define CUE_ADVANCED_OPMODES 0x22 +#define CUE_TX_BUFPKTS 0x23 +#define CUE_RX_BUFPKTS 0x24 +#define CUE_RX_MAXCHAIN 0x25 + +#define CUE_ETHCTL 0x60 +#define CUE_ETHSTS 0x61 +#define CUE_PAR5 0x62 +#define CUE_PAR4 0x63 +#define CUE_PAR3 0x64 +#define CUE_PAR2 0x65 +#define CUE_PAR1 0x66 +#define CUE_PAR0 0x67 + +/* Error counters, all 16 bits wide. */ +#define CUE_TX_SINGLECOLL 0x69 +#define CUE_TX_MULTICOLL 0x6B +#define CUE_TX_EXCESSCOLL 0x6D +#define CUE_RX_FRAMEERR 0x6F + +#define CUE_LEDCTL 0x81 + +/* Advenced operating mode register */ +#define CUE_AOP_SRAMWAITS 0x03 +#define CUE_AOP_EMBED_RXLEN 0x08 +#define CUE_AOP_RXCOMBINE 0x10 +#define CUE_AOP_TXCOMBINE 0x20 +#define CUE_AOP_EVEN_PKT_READS 0x40 +#define CUE_AOP_LOOPBK 0x80 + +/* Ethernet control register */ +#define CUE_ETHCTL_RX_ON 0x01 +#define CUE_ETHCTL_LINK_POLARITY 0x02 +#define CUE_ETHCTL_LINK_FORCE_OK 0x04 +#define CUE_ETHCTL_MCAST_ON 0x08 +#define CUE_ETHCTL_PROMISC 0x10 + +/* Ethernet status register */ +#define CUE_ETHSTS_NO_CARRIER 0x01 +#define CUE_ETHSTS_LATECOLL 0x02 +#define CUE_ETHSTS_EXCESSCOLL 0x04 +#define CUE_ETHSTS_TXBUF_AVAIL 0x08 +#define CUE_ETHSTS_BAD_POLARITY 0x10 +#define CUE_ETHSTS_LINK_OK 0x20 + +/* LED control register */ +#define CUE_LEDCTL_BLINK_1X 0x00 +#define CUE_LEDCTL_BLINK_2X 0x01 +#define CUE_LEDCTL_BLINK_QUARTER_ON 0x02 +#define CUE_LEDCTL_BLINK_QUARTER_OFF 0x03 +#define CUE_LEDCTL_OFF 0x04 +#define CUE_LEDCTL_FOLLOW_LINK 0x08 + +/* + * Address in ASIC's internal SRAM where the + * multicast hash table lives. The table is 64 bytes long, + * giving us a 512-bit table. We have to set the bit that + * corresponds to the broadcast address in order to enable + * reception of broadcast frames. + */ +#define CUE_MCAST_TABLE_ADDR 0xFA80 +#define CUE_MCAST_TABLE_LEN 64 + +#define CUE_TIMEOUT 1000 +#define ETHER_ALIGN 2 +#define CUE_BUFSZ 1536 +#define CUE_MIN_FRAMELEN 60 +#define CUE_RX_FRAMES 1 +#define CUE_TX_FRAMES 1 + +#define CUE_RX_LIST_CNT 1 +#define CUE_TX_LIST_CNT 1 + +#define CUE_CTL_READ 0x01 +#define CUE_CTL_WRITE 0x02 + +#define CUE_CONFIG_NO 1 +#define CUE_IFACE_IDX 0 + +/* + * The interrupt endpoint is currently unused by the CATC part. + */ +#define CUE_ENDPT_RX 0x0 +#define CUE_ENDPT_TX 0x1 +#define CUE_ENDPT_INTR 0x2 +#define CUE_ENDPT_MAX 0x3 + +struct cue_type { + u_int16_t cue_vid; + u_int16_t cue_did; +}; + +struct cue_softc; + +struct cue_chain { + struct cue_softc *cue_sc; + usbd_xfer_handle cue_xfer; + char *cue_buf; + struct mbuf *cue_mbuf; + int cue_idx; +}; + +struct cue_cdata { + struct cue_chain cue_tx_chain[CUE_TX_LIST_CNT]; + struct cue_chain cue_rx_chain[CUE_RX_LIST_CNT]; + int cue_tx_prod; + int cue_tx_cons; + int cue_tx_cnt; + int cue_rx_prod; +}; + +struct cue_softc { + USBBASEDEVICE cue_dev; + +#if defined(__FreeBSD__) || defined(__OpenBSD__) + struct arpcom arpcom; +#define GET_IFP(sc) (&(sc)->arpcom.ac_if) +#elif defined(__NetBSD__) + struct ethercom cue_ec; +#if NRND > 0 + rndsource_element_t rnd_source; +#endif +#define GET_IFP(sc) (&(sc)->cue_ec.ec_if) +#endif + + usb_callout_t cue_stat_ch; + + usbd_device_handle cue_udev; + usbd_interface_handle cue_iface; + u_int16_t cue_vendor; + u_int16_t cue_product; + int cue_ed[CUE_ENDPT_MAX]; + usbd_pipe_handle cue_ep[CUE_ENDPT_MAX]; + int cue_unit; + u_int8_t cue_mctab[CUE_MCAST_TABLE_LEN]; + int cue_if_flags; + u_int16_t cue_rxfilt; + struct cue_cdata cue_cdata; + + char cue_dying; + char cue_attached; + u_int cue_rx_errs; + struct timeval cue_rx_notice; +}; diff --git a/sys/dev/usb/if_kue.c b/sys/dev/usb/if_kue.c index 6ae0101b812..0f0e7c567cb 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.1 2000/03/26 18:49:44 aaron Exp $ */ -/* $NetBSD: if_kue.c,v 1.21 2000/03/24 22:03:30 augustss Exp $ */ +/* $OpenBSD: if_kue.c,v 1.2 2000/03/28 19:37:47 aaron Exp $ */ +/* $NetBSD: if_kue.c,v 1.23 2000/03/26 15:08:44 augustss Exp $ */ /* * Copyright (c) 1997, 1998, 1999, 2000 * Bill Paul . All rights reserved. @@ -76,7 +76,14 @@ * more DPRINTF * proper cleanup on errors */ +#if defined(__NetBSD__) +#include "opt_inet.h" +#include "opt_ns.h" #include "bpfilter.h" +#include "rnd.h" +#elif defined(__OpenBSD__) +#include "bpfilter.h" +#endif #include #include @@ -86,12 +93,46 @@ #include #include +#if defined(__FreeBSD__) + +#include +#include /* for DELAY */ +#include + +#elif defined(__NetBSD__) || defined(__OpenBSD__) + #include +#if NRND > 0 +#include +#endif + +#endif #include +#if defined(__NetBSD__) || defined(__FreeBSD__) +#include +#endif #include -#include +#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 +#include +#endif + +#if defined(__NetBSD__) +#include +#ifdef INET +#include +#include +#endif +#endif /* defined (__NetBSD__) */ + +#if defined(__OpenBSD__) #ifdef INET #include #include @@ -99,23 +140,24 @@ #include #include #endif +#endif /* defined (__OpenBSD__) */ -#include - -#if NBPFILTER > 0 -#include -#endif - +#if defined(__NetBSD__) || defined(__OpenBSD__) #ifdef NS #include #include #endif +#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ #include #include #include #include +#ifdef __FreeBSD__ +#include +#endif + #include #include @@ -145,40 +187,74 @@ static struct kue_type kue_devs[] = { { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650C }, { USB_VENDOR_SMC, USB_PRODUCT_SMC_2102USB }, { USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10T }, - { USB_VENDOR_KLSI, USB_PRODUCT_KLSI_USB101 }, + { USB_VENDOR_KLSI, USB_PRODUCT_KLSI_DUH3E10BT }, { 0, 0 } }; USB_DECLARE_DRIVER(kue); -int kue_tx_list_init __P((struct kue_softc *)); -int kue_rx_list_init __P((struct kue_softc *)); -int kue_newbuf __P((struct kue_softc *, struct kue_chain *, - struct mbuf *)); -int kue_send __P((struct kue_softc *, struct mbuf *, int)); -int kue_open_pipes __P((struct kue_softc *)); -void kue_rxeof __P((usbd_xfer_handle, - usbd_private_handle, usbd_status)); -void kue_txeof __P((usbd_xfer_handle, - usbd_private_handle, usbd_status)); -void kue_start __P((struct ifnet *)); -int kue_ioctl __P((struct ifnet *, u_long, caddr_t)); -void kue_init __P((void *)); -void kue_stop __P((struct kue_softc *)); -void kue_watchdog __P((struct ifnet *)); - -void kue_setmulti __P((struct kue_softc *)); -void kue_reset __P((struct kue_softc *)); - -usbd_status kue_ctl __P((struct kue_softc *, int, u_int8_t, - u_int16_t, void *, u_int32_t)); -usbd_status kue_setword __P((struct kue_softc *, u_int8_t, u_int16_t)); -int kue_load_fw __P((struct kue_softc *)); +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) -usbd_status +static usbd_status kue_setword(sc, breq, word) struct kue_softc *sc; u_int8_t breq; @@ -203,7 +279,7 @@ kue_setword(sc, breq, word) return (err); } -usbd_status +static usbd_status kue_ctl(sc, rw, breq, val, data, len) struct kue_softc *sc; int rw; @@ -236,7 +312,26 @@ kue_ctl(sc, rw, breq, val, data, len) return (err); } -int +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; { @@ -256,9 +351,7 @@ kue_load_fw(sc) * We can test this quickly by issuing a request that * is only valid after firmware download. */ - err = kue_ctl(sc, KUE_CTL_READ, KUE_CMD_GET_ETHER_DESCRIPTOR, - 0, &sc->kue_desc, sizeof(sc->kue_desc)); - if (!err) { + if (kue_is_warm(sc)) { printf("%s: warm boot, no firmware download\n", USBDEVNAME(sc->kue_dev)); return (0); @@ -320,18 +413,19 @@ kue_load_fw(sc) return (0); } -void +static void kue_setmulti(sc) struct kue_softc *sc; { - struct ifnet *ifp; - struct arpcom *ac = &sc->arpcom; + 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; - ifp = &sc->arpcom.ac_if; - DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->kue_dev), __FUNCTION__)); if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) { @@ -344,7 +438,27 @@ kue_setmulti(sc) sc->kue_rxfilt &= ~KUE_RXFILT_ALLMULTI; i = 0; - ETHER_FIRST_MULTI(step, ac, enm); +#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; @@ -360,6 +474,7 @@ kue_setmulti(sc) ETHER_NEXT_MULTI(step, enm); i++; } +#endif if (i == KUE_MCFILTCNT(sc)) sc->kue_rxfilt |= KUE_RXFILT_ALLMULTI; @@ -377,7 +492,7 @@ kue_setmulti(sc) * done after the firmware is loaded into the adapter in order to * bring it into proper operation. */ -void +static void kue_reset(sc) struct kue_softc *sc; { @@ -430,6 +545,10 @@ 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); @@ -511,11 +630,44 @@ USB_ATTACH(kue) /* * 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)); /* Initialize interface info.*/ - ifp = &sc->arpcom.ac_if; + ifp = GET_IFP(sc); ifp->if_softc = sc; ifp->if_mtu = ETHERMTU; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; @@ -526,12 +678,22 @@ USB_ATTACH(kue) /* Attach the interface. */ if_attach(ifp); +#if defined(__NetBSD__) + ether_ifattach(ifp, sc->kue_desc.kue_macaddr); +#else ether_ifattach(ifp); +#endif #if NBPFILTER > 0 - bpfattach(&sc->arpcom.ac_if.if_bpf, ifp, DLT_EN10MB, + bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header)); #endif +#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); @@ -544,7 +706,7 @@ USB_ATTACH(kue) USB_DETACH(kue) { USB_DETACH_START(kue, sc); - struct ifnet *ifp = &sc->arpcom.ac_if; + struct ifnet *ifp = GET_IFP(sc); int s; s = splusb(); /* XXX why? */ @@ -563,10 +725,15 @@ USB_DETACH(kue) if (ifp->if_flags & IFF_RUNNING) kue_stop(sc); +#if defined(__NetBSD__) +#if NRND > 0 + rnd_detach_source(&sc->rnd_source); +#endif #if NBPFILTER > 0 bpfdetach(ifp); #endif ether_ifdetach(ifp); +#endif /* __NetBSD__ */ if_detach(ifp); @@ -584,6 +751,7 @@ USB_DETACH(kue) return (0); } +#if defined(__NetBSD__) || defined(__OpenBSD__) int kue_activate(self, act) device_ptr_t self; @@ -599,17 +767,21 @@ kue_activate(self, act) break; case DVACT_DEACTIVATE: +#if defined(__NetBSD__) + /* Deactivate the interface. */ + if_deactivate(&sc->kue_ec.ec_if); +#endif sc->kue_dying = 1; - return (EOPNOTSUPP); break; } return (0); } +#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ /* * Initialize an RX descriptor and attach an MBUF cluster. */ -int +static int kue_newbuf(sc, c, m) struct kue_softc *sc; struct kue_chain *c; @@ -646,7 +818,7 @@ kue_newbuf(sc, c, m) return (0); } -int +static int kue_rx_list_init(sc) struct kue_softc *sc; { @@ -676,7 +848,7 @@ kue_rx_list_init(sc) return (0); } -int +static int kue_tx_list_init(sc) struct kue_softc *sc; { @@ -733,19 +905,21 @@ kue_rxstart(ifp) * A frame has been uploaded: pass the resulting mbuf chain up to * the higher level protocols. */ -void +static void kue_rxeof(xfer, priv, status) usbd_xfer_handle xfer; usbd_private_handle priv; usbd_status status; { - struct ether_header *eh; struct kue_chain *c = priv; struct kue_softc *sc = c->kue_sc; - struct ifnet *ifp = &sc->arpcom.ac_if; + struct ifnet *ifp = GET_IFP(sc); struct mbuf *m; int total_len = 0; +#if defined(__NetBSD__) || defined(__OpenBSD__) int s; + struct ether_header *eh; +#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ DPRINTFN(10,("%s: %s: enter status=%d\n", USBDEVNAME(sc->kue_dev), __FUNCTION__, status)); @@ -796,6 +970,14 @@ 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(); @@ -809,15 +991,36 @@ kue_rxeof(xfer, priv, status) eh = mtod(m, struct ether_header *); #if NBPFILTER > 0 - if (ifp->if_bpf) - bpf_mtap(ifp->if_bpf, m); + /* + * Handle BPF listeners. Let the BPF user see the packet, but + * don't pass it up to the ether_input() layer unless it's + * a broadcast packet, multicast packet, matches our ethernet + * address or the interface is in promiscuous mode. + */ + if (ifp->if_bpf) { + BPF_MTAP(ifp, m); +#if defined(__NetBSD__) + 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; + } +#endif + } #endif DPRINTFN(10,("%s: %s: deliver %d\n", USBDEVNAME(sc->kue_dev), __FUNCTION__, m->m_len)); +#if defined(__NetBSD__) + (*ifp->if_input)(ifp, m); +#else ether_input(ifp, eh, m); +#endif done1: splx(s); +#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */ done: @@ -836,7 +1039,7 @@ kue_rxeof(xfer, priv, status) * the list buffers. */ -void +static void kue_txeof(xfer, priv, status) usbd_xfer_handle xfer; usbd_private_handle priv; @@ -844,7 +1047,7 @@ kue_txeof(xfer, priv, status) { struct kue_chain *c = priv; struct kue_softc *sc = c->kue_sc; - struct ifnet *ifp = &sc->arpcom.ac_if; + struct ifnet *ifp = GET_IFP(sc); int s; if (sc->kue_dying) @@ -874,16 +1077,22 @@ 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); } -int +static int kue_send(sc, m, idx) struct kue_softc *sc; struct mbuf *m; @@ -928,7 +1137,7 @@ kue_send(sc, m, idx) return (0); } -void +static void kue_start(ifp) struct ifnet *ifp; { @@ -959,7 +1168,7 @@ kue_start(ifp) * to him. */ if (ifp->if_bpf) - bpf_mtap(ifp->if_bpf, m_head); + BPF_MTAP(ifp, m_head); #endif ifp->if_flags |= IFF_OACTIVE; @@ -970,12 +1179,12 @@ kue_start(ifp) ifp->if_timer = 5; } -void +static void kue_init(xsc) void *xsc; { struct kue_softc *sc = xsc; - struct ifnet *ifp = &sc->arpcom.ac_if; + struct ifnet *ifp = GET_IFP(sc); int s; u_char *eaddr; @@ -986,8 +1195,11 @@ kue_init(xsc) s = splimp(); +#if defined(__FreeBSD__) || defined(__OpenBSD__) eaddr = sc->arpcom.ac_enaddr; - +#elif defined(__NetBSD__) + eaddr = LLADDR(ifp->if_sadl); +#endif /* defined(__NetBSD__) */ /* Set MAC address */ kue_ctl(sc, KUE_CTL_WRITE, KUE_CMD_SET_MAC, 0, eaddr, ETHER_ADDR_LEN); @@ -1039,7 +1251,7 @@ kue_init(xsc) splx(s); } -int +static int kue_open_pipes(sc) struct kue_softc *sc; { @@ -1081,15 +1293,17 @@ kue_open_pipes(sc) return (0); } -int +static int kue_ioctl(ifp, command, data) 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__)); @@ -1100,6 +1314,13 @@ kue_ioctl(ifp, command, data) s = splimp(); 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); @@ -1107,7 +1328,11 @@ kue_ioctl(ifp, command, data) switch (ifa->ifa_addr->sa_family) { #ifdef INET case AF_INET: +#if defined(__NetBSD__) + arp_ifinit(ifp, ifa); +#else arp_ifinit(&sc->arpcom, ifa); +#endif break; #endif /* INET */ #ifdef NS @@ -1117,9 +1342,9 @@ kue_ioctl(ifp, command, data) if (ns_nullhost(*ina)) ina->x_host = *(union ns_host *) - sc->arpcom.ac_enaddr; + LLADDR(ifp->if_sadl); else - memcpy(sc->arpcom.ac_enaddr, + memcpy(LLADDR(ifp->if_sadl), ina->x_host.c_host, ifp->if_addrlen); break; @@ -1135,6 +1360,8 @@ 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 && @@ -1173,7 +1400,7 @@ kue_ioctl(ifp, command, data) return (error); } -void +static void kue_watchdog(ifp) struct ifnet *ifp; { @@ -1206,7 +1433,7 @@ kue_watchdog(ifp) * Stop the adapter and free any mbufs allocated to the * RX and TX lists. */ -void +static void kue_stop(sc) struct kue_softc *sc; { @@ -1216,7 +1443,7 @@ kue_stop(sc) DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->kue_dev),__FUNCTION__)); - ifp = &sc->arpcom.ac_if; + ifp = GET_IFP(sc); ifp->if_timer = 0; /* Stop transfers. */ diff --git a/sys/dev/usb/if_kuereg.h b/sys/dev/usb/if_kuereg.h index dba241d9dad..ad5cf17b517 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.1 2000/03/26 18:49:44 aaron Exp $ */ +/* $OpenBSD: if_kuereg.h,v 1.2 2000/03/28 19:37:48 aaron Exp $ */ /* $NetBSD: if_kuereg.h,v 1.9 2000/03/24 22:13:24 augustss Exp $ */ /* * Copyright (c) 1997, 1998, 1999, 2000 @@ -161,7 +161,17 @@ struct kue_cdata { struct kue_softc { USBBASEDEVICE kue_dev; +#if defined(__FreeBSD__) || defined(__OpenBSD__) struct arpcom arpcom; +#define GET_IFP(sc) (&(sc)->arpcom.ac_if) +#elif defined(__NetBSD__) + struct ethercom kue_ec; +#if NRND > 0 + rndsource_element_t rnd_source; +#endif +#define GET_IFP(sc) (&(sc)->kue_ec.ec_if) +#endif + usbd_device_handle kue_udev; usbd_interface_handle kue_iface; u_int16_t kue_vendor; diff --git a/sys/dev/usb/kue_fw.h b/sys/dev/usb/kue_fw.h index bf0f16e1c07..6de46b531e8 100644 --- a/sys/dev/usb/kue_fw.h +++ b/sys/dev/usb/kue_fw.h @@ -1,4 +1,5 @@ -/* $OpenBSD: kue_fw.h,v 1.1 2000/03/26 19:09:17 aaron Exp $ */ +/* $OpenBSD: kue_fw.h,v 1.2 2000/03/28 19:37:48 aaron Exp $ */ +/* $NetBSD: kue_fw.h,v 1.1 2000/01/17 01:38:43 augustss Exp $ */ /* * Copyright (c) 1997, 1998, 1999, 2000 * Bill Paul . All rights reserved. @@ -76,7 +77,7 @@ */ #define KUE_QTBTYPE_WRITE_WITH_INTR 0x07 /* Cause data from stream to be written using specified QT interrupt. */ -#define KUE_QTBTYPE_WRITE_STR_WITH_INTR 0x08 +#define KUE_QTBTYPE_WRITE_STR_WITH_INTR 0x08 /* Cause data to be written to config locations. */ /* Addresses assume 0xc000 offset. */ #define KUE_QTBTYPE_WRITE_CONFIG 0x09 @@ -90,9 +91,9 @@ static unsigned char kue_code_seg[] = { /******************************************/ /* NOTE: B6/C3 is data header signature */ - /* 0xAA/0xBB is data length = total */ - /* bytes - 7, 0xCC is type, 0xDD is */ - /* interrupt to use. */ + /* 0xAA/0xBB is data length = total */ + /* bytes - 7, 0xCC is type, 0xDD is */ + /* interrupt to use. */ /******************************************/ 0xB6, 0xC3, 0xf7, 0x0e, 0x02, 0x64, 0x9f, 0xcf, 0xbc, 0x08, 0xe7, 0x57, 0x00, 0x00, @@ -574,7 +575,7 @@ static unsigned char kue_code_seg[] = 0x43, 0x04, 0x21, 0x04, 0xe0, 0x00, 0x43, 0x04, 0x21, 0x04, 0xe0, 0x00, 0xc1, 0x07, 0x01, 0x00, 0xc9, 0x05, 0xc8, 0x05, 0x97, 0xcf, - 0, 0 + 0, 0 }; /* Firmware fixup (data?) segment */ @@ -582,9 +583,9 @@ static unsigned char kue_fix_seg[] = { /******************************************/ /* NOTE: B6/C3 is data header signature */ - /* 0xAA/0xBB is data length = total */ - /* bytes - 7, 0xCC is type, 0xDD is */ - /* interrupt to use. */ + /* 0xAA/0xBB is data length = total */ + /* bytes - 7, 0xCC is type, 0xDD is */ + /* interrupt to use. */ /******************************************/ 0xB6, 0xC3, 0xc9, 0x02, 0x03, 0x64, 0x02, 0x00, 0x08, 0x00, 0x24, 0x00, 0x2e, 0x00, @@ -676,11 +677,11 @@ static unsigned char kue_fix_seg[] = 0xd4, 0x0d, 0xdc, 0x0d, 0x1e, 0x0e, 0x2c, 0x0e, 0x3e, 0x0e, 0x4c, 0x0e, 0x50, 0x0e, 0x5e, 0x0e, 0xae, 0x0e, 0xb8, 0x0e, 0xc6, 0x0e, 0xca, 0x0e, - 0, 0 + 0, 0 }; /* Fixup command. */ #define KUE_TRIGCMD_OFFSET 5 static unsigned char kue_trig_seg[] = { -0xb6, 0xc3, 0x01, 0x00, 0x06, 0x64, 0x00, 0x00 + 0xb6, 0xc3, 0x01, 0x00, 0x06, 0x64, 0x00, 0x00 }; diff --git a/sys/dev/usb/ohci.c b/sys/dev/usb/ohci.c index d57b51f1d45..83b2105b4cb 100644 --- a/sys/dev/usb/ohci.c +++ b/sys/dev/usb/ohci.c @@ -1,5 +1,6 @@ -/* $OpenBSD: ohci.c,v 1.8 2000/03/26 08:39:45 aaron Exp $ */ -/* $NetBSD: ohci.c,v 1.78 2000/03/20 00:37:00 augustss Exp $ */ +/* $OpenBSD: ohci.c,v 1.9 2000/03/28 19:37:48 aaron Exp $ */ +/* $NetBSD: ohci.c,v 1.81 2000/03/25 18:02:32 augustss Exp $ */ +/* $FreeBSD: src/sys/dev/usb/ohci.c,v 1.22 1999/11/17 22:33:40 n_hibma Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -101,114 +102,122 @@ int ohcidebug = 0; * The OHCI controller is little endian, so on big endian machines * the data strored in memory needs to be swapped. */ +#if defined(__FreeBSD__) || defined(__OpenBSD__) #if BYTE_ORDER == BIG_ENDIAN -#define LE(x) (bswap32(x)) +#define htole32(x) (bswap32(x)) +#define le32toh(x) (bswap32(x)) #else -#define LE(x) (x) +#define htole32(x) (x) +#define le32toh(x) (x) +#endif #endif struct ohci_pipe; -ohci_soft_ed_t *ohci_alloc_sed __P((ohci_softc_t *)); -void ohci_free_sed __P((ohci_softc_t *, ohci_soft_ed_t *)); +static ohci_soft_ed_t *ohci_alloc_sed __P((ohci_softc_t *)); +static void ohci_free_sed __P((ohci_softc_t *, ohci_soft_ed_t *)); -ohci_soft_td_t *ohci_alloc_std __P((ohci_softc_t *)); -void ohci_free_std __P((ohci_softc_t *, ohci_soft_td_t *)); +static ohci_soft_td_t *ohci_alloc_std __P((ohci_softc_t *)); +static void ohci_free_std __P((ohci_softc_t *, ohci_soft_td_t *)); -ohci_soft_itd_t *ohci_alloc_sitd __P((ohci_softc_t *)); -void ohci_free_sitd __P((ohci_softc_t *, ohci_soft_itd_t *)); +static ohci_soft_itd_t *ohci_alloc_sitd __P((ohci_softc_t *)); +static void ohci_free_sitd __P((ohci_softc_t *,ohci_soft_itd_t *)); #if 0 -void ohci_free_std_chain __P((ohci_softc_t *, - ohci_soft_td_t *, ohci_soft_td_t *)); +static void ohci_free_std_chain __P((ohci_softc_t *, + ohci_soft_td_t *, ohci_soft_td_t *)); #endif -usbd_status ohci_alloc_std_chain __P((struct ohci_pipe *, ohci_softc_t *, - int, int, usbd_xfer_handle, - ohci_soft_td_t *, - ohci_soft_td_t **)); - -void ohci_shutdown __P((void *v)); -void ohci_power __P((int, void *)); -usbd_status ohci_open __P((usbd_pipe_handle)); -void ohci_poll __P((struct usbd_bus *)); -void ohci_softintr __P((struct usbd_bus *)); -void ohci_waitintr __P((ohci_softc_t *, usbd_xfer_handle)); -void ohci_rhsc __P((ohci_softc_t *, usbd_xfer_handle)); - -usbd_status ohci_device_request __P((usbd_xfer_handle xfer)); -void ohci_add_ed __P((ohci_soft_ed_t *, ohci_soft_ed_t *)); -void ohci_rem_ed __P((ohci_soft_ed_t *, ohci_soft_ed_t *)); -void ohci_hash_add_td __P((ohci_softc_t *, ohci_soft_td_t *)); -void ohci_hash_rem_td __P((ohci_softc_t *, ohci_soft_td_t *)); -ohci_soft_td_t *ohci_hash_find_td __P((ohci_softc_t *, ohci_physaddr_t)); - -usbd_status ohci_setup_isoc __P((usbd_pipe_handle pipe)); -void ohci_device_isoc_enter __P((usbd_xfer_handle)); - -usbd_status ohci_allocm __P((struct usbd_bus *, usb_dma_t *, u_int32_t)); -void ohci_freem __P((struct usbd_bus *, usb_dma_t *)); - -usbd_xfer_handle ohci_allocx __P((struct usbd_bus *)); -void ohci_freex __P((struct usbd_bus *, usbd_xfer_handle)); - -usbd_status ohci_root_ctrl_transfer __P((usbd_xfer_handle)); -usbd_status ohci_root_ctrl_start __P((usbd_xfer_handle)); -void ohci_root_ctrl_abort __P((usbd_xfer_handle)); -void ohci_root_ctrl_close __P((usbd_pipe_handle)); -void ohci_root_ctrl_done __P((usbd_xfer_handle)); - -usbd_status ohci_root_intr_transfer __P((usbd_xfer_handle)); -usbd_status ohci_root_intr_start __P((usbd_xfer_handle)); -void ohci_root_intr_abort __P((usbd_xfer_handle)); -void ohci_root_intr_close __P((usbd_pipe_handle)); -void ohci_root_intr_done __P((usbd_xfer_handle)); - -usbd_status ohci_device_ctrl_transfer __P((usbd_xfer_handle)); -usbd_status ohci_device_ctrl_start __P((usbd_xfer_handle)); -void ohci_device_ctrl_abort __P((usbd_xfer_handle)); -void ohci_device_ctrl_close __P((usbd_pipe_handle)); -void ohci_device_ctrl_done __P((usbd_xfer_handle)); - -usbd_status ohci_device_bulk_transfer __P((usbd_xfer_handle)); -usbd_status ohci_device_bulk_start __P((usbd_xfer_handle)); -void ohci_device_bulk_abort __P((usbd_xfer_handle)); -void ohci_device_bulk_close __P((usbd_pipe_handle)); -void ohci_device_bulk_done __P((usbd_xfer_handle)); - -usbd_status ohci_device_intr_transfer __P((usbd_xfer_handle)); -usbd_status ohci_device_intr_start __P((usbd_xfer_handle)); -void ohci_device_intr_abort __P((usbd_xfer_handle)); -void ohci_device_intr_close __P((usbd_pipe_handle)); -void ohci_device_intr_done __P((usbd_xfer_handle)); - -usbd_status ohci_device_isoc_transfer __P((usbd_xfer_handle)); -usbd_status ohci_device_isoc_start __P((usbd_xfer_handle)); -void ohci_device_isoc_abort __P((usbd_xfer_handle)); -void ohci_device_isoc_close __P((usbd_pipe_handle)); -void ohci_device_isoc_done __P((usbd_xfer_handle)); - -usbd_status ohci_device_setintr __P((ohci_softc_t *sc, - struct ohci_pipe *pipe, int ival)); - -int ohci_str __P((usb_string_descriptor_t *, int, char *)); - -void ohci_timeout __P((void *)); -void ohci_rhsc_able __P((ohci_softc_t *, int)); - -void ohci_close_pipe __P((usbd_pipe_handle pipe, - ohci_soft_ed_t *head)); -void ohci_abort_xfer __P((usbd_xfer_handle xfer, - usbd_status status)); -void ohci_abort_xfer_end __P((void *)); - -void ohci_device_clear_toggle __P((usbd_pipe_handle pipe)); -void ohci_noop __P((usbd_pipe_handle pipe)); +static usbd_status ohci_alloc_std_chain __P((struct ohci_pipe *, + ohci_softc_t *, int, int, usbd_xfer_handle, + ohci_soft_td_t *, ohci_soft_td_t **)); + +static void ohci_shutdown __P((void *v)); +static void ohci_power __P((int, void *)); +static usbd_status ohci_open __P((usbd_pipe_handle)); +static void ohci_poll __P((struct usbd_bus *)); +static void ohci_softintr __P((struct usbd_bus *)); +static void ohci_waitintr __P((ohci_softc_t *, + usbd_xfer_handle)); +static void ohci_rhsc __P((ohci_softc_t *, usbd_xfer_handle)); + +static usbd_status ohci_device_request __P((usbd_xfer_handle xfer)); +static void ohci_add_ed __P((ohci_soft_ed_t *, ohci_soft_ed_t *)); +static void ohci_rem_ed __P((ohci_soft_ed_t *, ohci_soft_ed_t *)); +static void ohci_hash_add_td __P((ohci_softc_t *, + ohci_soft_td_t *)); +static void ohci_hash_rem_td __P((ohci_softc_t *, + ohci_soft_td_t *)); +static ohci_soft_td_t *ohci_hash_find_td __P((ohci_softc_t *, + ohci_physaddr_t)); + +static usbd_status ohci_setup_isoc __P((usbd_pipe_handle pipe)); +static void ohci_device_isoc_enter __P((usbd_xfer_handle)); + +static usbd_status ohci_allocm __P((struct usbd_bus *, usb_dma_t *, + u_int32_t)); +static void ohci_freem __P((struct usbd_bus *, usb_dma_t *)); + +static usbd_xfer_handle ohci_allocx __P((struct usbd_bus *)); +static void ohci_freex __P((struct usbd_bus *, usbd_xfer_handle)); + +static usbd_status ohci_root_ctrl_transfer __P((usbd_xfer_handle)); +static usbd_status ohci_root_ctrl_start __P((usbd_xfer_handle)); +static void ohci_root_ctrl_abort __P((usbd_xfer_handle)); +static void ohci_root_ctrl_close __P((usbd_pipe_handle)); +static void ohci_root_ctrl_done __P((usbd_xfer_handle)); + +static usbd_status ohci_root_intr_transfer __P((usbd_xfer_handle)); +static usbd_status ohci_root_intr_start __P((usbd_xfer_handle)); +static void ohci_root_intr_abort __P((usbd_xfer_handle)); +static void ohci_root_intr_close __P((usbd_pipe_handle)); +static void ohci_root_intr_done __P((usbd_xfer_handle)); + +static usbd_status ohci_device_ctrl_transfer __P((usbd_xfer_handle)); +static usbd_status ohci_device_ctrl_start __P((usbd_xfer_handle)); +static void ohci_device_ctrl_abort __P((usbd_xfer_handle)); +static void ohci_device_ctrl_close __P((usbd_pipe_handle)); +static void ohci_device_ctrl_done __P((usbd_xfer_handle)); + +static usbd_status ohci_device_bulk_transfer __P((usbd_xfer_handle)); +static usbd_status ohci_device_bulk_start __P((usbd_xfer_handle)); +static void ohci_device_bulk_abort __P((usbd_xfer_handle)); +static void ohci_device_bulk_close __P((usbd_pipe_handle)); +static void ohci_device_bulk_done __P((usbd_xfer_handle)); + +static usbd_status ohci_device_intr_transfer __P((usbd_xfer_handle)); +static usbd_status ohci_device_intr_start __P((usbd_xfer_handle)); +static void ohci_device_intr_abort __P((usbd_xfer_handle)); +static void ohci_device_intr_close __P((usbd_pipe_handle)); +static void ohci_device_intr_done __P((usbd_xfer_handle)); + +static usbd_status ohci_device_isoc_transfer __P((usbd_xfer_handle)); +static usbd_status ohci_device_isoc_start __P((usbd_xfer_handle)); +static void ohci_device_isoc_abort __P((usbd_xfer_handle)); +static void ohci_device_isoc_close __P((usbd_pipe_handle)); +static void ohci_device_isoc_done __P((usbd_xfer_handle)); + +static usbd_status ohci_device_setintr __P((ohci_softc_t *sc, + struct ohci_pipe *pipe, int ival)); + +static int ohci_str __P((usb_string_descriptor_t *, int, char *)); + +static void ohci_timeout __P((void *)); +static void ohci_rhsc_able __P((ohci_softc_t *, int)); + +static void ohci_close_pipe __P((usbd_pipe_handle pipe, + ohci_soft_ed_t *head)); +static void ohci_abort_xfer __P((usbd_xfer_handle xfer, + usbd_status status)); +static void ohci_abort_xfer_end __P((void *)); + +static void ohci_device_clear_toggle __P((usbd_pipe_handle pipe)); +static void ohci_noop __P((usbd_pipe_handle pipe)); #ifdef OHCI_DEBUG -void ohci_dumpregs __P((ohci_softc_t *)); -void ohci_dump_tds __P((ohci_soft_td_t *)); -void ohci_dump_td __P((ohci_soft_td_t *)); -void ohci_dump_ed __P((ohci_soft_ed_t *)); +static void ohci_dumpregs __P((ohci_softc_t *)); +static void ohci_dump_tds __P((ohci_soft_td_t *)); +static void ohci_dump_td __P((ohci_soft_td_t *)); +static void ohci_dump_ed __P((ohci_soft_ed_t *)); #endif #define OWRITE4(sc, r, x) bus_space_write_4((sc)->iot, (sc)->ioh, (r), (x)) @@ -249,7 +258,6 @@ struct ohci_pipe { } bulk; /* Iso pipe */ struct iso { - int xxxxx; int next, inuse; } iso; } u; @@ -257,7 +265,7 @@ struct ohci_pipe { #define OHCI_INTR_ENDPT 1 -struct usbd_bus_methods ohci_bus_methods = { +static struct usbd_bus_methods ohci_bus_methods = { ohci_open, ohci_softintr, ohci_poll, @@ -267,7 +275,7 @@ struct usbd_bus_methods ohci_bus_methods = { ohci_freex, }; -struct usbd_pipe_methods ohci_root_ctrl_methods = { +static struct usbd_pipe_methods ohci_root_ctrl_methods = { ohci_root_ctrl_transfer, ohci_root_ctrl_start, ohci_root_ctrl_abort, @@ -276,7 +284,7 @@ struct usbd_pipe_methods ohci_root_ctrl_methods = { ohci_root_ctrl_done, }; -struct usbd_pipe_methods ohci_root_intr_methods = { +static struct usbd_pipe_methods ohci_root_intr_methods = { ohci_root_intr_transfer, ohci_root_intr_start, ohci_root_intr_abort, @@ -285,7 +293,7 @@ struct usbd_pipe_methods ohci_root_intr_methods = { ohci_root_intr_done, }; -struct usbd_pipe_methods ohci_device_ctrl_methods = { +static struct usbd_pipe_methods ohci_device_ctrl_methods = { ohci_device_ctrl_transfer, ohci_device_ctrl_start, ohci_device_ctrl_abort, @@ -294,7 +302,7 @@ struct usbd_pipe_methods ohci_device_ctrl_methods = { ohci_device_ctrl_done, }; -struct usbd_pipe_methods ohci_device_intr_methods = { +static struct usbd_pipe_methods ohci_device_intr_methods = { ohci_device_intr_transfer, ohci_device_intr_start, ohci_device_intr_abort, @@ -303,7 +311,7 @@ struct usbd_pipe_methods ohci_device_intr_methods = { ohci_device_intr_done, }; -struct usbd_pipe_methods ohci_device_bulk_methods = { +static struct usbd_pipe_methods ohci_device_bulk_methods = { ohci_device_bulk_transfer, ohci_device_bulk_start, ohci_device_bulk_abort, @@ -312,7 +320,7 @@ struct usbd_pipe_methods ohci_device_bulk_methods = { ohci_device_bulk_done, }; -struct usbd_pipe_methods ohci_device_isoc_methods = { +static struct usbd_pipe_methods ohci_device_isoc_methods = { ohci_device_isoc_transfer, ohci_device_isoc_start, ohci_device_isoc_abort, @@ -356,8 +364,10 @@ ohci_detach(sc, flags) if (rv != 0) return (rv); +#if defined(__NetBSD__) || defined(__OpenBSD__) powerhook_disestablish(sc->sc_powerhook); shutdownhook_disestablish(sc->sc_shutdownhook); +#endif /* free data structures XXX */ @@ -377,7 +387,7 @@ ohci_alloc_sed(sc) if (sc->sc_freeeds == NULL) { DPRINTFN(2, ("ohci_alloc_sed: allocating chunk\n")); err = usb_allocmem(&sc->sc_bus, OHCI_SED_SIZE * OHCI_SED_CHUNK, - OHCI_ED_ALIGN, &dma); + OHCI_ED_ALIGN, &dma); if (err) return (0); for(i = 0; i < OHCI_SED_CHUNK; i++) { @@ -417,7 +427,7 @@ ohci_alloc_std(sc) if (sc->sc_freetds == NULL) { DPRINTFN(2, ("ohci_alloc_std: allocating chunk\n")); err = usb_allocmem(&sc->sc_bus, OHCI_STD_SIZE * OHCI_STD_CHUNK, - OHCI_TD_ALIGN, &dma); + OHCI_TD_ALIGN, &dma); if (err) return (0); s = splusb(); @@ -479,8 +489,8 @@ ohci_alloc_std_chain(opipe, sc, alen, rd, xfer, sp, ep) cur = sp; dataphys = DMAADDR(dma); dataphysend = OHCI_PAGE(dataphys + len - 1); - tdflags = LE( - (rd ? OHCI_TD_IN : OHCI_TD_OUT) | + tdflags = htole32( + (rd ? OHCI_TD_IN : OHCI_TD_OUT) | (flags & USBD_SHORT_XFER_OK ? OHCI_TD_R : 0) | OHCI_TD_NOCC | OHCI_TD_TOGGLE_CARRY | OHCI_TD_NOINTR); @@ -512,10 +522,10 @@ ohci_alloc_std_chain(opipe, sc, alen, rd, xfer, sp, ep) len -= curlen; cur->td.td_flags = tdflags; - cur->td.td_cbp = LE(dataphys); + cur->td.td_cbp = htole32(dataphys); cur->nexttd = next; - cur->td.td_nexttd = LE(next->physaddr); - cur->td.td_be = LE(dataphys + curlen - 1); + cur->td.td_nexttd = htole32(next->physaddr); + cur->td.td_be = htole32(dataphys + curlen - 1); cur->len = curlen; cur->flags = OHCI_ADD_LEN; cur->xfer = xfer; @@ -539,7 +549,7 @@ ohci_alloc_std_chain(opipe, sc, alen, rd, xfer, sp, ep) cur->td.td_flags = tdflags; cur->td.td_cbp = 0; /* indicate 0 length packet */ cur->nexttd = next; - cur->td.td_nexttd = LE(next->physaddr); + cur->td.td_nexttd = htole32(next->physaddr); cur->td.td_be = ~0; cur->len = 0; cur->flags = 0; @@ -550,13 +560,13 @@ ohci_alloc_std_chain(opipe, sc, alen, rd, xfer, sp, ep) return (USBD_NORMAL_COMPLETION); -nomem: + nomem: /* XXX free chain */ return (USBD_NOMEM); } #if 0 -void +static void ohci_free_std_chain(sc, std, stdend) ohci_softc_t *sc; ohci_soft_td_t *std; @@ -586,7 +596,7 @@ ohci_alloc_sitd(sc) OHCI_TD_ALIGN, &dma); if (err) return (0); - for (i = 0; i < OHCI_STD_CHUNK; i++) { + for(i = 0; i < OHCI_STD_CHUNK; i++) { offs = i * OHCI_STD_SIZE; sitd = (ohci_soft_itd_t *)((char*)KERNADDR(&dma)+offs); sitd->physaddr = DMAADDR(&dma) + offs; @@ -628,6 +638,7 @@ ohci_init(sc) rev = OREAD4(sc, OHCI_REVISION); printf(" OHCI version %d.%d%s\n", OHCI_REV_HI(rev), OHCI_REV_LO(rev), OHCI_REV_LEGACY(rev) ? ", legacy support" : ""); + if (OHCI_REV_HI(rev) != 1 || OHCI_REV_LO(rev) != 0) { printf("%s: unsupported OHCI revision\n", USBDEVNAME(sc->sc_bus.bdev)); @@ -658,7 +669,7 @@ ohci_init(sc) err = USBD_NOMEM; goto bad1; } - sc->sc_ctrl_head->ed.ed_flags |= LE(OHCI_ED_SKIP); + sc->sc_ctrl_head->ed.ed_flags |= htole32(OHCI_ED_SKIP); /* Allocate dummy ED that starts the bulk list. */ sc->sc_bulk_head = ohci_alloc_sed(sc); @@ -666,7 +677,7 @@ ohci_init(sc) err = USBD_NOMEM; goto bad2; } - sc->sc_bulk_head->ed.ed_flags |= LE(OHCI_ED_SKIP); + sc->sc_bulk_head->ed.ed_flags |= htole32(OHCI_ED_SKIP); /* Allocate dummy ED that starts the isochronous list. */ sc->sc_isoc_head = ohci_alloc_sed(sc); @@ -674,7 +685,7 @@ ohci_init(sc) err = USBD_NOMEM; goto bad3; } - sc->sc_isoc_head->ed.ed_flags |= LE(OHCI_ED_SKIP); + sc->sc_isoc_head->ed.ed_flags |= htole32(OHCI_ED_SKIP); /* Allocate all the dummy EDs that make up the interrupt tree. */ for (i = 0; i < OHCI_NO_EDS; i++) { @@ -687,13 +698,13 @@ ohci_init(sc) } /* All ED fields are set to 0. */ sc->sc_eds[i] = sed; - sed->ed.ed_flags |= LE(OHCI_ED_SKIP); + sed->ed.ed_flags |= htole32(OHCI_ED_SKIP); if (i != 0) psed = sc->sc_eds[(i-1) / 2]; else - psed = sc->sc_isoc_head; + psed= sc->sc_isoc_head; sed->next = psed; - sed->ed.ed_nexted = LE(psed->physaddr); + sed->ed.ed_nexted = htole32(psed->physaddr); } /* * Fill HCCA interrupt table. The bit reversal is to get @@ -701,7 +712,7 @@ ohci_init(sc) */ for (i = 0; i < OHCI_NO_INTRS; i++) sc->sc_hcca->hcca_interrupt_table[revbits[i]] = - LE(sc->sc_eds[OHCI_NO_EDS-OHCI_NO_INTRS+i]->physaddr); + htole32(sc->sc_eds[OHCI_NO_EDS-OHCI_NO_INTRS+i]->physaddr); #ifdef OHCI_DEBUG if (ohcidebug > 15) { @@ -820,8 +831,10 @@ ohci_init(sc) sc->sc_bus.methods = &ohci_bus_methods; sc->sc_bus.pipe_size = sizeof(struct ohci_pipe); +#if defined(__NetBSD__) || defined(__OpenBSD__) sc->sc_powerhook = powerhook_establish(ohci_power, sc); sc->sc_shutdownhook = shutdownhook_establish(ohci_shutdown, sc); +#endif return (USBD_NORMAL_COMPLETION); @@ -873,7 +886,7 @@ ohci_allocx(bus) xfer = SIMPLEQ_FIRST(&sc->sc_free_xfers); if (xfer != NULL) - SIMPLEQ_REMOVE_HEAD(&sc->sc_free_xfers, xfer, next); + SIMPLEQ_REMOVE_HEAD(&sc->sc_free_xfers, xfer, next); else xfer = malloc(sizeof(*xfer), M_USB, M_NOWAIT); if (xfer != NULL) @@ -881,7 +894,8 @@ ohci_allocx(bus) return (xfer); } -void ohci_freex(bus, xfer) +void +ohci_freex(bus, xfer) struct usbd_bus *bus; usbd_xfer_handle xfer; { @@ -890,6 +904,9 @@ void ohci_freex(bus, xfer) SIMPLEQ_INSERT_HEAD(&sc->sc_free_xfers, xfer, next); } +/* + * Shut down the controller when the system is going down. + */ void ohci_shutdown(v) void *v; @@ -904,7 +921,7 @@ ohci_shutdown(v) * Handle suspend/resume. * * We need to switch to polling mode here, because this routine is - * called from an interrupt context. This is all right since we + * called from an intterupt context. This is all right since we * are almost suspended anyway. */ void @@ -958,12 +975,12 @@ ohci_dumpregs(sc) OREAD4(sc, OHCI_RH_PORT_STATUS(1)), OREAD4(sc, OHCI_RH_PORT_STATUS(2)))); DPRINTF((" HCCA: frame_number=0x%04x done_head=0x%08x\n", - LE(sc->sc_hcca->hcca_frame_number), - LE(sc->sc_hcca->hcca_done_head))); + le32toh(sc->sc_hcca->hcca_frame_number), + le32toh(sc->sc_hcca->hcca_done_head))); } #endif -int ohci_intr1 __P((ohci_softc_t *)); +static int ohci_intr1 __P((ohci_softc_t *)); int ohci_intr(p) @@ -979,10 +996,10 @@ ohci_intr(p) return (0); } - return (ohci_intr1(sc)); + return (ohci_intr1(sc)); } -int +static int ohci_intr1(sc) ohci_softc_t *sc; { @@ -998,9 +1015,8 @@ ohci_intr1(sc) } intrs = 0; - done = LE(sc->sc_hcca->hcca_done_head); + done = le32toh(sc->sc_hcca->hcca_done_head); if (done != 0) { - sc->sc_hcca->hcca_done_head = 0; if (done & ~OHCI_DONE_INTRS) intrs = OHCI_WDH; if (done & OHCI_DONE_INTRS) @@ -1019,7 +1035,7 @@ ohci_intr1(sc) sc->sc_bus.intr_context++; sc->sc_bus.no_intrs++; - DPRINTFN(7, ("ohci_intr: sc=%p intrs=0x%x(0x%x) eintr=0x%x\n", + DPRINTFN(7, ("ohci_intr: sc=%p intrs=0x%x(0x%x) eintrs=0x%x\n", sc, (u_int)intrs, OREAD4(sc, OHCI_INTERRUPT_STATUS), (u_int)eintrs)); @@ -1033,14 +1049,14 @@ ohci_intr1(sc) if (sc->sc_done == 0) sc->sc_done = done; else { - /* Tack on at end of the sc_dne. */ + /* Tack on at the end of sc_done. */ ohci_physaddr_t ldone; ohci_soft_td_t *std; - for (ldone = sc->sc_done; ldone != 0; - ldone = LE(std->td.td_nexttd)) + for (ldone = sc->sc_done; ldone != 0; + ldone = le32toh(std->td.td_nexttd)) std = ohci_hash_find_td(sc, ldone); - std->td.td_nexttd = LE(done); + std->td.td_nexttd = htole32(done); } sc->sc_hcca->hcca_done_head = 0; usb_schedsoftintr(&sc->sc_bus); @@ -1107,7 +1123,7 @@ char *ohci_cc_strs[] = { "BUFFER_UNDERRUN", "reserved", "reserved", - "NOT ACCESSED", + "NOT_ACCESSED", "NOT_ACCESSED", }; #endif @@ -1132,7 +1148,7 @@ ohci_softintr(bus) DPRINTFN(10,("ohci_process_done: done=0x%08lx\n", (u_long)done)); /* Reverse the done list. */ - for (sdone = NULL; done != 0; done = LE(std->td.td_nexttd)) { + for (sdone = NULL; done != 0; done = le32toh(std->td.td_nexttd)) { std = ohci_hash_find_td(sc, done); std->dnext = sdone; sdone = std; @@ -1150,8 +1166,15 @@ ohci_softintr(bus) stdnext = std->dnext; DPRINTFN(10, ("ohci_process_done: std=%p xfer=%p hcpriv=%p\n", std, xfer, xfer ? xfer->hcpriv : 0)); - cc = OHCI_TD_GET_CC(LE(std->td.td_flags)); - usb_untimeout(ohci_timeout, xfer, xfer->timo_handle); + if (xfer == NULL) { + /* xfer == NULL: There seems to be no xfer associated + * with this TD. It is tailp that happened to end up on + * the done queue. + */ + continue; + } + cc = OHCI_TD_GET_CC(le32toh(std->td.td_flags)); + usb_uncallout(xfer->timeout_handle, ohci_timeout, xfer); if (xfer->status == USBD_CANCELLED || xfer->status == USBD_TIMEOUT) { DPRINTF(("ohci_process_done: cancel/timeout %p\n", @@ -1160,8 +1183,8 @@ ohci_softintr(bus) } else if (cc == OHCI_CC_NO_ERROR) { len = std->len; if (std->td.td_cbp != 0) - len -= LE(std->td.td_be) - - LE(std->td.td_cbp) + 1; + len -= le32toh(std->td.td_be) - + le32toh(std->td.td_cbp) + 1; DPRINTFN(10, ("ohci_process_done: len=%d, flags=0x%x\n", len, std->flags)); if (std->flags & OHCI_ADD_LEN) @@ -1181,9 +1204,9 @@ ohci_softintr(bus) struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe; - DPRINTF(("ohci_process_done: error cc=%d (%s)\n", - OHCI_TD_GET_CC(LE(std->td.td_flags)), - ohci_cc_strs[OHCI_TD_GET_CC(LE(std->td.td_flags))])); + DPRINTFN(15,("ohci_process_done: error cc=%d (%s)\n", + OHCI_TD_GET_CC(le32toh(std->td.td_flags)), + ohci_cc_strs[OHCI_TD_GET_CC(le32toh(std->td.td_flags))])); /* remove TDs */ for (p = std; p->xfer == xfer; p = n) { @@ -1192,7 +1215,7 @@ ohci_softintr(bus) } /* clear halt */ - opipe->sed->ed.ed_headp = LE(p->physaddr); + opipe->sed->ed.ed_headp = htole32(p->physaddr); OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF); if (cc == OHCI_CC_STALL) @@ -1229,6 +1252,7 @@ ohci_device_intr_done(xfer) ohci_soft_ed_t *sed = opipe->sed; ohci_soft_td_t *data, *tail; + DPRINTFN(10,("ohci_intr_done: xfer=%p, actlen=%d\n", xfer, xfer->actlen)); @@ -1243,22 +1267,23 @@ ohci_device_intr_done(xfer) } tail->xfer = NULL; - data->td.td_flags = LE( + data->td.td_flags = htole32( OHCI_TD_IN | OHCI_TD_NOCC | OHCI_TD_SET_DI(1) | OHCI_TD_TOGGLE_CARRY); if (xfer->flags & USBD_SHORT_XFER_OK) - data->td.td_flags |= LE(OHCI_TD_R); - data->td.td_cbp = LE(DMAADDR(&xfer->dmabuf)); + data->td.td_flags |= htole32(OHCI_TD_R); + data->td.td_cbp = htole32(DMAADDR(&xfer->dmabuf)); data->nexttd = tail; - data->td.td_nexttd = LE(tail->physaddr); - data->td.td_be = LE(LE(data->td.td_cbp) + xfer->length - 1); + data->td.td_nexttd = htole32(tail->physaddr); + data->td.td_be = htole32(le32toh(data->td.td_cbp) + + xfer->length - 1); data->len = xfer->length; data->xfer = xfer; data->flags = OHCI_CALL_DONE | OHCI_ADD_LEN; xfer->hcpriv = data; xfer->actlen = 0; - sed->ed.ed_tailp = LE(tail->physaddr); + sed->ed.ed_tailp = htole32(tail->physaddr); opipe->tail.td = tail; } } @@ -1270,7 +1295,7 @@ ohci_device_bulk_done(xfer) DPRINTFN(10,("ohci_bulk_done: xfer=%p, actlen=%d\n", xfer, xfer->actlen)); - xfer->hcpriv = 0; + xfer->hcpriv = NULL; } void @@ -1288,7 +1313,7 @@ ohci_rhsc(sc, xfer) DPRINTF(("ohci_rhsc: sc=%p xfer=%p hstatus=0x%08x\n", sc, xfer, hstatus)); - if (xfer == 0) { + if (xfer == NULL) { /* Just ignore the change. */ return; } @@ -1415,8 +1440,8 @@ ohci_device_request(xfer) /* Update device address and length since they may have changed. */ /* XXX This only needs to be done once, but it's too early in open. */ /* XXXX Should not touch ED here! */ - sed->ed.ed_flags = LE( - (LE(sed->ed.ed_flags) & ~(OHCI_ED_ADDRMASK | OHCI_ED_MAXPMASK)) | + sed->ed.ed_flags = htole32( + (le32toh(sed->ed.ed_flags) & ~(OHCI_ED_ADDRMASK | OHCI_ED_MAXPMASK)) | OHCI_ED_SET_FA(addr) | OHCI_ED_SET_MAXP(UGETW(opipe->pipe.endpoint->edesc->wMaxPacketSize))); @@ -1427,34 +1452,34 @@ ohci_device_request(xfer) ohci_soft_td_t *std = stat; err = ohci_alloc_std_chain(opipe, sc, len, isread, xfer, - std, &stat); + std, &stat); stat = stat->nexttd; /* point at free TD */ if (err) goto bad3; /* Start toggle at 1 and then use the carried toggle. */ - std->td.td_flags &= LE(~OHCI_TD_TOGGLE_MASK); - std->td.td_flags |= LE(OHCI_TD_TOGGLE_1); + std->td.td_flags &= htole32(~OHCI_TD_TOGGLE_MASK); + std->td.td_flags |= htole32(OHCI_TD_TOGGLE_1); } memcpy(KERNADDR(&opipe->u.ctl.reqdma), req, sizeof *req); - setup->td.td_flags = LE(OHCI_TD_SETUP | OHCI_TD_NOCC | - OHCI_TD_TOGGLE_0 | OHCI_TD_NOINTR); - setup->td.td_cbp = LE(DMAADDR(&opipe->u.ctl.reqdma)); + setup->td.td_flags = htole32(OHCI_TD_SETUP | OHCI_TD_NOCC | + OHCI_TD_TOGGLE_0 | OHCI_TD_NOINTR); + setup->td.td_cbp = htole32(DMAADDR(&opipe->u.ctl.reqdma)); setup->nexttd = next; - setup->td.td_nexttd = LE(next->physaddr); - setup->td.td_be = LE(LE(setup->td.td_cbp) + sizeof *req - 1); + setup->td.td_nexttd = htole32(next->physaddr); + setup->td.td_be = htole32(le32toh(setup->td.td_cbp) + sizeof *req - 1); setup->len = 0; setup->xfer = xfer; setup->flags = 0; xfer->hcpriv = setup; - stat->td.td_flags = LE( + stat->td.td_flags = htole32( (isread ? OHCI_TD_OUT : OHCI_TD_IN) | OHCI_TD_NOCC | OHCI_TD_TOGGLE_1 | OHCI_TD_SET_DI(1)); stat->td.td_cbp = 0; stat->nexttd = tail; - stat->td.td_nexttd = LE(tail->physaddr); + stat->td.td_nexttd = htole32(tail->physaddr); stat->td.td_be = 0; stat->flags = OHCI_CALL_DONE; stat->len = 0; @@ -1470,12 +1495,12 @@ ohci_device_request(xfer) /* Insert ED in schedule */ s = splusb(); - sed->ed.ed_tailp = LE(tail->physaddr); + sed->ed.ed_tailp = htole32(tail->physaddr); opipe->tail.td = tail; OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF); if (xfer->timeout && !sc->sc_bus.use_polling) { - usb_timeout(ohci_timeout, xfer, - MS_TO_TICKS(xfer->timeout), xfer->timo_handle); + usb_callout(xfer->timeout_handle, MS_TO_TICKS(xfer->timeout), + ohci_timeout, xfer); } splx(s); @@ -1511,7 +1536,7 @@ ohci_add_ed(sed, head) sed->next = head->next; sed->ed.ed_nexted = head->ed.ed_nexted; head->next = sed; - head->ed.ed_nexted = LE(sed->physaddr); + head->ed.ed_nexted = htole32(sed->physaddr); } /* @@ -1527,7 +1552,7 @@ ohci_rem_ed(sed, head) SPLUSBCHECK; /* XXX */ - for (p = head; p != NULL && p->next != sed; p = p->next) + for (p = head; p == NULL && p->next != sed; p = p->next) ; if (p == NULL) panic("ohci_rem_ed: ED not found\n"); @@ -1579,7 +1604,7 @@ ohci_hash_find_td(sc, a) ohci_soft_td_t *std; for (std = LIST_FIRST(&sc->sc_hash_tds[h]); - std != NULL; + std != NULL; std = LIST_NEXT(std, hnext)) if (std->physaddr == a) return (std); @@ -1618,13 +1643,14 @@ ohci_dump_td(std) DPRINTF(("TD(%p) at %08lx: %b delay=%d ec=%d cc=%d\ncbp=0x%08lx " "nexttd=0x%08lx be=0x%08lx\n", std, (u_long)std->physaddr, - (int)LE(std->td.td_flags), + (int)le32toh(std->td.td_flags), "\20\23R\24OUT\25IN\31TOG1\32SETTOGGLE", - OHCI_TD_GET_DI(LE(std->td.td_flags)), - OHCI_TD_GET_EC(LE(std->td.td_flags)), - OHCI_TD_GET_CC(LE(std->td.td_flags)), - (u_long)LE(std->td.td_cbp), - (u_long)LE(std->td.td_nexttd), (u_long)LE(std->td.td_be))); + OHCI_TD_GET_DI(le32toh(std->td.td_flags)), + OHCI_TD_GET_EC(le32toh(std->td.td_flags)), + OHCI_TD_GET_CC(le32toh(std->td.td_flags)), + (u_long)le32toh(std->td.td_cbp), + (u_long)le32toh(std->td.td_nexttd), + (u_long)le32toh(std->td.td_be))); } void @@ -1632,18 +1658,18 @@ ohci_dump_ed(sed) ohci_soft_ed_t *sed; { DPRINTF(("ED(%p) at 0x%08lx: addr=%d endpt=%d maxp=%d %b\ntailp=0x%08lx " - "headsflags=%b headp=%b nexted=0x%08lx\n", + "headflags=%b headp=0x%08lx nexted=0x%08lx\n", sed, (u_long)sed->physaddr, - OHCI_ED_GET_FA(LE(sed->ed.ed_flags)), - OHCI_ED_GET_EN(LE(sed->ed.ed_flags)), - OHCI_ED_GET_MAXP(LE(sed->ed.ed_flags)), - (int)LE(sed->ed.ed_flags), + OHCI_ED_GET_FA(le32toh(sed->ed.ed_flags)), + OHCI_ED_GET_EN(le32toh(sed->ed.ed_flags)), + OHCI_ED_GET_MAXP(le32toh(sed->ed.ed_flags)), + (int)le32toh(sed->ed.ed_flags), "\20\14OUT\15IN\16LOWSPEED\17SKIP\20ISO", - (u_long)LE(sed->ed.ed_tailp), - (u_long)LE(sed->ed.ed_headp), + (u_long)le32toh(sed->ed.ed_tailp), + (u_long)le32toh(sed->ed.ed_headp), "\20\1HALT\2CARRY", - (u_long)LE(sed->ed.ed_headp), - (u_long)LE(sed->ed.ed_nexted))); + (u_long)le32toh(sed->ed.ed_headp), + (u_long)le32toh(sed->ed.ed_nexted))); } #endif @@ -1668,6 +1694,7 @@ ohci_open(pipe) DPRINTFN(1, ("ohci_open: pipe=%p, addr=%d, endpt=%d (%d)\n", pipe, addr, ed->bEndpointAddress, sc->sc_addr)); + if (addr == sc->sc_addr) { switch (ed->bEndpointAddress) { case USB_CONTROL_ENDPOINT: @@ -1691,7 +1718,7 @@ ohci_open(pipe) goto bad1; } opipe->tail.itd = sitd; - tdphys = LE(sitd->physaddr); + tdphys = sitd->physaddr; fmt = OHCI_ED_FORMAT_ISO; } else { std = ohci_alloc_std(sc); @@ -1700,23 +1727,23 @@ ohci_open(pipe) goto bad1; } opipe->tail.td = std; - tdphys = LE(std->physaddr); + tdphys = std->physaddr; fmt = OHCI_ED_FORMAT_GEN; } - sed->ed.ed_flags = LE( + sed->ed.ed_flags = htole32( OHCI_ED_SET_FA(addr) | OHCI_ED_SET_EN(ed->bEndpointAddress) | OHCI_ED_DIR_TD | (dev->lowspeed ? OHCI_ED_SPEED : 0) | fmt | OHCI_ED_SET_MAXP(UGETW(ed->wMaxPacketSize))); - sed->ed.ed_headp = sed->ed.ed_tailp = tdphys; + sed->ed.ed_headp = sed->ed.ed_tailp = htole32(tdphys); switch (xfertype) { case UE_CONTROL: pipe->methods = &ohci_device_ctrl_methods; err = usb_allocmem(&sc->sc_bus, - sizeof(usb_device_request_t), - 0, &opipe->u.ctl.reqdma); + sizeof(usb_device_request_t), + 0, &opipe->u.ctl.reqdma); if (err) goto bad; s = splusb(); @@ -1767,10 +1794,10 @@ ohci_close_pipe(pipe, head) s = splusb(); #ifdef DIAGNOSTIC - sed->ed.ed_flags |= LE(OHCI_ED_SKIP); - if ((sed->ed.ed_tailp & LE(OHCI_HEADMASK)) != - (sed->ed.ed_headp & LE(OHCI_HEADMASK))) { - ohci_physaddr_t td = sed->ed.ed_headp; + sed->ed.ed_flags |= htole32(OHCI_ED_SKIP); + if ((le32toh(sed->ed.ed_tailp) & OHCI_HEADMASK) != + (le32toh(sed->ed.ed_headp) & OHCI_HEADMASK)) { + ohci_physaddr_t td = le32toh(sed->ed.ed_headp); ohci_soft_td_t *std; for (std = LIST_FIRST(&sc->sc_hash_tds[HASH(td)]); std != NULL; @@ -1779,11 +1806,12 @@ ohci_close_pipe(pipe, head) break; printf("ohci_close_pipe: pipe not empty sed=%p hd=0x%x " "tl=0x%x pipe=%p, std=%p\n", sed, - (int)LE(sed->ed.ed_headp), (int)LE(sed->ed.ed_tailp), + (int)le32toh(sed->ed.ed_headp), + (int)le32toh(sed->ed.ed_tailp), pipe, std); usb_delay_ms(&sc->sc_bus, 2); - if ((sed->ed.ed_tailp & LE(OHCI_HEADMASK)) != - (sed->ed.ed_headp & LE(OHCI_HEADMASK))) + if ((le32toh(sed->ed.ed_tailp) & OHCI_HEADMASK) != + (le32toh(sed->ed.ed_headp) & OHCI_HEADMASK)) printf("ohci_close_pipe: pipe still not empty\n"); } #endif @@ -1814,20 +1842,21 @@ ohci_abort_xfer(xfer, status) xfer->status = status; - usb_untimeout(ohci_timeout, xfer, xfer->timo_handle); + usb_uncallout(xfer->timeout_handle, ohci_timeout, xfer); sed = opipe->sed; DPRINTFN(1,("ohci_abort_xfer: stop ed=%p\n", sed)); - sed->ed.ed_flags |= LE(OHCI_ED_SKIP); /* force hardware skip */ + sed->ed.ed_flags |= htole32(OHCI_ED_SKIP); /* force hardware skip */ #if 1 if (xfer->device->bus->intr_context) { /* We have no process context, so we can't use tsleep(). */ - timeout(ohci_abort_xfer_end, xfer, hz / USB_FRAMES_PER_SECOND); + usb_callout(xfer->pipe->abort_handle, + hz / USB_FRAMES_PER_SECOND, ohci_abort_xfer_end, xfer); } else { #if defined(DIAGNOSTIC) && defined(__i386__) && defined(__FreeBSD__) KASSERT(intr_nesting_level == 0, - ("ohci_abort_req in interrupt context")); + ("ohci_abort_req in interrupt context")); #endif usb_delay_ms(opipe->pipe.device->bus, 1); ohci_abort_xfer_end(xfer); @@ -1865,9 +1894,9 @@ ohci_abort_xfer_end(v) sed = opipe->sed; DPRINTFN(2,("ohci_abort_xfer: set hd=%x, tl=%x\n", - (int)LE(p->physaddr), (int)LE(sed->ed.ed_tailp))); - sed->ed.ed_headp = p->physaddr; /* unlink TDs */ - sed->ed.ed_flags &= LE(~OHCI_ED_SKIP); /* remove hardware skip */ + (int)p->physaddr, (int)le32toh(sed->ed.ed_tailp))); + sed->ed.ed_headp = htole32(p->physaddr); /* unlink TDs */ + sed->ed.ed_flags &= htole32(~OHCI_ED_SKIP); /* remove hardware skip */ usb_transfer_complete(xfer); @@ -1877,7 +1906,7 @@ ohci_abort_xfer_end(v) /* * Data structures and routines to emulate the root hub. */ -usb_device_descriptor_t ohci_devd = { +static usb_device_descriptor_t ohci_devd = { USB_DEVICE_DESCRIPTOR_SIZE, UDESC_DEVICE, /* type */ {0x00, 0x01}, /* USB version */ @@ -1890,7 +1919,7 @@ usb_device_descriptor_t ohci_devd = { 1 /* # of configurations */ }; -usb_config_descriptor_t ohci_confd = { +static usb_config_descriptor_t ohci_confd = { USB_CONFIG_DESCRIPTOR_SIZE, UDESC_CONFIG, {USB_CONFIG_DESCRIPTOR_SIZE + @@ -1903,7 +1932,7 @@ usb_config_descriptor_t ohci_confd = { 0 /* max power */ }; -usb_interface_descriptor_t ohci_ifcd = { +static usb_interface_descriptor_t ohci_ifcd = { USB_INTERFACE_DESCRIPTOR_SIZE, UDESC_INTERFACE, 0, @@ -1915,7 +1944,7 @@ usb_interface_descriptor_t ohci_ifcd = { 0 }; -usb_endpoint_descriptor_t ohci_endpd = { +static usb_endpoint_descriptor_t ohci_endpd = { USB_ENDPOINT_DESCRIPTOR_SIZE, UDESC_ENDPOINT, UE_DIR_IN | OHCI_INTR_ENDPT, @@ -1924,7 +1953,7 @@ usb_endpoint_descriptor_t ohci_endpd = { 255 }; -usb_hub_descriptor_t ohci_hubd = { +static usb_hub_descriptor_t ohci_hubd = { USB_HUB_DESCRIPTOR_SIZE, UDESC_HUB, 0, @@ -1934,7 +1963,7 @@ usb_hub_descriptor_t ohci_hubd = { {0}, }; -int +static int ohci_str(p, l, s) usb_string_descriptor_t *p; int l; @@ -1957,7 +1986,7 @@ ohci_str(p, l, s) /* * Simulate a hardware hub by handling all the necessary requests. */ -usbd_status +static usbd_status ohci_root_ctrl_transfer(xfer) usbd_xfer_handle xfer; { @@ -1972,7 +2001,7 @@ ohci_root_ctrl_transfer(xfer) return (ohci_root_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); } -usbd_status +static usbd_status ohci_root_ctrl_start(xfer) usbd_xfer_handle xfer; { @@ -2272,7 +2301,7 @@ ohci_root_ctrl_start(xfer) } /* Abort a root control request. */ -void +static void ohci_root_ctrl_abort(xfer) usbd_xfer_handle xfer; { @@ -2280,7 +2309,7 @@ ohci_root_ctrl_abort(xfer) } /* Close the root pipe. */ -void +static void ohci_root_ctrl_close(pipe) usbd_pipe_handle pipe; { @@ -2288,7 +2317,7 @@ ohci_root_ctrl_close(pipe) /* Nothing to do. */ } -usbd_status +static usbd_status ohci_root_intr_transfer(xfer) usbd_xfer_handle xfer; { @@ -2303,7 +2332,7 @@ ohci_root_intr_transfer(xfer) return (ohci_root_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); } -usbd_status +static usbd_status ohci_root_intr_start(xfer) usbd_xfer_handle xfer; { @@ -2316,7 +2345,7 @@ ohci_root_intr_start(xfer) } /* Abort a root interrupt request. */ -void +static void ohci_root_intr_abort(xfer) usbd_xfer_handle xfer; { @@ -2333,7 +2362,7 @@ ohci_root_intr_abort(xfer) } /* Close the root pipe. */ -void +static void ohci_root_intr_close(pipe) usbd_pipe_handle pipe; { @@ -2346,7 +2375,7 @@ ohci_root_intr_close(pipe) /************************/ -usbd_status +static usbd_status ohci_device_ctrl_transfer(xfer) usbd_xfer_handle xfer; { @@ -2361,7 +2390,7 @@ ohci_device_ctrl_transfer(xfer) return (ohci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); } -usbd_status +static usbd_status ohci_device_ctrl_start(xfer) usbd_xfer_handle xfer; { @@ -2386,7 +2415,7 @@ ohci_device_ctrl_start(xfer) } /* Abort a device control request. */ -void +static void ohci_device_ctrl_abort(xfer) usbd_xfer_handle xfer; { @@ -2395,7 +2424,7 @@ ohci_device_ctrl_abort(xfer) } /* Close a device control pipe. */ -void +static void ohci_device_ctrl_close(pipe) usbd_pipe_handle pipe; { @@ -2409,22 +2438,22 @@ ohci_device_ctrl_close(pipe) /************************/ -void +static void ohci_device_clear_toggle(pipe) usbd_pipe_handle pipe; { struct ohci_pipe *opipe = (struct ohci_pipe *)pipe; - opipe->sed->ed.ed_headp &= LE(~OHCI_TOGGLECARRY); + opipe->sed->ed.ed_headp &= htole32(~OHCI_TOGGLECARRY); } -void +static void ohci_noop(pipe) usbd_pipe_handle pipe; { } -usbd_status +static usbd_status ohci_device_bulk_transfer(xfer) usbd_xfer_handle xfer; { @@ -2439,7 +2468,7 @@ ohci_device_bulk_transfer(xfer) return (ohci_device_bulk_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); } -usbd_status +static usbd_status ohci_device_bulk_start(xfer) usbd_xfer_handle xfer; { @@ -2473,16 +2502,17 @@ ohci_device_bulk_start(xfer) opipe->u.bulk.length = len; /* Update device address */ - sed->ed.ed_flags = LE( - (LE(sed->ed.ed_flags) & ~OHCI_ED_ADDRMASK) | + sed->ed.ed_flags = htole32( + (le32toh(sed->ed.ed_flags) & ~OHCI_ED_ADDRMASK) | OHCI_ED_SET_FA(addr)); /* Allocate a chain of new TDs (including a new tail). */ data = opipe->tail.td; - err = ohci_alloc_std_chain(opipe, sc, len, isread, xfer, data, &tail); + err = ohci_alloc_std_chain(opipe, sc, len, isread, xfer, + data, &tail); /* We want interrupt at the end of the transfer. */ - tail->td.td_flags &= LE(~OHCI_TD_INTR_MASK); - tail->td.td_flags |= LE(OHCI_TD_SET_DI(1)); + tail->td.td_flags &= htole32(~OHCI_TD_INTR_MASK); + tail->td.td_flags |= htole32(OHCI_TD_SET_DI(1)); tail->flags |= OHCI_CALL_DONE; tail = tail->nexttd; /* point at sentinel */ if (err) @@ -2493,8 +2523,10 @@ ohci_device_bulk_start(xfer) DPRINTFN(4,("ohci_device_bulk_start: ed_flags=0x%08x td_flags=0x%08x " "td_cbp=0x%08x td_be=0x%08x\n", - (int)LE(sed->ed.ed_flags), (int)LE(data->td.td_flags), - (int)LE(data->td.td_cbp), (int)LE(data->td.td_be))); + (int)le32toh(sed->ed.ed_flags), + (int)le32toh(data->td.td_flags), + (int)le32toh(data->td.td_cbp), + (int)le32toh(data->td.td_be))); #ifdef OHCI_DEBUG if (ohcidebug > 5) { @@ -2508,13 +2540,13 @@ ohci_device_bulk_start(xfer) for (tdp = data; tdp != tail; tdp = tdp->nexttd) { tdp->xfer = xfer; } - sed->ed.ed_tailp = LE(tail->physaddr); + sed->ed.ed_tailp = htole32(tail->physaddr); opipe->tail.td = tail; - sed->ed.ed_flags &= LE(~OHCI_ED_SKIP); + sed->ed.ed_flags &= htole32(~OHCI_ED_SKIP); OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_BLF); if (xfer->timeout && !sc->sc_bus.use_polling) { - usb_timeout(ohci_timeout, xfer, - MS_TO_TICKS(xfer->timeout), xfer->timo_handle); + usb_callout(xfer->timeout_handle, MS_TO_TICKS(xfer->timeout), + ohci_timeout, xfer); } #if 0 @@ -2533,7 +2565,7 @@ ohci_device_bulk_start(xfer) return (USBD_IN_PROGRESS); } -void +static void ohci_device_bulk_abort(xfer) usbd_xfer_handle xfer; { @@ -2544,7 +2576,7 @@ ohci_device_bulk_abort(xfer) /* * Close a device bulk pipe. */ -void +static void ohci_device_bulk_close(pipe) usbd_pipe_handle pipe; { @@ -2558,7 +2590,7 @@ ohci_device_bulk_close(pipe) /************************/ -usbd_status +static usbd_status ohci_device_intr_transfer(xfer) usbd_xfer_handle xfer; { @@ -2573,7 +2605,7 @@ ohci_device_intr_transfer(xfer) return (ohci_device_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); } -usbd_status +static usbd_status ohci_device_intr_start(xfer) usbd_xfer_handle xfer; { @@ -2602,15 +2634,15 @@ ohci_device_intr_start(xfer) return (USBD_NOMEM); tail->xfer = NULL; - data->td.td_flags = LE( + data->td.td_flags = htole32( OHCI_TD_IN | OHCI_TD_NOCC | OHCI_TD_SET_DI(1) | OHCI_TD_TOGGLE_CARRY); if (xfer->flags & USBD_SHORT_XFER_OK) - data->td.td_flags |= LE(OHCI_TD_R); - data->td.td_cbp = LE(DMAADDR(&xfer->dmabuf)); + data->td.td_flags |= htole32(OHCI_TD_R); + data->td.td_cbp = htole32(DMAADDR(&xfer->dmabuf)); data->nexttd = tail; - data->td.td_nexttd = LE(tail->physaddr); - data->td.td_be = LE(LE(data->td.td_cbp) + len - 1); + data->td.td_nexttd = htole32(tail->physaddr); + data->td.td_be = htole32(le32toh(data->td.td_cbp) + len - 1); data->len = len; data->xfer = xfer; data->flags = OHCI_CALL_DONE | OHCI_ADD_LEN; @@ -2626,9 +2658,9 @@ ohci_device_intr_start(xfer) /* Insert ED in schedule */ s = splusb(); - sed->ed.ed_tailp = LE(tail->physaddr); + sed->ed.ed_tailp = htole32(tail->physaddr); opipe->tail.td = tail; - sed->ed.ed_flags &= LE(~OHCI_ED_SKIP); + sed->ed.ed_flags &= htole32(~OHCI_ED_SKIP); #if 0 /* @@ -2650,7 +2682,7 @@ ohci_device_intr_start(xfer) } /* Abort a device control request. */ -void +static void ohci_device_intr_abort(xfer) usbd_xfer_handle xfer; { @@ -2662,7 +2694,7 @@ ohci_device_intr_abort(xfer) } /* Close a device interrupt pipe. */ -void +static void ohci_device_intr_close(pipe) usbd_pipe_handle pipe; { @@ -2677,9 +2709,9 @@ ohci_device_intr_close(pipe) DPRINTFN(1,("ohci_device_intr_close: pipe=%p nslots=%d pos=%d\n", pipe, nslots, pos)); s = splusb(); - sed->ed.ed_flags |= LE(OHCI_ED_SKIP); - if ((sed->ed.ed_tailp & LE(OHCI_HEADMASK)) != - (sed->ed.ed_headp & LE(OHCI_HEADMASK))) + sed->ed.ed_flags |= htole32(OHCI_ED_SKIP); + if ((le32toh(sed->ed.ed_tailp) & OHCI_HEADMASK) != + (le32toh(sed->ed.ed_headp) & OHCI_HEADMASK)) usb_delay_ms(&sc->sc_bus, 2); for (p = sc->sc_eds[pos]; p && p->next != sed; p = p->next) @@ -2699,7 +2731,7 @@ ohci_device_intr_close(pipe) ohci_free_sed(sc, opipe->sed); } -usbd_status +static usbd_status ohci_device_setintr(sc, opipe, ival) ohci_softc_t *sc; struct ohci_pipe *opipe; @@ -2752,7 +2784,7 @@ ohci_device_setintr(sc, opipe, ival) sed->next = hsed->next; sed->ed.ed_nexted = hsed->ed.ed_nexted; hsed->next = sed; - hsed->ed.ed_nexted = LE(sed->physaddr); + hsed->ed.ed_nexted = htole32(sed->physaddr); splx(s); for (j = 0; j < nslots; j++) @@ -2783,7 +2815,7 @@ ohci_device_isoc_transfer(xfer) /* XXX should check inuse here */ - /* insert into schedule */ + /* insert into schedule, */ ohci_device_isoc_enter(xfer); /* and put on interrupt list if the pipe wasn't running */ @@ -2802,7 +2834,7 @@ ohci_device_isoc_enter(xfer) ohci_softc_t *sc = (ohci_softc_t *)dev->bus; ohci_soft_ed_t *sed = opipe->sed; struct iso *iso = &opipe->u.iso; - ohci_soft_itd_t *sitd, *nsitd; + ohci_soft_itd_t *sitd, *nsitd; ohci_physaddr_t buf, offs; int i, ncur, nframes; int ncross; @@ -2811,34 +2843,37 @@ ohci_device_isoc_enter(xfer) s = splusb(); sitd = opipe->tail.itd; buf = DMAADDR(&xfer->dmabuf); - sitd->itd.itd_bp0 = LE(buf & OHCI_ITD_PAGE_MASK); + sitd->itd.itd_bp0 = htole32(buf & OHCI_ITD_PAGE_MASK); nframes = xfer->nframes; offs = buf & OHCI_ITD_OFFSET_MASK; ncross = 0; - for (i = ncur = 0; i < nframes; i ++, ncur++) { - if (ncur == OHCI_ITD_NOFFSET || /* all offsets used */ - ncross > 1) { /* too many page crossings */ + for (i = ncur = 0; i < nframes; i++, ncur++) { + if (ncur == OHCI_ITD_NOFFSET || /* all offsets used */ + ncross > 1) { /* too many page crossings */ + nsitd = ohci_alloc_sitd(sc); if (nsitd == NULL) { /* XXX what now? */ return; } sitd->nextitd = nsitd; - sitd->itd.itd_nextitd = LE(nsitd->physaddr); - sitd->itd.itd_flags = LE( - OHCI_ITD_NOCC | + sitd->itd.itd_nextitd = htole32(nsitd->physaddr); + sitd->itd.itd_flags = htole32( + OHCI_ITD_NOCC | OHCI_ITD_SET_SF(iso->next) | OHCI_ITD_NOINTR | OHCI_ITD_SET_FC(OHCI_ITD_NOFFSET)); - sitd->itd.itd_be = LE(LE(sitd->itd.itd_bp0) + offs - 1); - nsitd->itd.itd_bp0 = LE((buf + offs) & OHCI_ITD_PAGE_MASK); + sitd->itd.itd_be = htole32( + le32toh(sitd->itd.itd_bp0) + offs - 1); + nsitd->itd.itd_bp0 = htole32( + (buf + offs) & OHCI_ITD_PAGE_MASK); sitd = nsitd; - iso->next = iso->next + ncur; + iso->next = iso->next + ncur; ncur = 0; ncross = 0; } /* XXX byte order */ - sitd->itd.itd_offset[i] = + sitd->itd.itd_offset[i] = offs | (ncross == 1 ? OHCI_ITD_PAGE_SELECT : 0); offs += xfer->frlengths[i]; /* XXX update ncross */ @@ -2849,17 +2884,17 @@ ohci_device_isoc_enter(xfer) return; } sitd->nextitd = nsitd; - sitd->itd.itd_nextitd = LE(nsitd->physaddr); - sitd->itd.itd_flags = LE( - OHCI_ITD_NOCC | + sitd->itd.itd_nextitd = htole32(nsitd->physaddr); + sitd->itd.itd_flags = le32toh( + OHCI_ITD_NOCC | OHCI_ITD_SET_SF(iso->next) | OHCI_ITD_SET_DI(0) | OHCI_ITD_SET_FC(ncur)); - sitd->itd.itd_be = LE(LE(sitd->itd.itd_bp0) + offs - 1); + sitd->itd.itd_be = htole32(le32toh(sitd->itd.itd_bp0) + offs - 1); iso->next = iso->next + ncur; opipe->tail.itd = nsitd; - sed->ed.ed_tailp = LE(nsitd->physaddr); + sed->ed.ed_tailp = htole32(nsitd->physaddr); /* XXX update ED */ splx(s); } @@ -2909,4 +2944,3 @@ ohci_device_isoc_close(pipe) ohci_close_pipe(pipe, sc->sc_isoc_head); ohci_free_sitd(sc, opipe->tail.itd); } - diff --git a/sys/dev/usb/ohcireg.h b/sys/dev/usb/ohcireg.h index c9700f6be29..c40926579a2 100644 --- a/sys/dev/usb/ohcireg.h +++ b/sys/dev/usb/ohcireg.h @@ -1,5 +1,7 @@ -/* $OpenBSD: ohcireg.h,v 1.4 2000/03/26 08:39:45 aaron Exp $ */ +/* $OpenBSD: ohcireg.h,v 1.5 2000/03/28 19:37:48 aaron Exp $ */ /* $NetBSD: ohcireg.h,v 1.15 2000/03/19 22:24:58 augustss Exp $ */ +/* $FreeBSD: src/sys/dev/usb/ohcireg.h,v 1.8 1999/11/17 22:33:40 n_hibma Exp $ */ + /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -204,26 +206,27 @@ typedef struct { u_int32_t itd_flags; #define OHCI_ITD_GET_SF(x) ((x) & 0x0000ffff) #define OHCI_ITD_SET_SF(x) ((x) & 0xffff) -#define OHCI_ITD_GET_DI(x) (((x) >> 21) & 7) /* Delay interrupt */ +#define OHCI_ITD_GET_DI(x) (((x) >> 21) & 7) /* Delay Interrupt */ #define OHCI_ITD_SET_DI(x) ((x) << 21) -#define OHCI_ITD_NOINTR 0x00e00000 +#define OHCI_ITD_NOINTR 0x00e00000 #define OHCI_ITD_GET_FC(x) ((((x) >> 24) & 7)+1) /* Frame Count */ #define OHCI_ITD_SET_FC(x) (((x)-1) << 24) #define OHCI_ITD_GET_CC(x) ((x) >> 28) /* Condition Code */ -#define OHCI_ITD_NOCC 0xf0000000 - ohci_physaddr_t itd_bp0; /* Buffer Page 0 */ +#define OHCI_ITD_NOCC 0xf0000000 + ohci_physaddr_t itd_bp0; /* Buffer Page 0 */ #define OHCI_ITD_OFFSET_MASK 0x00000fff #define OHCI_ITD_PAGE_MASK (~OHCI_ITD_OFFSET_MASK) - ohci_physaddr_t itd_nextitd; /* Next ITD */ - ohci_physaddr_t itd_be; /* Buffer End */ + ohci_physaddr_t itd_nextitd; /* Next ITD */ + ohci_physaddr_t itd_be; /* Buffer End */ u_int16_t itd_offset[OHCI_ITD_NOFFSET]; /* Buffer offsets */ -#define itd_pswn itd_offset /* Packet Status Word */ +#define itd_pswn itd_offset /* Packet Status Word*/ #define OHCI_ITD_PAGE_SELECT 0x00001000 #define OHCI_ITD_PSW_LENGTH(x) ((x) & 0xfff) /* Transfer length */ #define OHCI_ITD_PSW_GET_CC(x) ((x) >> 12) /* Condition Code */ } ohci_itd_t; /* #define OHCI_ITD_SIZE 32 */ #define OHCI_ITD_ALIGN 32 + #define OHCI_CC_NO_ERROR 0 #define OHCI_CC_CRC 1 diff --git a/sys/dev/usb/ohcivar.h b/sys/dev/usb/ohcivar.h index a0ad463063c..e1f310171cf 100644 --- a/sys/dev/usb/ohcivar.h +++ b/sys/dev/usb/ohcivar.h @@ -1,5 +1,6 @@ -/* $OpenBSD: ohcivar.h,v 1.7 2000/03/26 08:39:45 aaron Exp $ */ +/* $OpenBSD: ohcivar.h,v 1.8 2000/03/28 19:37:48 aaron Exp $ */ /* $NetBSD: ohcivar.h,v 1.20 2000/02/22 11:30:55 augustss Exp $ */ +/* $FreeBSD: src/sys/dev/usb/ohcivar.h,v 1.13 1999/11/17 22:33:41 n_hibma Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. diff --git a/sys/dev/usb/uaudio.c b/sys/dev/usb/uaudio.c index 558f721b9d7..27dee78b7b8 100644 --- a/sys/dev/usb/uaudio.c +++ b/sys/dev/usb/uaudio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uaudio.c,v 1.2 2000/03/26 08:39:45 aaron Exp $ */ +/* $OpenBSD: uaudio.c,v 1.3 2000/03/28 19:37:49 aaron Exp $ */ /* $NetBSD: uaudio.c,v 1.20 2000/03/24 13:02:00 augustss Exp $ */ /* @@ -71,8 +71,8 @@ #include #ifdef UAUDIO_DEBUG -#define DPRINTF(x) if (uaudiodebug) printf x -#define DPRINTFN(n,x) if (uaudiodebug>(n)) printf x +#define DPRINTF(x) if (uaudiodebug) logprintf x +#define DPRINTFN(n,x) if (uaudiodebug>(n)) logprintf x int uaudiodebug = 0; #else #define DPRINTF(x) @@ -180,96 +180,105 @@ struct uaudio_softc { #define UAC_INPUT 1 #define UAC_EQUAL 2 -usbd_status uaudio_identify_ac __P((struct uaudio_softc *sc, - usb_config_descriptor_t *cdesc)); -usbd_status uaudio_identify_as __P((struct uaudio_softc *sc, - usb_config_descriptor_t *cdesc)); -usbd_status uaudio_process_as __P((struct uaudio_softc *sc, char *buf, - int *offsp, int size, - usb_interface_descriptor_t *id)); +static usbd_status uaudio_identify_ac __P((struct uaudio_softc *sc, + usb_config_descriptor_t *cdesc)); +static usbd_status uaudio_identify_as __P((struct uaudio_softc *sc, + usb_config_descriptor_t *cdesc)); +static usbd_status uaudio_process_as __P((struct uaudio_softc *sc, + char *buf, int *offsp, int size, + usb_interface_descriptor_t *id)); -void uaudio_add_alt __P((struct uaudio_softc *sc, struct as_info *ai)); +static void uaudio_add_alt __P((struct uaudio_softc *sc, + struct as_info *ai)); -usb_interface_descriptor_t *uaudio_find_iface +static usb_interface_descriptor_t *uaudio_find_iface __P((char *buf, int size, int *offsp, int subtype)); -void uaudio_mixer_add_ctl __P((struct uaudio_softc *sc, struct mixerctl *mp)); -char *uaudio_id_name __P((struct uaudio_softc *sc, usb_descriptor_t **dps, - int id)); -struct usb_audio_cluster uaudio_get_cluster __P((int id, - usb_descriptor_t **dps)); -void uaudio_add_input __P((struct uaudio_softc *sc, usb_descriptor_t *v, - usb_descriptor_t **dps)); -void uaudio_add_output __P((struct uaudio_softc *sc, usb_descriptor_t *v, +static void uaudio_mixer_add_ctl __P((struct uaudio_softc *sc, + struct mixerctl *mp)); +static char *uaudio_id_name __P((struct uaudio_softc *sc, + usb_descriptor_t **dps, int id)); +static struct usb_audio_cluster uaudio_get_cluster __P((int id, usb_descriptor_t **dps)); -void uaudio_add_mixer __P((struct uaudio_softc *sc, usb_descriptor_t *v, - usb_descriptor_t **dps)); -void uaudio_add_selector __P((struct uaudio_softc *sc, usb_descriptor_t *v, - usb_descriptor_t **dps)); -void uaudio_add_feature __P((struct uaudio_softc *sc, usb_descriptor_t *v, - usb_descriptor_t **dps)); -void uaudio_add_processing_updown __P((struct uaudio_softc *sc, - usb_descriptor_t *v, - usb_descriptor_t **dps)); -void uaudio_add_processing __P((struct uaudio_softc *sc, usb_descriptor_t *v, - usb_descriptor_t **dps)); -void uaudio_add_extension __P((struct uaudio_softc *sc, usb_descriptor_t *v, - usb_descriptor_t **dps)); -usbd_status uaudio_identify __P((struct uaudio_softc *sc, - usb_config_descriptor_t *cdesc)); - -int uaudio_signext __P((int type, int val)); -int uaudio_value2bsd __P((struct mixerctl *mc, int val)); -int uaudio_bsd2value __P((struct mixerctl *mc, int val)); -int uaudio_get __P((struct uaudio_softc *sc, int type, int which, int wValue, - int wIndex, int len)); -int uaudio_ctl_get __P((struct uaudio_softc *sc, int which, - struct mixerctl *mc, int chan)); -void uaudio_set __P((struct uaudio_softc *sc, int type, int which, int wValue, - int wIndex, int len, int val)); -void uaudio_ctl_set __P((struct uaudio_softc *sc, int which, - struct mixerctl *mc, int chan, int val)); - -usbd_status uaudio_set_speed __P((struct uaudio_softc *, int, u_int)); - -usbd_status uaudio_chan_open __P((struct uaudio_softc *sc, struct chan *ch)); -void uaudio_chan_close __P((struct uaudio_softc *sc, struct chan *ch)); -usbd_status uaudio_chan_alloc_buffers __P((struct uaudio_softc *, struct chan *)); -void uaudio_chan_free_buffers __P((struct uaudio_softc *, struct chan *)); -void uaudio_chan_set_param __P((struct chan *ch, struct audio_params *param, - u_char *start, u_char *end, int blksize)); -void uaudio_chan_ptransfer __P((struct chan *ch)); -void uaudio_chan_pintr __P((usbd_xfer_handle xfer, - usbd_private_handle priv, usbd_status status)); - -void uaudio_chan_rtransfer __P((struct chan *ch)); -void uaudio_chan_rintr __P((usbd_xfer_handle xfer, - usbd_private_handle priv, usbd_status status)); - - - -int uaudio_open __P((void *, int)); -void uaudio_close __P((void *)); -int uaudio_drain __P((void *)); -int uaudio_query_encoding __P((void *, struct audio_encoding *)); -int uaudio_set_params __P((void *, int, int, - struct audio_params *, struct audio_params *)); -int uaudio_round_blocksize __P((void *, int)); -int uaudio_trigger_output __P((void *, void *, void *, int, - void (*)(void *), void *, - struct audio_params *)); -int uaudio_trigger_input __P((void *, void *, void *, int, - void (*)(void *), void *, - struct audio_params *)); -int uaudio_halt_in_dma __P((void *)); -int uaudio_halt_out_dma __P((void *)); -int uaudio_getdev __P((void *, struct audio_device *)); -int uaudio_mixer_set_port __P((void *, mixer_ctrl_t *)); -int uaudio_mixer_get_port __P((void *, mixer_ctrl_t *)); -int uaudio_query_devinfo __P((void *, mixer_devinfo_t *)); -int uaudio_get_props __P((void *)); - -struct audio_hw_if uaudio_hw_if = { +static void uaudio_add_input __P((struct uaudio_softc *sc, + usb_descriptor_t *v, usb_descriptor_t **dps)); +static void uaudio_add_output __P((struct uaudio_softc *sc, + usb_descriptor_t *v, usb_descriptor_t **dps)); +static void uaudio_add_mixer __P((struct uaudio_softc *sc, + usb_descriptor_t *v, usb_descriptor_t **dps)); +static void uaudio_add_selector __P((struct uaudio_softc *sc, + usb_descriptor_t *v, usb_descriptor_t **dps)); +static void uaudio_add_feature __P((struct uaudio_softc *sc, + usb_descriptor_t *v, usb_descriptor_t **dps)); +static void uaudio_add_processing_updown + __P((struct uaudio_softc *sc, + usb_descriptor_t *v, usb_descriptor_t **dps)); +static void uaudio_add_processing __P((struct uaudio_softc *sc, + usb_descriptor_t *v, usb_descriptor_t **dps)); +static void uaudio_add_extension __P((struct uaudio_softc *sc, + usb_descriptor_t *v, usb_descriptor_t **dps)); +static usbd_status uaudio_identify __P((struct uaudio_softc *sc, + usb_config_descriptor_t *cdesc)); + +static int uaudio_signext __P((int type, int val)); +static int uaudio_value2bsd __P((struct mixerctl *mc, int val)); +static int uaudio_bsd2value __P((struct mixerctl *mc, int val)); +static int uaudio_get __P((struct uaudio_softc *sc, int type, + int which, int wValue, int wIndex, int len)); +static int uaudio_ctl_get __P((struct uaudio_softc *sc, int which, + struct mixerctl *mc, int chan)); +static void uaudio_set __P((struct uaudio_softc *sc, int type, + int which, int wValue, int wIndex, int l, int v)); +static void uaudio_ctl_set __P((struct uaudio_softc *sc, int which, + struct mixerctl *mc, int chan, int val)); + +static usbd_status uaudio_set_speed __P((struct uaudio_softc *, int, + u_int)); + +static usbd_status uaudio_chan_open __P((struct uaudio_softc *sc, + struct chan *ch)); +static void uaudio_chan_close __P((struct uaudio_softc *sc, + struct chan *ch)); +static usbd_status uaudio_chan_alloc_buffers __P((struct uaudio_softc *, + struct chan *)); +static void uaudio_chan_free_buffers __P((struct uaudio_softc *, + struct chan *)); +static void uaudio_chan_set_param __P((struct chan *ch, + struct audio_params *param, u_char *start, + u_char *end, int blksize)); +static void uaudio_chan_ptransfer __P((struct chan *ch)); +static void uaudio_chan_pintr __P((usbd_xfer_handle xfer, + usbd_private_handle priv, usbd_status status)); + +static void uaudio_chan_rtransfer __P((struct chan *ch)); +static void uaudio_chan_rintr __P((usbd_xfer_handle xfer, + usbd_private_handle priv, usbd_status status)); + + + +static int uaudio_open __P((void *, int)); +static void uaudio_close __P((void *)); +static int uaudio_drain __P((void *)); +static int uaudio_query_encoding __P((void *, + struct audio_encoding *)); +static int uaudio_set_params __P((void *, int, int, + struct audio_params *, struct audio_params *)); +static int uaudio_round_blocksize __P((void *, int)); +static int uaudio_trigger_output __P((void *, void *, void *, + int, void (*)(void *), void *, + struct audio_params *)); +static int uaudio_trigger_input __P((void *, void *, void *, + int, void (*)(void *), void *, + struct audio_params *)); +static int uaudio_halt_in_dma __P((void *)); +static int uaudio_halt_out_dma __P((void *)); +static int uaudio_getdev __P((void *, struct audio_device *)); +static int uaudio_mixer_set_port __P((void *, mixer_ctrl_t *)); +static int uaudio_mixer_get_port __P((void *, mixer_ctrl_t *)); +static int uaudio_query_devinfo __P((void *, mixer_devinfo_t *)); +static int uaudio_get_props __P((void *)); + +static struct audio_hw_if uaudio_hw_if = { uaudio_open, uaudio_close, uaudio_drain, @@ -298,7 +307,7 @@ struct audio_hw_if uaudio_hw_if = { uaudio_trigger_input, }; -struct audio_device uaudio_device = { +static struct audio_device uaudio_device = { "USB audio", "", "uaudio" @@ -379,7 +388,11 @@ USB_ATTACH(uaudio) sc->sc_chan.sc = sc; DPRINTF(("uaudio_attach: doing audio_attach_mi\n")); - /* sc->sc_audiodev = */ audio_attach_mi(&uaudio_hw_if, sc, &sc->sc_dev); +#if defined(__OpenBSD__) + audio_attach_mi(&uaudio_hw_if, sc, &sc->sc_dev); +#else + 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)); @@ -527,21 +540,9 @@ uaudio_mixer_add_ctl(sc, mc) if (sc->sc_nctls == NULL) sc->sc_ctls = malloc(sizeof *mc, M_USBDEV, M_NOWAIT); else -#ifdef __OpenBSD__ - { - void *p; - - p = malloc((sc->sc_nctls+1) * sizeof *mc, M_USBDEV, M_NOWAIT); - if (p != NULL) - bcopy(sc->sc_ctls, p, sc->sc_nctls * sizeof *mc); - free(sc->sc_ctls, M_USBDEV); - sc->sc_ctls = p; - } -#else sc->sc_ctls = realloc(sc->sc_ctls, (sc->sc_nctls+1) * sizeof *mc, M_USBDEV, M_NOWAIT); -#endif if (sc->sc_ctls == NULL) { printf("uaudio_mixer_add_ctl: no memory\n"); return; @@ -911,7 +912,7 @@ uaudio_add_processing_updown(sc, v, dps) (struct usb_audio_processing_unit_1 *)&d->baSourceId[d->bNrInPins]; struct usb_audio_processing_unit_updown *ud = (struct usb_audio_processing_unit_updown *) - &d1->bmControls[d1->bControlSize]; + &d1->bmControls[d1->bControlSize]; struct mixerctl mix; int i; @@ -927,7 +928,7 @@ uaudio_add_processing_updown(sc, v, dps) mix.nchan = 1; mix.wValue[0] = MAKE(UD_MODE_SELECT_CONTROL, 0); mix.class = -1; - mix.type = MIX_ON_OFF; /* XXX */ + mix.type = MIX_ON_OFF; /* XXX */ mix.ctlunit = ""; sprintf(mix.ctlname, "pro%d-mode", d->bUnitId); @@ -966,7 +967,7 @@ uaudio_add_processing(sc, v, dps) uaudio_mixer_add_ctl(sc, &mix); } - switch (ptype) { + switch(ptype) { case UPDOWNMIX_PROCESS: uaudio_add_processing_updown(sc, v, dps); break; @@ -1032,22 +1033,10 @@ uaudio_add_alt(sc, ai) if (sc->sc_nalts == NULL) sc->sc_alts = malloc(sizeof *ai, M_USBDEV, M_NOWAIT); else -#ifdef __OpenBSD__ - { - void *p; - - p = malloc((sc->sc_nalts+1) * sizeof *ai, M_USBDEV, M_NOWAIT); - if (p != NULL) - bcopy(sc->sc_alts, p, sc->sc_nalts * sizeof *ai); - free(sc->sc_alts, M_USBDEV); - sc->sc_alts = p; - } -#else sc->sc_alts = realloc(sc->sc_alts, (sc->sc_nalts+1) * sizeof *ai, M_USBDEV, M_NOWAIT); -#endif - if (sc->sc_alts == 0) { + if (sc->sc_alts == NULL) { printf("uaudio_add_alt: no memory\n"); return; } @@ -1217,7 +1206,7 @@ uaudio_identify_as(sc, cdesc) break; } id = uaudio_find_iface(buf, size, &offs,UISUBCLASS_AUDIOSTREAM); - if (!id) + if (id == NULL) break; } if (offs > size) @@ -1612,7 +1601,7 @@ uaudio_set(sc, which, type, wValue, wIndex, len, val) err = usbd_do_request(sc->sc_udev, &req, &data); #ifdef UAUDIO_DEBUG if (err) - DPRINTF(("uaudio_set: r=%d\n", r)); + DPRINTF(("uaudio_set: err=%d\n", err)); #endif } @@ -1884,7 +1873,7 @@ uaudio_chan_open(sc, ch) #ifdef UAUDIO_DEBUG err = uaudio_set_speed(sc, endpt, ch->sample_rate); if (err) - DPRINTF(("uaudio_chan_open: set_speed failed r=%s\n", + DPRINTF(("uaudio_chan_open: set_speed failed err=%s\n", usbd_errstr(err))); #else (void)uaudio_set_speed(sc, endpt, ch->sample_rate); @@ -2012,9 +2001,9 @@ uaudio_chan_ptransfer(ch) DPRINTFN(5,("uaudio_chan_transfer: ptransfer xfer=%p\n", cb->xfer)); /* Fill the request */ - usbd_setup_isoc_xfer(cb->xfer, ch->pipe, cb, cb->sizes, - UAUDIO_NFRAMES, USBD_NO_COPY, - uaudio_chan_pintr); + usbd_setup_isoc_xfer(cb->xfer, ch->pipe, cb, cb->sizes, + UAUDIO_NFRAMES, USBD_NO_COPY, + uaudio_chan_pintr); (void)usbd_transfer(cb->xfer); } @@ -2034,7 +2023,7 @@ uaudio_chan_pintr(xfer, priv, status) if (status == USBD_CANCELLED) return; - usbd_get_xfer_status(xfer, NULL, NULL, &count, 0); + usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL); DPRINTFN(5,("uaudio_chan_pintr: count=%d, transferred=%d\n", count, ch->transferred)); #ifdef DIAGNOSTIC @@ -2104,8 +2093,8 @@ uaudio_chan_rtransfer(ch) DPRINTFN(5,("uaudio_chan_rtransfer: transfer xfer=%p\n", cb->xfer)); /* Fill the request */ usbd_setup_isoc_xfer(cb->xfer, ch->pipe, cb, cb->sizes, - UAUDIO_NFRAMES, USBD_NO_COPY, - uaudio_chan_rintr); + UAUDIO_NFRAMES, USBD_NO_COPY, + uaudio_chan_rintr); (void)usbd_transfer(cb->xfer); } @@ -2125,7 +2114,7 @@ uaudio_chan_rintr(xfer, priv, status) if (status == USBD_CANCELLED) return; - usbd_get_xfer_status(xfer, NULL, NULL, &count, 0); + usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL); DPRINTFN(5,("uaudio_chan_rintr: count=%d, transferred=%d\n", count, ch->transferred)); #ifdef DIAGNOSTIC @@ -2230,8 +2219,8 @@ uaudio_set_params(addr, setmode, usemode, p, r) break; case AUDIO_ENCODING_ULINEAR_BE: if (p->precision == 16) { - pswcode = swap_bytes_change_sign16; - rswcode = change_sign16_swap_bytes; + pswcode = swap_bytes_change_sign16_le; + rswcode = change_sign16_swap_bytes_le; enc = AUDIO_ENCODING_SLINEAR_LE; } else if (p->precision == 8 && !(flags & HAS_8U)) { pswcode = rswcode = change_sign8; @@ -2240,7 +2229,7 @@ uaudio_set_params(addr, setmode, usemode, p, r) break; case AUDIO_ENCODING_ULINEAR_LE: if (p->precision == 16) { - pswcode = rswcode = change_sign16; + pswcode = rswcode = change_sign16_le; enc = AUDIO_ENCODING_SLINEAR_LE; } else if (p->precision == 8 && !(flags & HAS_8U)) { pswcode = rswcode = change_sign8; @@ -2326,8 +2315,8 @@ uaudio_set_params(addr, setmode, usemode, p, r) found: p->sw_code = pswcode; r->sw_code = rswcode; - p->factor = pfactor; - r->factor = rfactor; + p->factor = pfactor; + r->factor = rfactor; sc->sc_curaltidx = i; DPRINTF(("uaudio_set_params: use altidx=%d, altno=%d\n", diff --git a/sys/dev/usb/uaudioreg.h b/sys/dev/usb/uaudioreg.h index 15da30f2193..d1ee2ef1cd4 100644 --- a/sys/dev/usb/uaudioreg.h +++ b/sys/dev/usb/uaudioreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: uaudioreg.h,v 1.2 2000/03/26 08:39:45 aaron Exp $ */ +/* $OpenBSD: uaudioreg.h,v 1.3 2000/03/28 19:37:49 aaron Exp $ */ /* $NetBSD: uaudioreg.h,v 1.4 2000/01/16 09:32:56 augustss Exp $ */ /* @@ -284,38 +284,32 @@ struct usb_audio_extension_unit_1 { #define FORMAT_TYPE_II 2 #define FORMAT_TYPE_III 3 -#define UA_PROC_MASK(n) (1 << ((n)-1)) +#define UA_PROC_MASK(n) (1<< ((n)-1)) #define PROCESS_UNDEFINED 0 -#define XX_ENABLE_CONTROL 1 - +#define XX_ENABLE_CONTROL 1 #define UPDOWNMIX_PROCESS 1 -#define UD_ENABLE_CONTROL 1 -#define UD_MODE_SELECT_CONTROL 2 - +#define UD_ENABLE_CONTROL 1 +#define UD_MODE_SELECT_CONTROL 2 #define DOLBY_PROLOGIC_PROCESS 2 -#define DP_ENABLE_CONTROL 1 -#define DP_MODE_SELECT_CONTROL 2 - +#define DP_ENABLE_CONTROL 1 +#define DP_MODE_SELECT_CONTROL 2 #define P3D_STEREO_EXTENDER_PROCESS 3 -#define P3D_ENABLE_CONTROL 1 -#define P3D_SPACIOUSNESS_CONTROL 2 - +#define P3D_ENABLE_CONTROL 1 +#define P3D_SPACIOUSNESS_CONTROL 2 #define REVERBATION_PROCESS 4 -#define RV_ENABLE_CONTROL 1 -#define RV_LEVEL_CONTROL 2 -#define RV_TIME_CONTROL 3 -#define RV_FEEDBACK_CONTROL 4 - +#define RV_ENABLE_CONTROL 1 +#define RV_LEVEL_CONTROL 2 +#define RV_TIME_CONTROL 3 +#define RV_FEEDBACK_CONTROL 4 #define CHORUS_PROCESS 5 -#define CH_ENABLE_CONTROL 1 -#define CH_LEVEL_CONTROL 2 -#define CH_RATE_CONTROL 3 -#define CH_DEPTH_CONTROL 4 - +#define CH_ENABLE_CONTROL 1 +#define CH_LEVEL_CONTROL 2 +#define CH_RATE_CONTROL 3 +#define CH_DEPTH_CONTROL 4 #define DYN_RANGE_COMP_PROCESS 6 -#define DR_ENABLE_CONTROL 1 -#define DR_COMPRESSION_RATE_CONTROL 2 -#define DR_MAXAMPL_CONTROL 3 -#define DR_THRESHOLD_CONTROL 4 -#define DR_ATTACK_TIME_CONTROL 5 -#define DR_RELEASE_TIME_CONTROL 6 +#define DR_ENABLE_CONTROL 1 +#define DR_COMPRESSION_RATE_CONTROL 2 +#define DR_MAXAMPL_CONTROL 3 +#define DR_THRESHOLD_CONTROL 4 +#define DR_ATTACK_TIME_CONTROL 5 +#define DR_RELEASE_TIME_CONTROL 6 diff --git a/sys/dev/usb/ugen.c b/sys/dev/usb/ugen.c index a8f62e257e9..7301f95b7e5 100644 --- a/sys/dev/usb/ugen.c +++ b/sys/dev/usb/ugen.c @@ -1,5 +1,6 @@ -/* $OpenBSD: ugen.c,v 1.8 2000/03/26 08:39:45 aaron Exp $ */ +/* $OpenBSD: ugen.c,v 1.9 2000/03/28 19:37:49 aaron Exp $ */ /* $NetBSD: ugen.c,v 1.36 2000/03/06 20:59:17 augustss Exp $ */ +/* $FreeBSD: src/sys/dev/usb/ugen.c,v 1.26 1999/11/17 22:33:41 n_hibma Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -136,18 +137,18 @@ static struct cdevsw ugen_cdevsw = { }; #endif -void ugenintr __P((usbd_xfer_handle xfer, usbd_private_handle addr, - usbd_status status)); +static void ugenintr __P((usbd_xfer_handle xfer, usbd_private_handle addr, + usbd_status status)); -int ugen_do_read __P((struct ugen_softc *, int, struct uio *, int)); -int ugen_do_write __P((struct ugen_softc *, int, struct uio *, int)); -int ugen_do_ioctl __P((struct ugen_softc *, int, u_long, - caddr_t, int, struct proc *)); -int ugen_set_config __P((struct ugen_softc *sc, int configno)); -usb_config_descriptor_t *ugen_get_cdesc __P((struct ugen_softc *sc, int index, - int *lenp)); -usbd_status ugen_set_interface __P((struct ugen_softc *, int, int)); -int ugen_get_alt_index __P((struct ugen_softc *sc, int ifaceidx)); +static int ugen_do_read __P((struct ugen_softc *, int, struct uio *, int)); +static int ugen_do_write __P((struct ugen_softc *, int, struct uio *, int)); +static int ugen_do_ioctl __P((struct ugen_softc *, int, u_long, + caddr_t, int, struct proc *)); +static int ugen_set_config __P((struct ugen_softc *sc, int configno)); +static usb_config_descriptor_t *ugen_get_cdesc __P((struct ugen_softc *sc, + int index, int *lenp)); +static usbd_status ugen_set_interface __P((struct ugen_softc *, int, int)); +static int ugen_get_alt_index __P((struct ugen_softc *sc, int ifaceidx)); #define UGENUNIT(n) ((minor(n) >> 4) & 0xf) #define UGENENDPOINT(n) (minor(n) & 0xf) @@ -182,7 +183,7 @@ USB_ATTACH(ugen) /* First set configuration index 0, the default one for ugen. */ err = usbd_set_config_index(udev, 0, 0); if (err) { - printf("%s: setting configuration index 0 failed\n", + printf("%s: setting configuration index 0 failed\n", USBDEVNAME(sc->sc_dev)); sc->sc_dying = 1; USB_ATTACH_ERROR_RETURN; @@ -200,7 +201,7 @@ USB_ATTACH(ugen) #ifdef __FreeBSD__ { - struct int global_init_done = 0; + static int global_init_done = 0; if (!global_init_done) { cdevsw_add(&ugen_cdevsw); global_init_done = 1; @@ -214,7 +215,7 @@ USB_ATTACH(ugen) USB_ATTACH_SUCCESS_RETURN; } -int +static int ugen_set_config(sc, configno) struct ugen_softc *sc; int configno; @@ -328,10 +329,10 @@ ugenopen(dev, flag, mode, p) if (clalloc(&sce->q, UGEN_IBSIZE, 0) == -1) return (ENOMEM); err = usbd_open_pipe_intr(sce->iface, - edesc->bEndpointAddress, - USBD_SHORT_XFER_OK, &sce->pipeh, sce, - sce->ibuf, isize, ugenintr, - USBD_DEFAULT_INTERVAL); + edesc->bEndpointAddress, + USBD_SHORT_XFER_OK, &sce->pipeh, sce, + sce->ibuf, isize, ugenintr, + USBD_DEFAULT_INTERVAL); if (err) { free(sce->ibuf, M_USBDEV); clfree(&sce->q); @@ -341,8 +342,7 @@ ugenopen(dev, flag, mode, p) break; case UE_BULK: err = usbd_open_pipe(sce->iface, - edesc->bEndpointAddress, 0, - &sce->pipeh); + edesc->bEndpointAddress, 0, &sce->pipeh); if (err) return (EIO); break; @@ -396,12 +396,13 @@ ugenclose(dev, flag, mode, p) usbd_abort_pipe(sce->pipeh); usbd_close_pipe(sce->pipeh); - sce->pipeh = 0; + sce->pipeh = NULL; - if (sce->ibuf) { + if (sce->ibuf != NULL) { free(sce->ibuf, M_USBDEV); sce->ibuf = NULL; clfree(&sce->q); + } } sc->sc_is_open[endpt] = 0; @@ -409,7 +410,7 @@ ugenclose(dev, flag, mode, p) return (0); } -int +static int ugen_do_read(sc, endpt, uio, flag) struct ugen_softc *sc; int endpt; @@ -425,7 +426,7 @@ ugen_do_read(sc, endpt, uio, flag) int error = 0; u_char buffer[UGEN_CHUNK]; -#if defined(__NetBSD__) || defined(__OpenBSD__) +#ifdef __NetBSD__ DPRINTFN(5, ("ugenread: %d:%d\n", sc->sc_dev.dv_unit, endpt)); #endif @@ -436,11 +437,11 @@ ugen_do_read(sc, endpt, uio, flag) return (ENODEV); #ifdef DIAGNOSTIC - if (!sce->edesc) { + if (sce->edesc == NULL) { printf("ugenread: no edesc\n"); return (EIO); } - if (!sce->pipeh) { + if (sce->pipeh == NULL) { printf("ugenread: no pipe\n"); return (EIO); } @@ -492,10 +493,10 @@ ugen_do_read(sc, endpt, uio, flag) DPRINTFN(1, ("ugenread: start transfer %d bytes\n",n)); tn = n; err = usbd_bulk_transfer( - xfer, sce->pipeh, - sce->state & UGEN_SHORT_OK ? - USBD_SHORT_XFER_OK : 0, - sce->timeout, buf, &tn, "ugenrb"); + xfer, sce->pipeh, + sce->state & UGEN_SHORT_OK ? + USBD_SHORT_XFER_OK : 0, + sce->timeout, buf, &tn, "ugenrb"); if (err) { if (err == USBD_INTERRUPTED) error = EINTR; @@ -537,7 +538,7 @@ ugenread(dev, uio, flag) return (error); } -int +static int ugen_do_write(sc, endpt, uio, flag) struct ugen_softc *sc; int endpt; @@ -551,7 +552,7 @@ ugen_do_write(sc, endpt, uio, flag) usbd_xfer_handle xfer; usbd_status err; - DPRINTFN(5, ("ugenwrite: %d:%d\n", sc->sc_dev.dv_unit, endpt)); + DPRINTFN(5, ("%s: ugenwrite: %d\n", USBDEVNAME(sc->sc_dev), endpt)); if (sc->sc_dying) return (EIO); @@ -560,11 +561,11 @@ ugen_do_write(sc, endpt, uio, flag) return (ENODEV); #ifdef DIAGNOSTIC - if (!sce->edesc) { + if (sce->edesc == NULL) { printf("ugenwrite: no edesc\n"); return (EIO); } - if (!sce->pipeh) { + if (sce->pipeh == NULL) { printf("ugenwrite: no pipe\n"); return (EIO); } @@ -581,7 +582,7 @@ ugen_do_write(sc, endpt, uio, flag) break; DPRINTFN(1, ("ugenwrite: transfer %d bytes\n", n)); err = usbd_bulk_transfer(xfer, sce->pipeh, 0, - sce->timeout, buf, &n,"ugenwb"); + sce->timeout, buf, &n,"ugenwb"); if (err) { if (err == USBD_INTERRUPTED) error = EINTR; @@ -693,7 +694,7 @@ USB_DETACH(ugen) return (0); } -void +static void ugenintr(xfer, addr, status) usbd_xfer_handle xfer; usbd_private_handle addr; @@ -713,7 +714,7 @@ ugenintr(xfer, addr, status) return; } - usbd_get_xfer_status(xfer, NULL, NULL, &count, 0); + usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL); ibuf = sce->ibuf; DPRINTFN(5, ("ugenintr: xfer=%p status=%d count=%d\n", @@ -731,7 +732,7 @@ ugenintr(xfer, addr, status) selwakeup(&sce->rsel); } -usbd_status +static usbd_status ugen_set_interface(sc, ifaceidx, altno) struct ugen_softc *sc; int ifaceidx, altno; @@ -788,7 +789,7 @@ ugen_set_interface(sc, ifaceidx, altno) } /* Retrieve a complete descriptor for a certain device and index. */ -usb_config_descriptor_t * +static usb_config_descriptor_t * ugen_get_cdesc(sc, index, lenp) struct ugen_softc *sc; int index; @@ -815,7 +816,7 @@ ugen_get_cdesc(sc, index, lenp) if (lenp) *lenp = len; cdesc = malloc(len, M_TEMP, M_WAITOK); - err = usbd_get_config_desc_full(sc->sc_udev, index, cdesc, len); + err = usbd_get_config_desc_full(sc->sc_udev, index, cdesc,len); if (err) { free(cdesc, M_TEMP); return (0); @@ -824,7 +825,7 @@ ugen_get_cdesc(sc, index, lenp) return (cdesc); } -int +static int ugen_get_alt_index(sc, ifaceidx) struct ugen_softc *sc; int ifaceidx; @@ -834,11 +835,11 @@ ugen_get_alt_index(sc, ifaceidx) err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface); if (err) - return (-1); + return (-1); return (usbd_get_interface_altindex(iface)); } -int +static int ugen_do_ioctl(sc, endpt, cmd, addr, flag, p) struct ugen_softc *sc; int endpt; @@ -876,7 +877,7 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p) if (sce == NULL) return (EINVAL); #ifdef DIAGNOSTIC - if (!sce->pipeh) { + if (sce->pipeh == NULL) { printf("ugenioctl: USB_SET_SHORT_XFER, no pipe\n"); return (EIO); } @@ -891,7 +892,7 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p) if (sce == NULL) return (EINVAL); #ifdef DIAGNOSTIC - if (!sce->pipeh) { + if (sce->pipeh == NULL) { printf("ugenioctl: USB_SET_TIMEOUT, no pipe\n"); return (EIO); } @@ -927,7 +928,7 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p) case USB_GET_ALTINTERFACE: ai = (struct usb_alt_interface *)addr; err = usbd_device2interface_handle(sc->sc_udev, - ai->interface_index, &iface); + ai->interface_index, &iface); if (err) return (EINVAL); idesc = usbd_get_interface_descriptor(iface); @@ -940,7 +941,7 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p) return (EPERM); ai = (struct usb_alt_interface *)addr; err = usbd_device2interface_handle(sc->sc_udev, - ai->interface_index, &iface); + ai->interface_index, &iface); if (err) return (EINVAL); err = ugen_set_interface(sc, ai->interface_index, ai->alt_no); @@ -1029,14 +1030,14 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p) uio.uio_segflg = UIO_USERSPACE; uio.uio_rw = UIO_READ; uio.uio_procp = p; - error = uiomove((caddr_t)cdesc, len, &uio); + error = uiomove((void *)cdesc, len, &uio); free(cdesc, M_TEMP); return (error); } case USB_GET_STRING_DESC: si = (struct usb_string_desc *)addr; err = usbd_get_string_desc(sc->sc_udev, si->string_index, - si->language_id, &si->desc); + si->language_id, &si->desc); if (err) return (EINVAL); break; @@ -1083,7 +1084,7 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p) } } err = usbd_do_request_flags(sc->sc_udev, &ur->request, - ptr, ur->flags, &ur->actlen); + ptr, ur->flags, &ur->actlen); if (err) { error = EIO; goto ret; @@ -1143,6 +1144,7 @@ ugenpoll(dev, events, p) int s; USB_GET_SC(ugen, UGENUNIT(dev), sc); + if (sc->sc_dying) return (EIO); diff --git a/sys/dev/usb/uhci.c b/sys/dev/usb/uhci.c index 184c2e930ae..ca3fe32acea 100644 --- a/sys/dev/usb/uhci.c +++ b/sys/dev/usb/uhci.c @@ -1,5 +1,6 @@ -/* $OpenBSD: uhci.c,v 1.9 2000/03/26 21:47:51 aaron Exp $ */ -/* $NetBSD: uhci.c,v 1.87 2000/02/29 21:37:01 augustss Exp $ */ +/* $OpenBSD: uhci.c,v 1.10 2000/03/28 19:37:49 aaron Exp $ */ +/* $NetBSD: uhci.c,v 1.100 2000/03/27 09:41:36 augustss Exp $ */ +/* $FreeBSD: src/sys/dev/usb/uhci.c,v 1.33 1999/11/17 22:33:41 n_hibma Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -93,6 +94,7 @@ struct cfdriver uhci_cd = { #endif #ifdef UHCI_DEBUG +uhci_softc_t *thesc; #define DPRINTF(x) if (uhcidebug) printf x #define DPRINTFN(n,x) if (uhcidebug>(n)) printf x int uhcidebug = 0; @@ -105,16 +107,23 @@ int uhcidebug = 0; * The UHCI controller is little endian, so on big endian machines * the data strored in memory needs to be swapped. */ +#if defined(__FreeBSD__) || defined(__OpenBSD__) #if BYTE_ORDER == BIG_ENDIAN -#define LE(x) (bswap32(x)) +#define htole32(x) (bswap32(x)) +#define le32toh(x) (bswap32(x)) #else -#define LE(x) (x) +#define htole32(x) (x) +#define le32toh(x) (x) +#endif #endif struct uhci_pipe { struct usbd_pipe pipe; - uhci_intr_info_t *iinfo; int nexttoggle; + + u_char aborting; + usbd_xfer_handle abortstart, abortend; + /* Info needed for different pipe kinds. */ union { /* Control pipe */ @@ -143,118 +152,116 @@ struct uhci_pipe { } u; }; -/* - * The uhci_intr_info free list can be global since they contain - * no dma specific data. The other free lists do. - */ -LIST_HEAD(, uhci_intr_info) uhci_ii_free; - -void uhci_busreset __P((uhci_softc_t *)); -void uhci_shutdown __P((void *v)); -void uhci_power __P((int, void *)); -usbd_status uhci_run __P((uhci_softc_t *, int run)); -uhci_soft_td_t *uhci_alloc_std __P((uhci_softc_t *)); -void uhci_free_std __P((uhci_softc_t *, uhci_soft_td_t *)); -uhci_soft_qh_t *uhci_alloc_sqh __P((uhci_softc_t *)); -void uhci_free_sqh __P((uhci_softc_t *, uhci_soft_qh_t *)); -uhci_intr_info_t *uhci_alloc_intr_info __P((uhci_softc_t *)); -void uhci_free_intr_info __P((uhci_intr_info_t *ii)); +static void uhci_busreset __P((uhci_softc_t *)); +static void uhci_shutdown __P((void *v)); +static void uhci_power __P((int, void *)); +static usbd_status uhci_run __P((uhci_softc_t *, int run)); +static uhci_soft_td_t *uhci_alloc_std __P((uhci_softc_t *)); +static void uhci_free_std __P((uhci_softc_t *, uhci_soft_td_t *)); +static uhci_soft_qh_t *uhci_alloc_sqh __P((uhci_softc_t *)); +static void uhci_free_sqh __P((uhci_softc_t *, uhci_soft_qh_t *)); #if 0 -void uhci_enter_ctl_q __P((uhci_softc_t *, uhci_soft_qh_t *, +static void uhci_enter_ctl_q __P((uhci_softc_t *, uhci_soft_qh_t *, uhci_intr_info_t *)); -void uhci_exit_ctl_q __P((uhci_softc_t *, uhci_soft_qh_t *)); +static void uhci_exit_ctl_q __P((uhci_softc_t *, uhci_soft_qh_t *)); #endif -void uhci_free_std_chain __P((uhci_softc_t *, +static void uhci_free_std_chain __P((uhci_softc_t *, uhci_soft_td_t *, uhci_soft_td_t *)); -usbd_status uhci_alloc_std_chain __P((struct uhci_pipe *, uhci_softc_t *, - int, int, u_int16_t, usb_dma_t *, - uhci_soft_td_t **, - uhci_soft_td_t **)); -void uhci_timo __P((void *)); -void uhci_waitintr __P((uhci_softc_t *, usbd_xfer_handle)); -void uhci_check_intr __P((uhci_softc_t *, uhci_intr_info_t *)); -void uhci_idone __P((uhci_intr_info_t *)); -void uhci_abort_xfer __P((usbd_xfer_handle, usbd_status status)); -void uhci_abort_xfer_end __P((void *v)); -void uhci_timeout __P((void *)); -void uhci_wakeup_ctrl __P((void *, int, int, void *, int)); -void uhci_lock_frames __P((uhci_softc_t *)); -void uhci_unlock_frames __P((uhci_softc_t *)); -void uhci_add_ctrl __P((uhci_softc_t *, uhci_soft_qh_t *)); -void uhci_add_bulk __P((uhci_softc_t *, uhci_soft_qh_t *)); -void uhci_remove_ctrl __P((uhci_softc_t *, uhci_soft_qh_t *)); -void uhci_remove_bulk __P((uhci_softc_t *, uhci_soft_qh_t *)); -int uhci_str __P((usb_string_descriptor_t *, int, char *)); - -usbd_status uhci_setup_isoc __P((usbd_pipe_handle pipe)); -void uhci_device_isoc_enter __P((usbd_xfer_handle)); - -void uhci_wakeup_cb __P((usbd_xfer_handle xfer)); - -usbd_status uhci_allocm __P((struct usbd_bus *, usb_dma_t *, u_int32_t)); -void uhci_freem __P((struct usbd_bus *, usb_dma_t *)); - -usbd_xfer_handle uhci_allocx __P((struct usbd_bus *)); -void uhci_freex __P((struct usbd_bus *, usbd_xfer_handle)); - -usbd_status uhci_device_ctrl_transfer __P((usbd_xfer_handle)); -usbd_status uhci_device_ctrl_start __P((usbd_xfer_handle)); -void uhci_device_ctrl_abort __P((usbd_xfer_handle)); -void uhci_device_ctrl_close __P((usbd_pipe_handle)); -void uhci_device_ctrl_done __P((usbd_xfer_handle)); - -usbd_status uhci_device_intr_transfer __P((usbd_xfer_handle)); -usbd_status uhci_device_intr_start __P((usbd_xfer_handle)); -void uhci_device_intr_abort __P((usbd_xfer_handle)); -void uhci_device_intr_close __P((usbd_pipe_handle)); -void uhci_device_intr_done __P((usbd_xfer_handle)); - -usbd_status uhci_device_bulk_transfer __P((usbd_xfer_handle)); -usbd_status uhci_device_bulk_start __P((usbd_xfer_handle)); -void uhci_device_bulk_abort __P((usbd_xfer_handle)); -void uhci_device_bulk_close __P((usbd_pipe_handle)); -void uhci_device_bulk_done __P((usbd_xfer_handle)); - -usbd_status uhci_device_isoc_transfer __P((usbd_xfer_handle)); -usbd_status uhci_device_isoc_start __P((usbd_xfer_handle)); -void uhci_device_isoc_abort __P((usbd_xfer_handle)); -void uhci_device_isoc_close __P((usbd_pipe_handle)); -void uhci_device_isoc_done __P((usbd_xfer_handle)); - -usbd_status uhci_root_ctrl_transfer __P((usbd_xfer_handle)); -usbd_status uhci_root_ctrl_start __P((usbd_xfer_handle)); -void uhci_root_ctrl_abort __P((usbd_xfer_handle)); -void uhci_root_ctrl_close __P((usbd_pipe_handle)); -void uhci_root_ctrl_done __P((usbd_xfer_handle)); - -usbd_status uhci_root_intr_transfer __P((usbd_xfer_handle)); -usbd_status uhci_root_intr_start __P((usbd_xfer_handle)); -void uhci_root_intr_abort __P((usbd_xfer_handle)); -void uhci_root_intr_close __P((usbd_pipe_handle)); -void uhci_root_intr_done __P((usbd_xfer_handle)); - -usbd_status uhci_open __P((usbd_pipe_handle)); -void uhci_poll __P((struct usbd_bus *)); -void uhci_softintr __P((struct usbd_bus *)); - -usbd_status uhci_device_request __P((usbd_xfer_handle xfer)); - -void uhci_add_intr __P((uhci_softc_t *, int, uhci_soft_qh_t *)); -void uhci_remove_intr __P((uhci_softc_t *, int, uhci_soft_qh_t *)); -usbd_status uhci_device_setintr __P((uhci_softc_t *sc, - struct uhci_pipe *pipe, int ival)); - -void uhci_device_clear_toggle __P((usbd_pipe_handle pipe)); -void uhci_noop __P((usbd_pipe_handle pipe)); +static usbd_status uhci_alloc_std_chain __P((struct uhci_pipe *, + uhci_softc_t *, int, int, u_int16_t, usb_dma_t *, + uhci_soft_td_t **, uhci_soft_td_t **)); +static void uhci_poll_hub __P((void *)); +static void uhci_waitintr __P((uhci_softc_t *, + usbd_xfer_handle)); +static void uhci_check_intr __P((uhci_softc_t *, + uhci_intr_info_t *)); +static void uhci_idone __P((uhci_intr_info_t *)); + +static void uhci_abort_xfer __P((usbd_xfer_handle, + usbd_status status)); +static void uhci_abort_xfer_end __P((void *v)); +static void uhci_abort_unlink_qh __P((struct uhci_pipe *)); +static void uhci_abort_relink_qh __P((struct uhci_pipe *)); +static void uhci_cancel_abort __P((usbd_pipe_handle)); + +static void uhci_timeout __P((void *)); +static void uhci_add_ctrl __P((uhci_softc_t *, uhci_soft_qh_t *)); +static void uhci_add_bulk __P((uhci_softc_t *, uhci_soft_qh_t *)); +static void uhci_remove_ctrl __P((uhci_softc_t *,uhci_soft_qh_t *)); +static void uhci_remove_bulk __P((uhci_softc_t *,uhci_soft_qh_t *)); +static int uhci_str __P((usb_string_descriptor_t *, int, char *)); + +static usbd_status uhci_setup_isoc __P((usbd_pipe_handle pipe)); +static void uhci_device_isoc_enter __P((usbd_xfer_handle)); + +static usbd_status uhci_allocm __P((struct usbd_bus *, usb_dma_t *, + u_int32_t)); +static void uhci_freem __P((struct usbd_bus *, usb_dma_t *)); + +static usbd_xfer_handle uhci_allocx __P((struct usbd_bus *)); +static void uhci_freex __P((struct usbd_bus *, usbd_xfer_handle)); + +static usbd_status uhci_device_ctrl_transfer __P((usbd_xfer_handle)); +static usbd_status uhci_device_ctrl_start __P((usbd_xfer_handle)); +static void uhci_device_ctrl_abort __P((usbd_xfer_handle)); +static void uhci_device_ctrl_close __P((usbd_pipe_handle)); +static void uhci_device_ctrl_done __P((usbd_xfer_handle)); + +static usbd_status uhci_device_intr_transfer __P((usbd_xfer_handle)); +static usbd_status uhci_device_intr_start __P((usbd_xfer_handle)); +static void uhci_device_intr_abort __P((usbd_xfer_handle)); +static void uhci_device_intr_close __P((usbd_pipe_handle)); +static void uhci_device_intr_done __P((usbd_xfer_handle)); + +static usbd_status uhci_device_bulk_transfer __P((usbd_xfer_handle)); +static usbd_status uhci_device_bulk_start __P((usbd_xfer_handle)); +static void uhci_device_bulk_abort __P((usbd_xfer_handle)); +static void uhci_device_bulk_close __P((usbd_pipe_handle)); +static void uhci_device_bulk_done __P((usbd_xfer_handle)); + +static usbd_status uhci_device_isoc_transfer __P((usbd_xfer_handle)); +static usbd_status uhci_device_isoc_start __P((usbd_xfer_handle)); +static void uhci_device_isoc_abort __P((usbd_xfer_handle)); +static void uhci_device_isoc_close __P((usbd_pipe_handle)); +static void uhci_device_isoc_done __P((usbd_xfer_handle)); + +static usbd_status uhci_root_ctrl_transfer __P((usbd_xfer_handle)); +static usbd_status uhci_root_ctrl_start __P((usbd_xfer_handle)); +static void uhci_root_ctrl_abort __P((usbd_xfer_handle)); +static void uhci_root_ctrl_close __P((usbd_pipe_handle)); +static void uhci_root_ctrl_done __P((usbd_xfer_handle)); + +static usbd_status uhci_root_intr_transfer __P((usbd_xfer_handle)); +static usbd_status uhci_root_intr_start __P((usbd_xfer_handle)); +static void uhci_root_intr_abort __P((usbd_xfer_handle)); +static void uhci_root_intr_close __P((usbd_pipe_handle)); +static void uhci_root_intr_done __P((usbd_xfer_handle)); + +static usbd_status uhci_open __P((usbd_pipe_handle)); +static void uhci_poll __P((struct usbd_bus *)); +static void uhci_softintr __P((struct usbd_bus *)); + +static usbd_status uhci_device_request __P((usbd_xfer_handle xfer)); + +static void uhci_add_intr __P((uhci_softc_t *, uhci_soft_qh_t *)); +static void uhci_remove_intr __P((uhci_softc_t*, uhci_soft_qh_t*)); +static usbd_status uhci_device_setintr __P((uhci_softc_t *sc, + struct uhci_pipe *pipe, int ival)); + +static void uhci_device_clear_toggle __P((usbd_pipe_handle pipe)); +static void uhci_noop __P((usbd_pipe_handle pipe)); + +static __inline__ uhci_soft_qh_t *uhci_find_prev_qh + __P((uhci_soft_qh_t *, uhci_soft_qh_t *)); #ifdef UHCI_DEBUG -static void uhci_dumpregs __P((uhci_softc_t *)); -void uhci_dump_qhs __P((uhci_soft_qh_t *)); -void uhci_dump_qh __P((uhci_soft_qh_t *)); -void uhci_dump __P((void)); -void uhci_dump_tds __P((uhci_soft_td_t *)); -void uhci_dump_td __P((uhci_soft_td_t *)); +static void uhci_dumpregs __P((uhci_softc_t *)); +static void uhci_dump_qhs __P((uhci_soft_qh_t *)); +static void uhci_dump_qh __P((uhci_soft_qh_t *)); +static void uhci_dump_tds __P((uhci_soft_td_t *)); +static void uhci_dump_td __P((uhci_soft_td_t *)); +static void uhci_dump_ii __P((uhci_intr_info_t *ii)); #endif #define UWRITE1(sc, r, x) bus_space_write_1((sc)->iot, (sc)->ioh, (r), (x)) @@ -337,6 +344,28 @@ struct usbd_pipe_methods uhci_device_isoc_methods = { uhci_device_isoc_done, }; +#define uhci_add_intr_info(sc, ii) \ + LIST_INSERT_HEAD(&(sc)->sc_intrhead, (ii), list); +#define uhci_del_intr_info(ii) \ + LIST_REMOVE((ii), list) + +static __inline__ uhci_soft_qh_t * +uhci_find_prev_qh(pqh, sqh) + uhci_soft_qh_t *pqh, *sqh; +{ + DPRINTFN(15,("uhci_find_prev_qh: pqh=%p sqh=%p\n", pqh, sqh)); + + for (; pqh->hlink != sqh; pqh = pqh->hlink) { +#if defined(DIAGNOSTIC) || defined(UHCI_DEBUG) + if (le32toh(pqh->qh.qh_hlink) & UHCI_PTR_T) { + printf("uhci_find_qh: QH not found\n"); + return (NULL); + } +#endif + } + return (pqh); +} + void uhci_busreset(sc) uhci_softc_t *sc; @@ -358,6 +387,8 @@ uhci_init(sc) DPRINTFN(1,("uhci_init: start\n")); #ifdef UHCI_DEBUG + thesc = sc; + if (uhcidebug > 2) uhci_dumpregs(sc); #endif @@ -369,8 +400,8 @@ uhci_init(sc) /* Allocate and initialize real frame array. */ err = usb_allocmem(&sc->sc_bus, - UHCI_FRAMELIST_COUNT * sizeof(uhci_physaddr_t), - UHCI_FRAMELIST_ALIGN, &sc->sc_dma); + UHCI_FRAMELIST_COUNT * sizeof(uhci_physaddr_t), + UHCI_FRAMELIST_ALIGN, &sc->sc_dma); if (err) return (err); sc->sc_pframes = KERNADDR(&sc->sc_dma); @@ -381,8 +412,8 @@ uhci_init(sc) bsqh = uhci_alloc_sqh(sc); if (bsqh == NULL) return (USBD_NOMEM); - bsqh->qh.qh_hlink = LE(UHCI_PTR_T); /* end of QH chain */ - bsqh->qh.qh_elink = LE(UHCI_PTR_T); + bsqh->qh.qh_hlink = htole32(UHCI_PTR_T); /* end of QH chain */ + bsqh->qh.qh_elink = htole32(UHCI_PTR_T); sc->sc_bulk_start = sc->sc_bulk_end = bsqh; /* Allocate the dummy QH where control traffic will be queued. */ @@ -390,8 +421,8 @@ uhci_init(sc) if (csqh == NULL) return (USBD_NOMEM); csqh->hlink = bsqh; - csqh->qh.qh_hlink = LE(bsqh->physaddr | UHCI_PTR_Q); - csqh->qh.qh_elink = LE(UHCI_PTR_T); + csqh->qh.qh_hlink = htole32(bsqh->physaddr | UHCI_PTR_Q); + csqh->qh.qh_elink = htole32(UHCI_PTR_T); sc->sc_ctl_start = sc->sc_ctl_end = csqh; /* @@ -405,14 +436,14 @@ uhci_init(sc) if (std == NULL || sqh == NULL) return (USBD_NOMEM); std->link.sqh = sqh; - std->td.td_link = LE(sqh->physaddr | UHCI_PTR_Q); - std->td.td_status = LE(UHCI_TD_IOS); /* iso, inactive */ - std->td.td_token = LE(0); - std->td.td_buffer = LE(0); + std->td.td_link = htole32(sqh->physaddr | UHCI_PTR_Q); + std->td.td_status = htole32(UHCI_TD_IOS); /* iso, inactive */ + std->td.td_token = htole32(0); + std->td.td_buffer = htole32(0); sqh->hlink = csqh; - sqh->qh.qh_hlink = LE(csqh->physaddr | UHCI_PTR_Q); + sqh->qh.qh_hlink = htole32(csqh->physaddr | UHCI_PTR_Q); sqh->elink = 0; - sqh->qh.qh_elink = LE(UHCI_PTR_T); + sqh->qh.qh_elink = htole32(UHCI_PTR_T); sc->sc_vframes[i].htd = std; sc->sc_vframes[i].etd = std; sc->sc_vframes[i].hqh = sqh; @@ -420,21 +451,24 @@ uhci_init(sc) for (j = i; j < UHCI_FRAMELIST_COUNT; j += UHCI_VFRAMELIST_COUNT) - sc->sc_pframes[j] = LE(std->physaddr); + sc->sc_pframes[j] = htole32(std->physaddr); } LIST_INIT(&sc->sc_intrhead); SIMPLEQ_INIT(&sc->sc_free_xfers); + usb_callout_init(sc->sc_poll_handle); + /* Set up the bus struct. */ sc->sc_bus.methods = &uhci_bus_methods; sc->sc_bus.pipe_size = sizeof(struct uhci_pipe); +#if defined(__NetBSD__) || defined(__OpenBSD__) sc->sc_suspend = PWR_RESUME; sc->sc_powerhook = powerhook_establish(uhci_power, sc); - sc->sc_shutdownhook = shutdownhook_establish(uhci_shutdown, sc); +#endif DPRINTFN(1,("uhci_init: enabling\n")); UWRITE2(sc, UHCI_INTR, UHCI_INTR_TOCRCIE | UHCI_INTR_RIE | @@ -481,8 +515,10 @@ uhci_detach(sc, flags) if (rv != 0) return (rv); +#if defined(__NetBSD__) || defined(__OpenBSD__) powerhook_disestablish(sc->sc_powerhook); shutdownhook_disestablish(sc->sc_shutdownhook); +#endif /* Free all xfers associated with this HC. */ for (;;) { @@ -491,7 +527,7 @@ uhci_detach(sc, flags) break; SIMPLEQ_REMOVE_HEAD(&sc->sc_free_xfers, xfer, next); free(xfer, M_USB); - } + } /* XXX free other data structures XXX */ @@ -525,12 +561,27 @@ uhci_allocx(bus) usbd_xfer_handle xfer; xfer = SIMPLEQ_FIRST(&sc->sc_free_xfers); - if (xfer != NULL) + if (xfer != NULL) { SIMPLEQ_REMOVE_HEAD(&sc->sc_free_xfers, xfer, next); - else - xfer = malloc(sizeof(*xfer), M_USB, M_NOWAIT); - if (xfer != NULL) - memset(xfer, 0, sizeof *xfer); +#ifdef DIAGNOSTIC + if (xfer->busy_free != XFER_FREE) { + printf("uhci_freex: xfer=%p not free, 0x%08x\n", xfer, + xfer->busy_free); + } +#endif + } else { + xfer = malloc(sizeof(struct uhci_xfer), M_USB, M_NOWAIT); + } + if (xfer != NULL) { + memset(xfer, 0, sizeof (struct uhci_xfer)); + UXFER(xfer)->iinfo.sc = sc; +#ifdef DIAGNOSTIC + UXFER(xfer)->iinfo.isdone = 1; +#endif + } +#ifdef DIAGNOSTIC + xfer->busy_free = XFER_BUSY; +#endif return (xfer); } @@ -541,6 +592,16 @@ uhci_freex(bus, xfer) { struct uhci_softc *sc = (struct uhci_softc *)bus; +#ifdef DIAGNOSTIC + if (xfer->busy_free != XFER_BUSY) { + printf("uhci_freex: xfer=%p not busy, 0x%08x\n", xfer, + xfer->busy_free); + return; + } + xfer->busy_free = XFER_FREE; + if (!UXFER(xfer)->iinfo.isdone) + printf("uhci_freex: !isdone\n"); +#endif SIMPLEQ_INSERT_HEAD(&sc->sc_free_xfers, xfer, next); } @@ -584,9 +645,9 @@ uhci_power(why, v) if (uhcidebug > 2) uhci_dumpregs(sc); #endif - if (sc->sc_has_timo != NULL) - usb_untimeout(uhci_timo, sc->sc_has_timo, - sc->sc_has_timo->timo_handle); + if (sc->sc_intr_xfer != NULL) + usb_uncallout(sc->sc_poll_handle, uhci_poll_hub, + sc->sc_intr_xfer); sc->sc_bus.use_polling++; uhci_run(sc, 0); /* stop the controller */ @@ -622,9 +683,9 @@ uhci_power(why, v) uhci_run(sc, 1); /* and start traffic again */ usb_delay_ms(&sc->sc_bus, USB_RESUME_RECOVERY); sc->sc_bus.use_polling--; - if (sc->sc_has_timo != NULL) - usb_timeout(uhci_timo, sc->sc_has_timo, - sc->sc_ival, sc->sc_has_timo->timo_handle); + if (sc->sc_intr_xfer != NULL) + usb_callout(sc->sc_poll_handle, sc->sc_ival, + uhci_poll_hub, sc->sc_intr_xfer); #ifdef UHCI_DEBUG if (uhcidebug > 2) uhci_dumpregs(sc); @@ -658,24 +719,24 @@ uhci_dump_td(p) DPRINTFN(-1,("TD(%p) at %08lx = link=0x%08lx status=0x%08lx " "token=0x%08lx buffer=0x%08lx\n", p, (long)p->physaddr, - (long)LE(p->td.td_link), - (long)LE(p->td.td_status), - (long)LE(p->td.td_token), - (long)LE(p->td.td_buffer))); + (long)le32toh(p->td.td_link), + (long)le32toh(p->td.td_status), + (long)le32toh(p->td.td_token), + (long)le32toh(p->td.td_buffer))); DPRINTFN(-1,(" %b %b,errcnt=%d,actlen=%d pid=%02x,addr=%d,endpt=%d," "D=%d,maxlen=%d\n", - (int)LE(p->td.td_link), + (int)le32toh(p->td.td_link), "\20\1T\2Q\3VF", - (int)LE(p->td.td_status), + (int)le32toh(p->td.td_status), "\20\22BITSTUFF\23CRCTO\24NAK\25BABBLE\26DBUFFER\27" "STALLED\30ACTIVE\31IOC\32ISO\33LS\36SPD", - UHCI_TD_GET_ERRCNT(LE(p->td.td_status)), - UHCI_TD_GET_ACTLEN(LE(p->td.td_status)), - UHCI_TD_GET_PID(LE(p->td.td_token)), - UHCI_TD_GET_DEVADDR(LE(p->td.td_token)), - UHCI_TD_GET_ENDPT(LE(p->td.td_token)), - UHCI_TD_GET_DT(LE(p->td.td_token)), - UHCI_TD_GET_MAXLEN(LE(p->td.td_token)))); + UHCI_TD_GET_ERRCNT(le32toh(p->td.td_status)), + UHCI_TD_GET_ACTLEN(le32toh(p->td.td_status)), + UHCI_TD_GET_PID(le32toh(p->td.td_token)), + UHCI_TD_GET_DEVADDR(le32toh(p->td.td_token)), + UHCI_TD_GET_ENDPT(le32toh(p->td.td_token)), + UHCI_TD_GET_DT(le32toh(p->td.td_token)), + UHCI_TD_GET_MAXLEN(le32toh(p->td.td_token)))); } void @@ -683,14 +744,16 @@ uhci_dump_qh(sqh) uhci_soft_qh_t *sqh; { DPRINTFN(-1,("QH(%p) at %08x: hlink=%08x elink=%08x\n", sqh, - (int)sqh->physaddr, LE(sqh->qh.qh_hlink), LE(sqh->qh.qh_elink))); + (int)sqh->physaddr, le32toh(sqh->qh.qh_hlink), + le32toh(sqh->qh.qh_elink))); } + #if 0 void uhci_dump() { - uhci_softc_t *sc = uhci; + uhci_softc_t *sc = thesc; uhci_dumpregs(sc); printf("intrs=%d\n", sc->sc_bus.no_intrs); @@ -699,6 +762,7 @@ uhci_dump() } #endif + void uhci_dump_qhs(sqh) uhci_soft_qh_t *sqh; @@ -719,12 +783,13 @@ uhci_dump_qhs(sqh) * TD2.x being the TDs queued at QH2 and QH1 being referenced from QH1. */ - if (sqh->hlink != NULL && !(sqh->qh.qh_hlink & UHCI_PTR_T)) + + if (sqh->hlink != NULL && !(le32toh(sqh->qh.qh_hlink) & UHCI_PTR_T)) uhci_dump_qhs(sqh->hlink); else DPRINTF(("No QH\n")); - if (sqh->elink != NULL && !(sqh->qh.qh_elink & UHCI_PTR_T)) + if (sqh->elink != NULL && !(le32toh(sqh->qh.qh_elink) & UHCI_PTR_T)) uhci_dump_tds(sqh->elink); else DPRINTF(("No TD\n")); @@ -744,10 +809,66 @@ uhci_dump_tds(std) * printing the free list in case the queue/TD has * already been moved there (seatbelt). */ - if (td->td.td_link & UHCI_PTR_T || td->td.td_link == 0) + if (le32toh(td->td.td_link) & UHCI_PTR_T || + le32toh(td->td.td_link) == 0) break; } } + +static void +uhci_dump_ii(ii) + uhci_intr_info_t *ii; +{ + usbd_pipe_handle pipe; + usb_endpoint_descriptor_t *ed; + usbd_device_handle dev; + +#ifdef DIAGNOSTIC +#define DONE ii->isdone +#else +#define DONE 0 +#endif + if (ii == NULL) { + printf("ii NULL\n"); + return; + } + if (ii->xfer == NULL) { + printf("ii %p: done=%d xfer=NULL\n", + ii, DONE); + return; + } + pipe = ii->xfer->pipe; + if (pipe == NULL) { + printf("ii %p: done=%d xfer=%p pipe=NULL\n", + ii, DONE, ii->xfer); + return; + } + ed = pipe->endpoint->edesc; + dev = pipe->device; + printf("ii %p: done=%d xfer=%p dev=%p vid=0x%04x pid=0x%04x addr=%d pipe=%p ep=0x%02x attr=0x%02x\n", + ii, DONE, ii->xfer, dev, + UGETW(dev->ddesc.idVendor), + UGETW(dev->ddesc.idProduct), + dev->address, pipe, + ed->bEndpointAddress, ed->bmAttributes); +#undef DONE +} + +void uhci_dump_iis(struct uhci_softc *); +void +uhci_dump_iis(sc) + struct uhci_softc *sc; +{ + uhci_intr_info_t *ii; + + printf("intr_info list:\n"); + for (ii = LIST_FIRST(&sc->sc_intrhead); ii; ii = LIST_NEXT(ii, list)) + uhci_dump_ii(ii); +} + +void iidump(void); +void iidump() { uhci_dump_iis(thesc); } + #endif /* @@ -755,7 +876,7 @@ uhci_dump_tds(std) * from the root controller interrupt pipe for port status change. */ void -uhci_timo(addr) +uhci_poll_hub(addr) void *addr; { usbd_xfer_handle xfer = addr; @@ -764,9 +885,9 @@ uhci_timo(addr) int s; u_char *p; - DPRINTFN(20, ("uhci_timo\n")); + DPRINTFN(20, ("uhci_poll_hub\n")); - usb_timeout(uhci_timo, xfer, sc->sc_ival, xfer->timo_handle); + usb_callout(sc->sc_poll_handle, sc->sc_ival, uhci_poll_hub, xfer); p = KERNADDR(&xfer->dmabuf); p[0] = 0; @@ -781,7 +902,6 @@ uhci_timo(addr) xfer->actlen = 1; xfer->status = USBD_NORMAL_COMPLETION; s = splusb(); - xfer->hcpriv = 0; xfer->device->bus->intr_context++; usb_transfer_complete(xfer); xfer->device->bus->intr_context--; @@ -800,64 +920,6 @@ uhci_root_ctrl_done(xfer) { } - -void -uhci_lock_frames(sc) - uhci_softc_t *sc; -{ - int s = splusb(); - - while (sc->sc_vflock & UHCI_HAS_LOCK) { - sc->sc_vflock |= UHCI_WANT_LOCK; - tsleep(&sc->sc_vflock, PRIBIO, "uhcqhl", 0); - } - sc->sc_vflock = UHCI_HAS_LOCK; - splx(s); -} - -void -uhci_unlock_frames(sc) - uhci_softc_t *sc; -{ - int s = splusb(); - - sc->sc_vflock &= ~UHCI_HAS_LOCK; - if (sc->sc_vflock & UHCI_WANT_LOCK) - wakeup(&sc->sc_vflock); - splx(s); -} - -/* - * Allocate an interrupt information struct. A free list is kept - * for fast allocation. - */ -uhci_intr_info_t * -uhci_alloc_intr_info(sc) - uhci_softc_t *sc; -{ - uhci_intr_info_t *ii; - - ii = LIST_FIRST(&uhci_ii_free); - if (ii) - LIST_REMOVE(ii, list); - else { - ii = malloc(sizeof(uhci_intr_info_t), M_USBHC, M_NOWAIT); - } - ii->sc = sc; -#if defined(__FreeBSD__) - callout_handle_init(&ii->timeout_handle); -#endif - - return ii; -} - -void -uhci_free_intr_info(ii) - uhci_intr_info_t *ii; -{ - LIST_INSERT_HEAD(&uhci_ii_free, ii, list); /* and put on free list */ -} - /* Add control QH, called at splusb(). */ void uhci_add_ctrl(sc, sqh) @@ -873,7 +935,7 @@ uhci_add_ctrl(sc, sqh) sqh->hlink = eqh->hlink; sqh->qh.qh_hlink = eqh->qh.qh_hlink; eqh->hlink = sqh; - eqh->qh.qh_hlink = LE(sqh->physaddr | UHCI_PTR_Q); + eqh->qh.qh_hlink = htole32(sqh->physaddr | UHCI_PTR_Q); sc->sc_ctl_end = sqh; } @@ -888,15 +950,7 @@ uhci_remove_ctrl(sc, sqh) SPLUSBCHECK; DPRINTFN(10, ("uhci_remove_ctrl: sqh=%p\n", sqh)); - for (pqh = sc->sc_ctl_start; pqh->hlink != sqh; pqh=pqh->hlink) -#if defined(DIAGNOSTIC) || defined(UHCI_DEBUG) - if (LE(pqh->qh.qh_hlink) & UHCI_PTR_T) { - printf("uhci_remove_ctrl: QH not found\n"); - return; - } -#else - ; -#endif + pqh = uhci_find_prev_qh(sc->sc_ctl_start, sqh); pqh->hlink = sqh->hlink; pqh->qh.qh_hlink = sqh->qh.qh_hlink; if (sc->sc_ctl_end == sqh) @@ -918,7 +972,7 @@ uhci_add_bulk(sc, sqh) sqh->hlink = eqh->hlink; sqh->qh.qh_hlink = eqh->qh.qh_hlink; eqh->hlink = sqh; - eqh->qh.qh_hlink = LE(sqh->physaddr | UHCI_PTR_Q); + eqh->qh.qh_hlink = htole32(sqh->physaddr | UHCI_PTR_Q); sc->sc_bulk_end = sqh; } @@ -933,15 +987,7 @@ uhci_remove_bulk(sc, sqh) SPLUSBCHECK; DPRINTFN(10, ("uhci_remove_bulk: sqh=%p\n", sqh)); - for (pqh = sc->sc_bulk_start; pqh->hlink != sqh; pqh = pqh->hlink) -#if defined(DIAGNOSTIC) || defined(UHCI_DEBUG) - if (LE(pqh->qh.qh_hlink) & UHCI_PTR_T) { - printf("uhci_remove_bulk: QH not found\n"); - return; - } -#else - ; -#endif + pqh = uhci_find_prev_qh(sc->sc_bulk_start, sqh); pqh->hlink = sqh->hlink; pqh->qh.qh_hlink = sqh->qh.qh_hlink; if (sc->sc_bulk_end == sqh) @@ -967,7 +1013,7 @@ uhci_intr(arg) if (status == 0) /* The interrupt was not for us. */ return (0); -#if defined(DIAGNOSTIC) && (defined(__NetBSD__) || defined(__OpenBSD__)) +#if defined(DIAGNOSTIC) && defined(__NetBSD__) if (sc->sc_suspend != PWR_RESUME) printf("uhci_intr: suspended sts=0x%x\n", status); #endif @@ -987,7 +1033,7 @@ uhci_intr(arg) } if (status & UHCI_STS_HCPE) { ack |= UHCI_STS_HCPE; - printf("%s: host controller process error\n", + printf("%s: host controller process error\n", USBDEVNAME(sc->sc_bus.bdev)); } if (status & UHCI_STS_HCH) { @@ -1068,10 +1114,10 @@ uhci_check_intr(sc, ii) * is a an error somewhere in the middle, or whether there was a * short packet (SPD and not ACTIVE). */ - if (LE(lstd->td.td_status) & UHCI_TD_ACTIVE) { - DPRINTFN(15, ("uhci_check_intr: active ii=%p\n", ii)); + if (le32toh(lstd->td.td_status) & UHCI_TD_ACTIVE) { + DPRINTFN(12, ("uhci_check_intr: active ii=%p\n", ii)); for (std = ii->stdstart; std != lstd; std = std->link.std) { - status = LE(std->td.td_status); + status = le32toh(std->td.td_status); /* If there's an active TD the xfer isn't done. */ if (status & UHCI_TD_ACTIVE) break; @@ -1080,17 +1126,17 @@ uhci_check_intr(sc, ii) goto done; /* We want short packets, and it is short: it's done */ if ((status & UHCI_TD_SPD) && - UHCI_TD_GET_ACTLEN(status) < - UHCI_TD_GET_MAXLEN(LE(std->td.td_token))) + UHCI_TD_GET_ACTLEN(status) < + UHCI_TD_GET_MAXLEN(le32toh(std->td.td_token))) goto done; } - DPRINTFN(15, ("uhci_check_intr: ii=%p std=%p still active\n", + DPRINTFN(12, ("uhci_check_intr: ii=%p std=%p still active\n", ii, ii->stdstart)); return; } done: - DPRINTFN(15, ("uhci_check_intr: ii=%p done\n", ii)); - usb_untimeout(uhci_timeout, ii, ii->timeout_handle); + DPRINTFN(12, ("uhci_check_intr: ii=%p done\n", ii)); + usb_uncallout(ii->xfer->timeout_handle, uhci_timeout, ii); uhci_idone(ii); } @@ -1110,7 +1156,12 @@ uhci_idone(ii) int s = splhigh(); if (ii->isdone) { splx(s); +#ifdef UHCI_DEBUG + printf("uhci_idone: ii is done!\n "); + uhci_dump_ii(ii); +#else printf("uhci_idone: ii=%p is done!\n", ii); +#endif return; } ii->isdone = 1; @@ -1133,7 +1184,7 @@ uhci_idone(ii) nframes = xfer->nframes; actlen = 0; - n = xfer->hcprivint; + n = UXFER(xfer)->curframe; for (i = 0; i < nframes; i++) { std = stds[n]; #ifdef UHCI_DEBUG @@ -1144,13 +1195,12 @@ uhci_idone(ii) #endif if (++n >= UHCI_VFRAMELIST_COUNT) n = 0; - status = LE(std->td.td_status); + status = le32toh(std->td.td_status); actlen += UHCI_TD_GET_ACTLEN(status); } upipe->u.iso.inuse -= nframes; xfer->actlen = actlen; xfer->status = USBD_NORMAL_COMPLETION; - xfer->hcpriv = ii; usb_transfer_complete(xfer); return; } @@ -1163,20 +1213,20 @@ uhci_idone(ii) #endif /* The transfer is done, compute actual length and status. */ - /* XXX Is this correct for control xfers? */ actlen = 0; for (std = ii->stdstart; std != NULL; std = std->link.std) { - nstatus = LE(std->td.td_status); + nstatus = le32toh(std->td.td_status); if (nstatus & UHCI_TD_ACTIVE) break; status = nstatus; - if (UHCI_TD_GET_PID(LE(std->td.td_token)) != UHCI_TD_PID_SETUP) + if (UHCI_TD_GET_PID(le32toh(std->td.td_token)) != + UHCI_TD_PID_SETUP) actlen += UHCI_TD_GET_ACTLEN(status); } /* If there are left over TDs we need to update the toggle. */ if (std != NULL) - upipe->nexttoggle = UHCI_TD_GET_DT(LE(std->td.td_token)); + upipe->nexttoggle = UHCI_TD_GET_DT(le32toh(std->td.td_token)); status &= UHCI_TD_ERROR; DPRINTFN(10, ("uhci_check_intr: actlen=%d, status=0x%x\n", @@ -1198,7 +1248,6 @@ uhci_idone(ii) } else { xfer->status = USBD_NORMAL_COMPLETION; } - xfer->hcpriv = ii; usb_transfer_complete(xfer); } @@ -1275,17 +1324,16 @@ uhci_poll(bus) #if 0 void -uhci_reset(p) - void *p; +uhci_reset(sc) + uhci_softc_t *sc; { - uhci_softc_t *sc = p; int n; UHCICMD(sc, UHCI_CMD_HCRESET); /* The reset bit goes low when the controller is done. */ for (n = 0; n < UHCI_RESET_TIMEOUT && (UREAD2(sc, UHCI_CMD) & UHCI_CMD_HCRESET); n++) - delay(100); + usb_delay_ms(&sc->sc_bus, 1); if (n >= UHCI_RESET_TIMEOUT) printf("%s: controller did not reset\n", USBDEVNAME(sc->sc_bus.bdev)); @@ -1348,7 +1396,7 @@ uhci_alloc_std(sc) if (sc->sc_freetds == NULL) { DPRINTFN(2,("uhci_alloc_std: allocating chunk\n")); err = usb_allocmem(&sc->sc_bus, UHCI_STD_SIZE * UHCI_STD_CHUNK, - UHCI_TD_ALIGN, &dma); + UHCI_TD_ALIGN, &dma); if (err) return (0); for(i = 0; i < UHCI_STD_CHUNK; i++) { @@ -1372,11 +1420,11 @@ uhci_free_std(sc, std) { #ifdef DIAGNOSTIC #define TD_IS_FREE 0x12345678 - if (std->td.td_token == LE(TD_IS_FREE)) { + if (le32toh(std->td.td_token) == TD_IS_FREE) { printf("uhci_free_std: freeing free TD %p\n", std); return; } - std->td.td_token = LE(TD_IS_FREE); + std->td.td_token = htole32(TD_IS_FREE); #endif std->link.std = sc->sc_freetds; sc->sc_freetds = std; @@ -1394,7 +1442,7 @@ uhci_alloc_sqh(sc) if (sc->sc_freeqhs == NULL) { DPRINTFN(2, ("uhci_alloc_sqh: allocating chunk\n")); err = usb_allocmem(&sc->sc_bus, UHCI_SQH_SIZE * UHCI_SQH_CHUNK, - UHCI_QH_ALIGN, &dma); + UHCI_QH_ALIGN, &dma); if (err) return (0); for(i = 0; i < UHCI_SQH_CHUNK; i++) { @@ -1420,22 +1468,6 @@ uhci_free_sqh(sc, sqh) sc->sc_freeqhs = sqh; } -#if 0 -/* - * Enter a list of transfers onto a control queue. - * Called at splusb() - */ -void -uhci_enter_ctl_q(sc, sqh, ii) - uhci_softc_t *sc; - uhci_soft_qh_t *sqh; - uhci_intr_info_t *ii; -{ - DPRINTFN(5, ("uhci_enter_ctl_q: sqh=%p\n", sqh)); - -} -#endif - void uhci_free_std_chain(sc, std, stdend) uhci_softc_t *sc; @@ -1467,8 +1499,8 @@ uhci_alloc_std_chain(upipe, sc, len, rd, flags, dma, sp, ep) int endpt = upipe->pipe.endpoint->edesc->bEndpointAddress; DPRINTFN(8, ("uhci_alloc_std_chain: addr=%d endpt=%d len=%d ls=%d " - "flags=0x%x\n", addr, UE_GET_ADDR(endpt), len, - upipe->pipe.device->lowspeed, flags)); + "flags=0x%x\n", addr, UE_GET_ADDR(endpt), len, + upipe->pipe.device->lowspeed, flags)); maxp = UGETW(upipe->pipe.endpoint->edesc->wMaxPacketSize); if (maxp == 0) { printf("uhci_alloc_std_chain: maxp=0\n"); @@ -1503,12 +1535,12 @@ uhci_alloc_std_chain(upipe, sc, len, rd, flags, dma, sp, ep) } p->link.std = lastp; if (lastlink == UHCI_PTR_T) - p->td.td_link = LE(lastlink); + p->td.td_link = htole32(lastlink); else - p->td.td_link = LE(lastlink|UHCI_PTR_VF); + p->td.td_link = htole32(lastlink|UHCI_PTR_VF); lastp = p; lastlink = p->physaddr; - p->td.td_status = LE(status); + p->td.td_status = htole32(status); if (i == ntd) { /* last TD */ l = len % maxp; @@ -1518,9 +1550,9 @@ uhci_alloc_std_chain(upipe, sc, len, rd, flags, dma, sp, ep) } else l = maxp; p->td.td_token = - LE(rd ? UHCI_TD_IN (l, endpt, addr, tog) : - UHCI_TD_OUT(l, endpt, addr, tog)); - p->td.td_buffer = LE(DMAADDR(dma) + i * maxp); + htole32(rd ? UHCI_TD_IN (l, endpt, addr, tog) : + UHCI_TD_OUT(l, endpt, addr, tog)); + p->td.td_buffer = htole32(DMAADDR(dma) + i * maxp); tog ^= 1; } *sp = lastp; @@ -1554,8 +1586,9 @@ uhci_device_bulk_transfer(xfer) if (err) return (err); - /* Pipe isn't running (otherwise err would be USBD_INPROG), - * start first + /* + * Pipe isn't running (otherwise err would be USBD_INPROG), + * so start it first. */ return (uhci_device_bulk_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); } @@ -1567,7 +1600,7 @@ uhci_device_bulk_start(xfer) struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe; usbd_device_handle dev = upipe->pipe.device; uhci_softc_t *sc = (uhci_softc_t *)dev->bus; - uhci_intr_info_t *ii = upipe->iinfo; + uhci_intr_info_t *ii = &UXFER(xfer)->iinfo; uhci_soft_td_t *data, *dataend; uhci_soft_qh_t *sqh; usbd_status err; @@ -1594,10 +1627,10 @@ uhci_device_bulk_start(xfer) upipe->u.bulk.length = len; err = uhci_alloc_std_chain(upipe, sc, len, isread, xfer->flags, - &xfer->dmabuf, &data, &dataend); + &xfer->dmabuf, &data, &dataend); if (err) return (err); - dataend->td.td_status |= LE(UHCI_TD_IOC); + dataend->td.td_status |= htole32(UHCI_TD_IOC); #ifdef UHCI_DEBUG if (uhcidebug > 8) { @@ -1610,9 +1643,6 @@ uhci_device_bulk_start(xfer) ii->xfer = xfer; ii->stdstart = data; ii->stdend = dataend; -#if defined(__FreeBSD__) - callout_handle_init(&ii->timeout_handle); -#endif #ifdef DIAGNOSTIC if (!ii->isdone) { printf("uhci_device_bulk_transfer: not done, ii=%p\n", ii); @@ -1621,17 +1651,17 @@ uhci_device_bulk_start(xfer) #endif sqh->elink = data; - sqh->qh.qh_elink = LE(data->physaddr); - sqh->intr_info = ii; + sqh->qh.qh_elink = htole32(data->physaddr); s = splusb(); uhci_add_bulk(sc, sqh); - LIST_INSERT_HEAD(&sc->sc_intrhead, ii, list); + uhci_add_intr_info(sc, ii); if (xfer->timeout && !sc->sc_bus.use_polling) { - usb_timeout(uhci_timeout, ii, MS_TO_TICKS(xfer->timeout), - ii->timeout_handle); + usb_callout(xfer->timeout_handle, MS_TO_TICKS(xfer->timeout), + uhci_timeout, ii); } + xfer->status = USBD_IN_PROGRESS; splx(s); #ifdef UHCI_DEBUG @@ -1656,61 +1686,317 @@ uhci_device_bulk_abort(xfer) uhci_abort_xfer(xfer, USBD_CANCELLED); } +/* + * Aborting a xfer on the UHCI host controller is tricky. + * The problem is that the HC can asynchronously manipulate + * the very fields in the QH and TD that we need to abort a + * xfer. + * The problematic field are qh_elink (which points to the first + * TD) and td_status which contains the active flag. + * + * Here's my current (convoluted) strategy: + * - Block HC interrupt. We need this to check if the xfer + * might already be over. If called outside splusb() this can + * happen. + * - Check if an abort is already in progress (see below), if so + * just link out the xfer, run the callback, and return. + * - Otherwise, flag that abort is in progress. + * - Remove the QH for the xfer from the list of QHs (this + * can be done safely). + * - Remove the transaction from the list of transactions examined + * when the HC interrupts. + * At this point we know that the transaction will never be considered + * by the interrupt routine. The trouble we have is that the HC might + * be following the chain of TDs rooted at the unlinked QH because it + * started before the unlink. + * We would like to run the xfer callback function at this point + * to inform it that the xfer has been aborted, but running the + * callback might result in freeing the xfer. This would be bad + * since the HC might still use it. So we need to avoid this by: + * - Disable the active flag in all TD belonging to the xfer. + * If we do this we can guarantee that the HC will execute at most one + * TD after we turn off the flag in the last TD. + * - Busy-wait until the HC has finished with the TD. We do this by + * keeping track of the longest TD and using delay() for the time it + * takes to complete it (one byte takes a little less than 1 (LS 6) us). + * - Run the callback routine, since at this point the HC can not be + * using any TDs in the xfer. + * We still cannot manipulate the qh_elink field in the QH since the + * HC might be following TDs further down the chain for another 1 ms. + * So... + * - Set up a timeout 1 ms into the future. + * - Turn on interrupts. + * - Return. + * + * When the timeout happens we do the following: + * - Check if the qh_elink field points anywhere in the TD chain we had + * when the timeout was set up. If it is, leave qh_elink alone, + * otherwise set qh_elink pointing to the next (if any) xfer in + * the TD chain. + * - Link the QH back where we got it. + * - Turn off flag about abort in progress. + * Done! + * + * The timeout is associated with the pipe and it must be cancelled if + * the pipe is closed. + */ + void uhci_abort_xfer(xfer, status) usbd_xfer_handle xfer; usbd_status status; { struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe; - uhci_intr_info_t *ii = upipe->iinfo; + uhci_intr_info_t *ii = &UXFER(xfer)->iinfo; uhci_soft_td_t *std; + int s; + int len, maxlen; - DPRINTFN(1,("uhci_abort_xfer: xfer=%p, status=%d\n", xfer, status)); + DPRINTFN(1,("uhci_abort_xfer: xfer=%p, xfer->status=%d, status=%d\n", + xfer, xfer->status, status)); - /* Make interrupt routine ignore it, */ + s = splusb(); + + /* Transfer is already done. */ + if (xfer->status != USBD_NOT_STARTED && + xfer->status != USBD_IN_PROGRESS) { + splx(s); + return; + } + + /* Give xfer the requested abort code. */ xfer->status = status; - /* don't timeout, */ - usb_untimeout(uhci_timeout, ii, ii->timeout_handle); + /* If already aborting, bail out early. */ + if (upipe->aborting) { + /* Unlink the xfer from HC */ + /*XXX only one xfer for now*/ + printf("uhci_abort_xfer: abort while aborting\n"); + /* Finalize xfer. */ + usb_transfer_complete(xfer); + splx(s); + return; + } - /* make hardware ignore it, */ - for (std = ii->stdstart; std != 0; std = std->link.std) - std->td.td_status &= LE(~(UHCI_TD_ACTIVE | UHCI_TD_IOC)); + upipe->aborting = 1; + upipe->abortstart = SIMPLEQ_NEXT(xfer, next); + upipe->abortend = NULL; /* XXX only one xfer for now */ - xfer->hcpriv = ii; + /* Remove QH(s) from HC schedule. */ + uhci_abort_unlink_qh(upipe); -#if 1 - /* Make sure hardware has completed, */ - if (xfer->device->bus->intr_context) { - /* We have no process context, so we can't use tsleep(). */ - timeout(uhci_abort_xfer_end, xfer, hz / USB_FRAMES_PER_SECOND); - } else { -#if defined(DIAGNOSTIC) && defined(__i386__) && defined(__FreeBSD__) - KASSERT(intr_nesting_level == 0, - ("ohci_abort_req in interrupt context")); -#endif - usb_delay_ms(xfer->pipe->device->bus, 1); - /* and call final part of interrupt handler. */ - uhci_abort_xfer_end(xfer); + /* Remove intr_info from list is done by usb_transfer_complete() .*/ + + /* Disable active bit. */ + maxlen = 0; + for (std = ii->stdstart; std != NULL; std = std->link.std) { + std->td.td_status &= htole32(~(UHCI_TD_ACTIVE | UHCI_TD_IOC)); + len = UHCI_TD_GET_MAXLEN(std->td.td_token); + if (len > maxlen) + maxlen = len; } -#else - delay(1000); - uhci_abort_xfer_end(xfer); + /* compute delay in us */ + if (upipe->pipe.device->lowspeed) + maxlen *= 6; + /* wait for HC to complete TDs */ + delay(maxlen); + + /* Don't timeout, */ + usb_uncallout(xfer->timeout_handle, uhci_timeout, ii); + +#ifdef DIAGNOSTIC + UXFER(xfer)->iinfo.isdone = 1; #endif + /* Run callback and remove from interrupt list. */ + usb_transfer_complete(xfer); + + /* Set up final processing. */ + usb_callout(xfer->pipe->abort_handle, hz / USB_FRAMES_PER_SECOND, + uhci_abort_xfer_end, upipe); + + /* And return. */ + splx(s); } void uhci_abort_xfer_end(v) void *v; { - usbd_xfer_handle xfer = v; + struct uhci_pipe *upipe = v; + usbd_xfer_handle xf; + uhci_soft_td_t *std; + uhci_soft_qh_t *sqh, **qhs; int s; + int i, nqhs; + + DPRINTFN(5,("uhci_abort_xfer_end: upipe=%p\n", upipe)); + + switch (UE_GET_XFERTYPE(upipe->pipe.endpoint->edesc->bmAttributes)) { + case UE_CONTROL: +#if 0 + qhs = &upipe->u.ctl.sqh; + nqhs = 1; +#else +/* only one ctl transfer; qh unlinked by usb_transfer_complete() */ + nqhs = 0; +#endif + break; + case UE_ISOCHRONOUS: + printf("uhci_abort_xfer_end: iso\n"); + nqhs = 0; + break; + case UE_BULK: + qhs = &upipe->u.bulk.sqh; + nqhs = 1; + break; + case UE_INTERRUPT: + qhs = upipe->u.intr.qhs; + nqhs = upipe->u.intr.npoll; + break; + } s = splusb(); - usb_transfer_complete(xfer); + + for (i = 0; i < nqhs; i++) { + sqh = qhs[i]; + /* Check if inside remaining TD chain. */ + for (xf = upipe->abortstart; xf != NULL; + xf = SIMPLEQ_NEXT(xf, next)) { + for (std = UXFER(xf)->iinfo.stdstart; std != NULL; + std = std->link.std) { + if (std->physaddr == le32toh(sqh->qh.qh_elink)) + goto outside; + } + if (xf == upipe->abortend) + break; + } + if (upipe->abortstart != NULL) { + std = UXFER(upipe->abortstart)->iinfo.stdstart; + DPRINTFN(5,("uhci_abort_xfer_end: new std=%p\n", std)); + sqh->elink = std; + sqh->qh.qh_elink = htole32(std->physaddr); + } else { + DPRINTFN(5,("uhci_abort_xfer_end: new std=NULL\n")); + sqh->elink = NULL; + sqh->qh.qh_elink = htole32(UHCI_PTR_T); + } + } + +outside: + + /* Insert QH again. */ + uhci_abort_relink_qh(upipe); + + /* No longer aborting */ + upipe->aborting = 0; + + splx(s); +} + +void +uhci_abort_unlink_qh(upipe) + struct uhci_pipe *upipe; +{ + uhci_softc_t *sc = (uhci_softc_t *)upipe->pipe.device->bus; + uhci_soft_qh_t *sqh, *pqh, **qhs; + int i, npoll; + + DPRINTFN(5,("uhci_abort_unlink_qh: sc=%p pipe=%p\n", sc, upipe)); + + switch (UE_GET_XFERTYPE(upipe->pipe.endpoint->edesc->bmAttributes)) { + case UE_CONTROL: +#if 0 +/* At the moment the done routine removes the QH */ + sqh = upipe->u.ctl.sqh; + pqh = uhci_find_prev_qh(sc->sc_ctl_start, sqh); + pqh->qh.qh_hlink = sqh->qh.qh_hlink; +#endif + break; +#ifdef DIAGNOSTIC + case UE_ISOCHRONOUS: + printf("uhci_abort_unlink_qh: iso\n"); + break; +#endif + case UE_BULK: +#if 0 +/* At the moment the done routine removes the QH */ + sqh = upipe->u.bulk.sqh; + pqh = uhci_find_prev_qh(sc->sc_bulk_start, sqh); + pqh->qh.qh_hlink = sqh->qh.qh_hlink; +#endif + break; + case UE_INTERRUPT: + npoll = upipe->u.intr.npoll; + qhs = upipe->u.intr.qhs; + for (i = 0; i < npoll; i++) { + sqh = qhs[i]; + pqh = uhci_find_prev_qh(sc->sc_vframes[sqh->pos].hqh, + sqh); + pqh->qh.qh_hlink = sqh->qh.qh_hlink; + } + break; + } +} + +void +uhci_abort_relink_qh(upipe) + struct uhci_pipe *upipe; +{ + uhci_softc_t *sc = (uhci_softc_t *)upipe->pipe.device->bus; + uhci_soft_qh_t *sqh, *pqh, **qhs; + int i, npoll; + + switch (UE_GET_XFERTYPE(upipe->pipe.endpoint->edesc->bmAttributes)) { + case UE_CONTROL: +#if 0 +/* At the moment the done routine removes the QH */ + sqh = upipe->u.ctl.sqh; + pqh = uhci_find_prev_qh(sc->sc_ctl_start, sqh); + pqh->qh.qh_hlink = htole32(sqh->physaddr | UHCI_PTR_Q); +#endif + break; +#ifdef DIAGNOSTIC + case UE_ISOCHRONOUS: + printf("uhci_abort_relink_qh: iso\n"); + break; +#endif + case UE_BULK: +#if 0 +/* At the moment the done routine removes the QH */ + sqh = upipe->u.bulk.sqh; + pqh = uhci_find_prev_qh(sc->sc_bulk_start, sqh); + pqh->qh.qh_hlink = htole32(sqh->physaddr | UHCI_PTR_Q); +#endif + break; + case UE_INTERRUPT: + npoll = upipe->u.intr.npoll; + qhs = upipe->u.intr.qhs; + for (i = 0; i < npoll; i++) { + sqh = qhs[i]; + pqh = uhci_find_prev_qh(sc->sc_vframes[sqh->pos].hqh, + sqh); + pqh->qh.qh_hlink = htole32(sqh->physaddr | UHCI_PTR_Q); + } + break; + } +} + +void +uhci_cancel_abort(pipe) + usbd_pipe_handle pipe; +{ + struct uhci_pipe *upipe = (struct uhci_pipe *)pipe; + int s; + + s = splusb(); + if (upipe->aborting) { + usb_uncallout(pipe->abort_handle, uhci_abort_xfer_end, upipe); + upipe->aborting = 0; + } splx(s); } + /* Close a device bulk pipe. */ void uhci_device_bulk_close(pipe) @@ -1720,9 +2006,8 @@ uhci_device_bulk_close(pipe) usbd_device_handle dev = upipe->pipe.device; uhci_softc_t *sc = (uhci_softc_t *)dev->bus; + uhci_cancel_abort(pipe); uhci_free_sqh(sc, upipe->u.bulk.sqh); - uhci_free_intr_info(upipe->iinfo); - /* XXX free other resources? */ } usbd_status @@ -1736,8 +2021,9 @@ uhci_device_ctrl_transfer(xfer) if (err) return (err); - /* Pipe isn't running (otherwise err would be USBD_INPROG), - * start first + /* + * Pipe isn't running (otherwise err would be USBD_INPROG), + * so start it first. */ return (uhci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); } @@ -1777,8 +2063,9 @@ uhci_device_intr_transfer(xfer) if (err) return (err); - /* Pipe isn't running (otherwise err would be USBD_INPROG), - * start first + /* + * Pipe isn't running (otherwise err would be USBD_INPROG), + * so start it first. */ return (uhci_device_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); } @@ -1790,7 +2077,7 @@ uhci_device_intr_start(xfer) struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe; usbd_device_handle dev = upipe->pipe.device; uhci_softc_t *sc = (uhci_softc_t *)dev->bus; - uhci_intr_info_t *ii = upipe->iinfo; + uhci_intr_info_t *ii = &UXFER(xfer)->iinfo; uhci_soft_td_t *data, *dataend; uhci_soft_qh_t *sqh; usbd_status err; @@ -1808,10 +2095,10 @@ uhci_device_intr_start(xfer) #endif err = uhci_alloc_std_chain(upipe, sc, xfer->length, 1, xfer->flags, - &xfer->dmabuf, &data, &dataend); + &xfer->dmabuf, &data, &dataend); if (err) return (err); - dataend->td.td_status |= LE(UHCI_TD_IOC); + dataend->td.td_status |= htole32(UHCI_TD_IOC); #ifdef UHCI_DEBUG if (uhcidebug > 10) { @@ -1826,9 +2113,6 @@ uhci_device_intr_start(xfer) ii->xfer = xfer; ii->stdstart = data; ii->stdend = dataend; -#if defined(__FreeBSD__) - callout_handle_init(&ii->timeout_handle); -#endif #ifdef DIAGNOSTIC if (!ii->isdone) { printf("uhci_device_intr_transfer: not done, ii=%p\n", ii); @@ -1841,8 +2125,10 @@ uhci_device_intr_start(xfer) for (i = 0; i < upipe->u.intr.npoll; i++) { sqh = upipe->u.intr.qhs[i]; sqh->elink = data; - sqh->qh.qh_elink = LE(data->physaddr); + sqh->qh.qh_elink = htole32(data->physaddr); } + uhci_add_intr_info(sc, ii); + xfer->status = USBD_IN_PROGRESS; splx(s); #ifdef UHCI_DEBUG @@ -1870,10 +2156,7 @@ void uhci_device_ctrl_close(pipe) usbd_pipe_handle pipe; { - struct uhci_pipe *upipe = (struct uhci_pipe *)pipe; - - uhci_free_intr_info(upipe->iinfo); - /* XXX free other resources */ + uhci_cancel_abort(pipe); } /* Abort a device interrupt request. */ @@ -1896,17 +2179,17 @@ uhci_device_intr_close(pipe) { struct uhci_pipe *upipe = (struct uhci_pipe *)pipe; uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus; - int i, s, npoll; + int i, npoll; + int s; - upipe->iinfo->stdstart = 0; /* inactive */ + uhci_cancel_abort(pipe); /* Unlink descriptors from controller data structures. */ npoll = upipe->u.intr.npoll; - uhci_lock_frames(sc); + s = splusb(); for (i = 0; i < npoll; i++) - uhci_remove_intr(sc, upipe->u.intr.qhs[i]->pos, - upipe->u.intr.qhs[i]); - uhci_unlock_frames(sc); + uhci_remove_intr(sc, upipe->u.intr.qhs[i]); + splx(s); /* * We now have to wait for any activity on the physical @@ -1918,11 +2201,6 @@ uhci_device_intr_close(pipe) uhci_free_sqh(sc, upipe->u.intr.qhs[i]); free(upipe->u.intr.qhs, M_USBHC); - s = splusb(); - LIST_REMOVE(upipe->iinfo, list); /* remove from active list */ - splx(s); - uhci_free_intr_info(upipe->iinfo); - /* XXX free other resources */ } @@ -1936,7 +2214,7 @@ uhci_device_request(xfer) uhci_softc_t *sc = (uhci_softc_t *)dev->bus; int addr = dev->address; int endpt = upipe->pipe.endpoint->edesc->bEndpointAddress; - uhci_intr_info_t *ii = upipe->iinfo; + uhci_intr_info_t *ii = &UXFER(xfer)->iinfo; uhci_soft_td_t *setup, *data, *stat, *next, *dataend; uhci_soft_qh_t *sqh; int len; @@ -1963,12 +2241,12 @@ uhci_device_request(xfer) if (len != 0) { upipe->nexttoggle = 1; err = uhci_alloc_std_chain(upipe, sc, len, isread, xfer->flags, - &xfer->dmabuf, &data, &dataend); + &xfer->dmabuf, &data, &dataend); if (err) return (err); next = data; dataend->link.std = stat; - dataend->td.td_link = LE(stat->physaddr | UHCI_PTR_VF); + dataend->td.td_link = htole32(stat->physaddr | UHCI_PTR_VF); } else { next = stat; } @@ -1977,19 +2255,20 @@ uhci_device_request(xfer) memcpy(KERNADDR(&upipe->u.ctl.reqdma), req, sizeof *req); setup->link.std = next; - setup->td.td_link = LE(next->physaddr | UHCI_PTR_VF); - setup->td.td_status = LE(UHCI_TD_SET_ERRCNT(3) | ls | UHCI_TD_ACTIVE); - setup->td.td_token = LE(UHCI_TD_SETUP(sizeof *req, endpt, addr)); - setup->td.td_buffer = LE(DMAADDR(&upipe->u.ctl.reqdma)); - - stat->link.std = 0; - stat->td.td_link = LE(UHCI_PTR_T); - stat->td.td_status = LE(UHCI_TD_SET_ERRCNT(3) | ls | + setup->td.td_link = htole32(next->physaddr | UHCI_PTR_VF); + setup->td.td_status = htole32(UHCI_TD_SET_ERRCNT(3) | ls | + UHCI_TD_ACTIVE); + setup->td.td_token = htole32(UHCI_TD_SETUP(sizeof *req, endpt, addr)); + setup->td.td_buffer = htole32(DMAADDR(&upipe->u.ctl.reqdma)); + + stat->link.std = NULL; + stat->td.td_link = htole32(UHCI_PTR_T); + stat->td.td_status = htole32(UHCI_TD_SET_ERRCNT(3) | ls | UHCI_TD_ACTIVE | UHCI_TD_IOC); stat->td.td_token = - LE(isread ? UHCI_TD_OUT(0, endpt, addr, 1) : - UHCI_TD_IN (0, endpt, addr, 1)); - stat->td.td_buffer = LE(0); + htole32(isread ? UHCI_TD_OUT(0, endpt, addr, 1) : + UHCI_TD_IN (0, endpt, addr, 1)); + stat->td.td_buffer = htole32(0); #ifdef UHCI_DEBUG if (uhcidebug > 10) { @@ -2002,9 +2281,6 @@ uhci_device_request(xfer) ii->xfer = xfer; ii->stdstart = setup; ii->stdend = stat; -#if defined(__FreeBSD__) - callout_handle_init(&ii->timeout_handle); -#endif #ifdef DIAGNOSTIC if (!ii->isdone) { printf("uhci_device_request: not done, ii=%p\n", ii); @@ -2013,12 +2289,11 @@ uhci_device_request(xfer) #endif sqh->elink = setup; - sqh->qh.qh_elink = LE(setup->physaddr); - sqh->intr_info = ii; + sqh->qh.qh_elink = htole32(setup->physaddr); s = splusb(); uhci_add_ctrl(sc, sqh); - LIST_INSERT_HEAD(&sc->sc_intrhead, ii, list); + uhci_add_intr_info(sc, ii); #ifdef UHCI_DEBUG if (uhcidebug > 12) { uhci_soft_td_t *std; @@ -2030,7 +2305,7 @@ uhci_device_request(xfer) for (std = sc->sc_vframes[0].htd, link = 0; (link & UHCI_PTR_Q) == 0; std = std->link.std) { - link = LE(std->td.td_link); + link = le32toh(std->td.td_link); uhci_dump_td(std); } sxqh = (uhci_soft_qh_t *)std; @@ -2047,9 +2322,10 @@ uhci_device_request(xfer) } #endif if (xfer->timeout && !sc->sc_bus.use_polling) { - usb_timeout(uhci_timeout, ii, - MS_TO_TICKS(xfer->timeout), ii->timeout_handle); + usb_callout(xfer->timeout_handle, MS_TO_TICKS(xfer->timeout), + uhci_timeout, ii); } + xfer->status = USBD_IN_PROGRESS; splx(s); return (USBD_NORMAL_COMPLETION); @@ -2103,6 +2379,7 @@ uhci_device_isoc_enter(xfer) if (xfer->status == USBD_IN_PROGRESS) { /* This request has already been entered into the frame list */ + printf("uhci_device_isoc_enter: xfer=%p in frame list\n", xfer); /* XXX */ } @@ -2119,12 +2396,12 @@ uhci_device_isoc_enter(xfer) } xfer->status = USBD_IN_PROGRESS; - xfer->hcprivint = next; + UXFER(xfer)->curframe = next; buf = DMAADDR(&xfer->dmabuf); - status = LE(UHCI_TD_ZERO_ACTLEN(UHCI_TD_SET_ERRCNT(0) | - UHCI_TD_ACTIVE | - UHCI_TD_IOS)); + status = UHCI_TD_ZERO_ACTLEN(UHCI_TD_SET_ERRCNT(0) | + UHCI_TD_ACTIVE | + UHCI_TD_IOS); nframes = xfer->nframes; s = splusb(); for (i = 0; i < nframes; i++) { @@ -2132,12 +2409,12 @@ uhci_device_isoc_enter(xfer) if (++next >= UHCI_VFRAMELIST_COUNT) next = 0; len = xfer->frlengths[i]; - std->td.td_buffer = LE(buf); + std->td.td_buffer = htole32(buf); if (i == nframes - 1) - status |= LE(UHCI_TD_IOC); - std->td.td_status = status; - std->td.td_token &= LE(~UHCI_TD_MAXLEN_MASK); - std->td.td_token |= LE(UHCI_TD_SET_MAXLEN(len)); + status |= UHCI_TD_IOC; + std->td.td_status = htole32(status); + std->td.td_token &= htole32(~UHCI_TD_MAXLEN_MASK); + std->td.td_token |= htole32(UHCI_TD_SET_MAXLEN(len)); #ifdef UHCI_DEBUG if (uhcidebug > 5) { DPRINTFN(5,("uhci_device_isoc_enter: TD %d\n", i)); @@ -2158,10 +2435,12 @@ uhci_device_isoc_start(xfer) { struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe; uhci_softc_t *sc = (uhci_softc_t *)upipe->pipe.device->bus; - uhci_intr_info_t *ii = upipe->iinfo; + uhci_intr_info_t *ii = &UXFER(xfer)->iinfo; uhci_soft_td_t *end; int s, i; + DPRINTFN(5,("uhci_device_isoc_start: xfer=%p\n", xfer)); + if (sc->sc_dying) return (USBD_IOERROR); @@ -2171,27 +2450,31 @@ uhci_device_isoc_start(xfer) #endif /* Find the last TD */ - i = xfer->hcprivint + xfer->nframes; + i = UXFER(xfer)->curframe + xfer->nframes; if (i >= UHCI_VFRAMELIST_COUNT) i -= UHCI_VFRAMELIST_COUNT; end = upipe->u.iso.stds[i]; +#ifdef DIAGNOSTIC + if (end == NULL) { + printf("uhci_device_isoc_start: end == NULL\n"); + return (USBD_INVAL); + } +#endif + s = splusb(); /* Set up interrupt info. */ ii->xfer = xfer; ii->stdstart = end; ii->stdend = end; -#if defined(__FreeBSD__) - callout_handle_init(&ii->timeout_handle); -#endif #ifdef DIAGNOSTIC if (!ii->isdone) { printf("uhci_device_isoc_start: not done, ii=%p\n", ii); } ii->isdone = 0; #endif - LIST_INSERT_HEAD(&sc->sc_intrhead, ii, list); + uhci_add_intr_info(sc, ii); splx(s); @@ -2203,35 +2486,46 @@ uhci_device_isoc_abort(xfer) usbd_xfer_handle xfer; { struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe; - uhci_intr_info_t *ii = upipe->iinfo; uhci_soft_td_t **stds = upipe->u.iso.stds; uhci_soft_td_t *std; - int i, n, nframes; + int i, n, s, nframes, maxlen, len; + + s = splusb(); + + /* Transfer is already done. */ + if (xfer->status != USBD_NOT_STARTED && + xfer->status != USBD_IN_PROGRESS) { + splx(s); + return; + } - /* Make interrupt routine ignore it, */ + /* Give xfer the requested abort code. */ xfer->status = USBD_CANCELLED; /* make hardware ignore it, */ nframes = xfer->nframes; - n = xfer->hcprivint; + n = UXFER(xfer)->curframe; + maxlen = 0; for (i = 0; i < nframes; i++) { std = stds[n]; - std->td.td_status &= LE(~(UHCI_TD_ACTIVE | UHCI_TD_IOC)); + std->td.td_status &= htole32(~(UHCI_TD_ACTIVE | UHCI_TD_IOC)); + len = UHCI_TD_GET_MAXLEN(std->td.td_token); + if (len > maxlen) + maxlen = len; if (++n >= UHCI_VFRAMELIST_COUNT) n = 0; } - xfer->hcpriv = ii; + /* and wait until we are sure the hardware has finished. */ + delay(maxlen); - /* make sure hardware has completed, */ - if (xfer->device->bus->intr_context) { - /* We have no process context, so we can't use tsleep(). */ - timeout(uhci_abort_xfer_end, xfer, hz / USB_FRAMES_PER_SECOND); - } else { - usb_delay_ms(xfer->pipe->device->bus, 1); - /* and call final part of interrupt handler. */ - uhci_abort_xfer_end(xfer); - } +#ifdef DIAGNOSTIC + UXFER(xfer)->iinfo.isdone = 1; +#endif + /* Run callback and remove from interrupt list. */ + usb_transfer_complete(xfer); + + splx(s); } void @@ -2243,7 +2537,7 @@ uhci_device_isoc_close(pipe) uhci_softc_t *sc = (uhci_softc_t *)dev->bus; uhci_soft_td_t *std, *vstd; struct iso *iso; - int i; + int i, s; /* * Make sure all TDs are marked as inactive. @@ -2254,10 +2548,10 @@ uhci_device_isoc_close(pipe) iso = &upipe->u.iso; for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++) - iso->stds[i]->td.td_status &= LE(~UHCI_TD_ACTIVE); + iso->stds[i]->td.td_status &= htole32(~UHCI_TD_ACTIVE); usb_delay_ms(&sc->sc_bus, 2); /* wait for completion */ - uhci_lock_frames(sc); + s = splusb(); for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++) { std = iso->stds[i]; for (vstd = sc->sc_vframes[i].htd; @@ -2267,14 +2561,14 @@ uhci_device_isoc_close(pipe) if (vstd == NULL) { /*panic*/ printf("uhci_device_isoc_close: %p not found\n", std); - uhci_unlock_frames(sc); + splx(s); return; } vstd->link = std->link; vstd->td.td_link = std->td.td_link; uhci_free_std(sc, std); } - uhci_unlock_frames(sc); + splx(s); free(iso->stds, M_USBHC); } @@ -2292,36 +2586,36 @@ uhci_setup_isoc(pipe) uhci_soft_td_t *std, *vstd; u_int32_t token; struct iso *iso; - int i; + int i, s; iso = &upipe->u.iso; iso->stds = malloc(UHCI_VFRAMELIST_COUNT * sizeof (uhci_soft_td_t *), M_USBHC, M_WAITOK); - token = LE(rd ? UHCI_TD_IN (0, endpt, addr, 0) : - UHCI_TD_OUT(0, endpt, addr, 0)); + token = rd ? UHCI_TD_IN (0, endpt, addr, 0) : + UHCI_TD_OUT(0, endpt, addr, 0); /* Allocate the TDs and mark as inactive; */ for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++) { std = uhci_alloc_std(sc); if (std == 0) goto bad; - std->td.td_status = LE(UHCI_TD_IOS); /* iso, inactive */ - std->td.td_token = token; + std->td.td_status = htole32(UHCI_TD_IOS); /* iso, inactive */ + std->td.td_token = htole32(token); iso->stds[i] = std; } /* Insert TDs into schedule. */ - uhci_lock_frames(sc); + s = splusb(); for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++) { std = iso->stds[i]; vstd = sc->sc_vframes[i].htd; std->link = vstd->link; std->td.td_link = vstd->td.td_link; vstd->link.std = std; - vstd->td.td_link = LE(std->physaddr); + vstd->td.td_link = htole32(std->physaddr); } - uhci_unlock_frames(sc); + splx(s); iso->next = -1; iso->inuse = 0; @@ -2339,21 +2633,41 @@ void uhci_device_isoc_done(xfer) usbd_xfer_handle xfer; { - uhci_intr_info_t *ii = xfer->hcpriv; + uhci_intr_info_t *ii = &UXFER(xfer)->iinfo; DPRINTFN(4, ("uhci_isoc_done: length=%d\n", xfer->actlen)); + if (ii->xfer != xfer) + /* Not on interrupt list, ignore it. */ + return; + +#ifdef DIAGNOSTIC + if (xfer->busy_free != XFER_BUSY) { + printf("uhci_device_isoc_done: xfer=%p not busy 0x%08x\n", + xfer, xfer->busy_free); + return; + } + + if (ii->stdend == NULL) { + printf("uhci_device_isoc_done: xfer=%p stdend==NULL\n", xfer); +#ifdef UHCI_DEBUG + uhci_dump_ii(ii); +#endif + return; + } +#endif + /* Turn off the interrupt since it is active even if the TD is not. */ - ii->stdend->td.td_status &= LE(~UHCI_TD_IOC); + ii->stdend->td.td_status &= htole32(~UHCI_TD_IOC); - LIST_REMOVE(ii, list); /* remove from active list */ + uhci_del_intr_info(ii); /* remove from active list */ } void uhci_device_intr_done(xfer) usbd_xfer_handle xfer; { - uhci_intr_info_t *ii = xfer->hcpriv; + uhci_intr_info_t *ii = &UXFER(xfer)->iinfo; uhci_softc_t *sc = ii->sc; struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe; uhci_soft_qh_t *sqh; @@ -2365,7 +2679,7 @@ uhci_device_intr_done(xfer) for(i = 0; i < npoll; i++) { sqh = upipe->u.intr.qhs[i]; sqh->elink = 0; - sqh->qh.qh_elink = LE(UHCI_PTR_T); + sqh->qh.qh_elink = htole32(UHCI_PTR_T); } uhci_free_std_chain(sc, ii->stdstart, 0); @@ -2373,10 +2687,12 @@ uhci_device_intr_done(xfer) if (xfer->pipe->repeat) { uhci_soft_td_t *data, *dataend; + DPRINTFN(5,("uhci_device_intr_done: requeing\n")); + /* This alloc cannot fail since we freed the chain above. */ uhci_alloc_std_chain(upipe, sc, xfer->length, 1, xfer->flags, &xfer->dmabuf, &data, &dataend); - dataend->td.td_status |= LE(UHCI_TD_IOC); + dataend->td.td_status |= htole32(UHCI_TD_IOC); #ifdef UHCI_DEBUG if (uhcidebug > 10) { @@ -2388,9 +2704,6 @@ uhci_device_intr_done(xfer) ii->stdstart = data; ii->stdend = dataend; -#if defined(__FreeBSD__) - callout_handle_init(&ii->timeout_handle); -#endif #ifdef DIAGNOSTIC if (!ii->isdone) { printf("uhci_device_intr_done: not done, ii=%p\n", ii); @@ -2400,10 +2713,13 @@ uhci_device_intr_done(xfer) for (i = 0; i < npoll; i++) { sqh = upipe->u.intr.qhs[i]; sqh->elink = data; - sqh->qh.qh_elink = LE(data->physaddr); + sqh->qh.qh_elink = htole32(data->physaddr); } + xfer->status = USBD_IN_PROGRESS; + /* The ii is already on the examined list, just leave it. */ } else { - ii->stdstart = 0; /* mark as inactive */ + DPRINTFN(5,("uhci_device_intr_done: removing\n")); + uhci_del_intr_info(ii); } } @@ -2412,7 +2728,7 @@ void uhci_device_ctrl_done(xfer) usbd_xfer_handle xfer; { - uhci_intr_info_t *ii = xfer->hcpriv; + uhci_intr_info_t *ii = &UXFER(xfer)->iinfo; uhci_softc_t *sc = ii->sc; struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe; @@ -2421,7 +2737,7 @@ uhci_device_ctrl_done(xfer) panic("uhci_ctrl_done: not a request\n"); #endif - LIST_REMOVE(ii, list); /* remove from active list */ + uhci_del_intr_info(ii); /* remove from active list */ uhci_remove_ctrl(sc, upipe->u.ctl.sqh); @@ -2436,11 +2752,11 @@ void uhci_device_bulk_done(xfer) usbd_xfer_handle xfer; { - uhci_intr_info_t *ii = xfer->hcpriv; + uhci_intr_info_t *ii = &UXFER(xfer)->iinfo; uhci_softc_t *sc = ii->sc; struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe; - LIST_REMOVE(ii, list); /* remove from active list */ + uhci_del_intr_info(ii); /* remove from active list */ uhci_remove_bulk(sc, upipe->u.bulk.sqh); @@ -2451,45 +2767,36 @@ uhci_device_bulk_done(xfer) /* Add interrupt QH, called with vflock. */ void -uhci_add_intr(sc, n, sqh) +uhci_add_intr(sc, sqh) uhci_softc_t *sc; - int n; uhci_soft_qh_t *sqh; { - struct uhci_vframe *vf = &sc->sc_vframes[n]; + struct uhci_vframe *vf = &sc->sc_vframes[sqh->pos]; uhci_soft_qh_t *eqh; - DPRINTFN(4, ("uhci_add_intr: n=%d sqh=%p\n", n, sqh)); + DPRINTFN(4, ("uhci_add_intr: n=%d sqh=%p\n", sqh->pos, sqh)); + eqh = vf->eqh; sqh->hlink = eqh->hlink; sqh->qh.qh_hlink = eqh->qh.qh_hlink; eqh->hlink = sqh; - eqh->qh.qh_hlink = LE(sqh->physaddr | UHCI_PTR_Q); + eqh->qh.qh_hlink = htole32(sqh->physaddr | UHCI_PTR_Q); vf->eqh = sqh; vf->bandwidth++; } /* Remove interrupt QH, called with vflock. */ void -uhci_remove_intr(sc, n, sqh) +uhci_remove_intr(sc, sqh) uhci_softc_t *sc; - int n; uhci_soft_qh_t *sqh; { - struct uhci_vframe *vf = &sc->sc_vframes[n]; + struct uhci_vframe *vf = &sc->sc_vframes[sqh->pos]; uhci_soft_qh_t *pqh; - DPRINTFN(4, ("uhci_remove_intr: n=%d sqh=%p\n", n, sqh)); + DPRINTFN(4, ("uhci_remove_intr: n=%d sqh=%p\n", sqh->pos, sqh)); - for (pqh = vf->hqh; pqh->hlink != sqh; pqh = pqh->hlink) -#if defined(DIAGNOSTIC) || defined(UHCI_DEBUG) - if (LE(pqh->qh.qh_hlink) & UHCI_PTR_T) { - DPRINTF(("uhci_remove_intr: QH not found\n")); - return; - } -#else - ; -#endif + pqh = uhci_find_prev_qh(vf->hqh, sqh); pqh->hlink = sqh->hlink; pqh->qh.qh_hlink = sqh->qh.qh_hlink; if (vf->eqh == sqh) @@ -2537,26 +2844,19 @@ uhci_device_setintr(sc, upipe, ival) } DPRINTFN(1, ("uhci_setintr: bw=%d offs=%d\n", bestbw, bestoffs)); - upipe->iinfo->stdstart = 0; for(i = 0; i < npoll; i++) { upipe->u.intr.qhs[i] = sqh = uhci_alloc_sqh(sc); sqh->elink = 0; - sqh->qh.qh_elink = LE(UHCI_PTR_T); + sqh->qh.qh_elink = htole32(UHCI_PTR_T); sqh->pos = MOD(i * ival + bestoffs); - sqh->intr_info = upipe->iinfo; } #undef MOD s = splusb(); - LIST_INSERT_HEAD(&sc->sc_intrhead, upipe->iinfo, list); - splx(s); - - uhci_lock_frames(sc); /* Enter QHs into the controller data structures. */ for(i = 0; i < npoll; i++) - uhci_add_intr(sc, upipe->u.intr.qhs[i]->pos, - upipe->u.intr.qhs[i]); - uhci_unlock_frames(sc); + uhci_add_intr(sc, upipe->u.intr.qhs[i]); + splx(s); DPRINTFN(5, ("uhci_setintr: returns %p\n", upipe)); return (USBD_NORMAL_COMPLETION); @@ -2576,6 +2876,10 @@ uhci_open(pipe) DPRINTFN(1, ("uhci_open: pipe=%p, addr=%d, endpt=%d (%d)\n", pipe, pipe->device->address, ed->bEndpointAddress, sc->sc_addr)); + + upipe->aborting = 0; + upipe->nexttoggle = 0; + if (pipe->device->address == sc->sc_addr) { switch (ed->bEndpointAddress) { case USB_CONTROL_ENDPOINT: @@ -2588,9 +2892,6 @@ uhci_open(pipe) return (USBD_INVAL); } } else { - upipe->iinfo = uhci_alloc_intr_info(sc); - if (upipe->iinfo == 0) - return (USBD_NOMEM); switch (ed->bmAttributes & UE_XFERTYPE) { case UE_CONTROL: pipe->methods = &uhci_device_ctrl_methods; @@ -2609,8 +2910,8 @@ uhci_open(pipe) goto bad; } err = usb_allocmem(&sc->sc_bus, - sizeof(usb_device_request_t), - 0, &upipe->u.ctl.reqdma); + sizeof(usb_device_request_t), + 0, &upipe->u.ctl.reqdma); if (err) { uhci_free_sqh(sc, upipe->u.ctl.sqh); uhci_free_std(sc, upipe->u.ctl.setup); @@ -2638,7 +2939,6 @@ uhci_open(pipe) return (USBD_NORMAL_COMPLETION); bad: - uhci_free_intr_info(upipe->iinfo); return (USBD_NOMEM); } @@ -2736,8 +3036,9 @@ uhci_root_ctrl_transfer(xfer) if (err) return (err); - /* Pipe isn't running (otherwise err would be USBD_INPROG), - * start first + /* + * Pipe isn't running (otherwise err would be USBD_INPROG), + * so start it first. */ return (uhci_root_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); } @@ -3067,7 +3368,6 @@ uhci_root_ctrl_start(xfer) err = USBD_NORMAL_COMPLETION; ret: xfer->status = err; - xfer->hcpriv = 0; s = splusb(); usb_transfer_complete(xfer); splx(s); @@ -3097,14 +3397,17 @@ uhci_root_intr_abort(xfer) { uhci_softc_t *sc = (uhci_softc_t *)xfer->pipe->device->bus; - usb_untimeout(uhci_timo, xfer, xfer->timo_handle); - sc->sc_has_timo = NULL; + usb_uncallout(sc->sc_poll_handle, uhci_poll_hub, xfer); + sc->sc_intr_xfer = NULL; if (xfer->pipe->intrxfer == xfer) { DPRINTF(("uhci_root_intr_abort: remove\n")); xfer->pipe->intrxfer = 0; } xfer->status = USBD_CANCELLED; +#ifdef DIAGNOSTIC + UXFER(xfer)->iinfo.isdone = 1; +#endif usb_transfer_complete(xfer); } @@ -3140,8 +3443,8 @@ uhci_root_intr_start(xfer) return (USBD_IOERROR); sc->sc_ival = MS_TO_TICKS(xfer->pipe->endpoint->edesc->bInterval); - usb_timeout(uhci_timo, xfer, sc->sc_ival, xfer->timo_handle); - sc->sc_has_timo = xfer; + usb_callout(sc->sc_poll_handle, sc->sc_ival, uhci_poll_hub, xfer); + sc->sc_intr_xfer = xfer; return (USBD_IN_PROGRESS); } @@ -3152,8 +3455,7 @@ uhci_root_intr_close(pipe) { uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus; - usb_untimeout(uhci_timo, pipe->intrxfer, pipe->intrxfer->timo_handle); - sc->sc_has_timo = NULL; + usb_uncallout(sc->sc_poll_handle, uhci_poll_hub, sc->sc_intr_xfer); + sc->sc_intr_xfer = NULL; DPRINTF(("uhci_root_intr_close\n")); } - diff --git a/sys/dev/usb/uhcireg.h b/sys/dev/usb/uhcireg.h index 2213fdea4b3..caf07cc2d6a 100644 --- a/sys/dev/usb/uhcireg.h +++ b/sys/dev/usb/uhcireg.h @@ -1,5 +1,6 @@ -/* $OpenBSD: uhcireg.h,v 1.3 2000/03/26 08:39:46 aaron Exp $ */ +/* $OpenBSD: uhcireg.h,v 1.4 2000/03/28 19:37:49 aaron Exp $ */ /* $NetBSD: uhcireg.h,v 1.9 1999/11/20 00:57:09 augustss Exp $ */ +/* $FreeBSD: src/sys/dev/usb/uhcireg.h,v 1.12 1999/11/17 22:33:42 n_hibma Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. diff --git a/sys/dev/usb/uhcivar.h b/sys/dev/usb/uhcivar.h index 3f526106f4d..7c30f652b90 100644 --- a/sys/dev/usb/uhcivar.h +++ b/sys/dev/usb/uhcivar.h @@ -1,5 +1,6 @@ -/* $OpenBSD: uhcivar.h,v 1.6 2000/03/26 08:39:46 aaron Exp $ */ -/* $NetBSD: uhcivar.h,v 1.23 2000/02/22 16:03:44 augustss Exp $ */ +/* $OpenBSD: uhcivar.h,v 1.7 2000/03/28 19:37:49 aaron Exp $ */ +/* $NetBSD: uhcivar.h,v 1.27 2000/03/25 18:02:33 augustss Exp $ */ +/* $FreeBSD: src/sys/dev/usb/uhcivar.h,v 1.14 1999/11/17 22:33:42 n_hibma Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -74,14 +75,19 @@ typedef struct uhci_intr_info { uhci_soft_td_t *stdstart; uhci_soft_td_t *stdend; LIST_ENTRY(uhci_intr_info) list; -#if defined(__FreeBSD__) - struct callout_handle timeout_handle; -#endif /* defined(__FreeBSD__) */ #ifdef DIAGNOSTIC int isdone; #endif } uhci_intr_info_t; +struct uhci_xfer { + struct usbd_xfer xfer; + uhci_intr_info_t iinfo; + int curframe; +}; + +#define UXFER(xfer) ((struct uhci_xfer *)(xfer)) + /* * Extra information that we need for a TD. */ @@ -108,8 +114,6 @@ struct uhci_soft_qh { uhci_soft_td_t *elink; /* soft version of qh_elink */ uhci_physaddr_t physaddr; /* QH's physical address. */ int pos; /* Timeslot position */ - uhci_intr_info_t *intr_info; /* Who to call on completion. */ -/* XXX should try to shrink with 4 bytes to fit into 32 bytes */ }; /* See comment about UHCI_STD_SIZE. */ #define UHCI_SQH_SIZE ((sizeof (struct uhci_soft_qh) + UHCI_QH_ALIGN - 1) / UHCI_QH_ALIGN * UHCI_QH_ALIGN) @@ -158,12 +162,9 @@ typedef struct uhci_softc { LIST_HEAD(, uhci_intr_info) sc_intrhead; /* Info for the root hub interrupt channel. */ - int sc_ival; /* time between root hub intrs */ - usbd_xfer_handle sc_has_timo; /* root hub interrupt transfer */ - - char sc_vflock; /* for lock virtual frame list */ -#define UHCI_HAS_LOCK 1 -#define UHCI_WANT_LOCK 2 + int sc_ival; /* time between root hug intrs */ + usbd_xfer_handle sc_intr_xfer; /* root hub interrupt transfer */ + usb_callout_t sc_poll_handle; char sc_vendor[16]; /* vendor string for root hub */ int sc_id_vendor; /* vendor ID for root hub */ @@ -180,3 +181,4 @@ int uhci_intr __P((void *)); int uhci_detach __P((uhci_softc_t *, int)); int uhci_activate __P((device_ptr_t, enum devact)); #endif + diff --git a/sys/dev/usb/uhid.c b/sys/dev/usb/uhid.c index 0443d21994a..fb8c3a27e3c 100644 --- a/sys/dev/usb/uhid.c +++ b/sys/dev/usb/uhid.c @@ -1,5 +1,6 @@ -/* $OpenBSD: uhid.c,v 1.7 2000/03/26 08:39:46 aaron Exp $ */ +/* $OpenBSD: uhid.c,v 1.8 2000/03/28 19:37:50 aaron Exp $ */ /* $NetBSD: uhid.c,v 1.35 2000/03/19 22:23:28 augustss Exp $ */ +/* $FreeBSD: src/sys/dev/usb/uhid.c,v 1.22 1999/11/17 22:33:43 n_hibma Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -147,11 +148,13 @@ static struct cdevsw uhid_cdevsw = { }; #endif -void uhid_intr __P((usbd_xfer_handle, usbd_private_handle, usbd_status)); +static void uhid_intr __P((usbd_xfer_handle, usbd_private_handle, + usbd_status)); -int uhid_do_read __P((struct uhid_softc *, struct uio *uio, int)); -int uhid_do_write __P((struct uhid_softc *, struct uio *uio, int)); -int uhid_do_ioctl __P((struct uhid_softc *, u_long, caddr_t, int, struct proc *)); +static int uhid_do_read __P((struct uhid_softc *, struct uio *uio, int)); +static int uhid_do_write __P((struct uhid_softc *, struct uio *uio, int)); +static int uhid_do_ioctl __P((struct uhid_softc *, u_long, caddr_t, int, + struct proc *)); USB_DECLARE_DRIVER(uhid); @@ -178,7 +181,7 @@ USB_ATTACH(uhid) void *desc; usbd_status err; char devinfo[1024]; - + sc->sc_udev = uaa->device; sc->sc_iface = iface; id = usbd_get_interface_descriptor(iface); @@ -327,10 +330,10 @@ uhid_intr(xfer, addr, status) #ifdef UHID_DEBUG if (uhiddebug > 5) { u_int32_t cc, i; - + usbd_get_xfer_status(xfer, NULL, NULL, &cc, NULL); DPRINTF(("uhid_intr: status=%d cc=%d\n", status, cc)); - DPRINTF(("uhid_intr: data=")); + DPRINTF(("uhid_intr: data =")); for (i = 0; i < cc; i++) DPRINTF((" %02x", sc->sc_ibuf[i])); DPRINTF(("\n")); @@ -387,8 +390,8 @@ uhidopen(dev, flag, mode, p) /* Set up interrupt pipe. */ err = usbd_open_pipe_intr(sc->sc_iface, sc->sc_ep_addr, - USBD_SHORT_XFER_OK, &sc->sc_intrpipe, sc, sc->sc_ibuf, - sc->sc_isize, uhid_intr, USBD_DEFAULT_INTERVAL); + USBD_SHORT_XFER_OK, &sc->sc_intrpipe, sc, sc->sc_ibuf, + sc->sc_isize, uhid_intr, USBD_DEFAULT_INTERVAL); if (err) { DPRINTF(("uhidopen: usbd_open_pipe_intr failed, " "error=%d\n",err)); @@ -537,10 +540,10 @@ uhid_do_write(sc, uio, flag) if (!error) { if (sc->sc_oid) err = usbd_set_report(sc->sc_iface, UHID_OUTPUT_REPORT, - sc->sc_obuf[0], sc->sc_obuf+1, size-1); + sc->sc_obuf[0], sc->sc_obuf+1, size-1); else err = usbd_set_report(sc->sc_iface, UHID_OUTPUT_REPORT, - 0, sc->sc_obuf, size); + 0, sc->sc_obuf, size); if (err) error = EIO; } @@ -600,7 +603,7 @@ uhid_do_ioctl(sc, cmd, addr, flag, p) if (*(int *)addr) { /* XXX should read into ibuf, but does it matter? */ err = usbd_get_report(sc->sc_iface, UHID_INPUT_REPORT, - sc->sc_iid, sc->sc_ibuf, sc->sc_isize); + sc->sc_iid, sc->sc_ibuf, sc->sc_isize); if (err) return (EOPNOTSUPP); @@ -628,10 +631,11 @@ uhid_do_ioctl(sc, cmd, addr, flag, p) return (EINVAL); } err = usbd_get_report(sc->sc_iface, re->report, id, re->data, - size); + size); if (err) return (EIO); break; + case USB_SET_REPORT: re = (struct usb_ctl_report *)addr; switch (re->report) { @@ -651,7 +655,7 @@ uhid_do_ioctl(sc, cmd, addr, flag, p) return (EINVAL); } err = usbd_set_report(sc->sc_iface, re->report, id, re->data, - size); + size); if (err) return (EIO); break; diff --git a/sys/dev/usb/uhub.c b/sys/dev/usb/uhub.c index 4ba332ef49e..92183cdcd46 100644 --- a/sys/dev/usb/uhub.c +++ b/sys/dev/usb/uhub.c @@ -1,5 +1,6 @@ -/* $OpenBSD: uhub.c,v 1.7 2000/03/26 08:39:46 aaron Exp $ */ +/* $OpenBSD: uhub.c,v 1.8 2000/03/28 19:37:50 aaron Exp $ */ /* $NetBSD: uhub.c,v 1.40 2000/02/29 21:37:01 augustss Exp $ */ +/* $FreeBSD: src/sys/dev/usb/uhub.c,v 1.18 1999/11/17 22:33:43 n_hibma Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -79,14 +80,15 @@ struct uhub_softc { u_char sc_running; }; -usbd_status uhub_init_port __P((struct usbd_port *)); -usbd_status uhub_explore __P((usbd_device_handle hub)); -void uhub_intr __P((usbd_xfer_handle, usbd_private_handle, usbd_status)); +static usbd_status uhub_init_port __P((struct usbd_port *)); +static usbd_status uhub_explore __P((usbd_device_handle hub)); +static void uhub_intr __P((usbd_xfer_handle, usbd_private_handle,usbd_status)); #if defined(__FreeBSD__) static bus_child_detached_t uhub_child_detached; #endif + /* * We need two attachment points: * hub to usb and hub to hub @@ -102,9 +104,9 @@ struct cfattach uhub_uhub_ca = { uhub_detach, uhub_activate }; #elif defined(__FreeBSD__) -USB_DECLARE_DRIVER_INIT(uhub. +USB_DECLARE_DRIVER_INIT(uhub, DEVMETHOD(bus_child_detached, uhub_child_detached)); - + /* Create the driver instance for the hub connected to usb case. */ devclass_t uhubroot_devclass; @@ -235,8 +237,8 @@ USB_ATTACH(uhub) } err = usbd_open_pipe_intr(iface, ed->bEndpointAddress, - USBD_SHORT_XFER_OK, &sc->sc_ipipe, sc, sc->sc_status, - sizeof(sc->sc_status), uhub_intr, USBD_DEFAULT_INTERVAL); + USBD_SHORT_XFER_OK, &sc->sc_ipipe, sc, sc->sc_status, + sizeof(sc->sc_status), uhub_intr, USBD_DEFAULT_INTERVAL); if (err) { printf("%s: cannot open interrupt pipe\n", USBDEVNAME(sc->sc_dev)); @@ -363,6 +365,7 @@ uhub_explore(dev) DPRINTFN(3,("uhub_explore: port %d status 0x%04x 0x%04x\n", port, status, change)); if (change & UPS_C_PORT_ENABLED) { + DPRINTF(("uhub_explore: C_PORT_ENABLED\n")); usbd_clear_port_feature(dev, port, UHF_C_PORT_ENABLE); if (status & UPS_PORT_ENABLED) { printf("%s: illegal enable change, port %d\n", @@ -430,8 +433,8 @@ uhub_explore(dev) /* Get device info and set its address. */ err = usbd_new_device(USBDEV(sc->sc_dev), dev->bus, - dev->depth + 1, status & UPS_LOW_SPEED, - port, up); + dev->depth + 1, status & UPS_LOW_SPEED, + port, up); /* XXX retry a few times? */ if (err) { DPRINTFN(-1,("uhub_explore: usb_new_device failed, " @@ -519,10 +522,10 @@ USB_DETACH(uhub) if (rup->device) usb_disconnect_port(rup, self); } - + usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_hub, USBDEV(sc->sc_dev)); - + free(hub, M_USBDEV); sc->sc_hub->hub = NULL; @@ -533,35 +536,36 @@ USB_DETACH(uhub) /* Called when a device has been detached from it */ static void uhub_child_detached(self, child) - device_t self; - device_t child; + device_t self; + device_t child; { - struct uhub_softc *sc = device_get_softc(self); - usbd_device_handle devhub = sc->sc_hub; - usbd_device_handle dev; - int nports; - int port; - int i; - - if (!devhub->hub) - /* should never happen; children are only created after init */ - panic("hub not fully initialised, but child deleted?"); - - nports = devhub->hub->hubdesc.bNbrPorts; - for (port = 0; port < nports; port++) { - dev = devhub->hub->ports[port].device; - if (dev && dev->subdevs) { - for (i = 0; dev->subdevs[i]; i++) { - if (dev->subdevs[i] == child) { - dev->subdevs[i] = NULL; - return; - } - } - } - } + struct uhub_softc *sc = device_get_softc(self); + usbd_device_handle devhub = sc->sc_hub; + usbd_device_handle dev; + int nports; + int port; + int i; + + if (!devhub->hub) + /* should never happen; children are only created after init */ + panic("hub not fully initialised, but child deleted?"); + + nports = devhub->hub->hubdesc.bNbrPorts; + for (port = 0; port < nports; port++) { + dev = devhub->hub->ports[port].device; + if (dev && dev->subdevs) { + for (i = 0; dev->subdevs[i]; i++) { + if (dev->subdevs[i] == child) { + dev->subdevs[i] = NULL; + return; + } + } + } + } } #endif + /* * Hub interrupt. * This an indication that some port has changed status. diff --git a/sys/dev/usb/ulpt.c b/sys/dev/usb/ulpt.c new file mode 100644 index 00000000000..93ade608e84 --- /dev/null +++ b/sys/dev/usb/ulpt.c @@ -0,0 +1,594 @@ +/* $OpenBSD: ulpt.c,v 1.1 2000/03/28 19:37:50 aaron Exp $ */ +/* $NetBSD: ulpt.c,v 1.33 2000/03/06 20:58:39 augustss Exp $ */ +/* $FreeBSD: src/sys/dev/usb/ulpt.c,v 1.24 1999/11/17 22:33:44 n_hibma Exp $ */ + +/* + * Copyright (c) 1998 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Lennart Augustsson (augustss@carlstedt.se) at + * Carlstedt Research & Technology. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Printer Class spec: http://www.usb.org/developers/data/usbprn10.pdf + */ + +#include +#include +#include +#include +#if defined(__NetBSD__) || defined(__OpenBSD__) +#include +#include +#elif defined(__FreeBSD__) +#include +#include +#include +#endif +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define TIMEOUT hz*16 /* wait up to 16 seconds for a ready */ +#define STEP hz/4 + +#define LPTPRI (PZERO+8) +#define ULPT_BSIZE 16384 + +#ifdef ULPT_DEBUG +#define DPRINTF(x) if (ulptdebug) logprintf x +#define DPRINTFN(n,x) if (ulptdebug>(n)) logprintf x +int ulptdebug = 0; +#else +#define DPRINTF(x) +#define DPRINTFN(n,x) +#endif + +#define UR_GET_DEVICE_ID 0 +#define UR_GET_PORT_STATUS 1 +#define UR_SOFT_RESET 2 + +#define LPS_NERR 0x08 /* printer no error */ +#define LPS_SELECT 0x10 /* printer selected */ +#define LPS_NOPAPER 0x20 /* printer out of paper */ +#define LPS_INVERT (LPS_SELECT|LPS_NERR) +#define LPS_MASK (LPS_SELECT|LPS_NERR|LPS_NOPAPER) + +struct ulpt_softc { + USBBASEDEVICE sc_dev; + 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; + + u_char sc_state; +#define ULPT_OPEN 0x01 /* device is open */ +#define ULPT_OBUSY 0x02 /* printer is busy doing output */ +#define ULPT_INIT 0x04 /* waiting to initialize for open */ + u_char sc_flags; +#define ULPT_NOPRIME 0x40 /* don't prime on open */ + u_char sc_laststatus; + + int sc_refcnt; + u_char sc_dying; + +#if defined(__FreeBSD__) + dev_t dev; + dev_t dev_noprime; +#endif +}; + +#if defined(__NetBSD__) || defined(__OpenBSD__) +cdev_decl(ulpt); +#elif defined(__FreeBSD__) +static d_open_t ulptopen; +static d_close_t ulptclose; +static d_write_t ulptwrite; +static d_ioctl_t ulptioctl; + +#define ULPT_CDEV_MAJOR 113 + +static struct cdevsw ulpt_cdevsw = { + /* open */ ulptopen, + /* close */ ulptclose, + /* read */ noread, + /* write */ ulptwrite, + /* ioctl */ ulptioctl, + /* poll */ nopoll, + /* mmap */ nommap, + /* strategy */ nostrategy, + /* name */ "ulpt", + /* maj */ ULPT_CDEV_MAJOR, + /* dump */ nodump, + /* psize */ nopsize, + /* flags */ 0, + /* bmaj */ -1 +}; +#endif + +void ulpt_disco __P((void *)); + +int ulpt_do_write __P((struct ulpt_softc *, struct uio *uio, int)); +int ulpt_status __P((struct ulpt_softc *)); +void ulpt_reset __P((struct ulpt_softc *)); +int ulpt_statusmsg __P((u_char, struct ulpt_softc *)); + +void ieee1284_print_id __P((char *)); + +#define ULPTUNIT(s) (minor(s) & 0x1f) +#define ULPTFLAGS(s) (minor(s) & 0xe0) + + +USB_DECLARE_DRIVER(ulpt); + +USB_MATCH(ulpt) +{ + USB_MATCH_START(ulpt, uaa); + usb_interface_descriptor_t *id; + + DPRINTFN(10,("ulpt_match\n")); + if (uaa->iface == NULL) + return (UMATCH_NONE); + id = usbd_get_interface_descriptor(uaa->iface); + if (id != NULL && + id->bInterfaceClass == UICLASS_PRINTER && + id->bInterfaceSubClass == UISUBCLASS_PRINTER && + (id->bInterfaceProtocol == UIPROTO_PRINTER_UNI || + id->bInterfaceProtocol == UIPROTO_PRINTER_BI)) + return (UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO); + return (UMATCH_NONE); +} + +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); + char devinfo[1024]; + usb_endpoint_descriptor_t *ed; + usbd_status err; + + 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; + } + 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) { + sc->sc_dying = 1; + USB_ATTACH_ERROR_RETURN; + } + sc->sc_ifaceno = id->bInterfaceNumber; + +#if 0 +/* + * This code is disabled because for some mysterious it causes + * printing not to work. But only sometimes, and mostly with + * UHCI and less often with OHCI. *sigh* + */ + { + usb_config_descriptor_t *cd = usbd_get_config_descriptor(dev); + usb_device_request_t req; + int len, alen; + + req.bmRequestType = UT_READ_CLASS_INTERFACE; + req.bRequest = UR_GET_DEVICE_ID; + USETW(req.wValue, cd->bConfigurationValue); + USETW2(req.wIndex, id->bInterfaceNumber, id->bAlternateSetting); + USETW(req.wLength, sizeof devinfo - 1); + err = usbd_do_request_flags(dev, &req, devinfo,USBD_SHORT_XFER_OK, + &alen); + if (err) { + printf("%s: cannot get device id\n", USBDEVNAME(sc->sc_dev)); + } else if (alen <= 2) { + printf("%s: empty device id, no printer connected?\n", + USBDEVNAME(sc->sc_dev)); + } else { + /* devinfo now contains an IEEE-1284 device ID */ + len = ((devinfo[0] & 0xff) << 8) | (devinfo[1] & 0xff); + if (len > sizeof devinfo - 3) + len = sizeof devinfo - 3; + devinfo[len] = 0; + printf("%s: device id <", USBDEVNAME(sc->sc_dev)); + ieee1284_print_id(devinfo+2); + printf(">\n"); + } + } +#endif + +#if defined(__FreeBSD__) + sc->dev = make_dev(&ulpt_cdevsw, device_get_unit(self), + UID_ROOT, GID_OPERATOR, 0644, "ulpt%d", device_get_unit(self)); + sc->dev_noprime = make_dev(&ulpt_cdevsw, + device_get_unit(self)|ULPT_NOPRIME, + UID_ROOT, GID_OPERATOR, 0644, "unlpt%d", device_get_unit(self)); +#endif + + usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, + 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__) +int +ulpt_activate(self, act) + device_ptr_t self; + enum devact act; +{ + struct ulpt_softc *sc = (struct ulpt_softc *)self; + + switch (act) { + case DVACT_ACTIVATE: + return (EOPNOTSUPP); + break; + + case DVACT_DEACTIVATE: + sc->sc_dying = 1; + break; + } + return (0); +} +#endif + +USB_DETACH(ulpt) +{ + USB_DETACH_START(ulpt, sc); + int s; +#if defined(__NetBSD__) || defined(__OpenBSD__) + int maj, mn; + + DPRINTF(("ulpt_detach: sc=%p flags=%d\n", sc, flags)); +#elif defined(__FreeBSD__) + DPRINTF(("ulpt_detach: sc=%p\n", sc)); +#endif + + sc->sc_dying = 1; + if (sc->sc_bulkpipe != NULL) + usbd_abort_pipe(sc->sc_bulkpipe); + + s = splusb(); + if (--sc->sc_refcnt >= 0) { + /* There is noone to wake, aborting the pipe is enough */ + /* Wait for processes to go away. */ + usb_detach_wait(USBDEV(sc->sc_dev)); + } + splx(s); + +#if defined(__NetBSD__) || defined(__OpenBSD__) + /* locate the major number */ + for (maj = 0; maj < nchrdev; maj++) + if (cdevsw[maj].d_open == ulptopen) + break; + + /* Nuke the vnodes for any open instances (calls close). */ + mn = self->dv_unit; + vdevgone(maj, mn, mn, VCHR); +#elif defined(__FreeBSD__) + /* XXX not implemented yet */ + + destroy_dev(sc->dev); + destroy_dev(sc->dev_noprime); +#endif + + usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, + USBDEV(sc->sc_dev)); + + return (0); +} + +int +ulpt_status(sc) + struct ulpt_softc *sc; +{ + usb_device_request_t req; + 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); + USETW(req.wLength, 1); + err = usbd_do_request(sc->sc_udev, &req, &status); + DPRINTFN(1, ("ulpt_status: status=0x%02x err=%d\n", status, err)); + if (!err) + return (status); + else + return (0); +} + +void +ulpt_reset(sc) + struct ulpt_softc *sc; +{ + usb_device_request_t req; + + DPRINTFN(1, ("ulpt_reset\n")); + req.bmRequestType = UT_WRITE_CLASS_OTHER; + req.bRequest = UR_SOFT_RESET; + USETW(req.wValue, 0); + USETW(req.wIndex, sc->sc_ifaceno); + USETW(req.wLength, 0); + (void)usbd_do_request(sc->sc_udev, &req, 0); +} + +/* + * Reset the printer, then wait until it's selected and not busy. + */ +int +ulptopen(dev, flag, mode, p) + dev_t dev; + int flag; + int mode; + struct proc *p; +{ + u_char flags = ULPTFLAGS(dev); + struct ulpt_softc *sc; + usbd_status err; + int spin, error; + + USB_GET_SC_OPEN(ulpt, ULPTUNIT(dev), sc); + + if (sc == NULL || sc->sc_iface == NULL || sc->sc_dying) + return (ENXIO); + + if (sc->sc_state) + return (EBUSY); + + sc->sc_state = ULPT_INIT; + sc->sc_flags = flags; + DPRINTF(("ulptopen: flags=0x%x\n", (unsigned)flags)); + +#if defined(ULPT_DEBUG) && defined(__FreeBSD__) + /* Ignoring these flags might not be a good idea */ + if ((flags & ~ULPT_NOPRIME) != 0) + printf("ulptopen: flags ignored: %b\n", flags, + "\20\3POS_INIT\4POS_ACK\6PRIME_OPEN\7AUTOLF\10BYPASS"); +#endif + + + if ((flags & ULPT_NOPRIME) == 0) + ulpt_reset(sc); + + for (spin = 0; (ulpt_status(sc) & LPS_SELECT) == 0; spin += STEP) { + if (spin >= TIMEOUT) { + sc->sc_state = 0; + return (EBUSY); + } + + /* wait 1/4 second, give up if we get a signal */ + error = tsleep((caddr_t)sc, LPTPRI | PCATCH, "ulptop", STEP); + if (error != EWOULDBLOCK) { + sc->sc_state = 0; + return (error); + } + } + + err = usbd_open_pipe(sc->sc_iface, sc->sc_bulk, 0, &sc->sc_bulkpipe); + if (err) { + sc->sc_state = 0; + return (EIO); + } + + sc->sc_state = ULPT_OPEN; + + DPRINTF(("ulptopen: done\n")); + return (0); +} + +int +ulpt_statusmsg(status, sc) + u_char status; + struct ulpt_softc *sc; +{ + u_char new; + + status = (status ^ LPS_INVERT) & LPS_MASK; + new = status & ~sc->sc_laststatus; + sc->sc_laststatus = status; + + if (new & LPS_SELECT) + log(LOG_NOTICE, "%s: offline\n", USBDEVNAME(sc->sc_dev)); + else if (new & LPS_NOPAPER) + log(LOG_NOTICE, "%s: out of paper\n", USBDEVNAME(sc->sc_dev)); + else if (new & LPS_NERR) + log(LOG_NOTICE, "%s: output error\n", USBDEVNAME(sc->sc_dev)); + + return (status); +} + +int +ulptclose(dev, flag, mode, p) + dev_t dev; + int flag; + int mode; + struct proc *p; +{ + struct ulpt_softc *sc; + + USB_GET_SC(ulpt, ULPTUNIT(dev), sc); + + if (sc->sc_state != ULPT_OPEN) + /* We are being forced to close before the open completed. */ + return (0); + + usbd_close_pipe(sc->sc_bulkpipe); + sc->sc_bulkpipe = 0; + + sc->sc_state = 0; + + DPRINTF(("ulptclose: closed\n")); + return (0); +} + +int +ulpt_do_write(sc, uio, flags) + struct ulpt_softc *sc; + struct uio *uio; + int flags; +{ + u_int32_t n; + int error = 0; + void *bufp; + usbd_xfer_handle xfer; + usbd_status err; + + DPRINTF(("ulptwrite\n")); + xfer = usbd_alloc_xfer(sc->sc_udev); + if (xfer == NULL) + return (ENOMEM); + bufp = usbd_alloc_buffer(xfer, ULPT_BSIZE); + if (bufp == NULL) { + usbd_free_xfer(xfer); + return (ENOMEM); + } + while ((n = min(ULPT_BSIZE, uio->uio_resid)) != 0) { + ulpt_statusmsg(ulpt_status(sc), sc); + error = uiomove(bufp, n, uio); + if (error) + break; + DPRINTFN(1, ("ulptwrite: transfer %d bytes\n", n)); + err = usbd_bulk_transfer(xfer, sc->sc_bulkpipe, USBD_NO_COPY, + USBD_NO_TIMEOUT, bufp, &n, "ulptwr"); + if (err) { + DPRINTF(("ulptwrite: error=%d\n", err)); + error = EIO; + break; + } + } + usbd_free_xfer(xfer); + + return (error); +} + +int +ulptwrite(dev, uio, flags) + dev_t dev; + struct uio *uio; + int flags; +{ + struct ulpt_softc *sc; + int error; + + USB_GET_SC(ulpt, ULPTUNIT(dev), sc); + + if (sc->sc_dying) + return (EIO); + + sc->sc_refcnt++; + error = ulpt_do_write(sc, uio, flags); + if (--sc->sc_refcnt < 0) + usb_detach_wakeup(USBDEV(sc->sc_dev)); + return (error); +} + +int +ulptioctl(dev, cmd, data, flag, p) + dev_t dev; + u_long cmd; + caddr_t data; + int flag; + struct proc *p; +{ + int error = 0; + + switch (cmd) { + default: + error = ENODEV; + } + + return (error); +} + +#if 0 +/* XXX This does not belong here. */ +/* + * Print select parts of a IEEE 1284 device ID. + */ +void +ieee1284_print_id(str) + char *str; +{ + char *p, *q; + + for (p = str-1; p; p = strchr(p, ';')) { + p++; /* skip ';' */ + if (strncmp(p, "MFG:", 4) == 0 || + strncmp(p, "MANUFACTURER:", 14) == 0 || + strncmp(p, "MDL:", 4) == 0 || + strncmp(p, "MODEL:", 6) == 0) { + q = strchr(p, ';'); + if (q) + printf("%.*s", (int)(q - p + 1), p); + } + } +} +#endif + +#if defined(__FreeBSD__) +DRIVER_MODULE(ulpt, uhub, ulpt_driver, ulpt_devclass, usbd_driver_load, 0); +#endif diff --git a/sys/dev/usb/usb.c b/sys/dev/usb/usb.c index dc3b352ddb1..0c901df0f59 100644 --- a/sys/dev/usb/usb.c +++ b/sys/dev/usb/usb.c @@ -1,5 +1,6 @@ -/* $OpenBSD: usb.c,v 1.9 2000/03/26 21:47:51 aaron Exp $ */ +/* $OpenBSD: usb.c,v 1.10 2000/03/28 19:37:50 aaron Exp $ */ /* $NetBSD: usb.c,v 1.41 2000/03/16 00:46:38 augustss Exp $ */ +/* $FreeBSD: src/sys/dev/usb/usb.c,v 1.20 1999/11/17 22:33:46 n_hibma Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -88,12 +89,12 @@ MALLOC_DEFINE(M_USBHC, "USBHC", "USB host controller"); #define DPRINTFN(n,x) if (usbdebug>(n)) logprintf x int usbdebug = 0; #ifdef UHCI_DEBUG -int uhcidebug; +int uhcidebug; #endif #ifdef OHCI_DEBUG -int ohcidebug; +int ohcidebug; #endif -/* +/* * 0 - do usual exploration * 1 - do not use timeout exploration * >1 - do no exploration @@ -109,7 +110,7 @@ struct usb_softc { usbd_bus_handle sc_bus; /* USB controller */ struct usbd_port sc_port; /* dummy port for root hub */ -#if defined (__FreeBSD__) +#if defined(__FreeBSD__) /* This part should be deleted when kthreads is available */ struct selinfo sc_consel; /* waiting for connect change */ #else @@ -146,23 +147,24 @@ struct cdevsw usb_cdevsw = { }; #endif -usbd_status usb_discover __P((struct usb_softc *)); -void usb_create_event_thread __P((void *)); -void usb_event_thread __P((void *)); +static usbd_status usb_discover __P((struct usb_softc *)); +static void usb_create_event_thread __P((void *)); +static void usb_event_thread __P((void *)); #define USB_MAX_EVENTS 100 struct usb_event_q { struct usb_event ue; SIMPLEQ_ENTRY(usb_event_q) next; }; -SIMPLEQ_HEAD(, usb_event_q) usb_events = SIMPLEQ_HEAD_INITIALIZER(usb_events); -int usb_nevents = 0; -struct selinfo usb_selevent; -struct proc *usb_async_proc; /* process who wants USB SIGIO */ -int usb_dev_open = 0; -void usb_add_event __P((int, struct usb_event *)); +static SIMPLEQ_HEAD(, usb_event_q) usb_events = + SIMPLEQ_HEAD_INITIALIZER(usb_events); +static int usb_nevents = 0; +static struct selinfo usb_selevent; +static struct proc *usb_async_proc; /* process who wants USB SIGIO */ +static int usb_dev_open = 0; +static void usb_add_event __P((int, struct usb_event *)); -int usb_get_next_event __P((struct usb_event *)); +static int usb_get_next_event __P((struct usb_event *)); #if defined(__NetBSD__) || defined(__OpenBSD__) /* Flag to see if we are in the cold boot process. */ @@ -191,7 +193,7 @@ USB_ATTACH(usb) usbd_status err; int usbrev; struct usb_event ue; - + #if defined(__FreeBSD__) printf("%s", USBDEVNAME(sc->sc_dev)); sc->sc_dev = self; @@ -220,7 +222,7 @@ USB_ATTACH(usb) usb_add_event(USB_EVENT_CTRLR_ATTACH, &ue); err = usbd_new_device(USBDEV(sc->sc_dev), sc->sc_bus, 0, 0, 0, - &sc->sc_port); + &sc->sc_port); if (!err) { dev = sc->sc_port.device; if (dev->hub == NULL) { @@ -230,7 +232,7 @@ USB_ATTACH(usb) USB_ATTACH_ERROR_RETURN; } sc->sc_bus->root_hub = dev; -#if 0 +#if 1 /* * Turning this code off will delay attachment of USB devices * until the USB event thread is running, which means that @@ -241,13 +243,18 @@ USB_ATTACH(usb) #endif } else { printf("%s: root hub problem, error=%d\n", - USBDEVNAME(sc->sc_dev), err); + USBDEVNAME(sc->sc_dev), err); sc->sc_dying = 1; } if (cold) sc->sc_bus->use_polling--; +#if defined(__NetBSD__) || defined(__FreeBSD__) + config_pending_incr(); + kthread_create(usb_create_event_thread, sc); +#else kthread_create_deferred(usb_create_event_thread, sc); +#endif #if defined(__FreeBSD__) make_dev(&usb_cdevsw, device_get_unit(self), UID_ROOT, GID_OPERATOR, @@ -264,11 +271,7 @@ usb_create_event_thread(arg) { struct usb_softc *sc = arg; -#if defined(__NetBSD__) if (kthread_create1(usb_event_thread, sc, &sc->sc_event_thread, -#else - if (kthread_create(usb_event_thread, sc, &sc->sc_event_thread, -#endif "%s", sc->sc_dev.dv_xname)) { printf("%s: unable to create event thread for\n", sc->sc_dev.dv_xname); @@ -281,6 +284,9 @@ usb_event_thread(arg) void *arg; { struct usb_softc *sc = arg; +#if defined(__NetBSD__) + int first = 1; +#endif DPRINTF(("usb_event_thread: start\n")); @@ -292,6 +298,12 @@ usb_event_thread(arg) if (usb_noexplore < 2) #endif usb_discover(sc); +#if defined(__NetBSD__) + if (first) { + config_pending_decr(); + first = 0; + } +#endif (void)tsleep(&sc->sc_bus->needs_explore, PWAIT, "usbevt", #ifdef USB_DEBUG usb_noexplore ? 0 : @@ -378,7 +390,7 @@ usbread(dev, uio, flag) } splx(s); if (!error) - error = uiomove((caddr_t)&ue, uio->uio_resid, uio); + error = uiomove((void *)&ue, uio->uio_resid, uio); return (error); } @@ -442,7 +454,7 @@ usbioctl(devt, cmd, data, flag, p) #endif #ifdef USB_DEBUG case USB_SETDEBUG: - usbdebug = ((*(int *)data) & 0x000000ff); + usbdebug = ((*(int *)data) & 0x000000ff); #ifdef UHCI_DEBUG uhcidebug = ((*(int *)data) & 0x0000ff00) >> 8; #endif @@ -488,7 +500,7 @@ usbioctl(devt, cmd, data, flag, p) } } err = usbd_do_request_flags(sc->sc_bus->devices[addr], - &ur->request, ptr, ur->flags, &ur->actlen); + &ur->request, ptr, ur->flags, &ur->actlen); if (err) { error = EIO; goto ret; @@ -542,14 +554,14 @@ usbpoll(dev, events, p) if (minor(dev) == USB_DEV_MINOR) { revents = 0; mask = POLLIN | POLLRDNORM; - + s = splusb(); if (events & mask && usb_nevents > 0) revents |= events & mask; if (revents == 0 && events & mask) selrecord(p, &usb_selevent); splx(s); - + return (revents); } else { #if defined(__FreeBSD__) @@ -585,6 +597,7 @@ usb_discover(sc) /* The splxxx parts should be deleted when kthreads is available */ int s; #endif + /* * We need mutual exclusion while traversing the device tree, * but this is guaranteed since this function is only called @@ -659,12 +672,12 @@ usbd_add_drv_event(type, udev, dev) struct usb_event ue; ue.u.ue_driver.ue_cookie = udev->cookie; - strncpy(ue.u.ue_driver.ue_devname, USBDEVPTRNAME(dev), + strncpy(ue.u.ue_driver.ue_devname, USBDEVPTRNAME(dev), sizeof ue.u.ue_driver.ue_devname); usb_add_event(type, &ue); } -void +static void usb_add_event(type, uep) int type; struct usb_event *uep; diff --git a/sys/dev/usb/usb.h b/sys/dev/usb/usb.h index 1878d444cd8..bc6ed25cdd9 100644 --- a/sys/dev/usb/usb.h +++ b/sys/dev/usb/usb.h @@ -1,5 +1,6 @@ -/* $OpenBSD: usb.h,v 1.7 2000/03/26 08:39:46 aaron Exp $ */ -/* $NetBSD: usb.h,v 1.42 2000/03/19 22:23:28 augustss Exp $ */ +/* $OpenBSD: usb.h,v 1.8 2000/03/28 19:37:50 aaron Exp $ */ +/* $NetBSD: usb.h,v 1.43 2000/03/24 22:16:42 augustss Exp $ */ +/* $FreeBSD: src/sys/dev/usb/usb.h,v 1.14 1999/11/17 22:33:46 n_hibma Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -336,77 +337,77 @@ typedef struct { } usb_port_status_t; /* Device class codes */ -#define UDCLASS_AUDIO 0x00 -#define UDCLASS_COMM 0x02 -#define UDCLASS_HID 0x00 -#define UDCLASS_HUB 0x09 -#define UDSUBCLASS_HUB 0 -#define UDCLASS_MASS 0x00 +#define UDCLASS_AUDIO 0x00 +#define UDCLASS_COMM 0x02 +#define UDCLASS_HID 0x00 +#define UDCLASS_HUB 0x09 +#define UDSUBCLASS_HUB 0 +#define UDCLASS_MASS 0x00 /* Interface class codes */ -#define UICLASS_UNSPEC 0x00 - -#define UICLASS_AUDIO 0x01 -#define UISUBCLASS_AUDIOCONTROL 1 -#define UISUBCLASS_AUDIOSTREAM 2 -#define UISUBCLASS_MIDISTREAM 3 - -#define UICLASS_CDC 0x02 /* communication */ -#define UI_SUBCLASS_DIRECT_LINE_CONTROL_MODEL 1 -#define UI_SUBCLASS_ABSTRACT_CONTROL_MODEL 2 -#define UI_SUBCLASS_TELEPHONE_CONTROL_MODEL 3 -#define UI_SUBCLASS_MULTICHANNEL_CONTROL_MODEL 4 -#define UI_SUBCLASS_CAPI_CONTROL_MODEL 5 -#define UI_SUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL 6 -#define UI_SUBCLASS_ATM_NETWORKING_CONTROL_MODEL 7 -#define UIPROTO_CDC_AT 1 - -#define UICLASS_HID 0x03 -#define UI_SUBCLASS_BOOT 1 -#define UIPROTO_BOOT_KEYBOARD 1 - -#define UICLASS_PHYSICAL 0x05 - -#define UICLASS_PRINTER 0x07 -#define UISUBCLASS_PRINTER 1 -#define UIPROTO_PRINTER_UNI 1 -#define UIPROTO_PRINTER_BI 2 - -#define UICLASS_MASS 0x08 -#define UISUBCLASS_RBC 1 -#define UISUBCLASS_SFF8020I 2 -#define UISUBCLASS_QIC157 3 -#define UISUBCLASS_UFI 4 -#define UISUBCLASS_SFF8070I 5 -#define UISUBCLASS_SCSI 6 -#define UIPROTO_MASS_CBI_I 0 -#define UIPROTO_MASS_CBI 1 -#define UIPROTO_MASS_BULK 2 -#define UIPROTO_MASS_BULK_P 80 - -#define UICLASS_HUB 0x09 -#define UISUBCLASS_HUB 0 - -#define UICLASS_CDC_DATA 0x0a -#define UISUBCLASS_DATA 0 -#define UIPROTO_DATA_ISDNBRI 0x30 -#define UIPROTO_DATA_HDLC 0x31 -#define UIPROTO_DATA_TRANSPARENT 0x32 -#define UIPROTO_DATA_Q921M 0x50 -#define UIPROTO_DATA_Q921 0x51 -#define UIPROTO_DATA_Q921TM 0x52 -#define UIPROTO_DATA_V42BIS 0x90 -#define UIPROTO_DATA_Q931 0x91 -#define UIPROTO_DATA_V120 0x92 -#define UIPROTO_DATA_CAPI 0x93 -#define UIPROTO_DATA_HOST_BASED 0xfd -#define UIPROTO_DATA_PUF 0xfe -#define UIPROTO_DATA_VENDOR 0xff - -#define UICLASS_FIRM_UPD 0x0c - -#define UICLASS_APPL_SPEC 0xfe -#define UICLASS_VENDOR 0xff +#define UICLASS_UNSPEC 0x00 + +#define UICLASS_AUDIO 0x01 +#define UISUBCLASS_AUDIOCONTROL 1 +#define UISUBCLASS_AUDIOSTREAM 2 +#define UISUBCLASS_MIDISTREAM 3 + +#define UICLASS_CDC 0x02 /* communication */ +#define UISUBCLASS_DIRECT_LINE_CONTROL_MODEL 1 +#define UISUBCLASS_ABSTRACT_CONTROL_MODEL 2 +#define UISUBCLASS_TELEPHONE_CONTROL_MODEL 3 +#define UISUBCLASS_MULTICHANNEL_CONTROL_MODEL 4 +#define UISUBCLASS_CAPI_CONTROLMODEL 5 +#define UISUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL 6 +#define UISUBCLASS_ATM_NETWORKING_CONTROL_MODEL 7 +#define UIPROTO_CDC_AT 1 + +#define UICLASS_HID 0x03 +#define UISUBCLASS_BOOT 1 +#define UIPROTO_BOOT_KEYBOARD 1 + +#define UICLASS_PHYSICAL 0x05 + +#define UICLASS_PRINTER 0x07 +#define UISUBCLASS_PRINTER 1 +#define UIPROTO_PRINTER_UNI 1 +#define UIPROTO_PRINTER_BI 2 + +#define UICLASS_MASS 0x08 +#define UISUBCLASS_RBC 1 +#define UISUBCLASS_SFF8020I 2 +#define UISUBCLASS_QIC157 3 +#define UISUBCLASS_UFI 4 +#define UISUBCLASS_SFF8070I 5 +#define UISUBCLASS_SCSI 6 +#define UIPROTO_MASS_CBI_I 0 +#define UIPROTO_MASS_CBI 1 +#define UIPROTO_MASS_BBB 2 +#define UIPROTO_MASS_BBB_P 80 /* 'P' for the Iomega Zip drive */ + +#define UICLASS_HUB 0x09 +#define UISUBCLASS_HUB 0 + +#define UICLASS_CDC_DATA 0x0a +#define UISUBCLASS_DATA 0 +#define UIPROTO_DATA_ISDNBRI 0x30 /* Physical iface */ +#define UIPROTO_DATA_HDLC 0x31 /* HDLC */ +#define UIPROTO_DATA_TRANSPARENT 0x32 /* Transparent */ +#define UIPROTO_DATA_Q921M 0x50 /* Management for Q921 */ +#define UIPROTO_DATA_Q921 0x51 /* Data for Q921 */ +#define UIPROTO_DATA_Q921TM 0x52 /* TEI multiplexer for Q921 */ +#define UIPROTO_DATA_V42BIS 0x90 /* Data compression */ +#define UIPROTO_DATA_Q931 0x91 /* Euro-ISDN */ +#define UIPROTO_DATA_V120 0x92 /* V.24 rate adaption */ +#define UIPROTO_DATA_CAPI 0x93 /* CAPI 2.0 commands */ +#define UIPROTO_DATA_HOST_BASED 0xfd /* Host based driver */ +#define UIPROTO_DATA_PUF 0xfe /* see Prot. Unit Func. Desc.*/ +#define UIPROTO_DATA_VENDOR 0xff /* Vendor specific */ + +#define UICLASS_FIRM_UPD 0x0c + +#define UICLASS_APPL_SPEC 0xfe +#define UICLASS_VENDOR 0xff #define USB_HUB_MAX_DEPTH 5 @@ -555,8 +556,8 @@ struct usb_event { struct usb_device_info ue_device; struct { usb_event_cookie_t ue_cookie; - char ue_devname[USB_MAX_DEVNAMELEN]; - } ue_driver; + char ue_devname[16]; + } ue_driver; } u; }; diff --git a/sys/dev/usb/usb_mem.c b/sys/dev/usb/usb_mem.c index df3bdf152ed..101bef93df5 100644 --- a/sys/dev/usb/usb_mem.c +++ b/sys/dev/usb/usb_mem.c @@ -1,5 +1,5 @@ -/* $OpenBSD: usb_mem.c,v 1.7 2000/03/26 08:39:46 aaron Exp $ */ -/* $NetBSD: usb_mem.c,v 1.17 1999/12/18 22:47:11 augustss Exp $ */ +/* $OpenBSD: usb_mem.c,v 1.8 2000/03/28 19:37:50 aaron Exp $ */ +/* $NetBSD: usb_mem.c,v 1.18 2000/03/27 08:27:03 augustss Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -86,10 +86,11 @@ static usbd_status usb_block_allocmem __P((bus_dma_tag_t, size_t, size_t, usb_dma_block_t **)); static void usb_block_freemem __P((usb_dma_block_t *)); -LIST_HEAD(, usb_dma_block) usb_blk_freelist = +static LIST_HEAD(, usb_dma_block) usb_blk_freelist = LIST_HEAD_INITIALIZER(usb_blk_freelist); +int usb_blk_nfree = 0; /* XXX should have different free list for different tags (for speed) */ -LIST_HEAD(, usb_frag_dma) usb_frag_freelist = +static LIST_HEAD(, usb_frag_dma) usb_frag_freelist = LIST_HEAD_INITIALIZER(usb_frag_freelist); static usbd_status @@ -103,7 +104,7 @@ usb_block_allocmem(tag, size, align, dmap) usb_dma_block_t *p; int s; - DPRINTFN(5, ("usb_block_allocmem: size=%lu align=%lu\n", + DPRINTFN(5, ("usb_block_allocmem: size=%lu align=%lu\n", (u_long)size, (u_long)align)); #ifdef DIAGNOSTIC @@ -118,6 +119,7 @@ usb_block_allocmem(tag, size, align, dmap) for (p = LIST_FIRST(&usb_blk_freelist); p; p = LIST_NEXT(p, next)) { if (p->tag == tag && p->size >= size && p->align >= align) { LIST_REMOVE(p, next); + usb_blk_nfree--; splx(s); *dmap = p; DPRINTFN(6,("usb_block_allocmem: free list size=%lu\n", @@ -207,6 +209,7 @@ usb_block_freemem(p) DPRINTFN(6, ("usb_block_freemem: size=%lu\n", (u_long)p->size)); s = splusb(); LIST_INSERT_HEAD(&usb_blk_freelist, p, next); + usb_blk_nfree++; splx(s); } @@ -243,7 +246,7 @@ usb_allocmem(bus, size, align, p) break; if (f == NULL) { DPRINTFN(1, ("usb_allocmem: adding fragments\n")); - err = usb_block_allocmem(tag, USB_MEM_BLOCK, USB_MEM_SMALL, &b); + err = usb_block_allocmem(tag, USB_MEM_BLOCK, USB_MEM_SMALL,&b); if (err) { splx(s); return (err); diff --git a/sys/dev/usb/usb_mem.h b/sys/dev/usb/usb_mem.h index 0e48fd4082d..bf9017b9ba9 100644 --- a/sys/dev/usb/usb_mem.h +++ b/sys/dev/usb/usb_mem.h @@ -1,5 +1,6 @@ -/* $OpenBSD: usb_mem.h,v 1.5 2000/03/26 08:39:46 aaron Exp $ */ +/* $OpenBSD: usb_mem.h,v 1.6 2000/03/28 19:37:50 aaron Exp $ */ /* $NetBSD: usb_mem.h,v 1.12 2000/03/12 23:10:29 nathanw Exp $ */ +/* $FreeBSD: src/sys/dev/usb/usb_mem.h,v 1.9 1999/11/17 22:33:47 n_hibma Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. diff --git a/sys/dev/usb/usb_port.h b/sys/dev/usb/usb_port.h index 83a8f6b8024..7f81ba9e4fc 100644 --- a/sys/dev/usb/usb_port.h +++ b/sys/dev/usb/usb_port.h @@ -1,5 +1,6 @@ -/* $OpenBSD: usb_port.h,v 1.7 2000/03/26 08:39:46 aaron Exp $ */ -/* $NetBSD: usb_port.h,v 1.21 2000/02/02 07:34:00 augustss Exp $ */ +/* $OpenBSD: usb_port.h,v 1.8 2000/03/28 19:37:50 aaron Exp $ */ +/* $NetBSD: usb_port.h,v 1.23 2000/03/24 22:03:32 augustss Exp $ */ +/* $FreeBSD: src/sys/dev/usb/usb_port.h,v 1.21 1999/11/17 22:33:47 n_hibma Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -80,12 +81,14 @@ typedef struct device *device_ptr_t; u_int offs; \ } usb_dma_t -#define usb_timeout(f, d, t, h) timeout((f), (d), (t)) -#define usb_untimeout(f, d, h) untimeout((f), (d)) +typedef struct callout usb_callout_t; +#define usb_callout_init(h) callout_init(&(h)) +#define usb_callout(h, t, f, d) callout_reset(&(h), (t), (f), (d)) +#define usb_uncallout(h, f, d) callout_stop(&(h)) #define logprintf printf -#define USB_DECLARE_DRIVER_(dname) \ +#define USB_DECLARE_DRIVER(dname) \ int __CONCAT(dname,_match) __P((struct device *, struct cfdata *, void *)); \ void __CONCAT(dname,_attach) __P((struct device *, struct device *, void *)); \ int __CONCAT(dname,_detach) __P((struct device *, int)); \ @@ -171,15 +174,29 @@ __CONCAT(dname,_detach)(self, flags) \ #define KUE_DEBUG 1 #endif -typedef struct device *device_ptr_t; #define memcpy(d, s, l) bcopy((s),(d),(l)) #define memset(d, v, l) bzero((d),(l)) #define bswap32(x) swap32(x) +#define kthread_create1 kthread_create #define usbpoll usbselect #define uhidpoll uhidselect #define ugenpoll ugenselect +#define powerhook_establish(fn, sc) (fn) +#define powerhook_disestablish(hdl) +#define PWR_RESUME 0 + +#define logprintf printf + +#define swap_bytes_change_sign16_le swap_bytes_change_sign16 +#define change_sign16_swap_bytes_le change_sign16_swap_bytes +#define change_sign16_le change_sign16 + +#define realloc usb_realloc +void *usb_realloc __P((void *, u_int, int, int)); + +typedef struct device *device_ptr_t; #define USBBASEDEVICE struct device #define USBDEV(bdev) (&(bdev)) #define USBDEVNAME(bdev) ((bdev).dv_xname) @@ -194,11 +211,13 @@ typedef struct device *device_ptr_t; u_int offs; \ } usb_dma_t -#define usb_timeout(f, d, t, h) timeout((f), (d), (t)) -#define usb_untimeout(f, d, h) untimeout((f), (d)) +typedef char usb_callout_t; +#define usb_callout_init(h) +#define usb_callout(h, t, f, d) timeout((f), (d), (t)) +#define usb_uncallout(h, f, d) untimeout((f), (d)) #define USB_DECLARE_DRIVER(dname) \ -int __CONCAT(dname,_match) __P((struct device *, void *, void *)); \ +int __CONCAT(dname,_match) __P((struct device *, void *, void *)); \ void __CONCAT(dname,_attach) __P((struct device *, struct device *, void *)); \ int __CONCAT(dname,_detach) __P((struct device *, int)); \ int __CONCAT(dname,_activate) __P((struct device *, enum devact)); \ @@ -294,8 +313,10 @@ __CONCAT(dname,_detach)(self, flags) \ #define kthread_create(create_function, sc) #define kthread_exit(err) -#define usb_timeout(f, d, t, h) ((h) = timeout((f), (d), (t))) -#define usb_untimeout(f, d, h) untimeout((f), (d), (h)) +typedef struct callout_handle usb_callout_t; +#define usb_callout_init(h) callout_handle_init(&(h)) +#define usb_callout(h, t, f, d) ((h) = timeout((f), (d), (t))) +#define usb_uncallout(h, f, d) uncallout((f), (d), (h)) #define clalloc(p, s, x) (clist_alloc_cblocks((p), (s), (s)), 0) #define clfree(p) clist_free_cblocks((p)) @@ -320,13 +341,14 @@ static device_method_t __CONCAT(dname,_methods)[] = { \ }; \ \ static driver_t __CONCAT(dname,_driver) = { \ - #dname, \ + #dname, \ __CONCAT(dname,_methods), \ sizeof(struct __CONCAT(dname,_softc)) \ } #define METHODS_NONE {0,0} #define USB_DECLARE_DRIVER(dname) USB_DECLARE_DRIVER_INIT(dname, METHODS_NONE) + #define USB_MATCH(dname) \ static int \ __CONCAT(dname,_match)(device_t self) diff --git a/sys/dev/usb/usb_quirks.c b/sys/dev/usb/usb_quirks.c index d607943fc90..7df8df233bd 100644 --- a/sys/dev/usb/usb_quirks.c +++ b/sys/dev/usb/usb_quirks.c @@ -1,5 +1,6 @@ -/* $OpenBSD: usb_quirks.c,v 1.3 2000/03/26 08:39:46 aaron Exp $ */ -/* $NetBSD: usb_quirks.c,v 1.22 2000/03/16 21:51:24 augustss Exp $ */ +/* $OpenBSD: usb_quirks.c,v 1.4 2000/03/28 19:37:50 aaron Exp $ */ +/* $NetBSD: usb_quirks.c,v 1.23 2000/03/25 17:30:00 augustss Exp $ */ +/* $FreeBSD: src/sys/dev/usb/usb_quirks.c,v 1.13 1999/11/17 22:33:47 n_hibma Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -50,7 +51,7 @@ extern int usbdebug; #endif -struct usbd_quirk_entry { +static struct usbd_quirk_entry { u_int16_t idVendor; u_int16_t idProduct; u_int16_t bcdDevice; @@ -62,10 +63,11 @@ struct usbd_quirk_entry { { USB_VENDOR_BTC, USB_PRODUCT_BTC_BTC7932, 0x100, { UQ_NO_STRINGS }}, { USB_VENDOR_ADS, USB_PRODUCT_ADS_UBS10BT, 0x002, { UQ_NO_STRINGS }}, { USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_SERIAL1, 0x101, { UQ_NO_STRINGS }}, + { USB_VENDOR_WACOM, USB_PRODUCT_WACOM_CT0405U, 0x101, { UQ_NO_STRINGS }}, { USB_VENDOR_DALLAS, USB_PRODUCT_DALLAS_J6502, 0x0a2, { UQ_BAD_ADC }}, - { USB_VENDOR_ALTEC, USB_PRODUCT_ALTEC_ADA70, 0x103, { UQ_BAD_ADC }}, + { USB_VENDOR_ALTEC, USB_PRODUCT_ALTEC_ADA70, 0x103, { UQ_BAD_ADC }}, { USB_VENDOR_ALTEC, USB_PRODUCT_ALTEC_ASC495, 0x000, { UQ_BAD_AUDIO }}, - { USB_VENDOR_QTRONIX, USB_PRODUCT_QTRONIX_980N, 0x110, {UQ_SPUR_BUT_UP}}, + { USB_VENDOR_QTRONIX, USB_PRODUCT_QTRONIX_980N, 0x110, { UQ_SPUR_BUT_UP }}, { 0, 0, 0, { 0 } } }; diff --git a/sys/dev/usb/usb_quirks.h b/sys/dev/usb/usb_quirks.h index 816791f8302..6ee1e4a826f 100644 --- a/sys/dev/usb/usb_quirks.h +++ b/sys/dev/usb/usb_quirks.h @@ -1,5 +1,6 @@ -/* $OpenBSD: usb_quirks.h,v 1.3 2000/03/26 08:39:46 aaron Exp $ */ +/* $OpenBSD: usb_quirks.h,v 1.4 2000/03/28 19:37:51 aaron Exp $ */ /* $NetBSD: usb_quirks.h,v 1.10 1999/11/18 23:32:31 augustss Exp $ */ +/* $FreeBSD: src/sys/dev/usb/usb_quirks.h,v 1.9 1999/11/12 23:31:03 n_hibma Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. diff --git a/sys/dev/usb/usb_subr.c b/sys/dev/usb/usb_subr.c index 1a4cd5af419..a3e10986a3e 100644 --- a/sys/dev/usb/usb_subr.c +++ b/sys/dev/usb/usb_subr.c @@ -1,5 +1,6 @@ -/* $OpenBSD: usb_subr.c,v 1.7 2000/03/26 08:39:46 aaron Exp $ */ -/* $NetBSD: usb_subr.c,v 1.67 2000/03/13 23:52:37 soren Exp $ */ +/* $OpenBSD: usb_subr.c,v 1.8 2000/03/28 19:37:51 aaron Exp $ */ +/* $NetBSD: usb_subr.c,v 1.68 2000/03/25 18:02:33 augustss Exp $ */ +/* $FreeBSD: src/sys/dev/usb/usb_subr.c,v 1.18 1999/11/17 22:33:47 n_hibma Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -76,17 +77,18 @@ extern int usbdebug; #endif static usbd_status usbd_set_config __P((usbd_device_handle, int)); -char *usbd_get_string __P((usbd_device_handle, int, char *)); -int usbd_getnewaddr __P((usbd_bus_handle bus)); -int usbd_print __P((void *aux, const char *pnp)); +static char *usbd_get_string __P((usbd_device_handle, int, char *)); +static int usbd_getnewaddr __P((usbd_bus_handle bus)); #if defined(__NetBSD__) -int usbd_submatch __P((device_ptr_t, struct cfdata *cf, void *)); +static int usbd_print __P((void *aux, const char *pnp)); +static int usbd_submatch __P((device_ptr_t, struct cfdata *cf, void *)); #elif defined(__OpenBSD__) -int usbd_submatch __P((device_ptr_t, void *, void *)); +static int usbd_print __P((void *aux, const char *pnp)); +static int usbd_submatch __P((device_ptr_t, void *, void *)); #endif -void usbd_free_iface_data __P((usbd_device_handle dev, int ifcno)); -void usbd_kill_pipe __P((usbd_pipe_handle)); -usbd_status usbd_probe_and_attach +static void usbd_free_iface_data __P((usbd_device_handle dev, int ifcno)); +static void usbd_kill_pipe __P((usbd_pipe_handle)); +static usbd_status usbd_probe_and_attach __P((device_ptr_t parent, usbd_device_handle dev, int port, int addr)); static u_int32_t usb_cookie_no = 0; @@ -109,7 +111,7 @@ struct usb_knowndev { #include #endif /* USBVERBOSE */ -const char *usbd_error_strs[] = { +static const char *usbd_error_strs[] = { "NORMAL_COMPLETION", "IN_PROGRESS", "PENDING_REQUESTS", @@ -141,11 +143,7 @@ usbd_errstr(err) if (err < USBD_ERROR_MAX) { return usbd_error_strs[err]; } else { -#if !defined(__OpenBSD__) snprintf(buffer, sizeof buffer, "%d", err); -#else - sprintf(buffer, "%d", err); -#endif return buffer; } } @@ -248,10 +246,10 @@ usbd_devinfo_vp(dev, v, p) } if (kdp->vendorname != NULL) { if (!vendor) - vendor = kdp->vendorname; + vendor = kdp->vendorname; if (!product) - product = (kdp->flags & USB_KNOWNDEV_NOPROD) == 0 ? - kdp->productname : NULL; + product = (kdp->flags & USB_KNOWNDEV_NOPROD) == 0 ? + kdp->productname : NULL; } } #endif @@ -361,7 +359,8 @@ usbd_reset_port(dev, port, ps) err = usbd_clear_port_feature(dev, port, UHF_C_PORT_RESET); #ifdef USB_DEBUG if (err) - DPRINTF(("usbd_reset_port: clear port feature failed %d\n",r)); + DPRINTF(("usbd_reset_port: clear port feature failed %d\n", + err)); #endif /* Wait for the device to recover from reset. */ @@ -701,6 +700,7 @@ usbd_setup_pipe(dev, iface, ep, ival, pipe) p->repeat = 0; p->interval = ival; SIMPLEQ_INIT(&p->queue); + usb_callout_init(p->abort_handle); err = dev->bus->methods->open_pipe(p); if (err) { DPRINTFN(-1,("usbd_setup_pipe: endpoint=0x%x failed, error=" @@ -782,7 +782,7 @@ usbd_probe_and_attach(parent, dev, port, addr) /* First try with device specific drivers. */ DPRINTF(("usbd_probe_and_attach: trying device specific drivers\n")); dv = USB_DO_ATTACH(dev, bdev, parent, &uaa, usbd_print, usbd_submatch); - if (dv != NULL) { + if (dv) { dev->subdevs = malloc(2 * sizeof dv, M_USB, M_NOWAIT); if (dev->subdevs == NULL) return (USBD_NOMEM); @@ -831,13 +831,13 @@ usbd_probe_and_attach(parent, dev, port, addr) found = 0; for (i = 0; i < nifaces; i++) { - if (!ifaces[i]) + if (ifaces[i] == NULL) continue; /* interface already claimed */ uaa.iface = ifaces[i]; uaa.ifaceno = ifaces[i]->idesc->bInterfaceNumber; dv = USB_DO_ATTACH(dev, bdev, parent, &uaa, usbd_print, usbd_submatch); - if (dv) { + if (dv != NULL) { dev->subdevs[found++] = dv; dev->subdevs[found] = 0; ifaces[i] = 0; /* consumed */ @@ -880,7 +880,7 @@ usbd_probe_and_attach(parent, dev, port, addr) uaa.product = UHUB_UNK_PRODUCT; uaa.release = UHUB_UNK_RELEASE; dv = USB_DO_ATTACH(dev, bdev, parent, &uaa, usbd_print, usbd_submatch); - if (dv) { + if (dv != NULL) { dev->subdevs = malloc(2 * sizeof dv, M_USB, M_NOWAIT); if (dev->subdevs == 0) return (USBD_NOMEM); @@ -925,7 +925,6 @@ usbd_new_device(parent, bus, depth, lowspeed, port, up) DPRINTF(("usbd_new_device bus=%p depth=%d lowspeed=%d\n", bus, depth, lowspeed)); - addr = usbd_getnewaddr(bus); if (addr < 0) { printf("%s: No free USB addresses, new device ignored.\n", @@ -1007,7 +1006,6 @@ usbd_new_device(parent, bus, depth, lowspeed, port, up) USETW(dev->def_ep_desc.wMaxPacketSize, dd->bMaxPacketSize); - /* Get the full device descriptor. */ err = usbd_reload_device_desc(dev); if (err) { DPRINTFN(-1, ("usbd_new_device: addr=%d, getting full desc " @@ -1037,7 +1035,7 @@ usbd_new_device(parent, bus, depth, lowspeed, port, up) DPRINTF(("usbd_new_device: new dev (addr %d), dev=%p, parent=%p\n", addr, dev, parent)); - + usbd_add_dev_event(USB_EVENT_DEVICE_ATTACH, dev); err = usbd_probe_and_attach(parent, dev, port, addr); @@ -1186,16 +1184,17 @@ usbd_fill_deviceinfo(dev, di) di->lowspeed = dev->lowspeed; if (dev->subdevs != NULL) { - for (i = 0; dev->subdevs[i] && i < USB_MAX_DEVNAMES; i++) { + for (i = 0; dev->subdevs[i] && + i < USB_MAX_DEVNAMES; i++) { strncpy(di->devnames[i], USBDEVPTRNAME(dev->subdevs[i]), USB_MAX_DEVNAMELEN); di->devnames[i][USB_MAX_DEVNAMELEN-1] = '\0'; - } - } else { - i = 0; - } - for (/* i is set */; i < USB_MAX_DEVNAMES; i++) - di->devnames[i][0] = 0; /* empty */ + } + } else { + i = 0; + } + for (/*i is set */; i < USB_MAX_DEVNAMES; i++) + di->devnames[i][0] = 0; /* empty */ if (dev->hub) { for (i = 0; @@ -1291,7 +1290,7 @@ usb_disconnect_port(up, parent) #if defined(__NetBSD__) || defined(__OpenBSD__) config_detach(dev->subdevs[i], DETACH_FORCE); #elif defined(__FreeBSD__) - device_delete_child(device_get_parent(dev->subdevs[i]), + device_delete_child(device_get_parent(dev->subdevs[i]), dev->subdevs[i]); #endif @@ -1304,3 +1303,20 @@ usb_disconnect_port(up, parent) usb_free_device(dev); } +#ifdef __OpenBSD__ +void *usb_realloc(p, size, pool, flags) + void *p; + u_int size; + int pool; + int flags; +{ + void *q; + + q = malloc(size, pool, flags); + if (q == NULL) + return (NULL); + bcopy(p, q, size); + free(p, pool); + return (q); +} +#endif diff --git a/sys/dev/usb/usbcdc.h b/sys/dev/usb/usbcdc.h index 993d6f726a5..a370d642cfe 100644 --- a/sys/dev/usb/usbcdc.h +++ b/sys/dev/usb/usbcdc.h @@ -1,5 +1,6 @@ -/* $OpenBSD: usbcdc.h,v 1.1 1999/08/19 08:18:39 fgsch Exp $ */ -/* $NetBSD: usbcdc.h,v 1.4 1999/08/16 20:20:19 augustss Exp $ */ +/* $OpenBSD: usbcdc.h,v 1.2 2000/03/28 19:37:51 aaron Exp $ */ +/* $NetBSD: usbcdc.h,v 1.5 1999/11/18 23:32:32 augustss Exp $ */ +/* $FreeBSD: src/sys/dev/usb/usbcdc.h,v 1.7 1999/11/17 22:33:48 n_hibma Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs index 12830b4e011..0a3eaba658d 100644 --- a/sys/dev/usb/usbdevs +++ b/sys/dev/usb/usbdevs @@ -1,5 +1,5 @@ - $OpenBSD: usbdevs,v 1.14 2000/03/26 19:29:17 aaron Exp $ -/* $NetBSD: usbdevs,v 1.56 1999/10/28 06:41:13 augustss Exp $ */ +$OpenBSD: usbdevs,v 1.15 2000/03/28 19:37:51 aaron Exp $ +/* $NetBSD: usbdevs,v 1.87 2000/03/26 15:08:02 augustss Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -44,15 +44,17 @@ vendor AOX 0x03e8 Aox Inc. vendor HP 0x03f0 Hewlett Packard +vendor FUTURE 0x0403 Future Technology Devices vendor NEC 0x0409 NEC vendor KODAK 0x040a Eastman Kodak Corp. vendor MELCO 0x0411 Melco Inc. vendor CATC 0x0423 Computer Access Technology Corp. vendor GRAVIS 0x0428 Advanced Gravis Computer Tech. Ltd. +vendor SUN 0x0430 Sun Microsystems vendor LEXMARK 0x043d Lexmark International Inc. vendor NANAO 0x0440 NANAO Corp. vendor THRUST 0x044f Thrustmaster -vendor TI 0x0451 Texas Instruments +vendor TI 0x0451 Texas Instruments vendor KYE 0x0458 KYE Systems Corp. vendor MICROSOFT 0x045e Microsoft vendor PRIMAX 0x0461 Primax Electronics @@ -61,22 +63,26 @@ vendor LOGITECH 0x046d Logitech Inc. vendor BTC 0x046e Behavior Tech. Computer vendor PHILIPS 0x0471 Philips vendor CONNECTIX 0x0478 Connectix Corp. +vendor KENSINGTON 0x047d Kensington vendor LUCENT 0x047e Lucent vendor STMICRO 0x0483 STMicroelectronics vendor ACER 0x04a5 Acer Peripheral Inc. vendor CANON 0x04a9 Canon Inc. vendor CYPRESS 0x04b4 Cypress Semiconductor vendor EPSON 0x04b8 Seiko Epson Corp. -vendor 3COM 0x04c1 U.S. Robotics +vendor IODATA 0x04bb I/O DATA +vendor 3COMUSR 0x04c1 U.S. Robotics vendor KONICA 0x04c8 Konica Corp. vendor ALTEC 0x04d2 Altec Lansing vendor SHUTTLE 0x04e6 Shuttle Technology vendor CHICONY 0x04f2 Chicony Electronics Co., Ltd. vendor BROTHER 0x04f9 Brother Industries Corp. vendor DALLAS 0x04fa Dallas Semiconductor +vendor 3COM 0x0506 3Com Corp. vendor BELKIN 0x050d Belkin Components vendor KAWATSU 0x050f Kawatsu Semiconductor, Inc. vendor APC 0x051d American Power Conversion +vendor NETCHIP 0x0525 NetChip Technology vendor AKS 0x0529 Fast Security AG vendor UNIACCESS 0x0540 Universal Access vendor ANCHOR 0x0547 Anchor Chips Inc. @@ -89,27 +95,36 @@ vendor WACOM 0x056a WACOM Corp. Ltd. vendor ETEK 0x056c e-TEK Labs vendor EIZO 0x056d EIZO vendor ELECOM 0x056e Elecom Corp. Ltd. +vendor YEDATA 0x057b Y-E Data +vendor QUICKSHOT 0x057f Quickshot vendor ROCKFIRE 0x0583 Rockfire vendor IOMEGA 0x059b Iomega Corp. vendor OMNIVISION 0x05a9 OmniVision vendor INSYSTEM 0x05ab In-System Design vendor APPLE 0x05ac Apple Computer +vendor DIGI 0x05c5 Digi International vendor QTRONIX 0x05c7 Qtronix Corp vendor ELSA 0x05cc ELSA Gmbh vendor EIZONANAO 0x05e7 EIZO Nanao vendor KLSI 0x05e9 Kawasaki LSI -vendor PIENGINEERING 0x05f3 P.I. Engineering +vendor PIENGINEERING 0x05f3 P.I. Engineering vendor CHIC 0x05fe Chic Technology +vendor SOLIDYEAR 0x060b Solid Year vendor MACALLY 0x0618 Macally vendor LINKSYS 0x066b Linksys Inc. vendor MULTITECH 0x06e0 MultiTech vendor ADS 0x06e1 ADS Technologies +vendor SIRIUS 0x06ea Sirius Technologies vendor SMC 0x0707 Standard Microsystems Corp vendor MIDIMAN 0x0763 Midiman vendor SANDISK 0x0781 SanDisk Corp +vendor ADMTEK 0x07a6 ADMtek Inc. vendor COREGA 0x07aa Corega vendor SIIG 0x07cc SIIG +vendor ZOOM 0x0803 Zoom Telephonics Inc. vendor HANDSPRING 0x082d Handspring Inc. +vendor PALM 0x0830 Palm Computing, Inc. +vendor DIAMOND 0x0841 Diamond vendor NETGEAR 0x0846 BayNETGEAR Inc. vendor ACTIVEWIRE 0x0854 ActiveWire Inc. vendor BILLIONTON 0x08dd Billionton Systems Inc. @@ -124,261 +139,346 @@ vendor INTEL 0x8086 Intel * List of known products. Grouped by vendor. */ -/* AOX products */ -product AOX USB101 0x0008 USB ethernet controller engine - -/* HP products */ -product HP 4100C 0x0101 Scanjet 4100C -product HP 6300C 0x0601 Scanjet 6300C - -/* NEC products */ -product NEC HUB 0x55aa hub -product NEC HUB_B 0x55ab hub - -/* Kodak products */ -product KODAK DC260 0x0110 Digital Science DC260 -product KODAK DC240 0x0120 Digital Science DC240 -product KODAK DC280 0x0130 Digital Science DC280 +/* 3Com products */ +product 3COM HOMECONN 0x009d HomeConnect USB Camera +product 3COM 3C19250 0x03E8 3C19250 Ethernet adapter +product 3COM USR56K 0x3021 U.S.Robotics 56000 Voice Faxmodem Pro +product 3COM 3C460 0x11f8 HomeConnect Ethernet USB Adapter -/* Melco Inc products */ -product MELCO LUATX 0x0001 LUA-TX Ethernet +product 3COMUSR OFFICECONN 0x0082 3Com OfficeConnect Analog Modem +product 3COMUSR USRISDN 0x008f 3Com U.S. Robotics Pro ISDN TA +product 3COMUSR HOMECONN 0x009d 3Com HomeConnect camera +product 3COMUSR USR56K 0x3021 U.S.Robotics 56000 Voice Faxmodem Pro -/* CATC products */ -product CATC CHIEF 0x000d USB Chief Bus & Protocol Analyzer -product CATC ANDROMEDA 0x1237 Andromeda hub +/* Acer products */ +product ACER ACERSCAN_C310U 0x12a6 Acerscan C310U -/* Gravis products */ -product GRAVIS GAMEPADPRO 0x4001 GamePad Pro +/* ActiveWire Inc. products */ +product ACTIVEWIRE IOBOARD 0x0100 I/O Board +product ACTIVEWIRE IOBOARD_FW1 0x0101 I/O Board, rev. 1 firmware -/* Lexmark products */ -product LEXMARK S2450 0x0009 Optra S 2450 +/* ADMtek products */ +product ADMTEK PEGASUS 0x0986 AN986 USB Ethernet adapter -/* Thrustmaster products */ -product THRUST FUSION_PAD 0xa0a3 Fusion Digital Gamepad +/* ADS products */ +product ADS UBS10BT 0x0008 UBS-10BT Ethernet adapter -/* Texas Intel products */ -product TI UTUSB41 0x1446 UT-USB41 hub +/* Agiler products */ +product ELECOM MOUSE29UO 0x0002 mouse 29UO -/* (KYE) Genius products */ -product KYE NICHE 0x0001 Niche mouse -product KYE FLIGHT2000 0x1004 Flight 2000 joystick +/* AKS products */ +product AKS USBHASP 0x0001 USB-HASP 0.06 -/* Microsoft products */ -product MICROSOFT INTELLIMOUSE 0x0009 IntelliMouse -product MICROSOFT NATURALKBD 0x000b Natural Keyboard Elite -product MICROSOFT DDS80 0x0014 Digital Sound System 80 +/* Altec Lansing products */ +product ALTEC ADA70 0x0070 ADA70 Speakers +product ALTEC ASC495 0xff05 ASC495 Speakers -/* Primax products */ -product PRIMAX COMFORT 0x4d01 Comfort -product PRIMAX MOUSEINABOX 0x4d02 Mouse-in-a-Box +/* American Power Conversion products */ +product APC UPSPRO500 0x0002 Back-UPS Pro 500 -/* Cherry products */ -product CHERRY MY3000KBD 0x0001 My3000 keyboard -product CHERRY MY3000HUB 0x0003 My3000 hub +/* Anchor products */ +product ANCHOR EZUSB 0x2131 EZUSB -/* Behavior Technology Computer products */ -product BTC BTC7932 0x6782 Keyboard with mouse port +/* AOX Inc. products */ +product AOX USB101 0x0008 USB ethernet controller engine -/* Philips products */ -product PHILIPS DSS350 0x0101 DSS 350 Digital Speaker System -product PHILIPS DSS 0x0104 DSS XXX Digital Speaker System -product PHILIPS HUB 0x0201 hub -product PHILIPS DSS150 0x0471 DSS XXX Digital Speaker System +/* ATen products */ +product ATEN UC1284 0x2001 Parallel printer adapter +product ATEN UC10T 0x2002 10Mbps ethernet adapter -/* Connectix products */ -product CONNECTIX QUICKCAM 0x0001 QuickCam +/* Belkin products */ +/*product BELKIN F5U111 0x???? F5U111 Ethernet adapter*/ -/* Lucent products */ -product LUCENT EVALKIT 0x1001 USS-720 evaluation kit +/* Billionton products */ +product BILLIONTON USB100 0x0986 USB100N 10/100 FastEthernet Adapter -/* STMicroelectronics products */ -product STMICRO COMMUNICATOR 0x7554 USB Communicator +/* Brother Industries products */ +product BROTHER HL1050 0x0002 HL-1050 laser printer -/* Acer products */ -product ACER ACERSCAN_C310U 0x12a6 Acerscan C310U +/* Behavior Technology Computer products */ +product BTC BTC7932 0x6782 Keyboard with mouse port /* Canon Inc. products */ product CANON S10 0x3041 PowerShot S10 -/* Cypress Semiconductor products */ -product CYPRESS MOUSE 0x0001 mouse -product CYPRESS THERMO 0x0002 thermometer +/* CATC products */ +product CATC NETMATE 0x000a Netmate ethernet adapter +product CATC NETMATE2 0x000c Netmate2 ethernet adapter +product CATC CHIEF 0x000d USB Chief Bus & Protocol Analyzer +product CATC ANDROMEDA 0x1237 Andromeda hub -/* Epson products */ -product EPSON PRINTER3 0x0003 ISD USB Smart Cable +/* Cherry products */ +product CHERRY MY3000KBD 0x0001 My3000 keyboard +product CHERRY MY3000HUB 0x0003 My3000 hub -/* 3Com products */ -product 3COM HOMECONN 0x009d HomeConnect USB Camera -product 3COM 3C19250 0x03e8 3C19250 Ethernet adapter -product 3COM 3C460 0x11f8 HomeConnect Ethernet USB Adapter -product 3COM USR56K 0x3021 U.S.Robotics 56000 Voice Faxmodem Pro +/* Chic Technology products */ +product CHIC MOUSE1 0x0001 mouse +product CHIC CYPRESS 0x0003 Cypress USB Mouse -/* Konica Corp. Products */ -product KONICA CAMERA 0x0720 Digital Color Camera +/* Chicony products */ +product CHICONY KB8933 0x0001 KB-8933 keyboard -/* Altec Lansing products */ -product ALTEC ADA70 0x0070 ADA70 Speakers -product ALTEC ASC495 0xff05 ASC495 Speakers +/* Connectix products */ +product CONNECTIX QUICKCAM 0x0001 QuickCam -/* Shuttle Technology products */ -product SHUTTLE EUSB 0x0001 E-USB Bridge +/* Corega products */ +product COREGA ETHER_USB_T 0x0001 Ether USB-T +product COREGA FETHER_USB_TX 0x0004 FEther USB-TX -/* Chicony products */ -product CHICONY KB8933 0x0001 KB-8933 keyboard +/* Cypress Semiconductor products */ +product CYPRESS MOUSE 0x0001 mouse +product CYPRESS THERMO 0x0002 thermometer -/* Brother Industries products */ -product BROTHER HL1050 0x0002 HL-1050 laser printer +/* D-Link products */ +/*product DLINK DSBS25 0x0100 DSB-S25 serial adapter*/ +product DLINK DSB650C 0x4000 10Mbps ethernet adapter +product DLINK DSB650TX 0x4002 10/100 ethernet adapter +product DLINK DSB650TX_PNA 0x4003 1/10/100 ethernet adapter /* Dallas Semiconductor products */ product DALLAS J6502 0x4201 J-6502 speakers -/* Kawatsu products */ -product KAWATSU MH4000P 0x0003 MiniHub 4000P +/* Diamond products */ +product DIAMOND RIO500USB 0x0001 Rio 500 USB -/* American Power Conversion products */ -product APC UPSPRO500 0x0002 Back-UPS Pro 500 +/* Digi International products */ +product DIGI ACCELEPORT2 0x0002 AccelePort USB 2 +product DIGI ACCELEPORT4 0x0004 AccelePort USB 4 +product DIGI ACCELEPORT8 0x0008 AccelePort USB 8 -/* AKS products */ -product AKS USBHASP 0x0001 USB-HASP 0.06 +/* EIZO products */ +product EIZO HUB 0x0000 hub +product EIZO MONITOR 0x0001 monitor -/* Universal Access products */ -product UNIACCESS PANACHE 0x0101 Panache Surf USB ISDN Adapter +/* Elsa products */ +product ELSA MODEM1 0x2265 ELSA Modem Board -/* Anchor products */ -product ANCHOR EZUSB 0x2131 EZUSB +/* Entrega products */ +product ENTREGA 1S 0x0001 1S serial connector +product ENTREGA 2S 0x0002 2S serial connector +product ENTREGA 1S25 0x0003 1S25 serial connector +product ENTREGA 4S 0x0004 4S serial connector +product ENTREGA E45 0x0005 E45 Ethernet adapter +product ENTREGA CENTRONICS 0x0006 Centronics connector +product ENTREGA 1S9 0x0093 1S9 serial connector +product ENTREGA EZUSB 0x8000 EZ-USB +/*product ENTREGA SERIAL 0x8001 DB25 Serial connector*/ +/*product ENTREGA SERIAL_DB9 0x8093 DB9 Serial connector*/ -/* Vision products */ -product VISION VC6452V002 0x0002 VC6452V002 Camera +/* e-TEK Labs products */ +product ETEK 1COM 0x8007 Serial port -/* ATen products */ -product ATEN UC1284 0x2001 Parallel printer adapter -product ATEN UC10T 0x2002 Ethernet adapter +/* Epson products */ +product EPSON PRINTER2 0x0002 ISD USB Smart Cable for Mac +product EPSON PRINTER3 0x0003 ISD USB Smart Cable -/* Mustek products */ -product MUSTEK MDC800 0xa800 MDC-800 digital camera +/* Gravis products */ +product GRAVIS GAMEPADPRO 0x4001 GamePad Pro -/* Telex Communications products */ -product TELEX MIC1 0x0001 Enhanced USB Microphone +/* Future Technology Devices products */ +product FUTURE SERIAL 0x8372 Serial converter -/* Peracom products */ -product PERACOM SERIAL1 0x0001 Serial Converter -product PERACOM ENET 0x0002 Ethernet adapter -product PERACOM ENET2 0x0005 Ethernet adapter +/* Handspring Inc. */ +product HANDSPRING VISOR 0x0100 Handspring Visor -/* Wacom products */ -product WACOM CT0405U 0x0000 CT-0405-U Tablet +/* HP products */ +product HP 4100C 0x0101 Scanjet 4100C +product HP S20 0x0102 Photosmart S20 +product HP 4200C 0x0105 ScanJet 4200C +product HP 6200C 0x0201 ScanJet 6200C +product HP S20b 0x0202 PhotoSmart S20 +product HP 3300C 0x0205 ScanJet 3300C +product HP 5200 0x0401 Scanjet 5200 +product HP 6300C 0x0601 Scanjet 6300C +product HP 970CSE 0x1004 Deskjet 970Cse +product HP P1100 0x3102 Photosmart P1100 -/* e-TEK Labs products */ -product ETEK 1COM 0x8007 Serial port +/* Inside Out Networks products */ +product INSIDEOUT EDGEPORT4 0x0001 EdgePort/4 serial ports -/* EIZO products */ -product EIZO HUB 0x0000 hub -product EIZO MONITOR 0x0001 monitor +/* In-System products */ +product INSYSTEM F5U002 0x0002 Parallel printer adapter +product INSYSTEM ISD110 0x0200 IDE adapter -/* Agiler products */ -product ELECOM MOUSE29UO 0x0002 mouse 29UO +/* Intel products */ +product INTEL TESTBOARD 0x9890 82930 test board -/* Rockfire products */ -product ROCKFIRE GAMEPAD 0x2033 gamepad 203USB +/* I/O DATA products */ +product IODATA USBETTX 0x0904 /* Iomega products */ product IOMEGA ZIP100 0x0001 Zip 100 -/* OmniVision Technologies Inc. products */ -product OMNIVISION OV511 0x0511 OV511 Camera +/* Kawasaki products */ +product KLSI DUH3E10BT 0x0008 USB ethernet controller engine -/* In-System products */ -product INSYSTEM F5U002 0x0002 Parallel printer adapter -product INSYSTEM ISD110 0x0200 IDE adapter +/* Kawatsu products */ +product KAWATSU MH4000P 0x0003 MiniHub 4000P -/* Qtronix products */ -product QTRONIX 980N 0x2011 Scorpion-980N keyboard +/* Kensington products */ +product KENSINGTON ORBIT 0x1003 Orbit USB/PS2 trackball +product KENSINGTON TURBOBALL 0x1005 TurboBall -/* Elsa products */ -product ELSA MODEM1 0x2265 ELSA Modem Board +/* Kodak products */ +product KODAK DC220 0x0100 Digital Science DC220 +product KODAK DC260 0x0110 Digital Science DC260 +product KODAK DC265 0x0111 Digital Science DC265 +product KODAK DC290 0x0112 Digital Science DC290 +product KODAK DC240 0x0120 Digital Science DC240 +product KODAK DC280 0x0130 Digital Science DC280 + +/* Konica Corp. Products */ +product KONICA CAMERA 0x0720 Digital Color Camera + +/* KYE products */ +product KYE NICHE 0x0001 Niche mouse +product KYE NETSCROLL 0x0003 Genius NetScroll mouse +product KYE FLIGHT2000 0x1004 Flight 2000 joystick + +/* Lexmark products */ +product LEXMARK S2450 0x0009 Optra S 2450 + +/* Linksys products */ +product LINKSYS USB10T 0x2202 USB10T Ethernet +product LINKSYS USB100TX 0x2203 USB100TX Ethernet /* Logitech products */ product LOGITECH M2452 0x0203 M2452 keyboard product LOGITECH M4848 0x0301 M4848 mouse product LOGITECH QUICKCAM 0x0801 QuickCam product LOGITECH QUICKCAMPRO 0x0810 QuickCam Pro +product LOGITECH N43 0xc000 N43 product LOGITECH N48 0xc001 N48 mouse product LOGITECH MBA47 0xc002 M-BA47 mouse +product LOGITECH WMMOUSE 0xc004 WingMan Gaming Mouse +product LOGITECH WMPAD 0xc208 WingMan GamePad Extreme +product LOGITECH WMJOY 0xc281 WingMan Force joystick -/* Kawasaki products */ -product KLSI USB101 0x0008 USB ethernet controller engine - -/* P.I. Engineering products */ -product PIENGINEERING PS2USB 0x020b PS2 to Mac USB Adapter - -/* Chic Technology products */ -product CHIC MOUSE1 0x0001 mouse +/* Lucent products */ +product LUCENT EVALKIT 0x1001 USS-720 evaluation kit /* Macally products */ product MACALLY MOUSE1 0x0101 mouse -/* Linksys products */ -product LINKSYS USB10T 0x2202 USB10T Ethernet -product LINKSYS USB100TX 0x2203 USB100TX Ethernet +/* Melco Inc products */ +product MELCO LUATX 0x0001 LU-ATX Ethernet + +/* Microsoft products */ +product MICROSOFT SIDEPREC 0x0008 SideWinder Precision Pro +product MICROSOFT INTELLIMOUSE 0x0009 IntelliMouse +product MICROSOFT NATURALKBD 0x000b Natural Keyboard Elite +product MICROSOFT DDS80 0x0014 Digital Sound System 80 +product MICROSOFT SIDEWINDER 0x001a Sidewinder Precision Racing Wheel +product MICROSOFT INTELLIEYE 0x0025 IntelliEye mouse +product MICROSOFT INETPRO 0x002b Internet Keyboard Pro + +/* Midiman products */ +product MIDIMAN MIDISPORT2X2 0x1001 Midisport 2x2 + +/* Motorola products */ +product MOTOROLA MC141555 0x1555 MC141555 hub controller /* MultiTech products */ product MULTITECH ATLAS 0xf101 MT5634ZBA-USB modem -/* ADS products */ -product ADS UBS10BT 0x0008 Ethernet adapter +/* Mustek products */ +product MUSTEK MDC800 0xa800 MDC-800 digital camera -/* SMC products */ -product SMC 2102USB 0x0100 10Mbps ethernet adapter -product SMC 2202USB 0x0200 10/100 ethernet adapter +/* NEC products */ +product NEC HUB 0x55aa hub +product NEC HUB_B 0x55ab hub -/* Entrega products */ -product ENTREGA 1S 0x0001 1S serial connector -product ENTREGA 2S 0x0002 2S serial connector -product ENTREGA 1S25 0x0003 1S25 serial connector -product ENTREGA 4S 0x0004 4S serial connector -product ENTREGA E45 0x0005 E45 Ethernet adapter -product ENTREGA CENTRONICS 0x0006 Centronics connector -product ENTREGA 1S9 0x0093 1S9 serial connector -product ENTREGA EZUSB 0x8000 EZ-USB -/*product ENTREGA SERIAL 0x8001 DB25 Serial connector*/ -/*product ENTREGA SERIAL_DB9 0x8093 DB9 Serial connector*/ +/* NetChip Technology Products */ +product NETCHIP TURBOCONNECT 0x1080 Turbo-Connect -/* D-Link products */ -product DLINK DSB650C 0x4000 10Mbps ethernet adapter +/* Netgear products */ +product NETGEAR EA101 0x1001 Ethernet adapter -/* Midiman products */ -product MIDIMAN MIDISPORT2X2 0x1001 Midisport 2x2 +/* OmniVision Technologies Inc. products */ +product OMNIVISION OV511 0x0511 OV511 Camera + +/* Palm Computing, Inc. */ +product PALM SERIAL 0x0080 USB Serial Adaptor + +/* Peracom products */ +product PERACOM SERIAL1 0x0001 Serial Converter +product PERACOM ENET 0x0002 Ethernet adapter +product PERACOM ENET2 0x0005 Ethernet adapter + +/* Philips products */ +product PHILIPS DSS350 0x0101 DSS 350 Digital Speaker System +product PHILIPS DSS 0x0104 DSS XXX Digital Speaker System +product PHILIPS HUB 0x0201 hub +product PHILIPS DSS150 0x0471 DSS 150 Digital Speaker System + +/* P.I. Engineering products */ +product PIENGINEERING PS2USB 0x020b PS2 to Mac USB Adapter + +/* PLX products */ +product PLX TESTBOARD 0x9060 test board + +/* Primax products */ +product PRIMAX COMFORT 0x4d01 Comfort +product PRIMAX MOUSEINABOX 0x4d02 Mouse-in-a-Box +product PRIMAX PCGAUMS1 0x4d04 Sony PCGA-UMS1 + +/* Quickshot products */ +product QUICKSHOT STRIKEPAD 0x6238 USB StrikePad + +/* Rockfire products */ +product ROCKFIRE GAMEPAD 0x2033 gamepad 203USB + +/* Qtronix products */ +product QTRONIX 980N 0x2011 Scorpion-980N keyboard /* SanDisk products */ -product SANDISK IMAGEMATE 0x0001 USB ImageMate +product SANDISK IMAGEMATE 0x0001 USB ImageMate -/* Corega products */ -product COREGA ETHER_USB_T 0x0001 Ether USB-T +/* Shuttle Technology products */ +product SHUTTLE EUSB 0x0001 E-USB Bridge /* SIIG products */ product SIIG DIGIFILMREADER 0x0004 DigiFilm-Combo Reader -/* Handspring Inc. */ -product HANDSPRING VISOR 0x0100 Handspring Visor +/* Sirius Technologies products */ +product SIRIUS ROADSTER 0x0001 NetComm Roadster II 56 USB -/* Netgear products */ -product NETGEAR EA101 0x1001 Ethernet adapter +/* SMC products */ +product SMC 2102USB 0x0100 10Mbps ethernet adapter +product SMC 2202USB 0x0200 10/100 ethernet adapter -/* ActiveWire Inc. products */ -product ACTIVEWIRE IOBOARD 0x0100 I/O Board -product ACTIVEWIRE IOBOARD_FW1 0x0101 I/O Board, rev. 1 firmware +/* SOLID YEAR products */ +product SOLIDYEAR KEYBOARD 0x2101 Solid Year USB keyboard -/* Billionton products */ -product BILLIONTON USB100 0x0986 USB100N 10/100 FastEthernet Adapter +/* STMicroelectronics products */ +product STMICRO COMMUNICATOR 0x7554 USB Communicator -/* Motorola products */ -product MOTOROLA MC141555 0x1555 MC141555 hub controller +/* Sun Microsystems products */ +product SUN KEYBOARD 0x0005 Type 6 USB +/* XXX The above is a North American PC style keyboard possibly */ -/* PLX products */ -product PLX TESTBOARD 0x9060 test board +/* Telex Communications products */ +product TELEX MIC1 0x0001 Enhanced USB Microphone -/* Inside Out Networks products */ -product INSIDEOUT EDGEPORT4 0x0001 EdgePort/4 serial ports +/* Texas Intel products */ +product TI UTUSB41 0x1446 UT-USB41 hub -/* Intel products */ -product INTEL TESTBOARD 0x9890 82930 test board +/* Thrustmaster products */ +product THRUST FUSION_PAD 0xa0a3 Fusion Digital Gamepad + +/* Universal Access products */ +product UNIACCESS PANACHE 0x0101 Panache Surf USB ISDN Adapter + +/* Vision products */ +product VISION VC6452V002 0x0002 VC6452V002 Camera + +/* Wacom products */ +product WACOM CT0405U 0x0000 CT-0405-U Tablet +product WACOM GRAPHIRE 0x0010 Graphire +product WACOM INTUOSA5 0x0021 Intuos A5 + +/* Y-E data products */ +product YEDATA FLASHBUSTERU 0x0000 Flashbuster-U + +/* Zoom Telephonics Inc. products */ +product ZOOM 2986L 0x9700 2986L Fax modem diff --git a/sys/dev/usb/usbdevs.h b/sys/dev/usb/usbdevs.h index 423fe15ebd6..1c4f48ada63 100644 --- a/sys/dev/usb/usbdevs.h +++ b/sys/dev/usb/usbdevs.h @@ -1,12 +1,11 @@ -/* $OpenBSD: usbdevs.h,v 1.13 2000/03/26 19:30:40 aaron Exp $ */ +/* $OpenBSD: usbdevs.h,v 1.14 2000/03/28 19:37:52 aaron Exp $ */ /* * THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. * * generated from: - * OpenBSD: usbdevs,v 1.14 2000/03/26 19:29:17 aaron Exp + * NetBSD: usbdevs,v 1.87 2000/03/26 15:08:02 augustss Exp */ -/* $NetBSD: usbdevs,v 1.56 1999/10/28 06:41:13 augustss Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -51,11 +50,13 @@ #define USB_VENDOR_AOX 0x03e8 /* Aox Inc. */ #define USB_VENDOR_HP 0x03f0 /* Hewlett Packard */ +#define USB_VENDOR_FUTURE 0x0403 /* Future Technology Devices */ #define USB_VENDOR_NEC 0x0409 /* NEC */ #define USB_VENDOR_KODAK 0x040a /* Eastman Kodak Corp. */ #define USB_VENDOR_MELCO 0x0411 /* Melco Inc. */ #define USB_VENDOR_CATC 0x0423 /* Computer Access Technology Corp. */ #define USB_VENDOR_GRAVIS 0x0428 /* Advanced Gravis Computer Tech. Ltd. */ +#define USB_VENDOR_SUN 0x0430 /* Sun Microsystems */ #define USB_VENDOR_LEXMARK 0x043d /* Lexmark International Inc. */ #define USB_VENDOR_NANAO 0x0440 /* NANAO Corp. */ #define USB_VENDOR_THRUST 0x044f /* Thrustmaster */ @@ -68,22 +69,26 @@ #define USB_VENDOR_BTC 0x046e /* Behavior Tech. Computer */ #define USB_VENDOR_PHILIPS 0x0471 /* Philips */ #define USB_VENDOR_CONNECTIX 0x0478 /* Connectix Corp. */ +#define USB_VENDOR_KENSINGTON 0x047d /* Kensington */ #define USB_VENDOR_LUCENT 0x047e /* Lucent */ #define USB_VENDOR_STMICRO 0x0483 /* STMicroelectronics */ #define USB_VENDOR_ACER 0x04a5 /* Acer Peripheral Inc. */ #define USB_VENDOR_CANON 0x04a9 /* Canon Inc. */ #define USB_VENDOR_CYPRESS 0x04b4 /* Cypress Semiconductor */ #define USB_VENDOR_EPSON 0x04b8 /* Seiko Epson Corp. */ -#define USB_VENDOR_3COM 0x04c1 /* U.S. Robotics */ +#define USB_VENDOR_IODATA 0x04bb /* I/O DATA */ +#define USB_VENDOR_3COMUSR 0x04c1 /* U.S. Robotics */ #define USB_VENDOR_KONICA 0x04c8 /* Konica Corp. */ #define USB_VENDOR_ALTEC 0x04d2 /* Altec Lansing */ #define USB_VENDOR_SHUTTLE 0x04e6 /* Shuttle Technology */ #define USB_VENDOR_CHICONY 0x04f2 /* Chicony Electronics Co., Ltd. */ #define USB_VENDOR_BROTHER 0x04f9 /* Brother Industries Corp. */ #define USB_VENDOR_DALLAS 0x04fa /* Dallas Semiconductor */ +#define USB_VENDOR_3COM 0x0506 /* 3Com Corp. */ #define USB_VENDOR_BELKIN 0x050d /* Belkin Components */ #define USB_VENDOR_KAWATSU 0x050f /* Kawatsu Semiconductor, Inc. */ #define USB_VENDOR_APC 0x051d /* American Power Conversion */ +#define USB_VENDOR_NETCHIP 0x0525 /* NetChip Technology */ #define USB_VENDOR_AKS 0x0529 /* Fast Security AG */ #define USB_VENDOR_UNIACCESS 0x0540 /* Universal Access */ #define USB_VENDOR_ANCHOR 0x0547 /* Anchor Chips Inc. */ @@ -96,27 +101,36 @@ #define USB_VENDOR_ETEK 0x056c /* e-TEK Labs */ #define USB_VENDOR_EIZO 0x056d /* EIZO */ #define USB_VENDOR_ELECOM 0x056e /* Elecom Corp. Ltd. */ +#define USB_VENDOR_YEDATA 0x057b /* Y-E Data */ +#define USB_VENDOR_QUICKSHOT 0x057f /* Quickshot */ #define USB_VENDOR_ROCKFIRE 0x0583 /* Rockfire */ #define USB_VENDOR_IOMEGA 0x059b /* Iomega Corp. */ #define USB_VENDOR_OMNIVISION 0x05a9 /* OmniVision */ #define USB_VENDOR_INSYSTEM 0x05ab /* In-System Design */ #define USB_VENDOR_APPLE 0x05ac /* Apple Computer */ +#define USB_VENDOR_DIGI 0x05c5 /* Digi International */ #define USB_VENDOR_QTRONIX 0x05c7 /* Qtronix Corp */ #define USB_VENDOR_ELSA 0x05cc /* ELSA Gmbh */ #define USB_VENDOR_EIZONANAO 0x05e7 /* EIZO Nanao */ #define USB_VENDOR_KLSI 0x05e9 /* Kawasaki LSI */ #define USB_VENDOR_PIENGINEERING 0x05f3 /* P.I. Engineering */ #define USB_VENDOR_CHIC 0x05fe /* Chic Technology */ +#define USB_VENDOR_SOLIDYEAR 0x060b /* Solid Year */ #define USB_VENDOR_MACALLY 0x0618 /* Macally */ #define USB_VENDOR_LINKSYS 0x066b /* Linksys Inc. */ #define USB_VENDOR_MULTITECH 0x06e0 /* MultiTech */ #define USB_VENDOR_ADS 0x06e1 /* ADS Technologies */ +#define USB_VENDOR_SIRIUS 0x06ea /* Sirius Technologies */ #define USB_VENDOR_SMC 0x0707 /* Standard Microsystems Corp */ #define USB_VENDOR_MIDIMAN 0x0763 /* Midiman */ #define USB_VENDOR_SANDISK 0x0781 /* SanDisk Corp */ +#define USB_VENDOR_ADMTEK 0x07a6 /* ADMtek Inc. */ #define USB_VENDOR_COREGA 0x07aa /* Corega */ #define USB_VENDOR_SIIG 0x07cc /* SIIG */ +#define USB_VENDOR_ZOOM 0x0803 /* Zoom Telephonics Inc. */ #define USB_VENDOR_HANDSPRING 0x082d /* Handspring Inc. */ +#define USB_VENDOR_PALM 0x0830 /* Palm Computing, Inc. */ +#define USB_VENDOR_DIAMOND 0x0841 /* Diamond */ #define USB_VENDOR_NETGEAR 0x0846 /* BayNETGEAR Inc. */ #define USB_VENDOR_ACTIVEWIRE 0x0854 /* ActiveWire Inc. */ #define USB_VENDOR_BILLIONTON 0x08dd /* Billionton Systems Inc. */ @@ -131,261 +145,346 @@ * List of known products. Grouped by vendor. */ -/* AOX products */ -#define USB_PRODUCT_AOX_USB101 0x0008 /* USB ethernet controller engine */ - -/* HP products */ -#define USB_PRODUCT_HP_4100C 0x0101 /* Scanjet 4100C */ -#define USB_PRODUCT_HP_6300C 0x0601 /* Scanjet 6300C */ - -/* NEC products */ -#define USB_PRODUCT_NEC_HUB 0x55aa /* hub */ -#define USB_PRODUCT_NEC_HUB_B 0x55ab /* hub */ - -/* Kodak products */ -#define USB_PRODUCT_KODAK_DC260 0x0110 /* Digital Science DC260 */ -#define USB_PRODUCT_KODAK_DC240 0x0120 /* Digital Science DC240 */ -#define USB_PRODUCT_KODAK_DC280 0x0130 /* Digital Science DC280 */ +/* 3Com products */ +#define USB_PRODUCT_3COM_HOMECONN 0x009d /* HomeConnect USB Camera */ +#define USB_PRODUCT_3COM_3C19250 0x03E8 /* 3C19250 Ethernet adapter */ +#define USB_PRODUCT_3COM_USR56K 0x3021 /* U.S.Robotics 56000 Voice Faxmodem Pro */ +#define USB_PRODUCT_3COM_3C460 0x11f8 /* HomeConnect Ethernet USB Adapter */ -/* Melco Inc products */ -#define USB_PRODUCT_MELCO_LUATX 0x0001 /* LUA-TX Ethernet */ +#define USB_PRODUCT_3COMUSR_OFFICECONN 0x0082 /* 3Com OfficeConnect Analog Modem */ +#define USB_PRODUCT_3COMUSR_USRISDN 0x008f /* 3Com U.S. Robotics Pro ISDN TA */ +#define USB_PRODUCT_3COMUSR_HOMECONN 0x009d /* 3Com HomeConnect camera */ +#define USB_PRODUCT_3COMUSR_USR56K 0x3021 /* U.S.Robotics 56000 Voice Faxmodem Pro */ -/* CATC products */ -#define USB_PRODUCT_CATC_CHIEF 0x000d /* USB Chief Bus & Protocol Analyzer */ -#define USB_PRODUCT_CATC_ANDROMEDA 0x1237 /* Andromeda hub */ +/* Acer products */ +#define USB_PRODUCT_ACER_ACERSCAN_C310U 0x12a6 /* Acerscan C310U */ -/* Gravis products */ -#define USB_PRODUCT_GRAVIS_GAMEPADPRO 0x4001 /* GamePad Pro */ +/* ActiveWire Inc. products */ +#define USB_PRODUCT_ACTIVEWIRE_IOBOARD 0x0100 /* I/O Board */ +#define USB_PRODUCT_ACTIVEWIRE_IOBOARD_FW1 0x0101 /* I/O Board, rev. 1 firmware */ -/* Lexmark products */ -#define USB_PRODUCT_LEXMARK_S2450 0x0009 /* Optra S 2450 */ +/* ADMtek products */ +#define USB_PRODUCT_ADMTEK_PEGASUS 0x0986 /* AN986 USB Ethernet adapter */ -/* Thrustmaster products */ -#define USB_PRODUCT_THRUST_FUSION_PAD 0xa0a3 /* Fusion Digital Gamepad */ +/* ADS products */ +#define USB_PRODUCT_ADS_UBS10BT 0x0008 /* UBS-10BT Ethernet adapter */ -/* Texas Intel products */ -#define USB_PRODUCT_TI_UTUSB41 0x1446 /* UT-USB41 hub */ +/* Agiler products */ +#define USB_PRODUCT_ELECOM_MOUSE29UO 0x0002 /* mouse 29UO */ -/* (KYE) Genius products */ -#define USB_PRODUCT_KYE_NICHE 0x0001 /* Niche mouse */ -#define USB_PRODUCT_KYE_FLIGHT2000 0x1004 /* Flight 2000 joystick */ +/* AKS products */ +#define USB_PRODUCT_AKS_USBHASP 0x0001 /* USB-HASP 0.06 */ -/* Microsoft products */ -#define USB_PRODUCT_MICROSOFT_INTELLIMOUSE 0x0009 /* IntelliMouse */ -#define USB_PRODUCT_MICROSOFT_NATURALKBD 0x000b /* Natural Keyboard Elite */ -#define USB_PRODUCT_MICROSOFT_DDS80 0x0014 /* Digital Sound System 80 */ +/* Altec Lansing products */ +#define USB_PRODUCT_ALTEC_ADA70 0x0070 /* ADA70 Speakers */ +#define USB_PRODUCT_ALTEC_ASC495 0xff05 /* ASC495 Speakers */ -/* Primax products */ -#define USB_PRODUCT_PRIMAX_COMFORT 0x4d01 /* Comfort */ -#define USB_PRODUCT_PRIMAX_MOUSEINABOX 0x4d02 /* Mouse-in-a-Box */ +/* American Power Conversion products */ +#define USB_PRODUCT_APC_UPSPRO500 0x0002 /* Back-UPS Pro 500 */ -/* Cherry products */ -#define USB_PRODUCT_CHERRY_MY3000KBD 0x0001 /* My3000 keyboard */ -#define USB_PRODUCT_CHERRY_MY3000HUB 0x0003 /* My3000 hub */ +/* Anchor products */ +#define USB_PRODUCT_ANCHOR_EZUSB 0x2131 /* EZUSB */ -/* Behavior Technology Computer products */ -#define USB_PRODUCT_BTC_BTC7932 0x6782 /* Keyboard with mouse port */ +/* AOX Inc. products */ +#define USB_PRODUCT_AOX_USB101 0x0008 /* USB ethernet controller engine */ -/* Philips products */ -#define USB_PRODUCT_PHILIPS_DSS350 0x0101 /* DSS 350 Digital Speaker System */ -#define USB_PRODUCT_PHILIPS_DSS 0x0104 /* DSS XXX Digital Speaker System */ -#define USB_PRODUCT_PHILIPS_HUB 0x0201 /* hub */ -#define USB_PRODUCT_PHILIPS_DSS150 0x0471 /* DSS XXX Digital Speaker System */ +/* ATen products */ +#define USB_PRODUCT_ATEN_UC1284 0x2001 /* Parallel printer adapter */ +#define USB_PRODUCT_ATEN_UC10T 0x2002 /* 10Mbps ethernet adapter */ -/* Connectix products */ -#define USB_PRODUCT_CONNECTIX_QUICKCAM 0x0001 /* QuickCam */ +/* Belkin products */ +/*product BELKIN F5U111 0x???? F5U111 Ethernet adapter*/ -/* Lucent products */ -#define USB_PRODUCT_LUCENT_EVALKIT 0x1001 /* USS-720 evaluation kit */ +/* Billionton products */ +#define USB_PRODUCT_BILLIONTON_USB100 0x0986 /* USB100N 10/100 FastEthernet Adapter */ -/* STMicroelectronics products */ -#define USB_PRODUCT_STMICRO_COMMUNICATOR 0x7554 /* USB Communicator */ +/* Brother Industries products */ +#define USB_PRODUCT_BROTHER_HL1050 0x0002 /* HL-1050 laser printer */ -/* Acer products */ -#define USB_PRODUCT_ACER_ACERSCAN_C310U 0x12a6 /* Acerscan C310U */ +/* Behavior Technology Computer products */ +#define USB_PRODUCT_BTC_BTC7932 0x6782 /* Keyboard with mouse port */ /* Canon Inc. products */ #define USB_PRODUCT_CANON_S10 0x3041 /* PowerShot S10 */ -/* Cypress Semiconductor products */ -#define USB_PRODUCT_CYPRESS_MOUSE 0x0001 /* mouse */ -#define USB_PRODUCT_CYPRESS_THERMO 0x0002 /* thermometer */ +/* CATC products */ +#define USB_PRODUCT_CATC_NETMATE 0x000a /* Netmate ethernet adapter */ +#define USB_PRODUCT_CATC_NETMATE2 0x000c /* Netmate2 ethernet adapter */ +#define USB_PRODUCT_CATC_CHIEF 0x000d /* USB Chief Bus & Protocol Analyzer */ +#define USB_PRODUCT_CATC_ANDROMEDA 0x1237 /* Andromeda hub */ -/* Epson products */ -#define USB_PRODUCT_EPSON_PRINTER3 0x0003 /* ISD USB Smart Cable */ +/* Cherry products */ +#define USB_PRODUCT_CHERRY_MY3000KBD 0x0001 /* My3000 keyboard */ +#define USB_PRODUCT_CHERRY_MY3000HUB 0x0003 /* My3000 hub */ -/* 3Com products */ -#define USB_PRODUCT_3COM_HOMECONN 0x009d /* HomeConnect USB Camera */ -#define USB_PRODUCT_3COM_3C19250 0x03e8 /* 3C19250 Ethernet adapter */ -#define USB_PRODUCT_3COM_3C460 0x11f8 /* HomeConnect Ethernet USB Adapter */ -#define USB_PRODUCT_3COM_USR56K 0x3021 /* U.S.Robotics 56000 Voice Faxmodem Pro */ +/* Chic Technology products */ +#define USB_PRODUCT_CHIC_MOUSE1 0x0001 /* mouse */ +#define USB_PRODUCT_CHIC_CYPRESS 0x0003 /* Cypress USB Mouse */ -/* Konica Corp. Products */ -#define USB_PRODUCT_KONICA_CAMERA 0x0720 /* Digital Color Camera */ +/* Chicony products */ +#define USB_PRODUCT_CHICONY_KB8933 0x0001 /* KB-8933 keyboard */ -/* Altec Lansing products */ -#define USB_PRODUCT_ALTEC_ADA70 0x0070 /* ADA70 Speakers */ -#define USB_PRODUCT_ALTEC_ASC495 0xff05 /* ASC495 Speakers */ +/* Connectix products */ +#define USB_PRODUCT_CONNECTIX_QUICKCAM 0x0001 /* QuickCam */ -/* Shuttle Technology products */ -#define USB_PRODUCT_SHUTTLE_EUSB 0x0001 /* E-USB Bridge */ +/* Corega products */ +#define USB_PRODUCT_COREGA_ETHER_USB_T 0x0001 /* Ether USB-T */ +#define USB_PRODUCT_COREGA_FETHER_USB_TX 0x0004 /* FEther USB-TX */ -/* Chicony products */ -#define USB_PRODUCT_CHICONY_KB8933 0x0001 /* KB-8933 keyboard */ +/* Cypress Semiconductor products */ +#define USB_PRODUCT_CYPRESS_MOUSE 0x0001 /* mouse */ +#define USB_PRODUCT_CYPRESS_THERMO 0x0002 /* thermometer */ -/* Brother Industries products */ -#define USB_PRODUCT_BROTHER_HL1050 0x0002 /* HL-1050 laser printer */ +/* D-Link products */ +/*product DLINK DSBS25 0x0100 DSB-S25 serial adapter*/ +#define USB_PRODUCT_DLINK_DSB650C 0x4000 /* 10Mbps ethernet adapter */ +#define USB_PRODUCT_DLINK_DSB650TX 0x4002 /* 10/100 ethernet adapter */ +#define USB_PRODUCT_DLINK_DSB650TX_PNA 0x4003 /* 1/10/100 ethernet adapter */ /* Dallas Semiconductor products */ #define USB_PRODUCT_DALLAS_J6502 0x4201 /* J-6502 speakers */ -/* Kawatsu products */ -#define USB_PRODUCT_KAWATSU_MH4000P 0x0003 /* MiniHub 4000P */ +/* Diamond products */ +#define USB_PRODUCT_DIAMOND_RIO500USB 0x0001 /* Rio 500 USB */ -/* American Power Conversion products */ -#define USB_PRODUCT_APC_UPSPRO500 0x0002 /* Back-UPS Pro 500 */ +/* Digi International products */ +#define USB_PRODUCT_DIGI_ACCELEPORT2 0x0002 /* AccelePort USB 2 */ +#define USB_PRODUCT_DIGI_ACCELEPORT4 0x0004 /* AccelePort USB 4 */ +#define USB_PRODUCT_DIGI_ACCELEPORT8 0x0008 /* AccelePort USB 8 */ -/* AKS products */ -#define USB_PRODUCT_AKS_USBHASP 0x0001 /* USB-HASP 0.06 */ +/* EIZO products */ +#define USB_PRODUCT_EIZO_HUB 0x0000 /* hub */ +#define USB_PRODUCT_EIZO_MONITOR 0x0001 /* monitor */ -/* Universal Access products */ -#define USB_PRODUCT_UNIACCESS_PANACHE 0x0101 /* Panache Surf USB ISDN Adapter */ +/* Elsa products */ +#define USB_PRODUCT_ELSA_MODEM1 0x2265 /* ELSA Modem Board */ -/* Anchor products */ -#define USB_PRODUCT_ANCHOR_EZUSB 0x2131 /* EZUSB */ +/* Entrega products */ +#define USB_PRODUCT_ENTREGA_1S 0x0001 /* 1S serial connector */ +#define USB_PRODUCT_ENTREGA_2S 0x0002 /* 2S serial connector */ +#define USB_PRODUCT_ENTREGA_1S25 0x0003 /* 1S25 serial connector */ +#define USB_PRODUCT_ENTREGA_4S 0x0004 /* 4S serial connector */ +#define USB_PRODUCT_ENTREGA_E45 0x0005 /* E45 Ethernet adapter */ +#define USB_PRODUCT_ENTREGA_CENTRONICS 0x0006 /* Centronics connector */ +#define USB_PRODUCT_ENTREGA_1S9 0x0093 /* 1S9 serial connector */ +#define USB_PRODUCT_ENTREGA_EZUSB 0x8000 /* EZ-USB */ +/*product ENTREGA SERIAL 0x8001 DB25 Serial connector*/ +/*product ENTREGA SERIAL_DB9 0x8093 DB9 Serial connector*/ -/* Vision products */ -#define USB_PRODUCT_VISION_VC6452V002 0x0002 /* VC6452V002 Camera */ +/* e-TEK Labs products */ +#define USB_PRODUCT_ETEK_1COM 0x8007 /* Serial port */ -/* ATen products */ -#define USB_PRODUCT_ATEN_UC1284 0x2001 /* Parallel printer adapter */ -#define USB_PRODUCT_ATEN_UC10T 0x2002 /* Ethernet adapter */ +/* Epson products */ +#define USB_PRODUCT_EPSON_PRINTER2 0x0002 /* ISD USB Smart Cable for Mac */ +#define USB_PRODUCT_EPSON_PRINTER3 0x0003 /* ISD USB Smart Cable */ -/* Mustek products */ -#define USB_PRODUCT_MUSTEK_MDC800 0xa800 /* MDC-800 digital camera */ +/* Gravis products */ +#define USB_PRODUCT_GRAVIS_GAMEPADPRO 0x4001 /* GamePad Pro */ -/* Telex Communications products */ -#define USB_PRODUCT_TELEX_MIC1 0x0001 /* Enhanced USB Microphone */ +/* Future Technology Devices products */ +#define USB_PRODUCT_FUTURE_SERIAL 0x8372 /* Serial converter */ -/* Peracom products */ -#define USB_PRODUCT_PERACOM_SERIAL1 0x0001 /* Serial Converter */ -#define USB_PRODUCT_PERACOM_ENET 0x0002 /* Ethernet adapter */ -#define USB_PRODUCT_PERACOM_ENET2 0x0005 /* Ethernet adapter */ +/* Handspring Inc. */ +#define USB_PRODUCT_HANDSPRING_VISOR 0x0100 /* Handspring Visor */ -/* Wacom products */ -#define USB_PRODUCT_WACOM_CT0405U 0x0000 /* CT-0405-U Tablet */ +/* HP products */ +#define USB_PRODUCT_HP_4100C 0x0101 /* Scanjet 4100C */ +#define USB_PRODUCT_HP_S20 0x0102 /* Photosmart S20 */ +#define USB_PRODUCT_HP_4200C 0x0105 /* ScanJet 4200C */ +#define USB_PRODUCT_HP_6200C 0x0201 /* ScanJet 6200C */ +#define USB_PRODUCT_HP_S20b 0x0202 /* PhotoSmart S20 */ +#define USB_PRODUCT_HP_3300C 0x0205 /* ScanJet 3300C */ +#define USB_PRODUCT_HP_5200 0x0401 /* Scanjet 5200 */ +#define USB_PRODUCT_HP_6300C 0x0601 /* Scanjet 6300C */ +#define USB_PRODUCT_HP_970CSE 0x1004 /* Deskjet 970Cse */ +#define USB_PRODUCT_HP_P1100 0x3102 /* Photosmart P1100 */ -/* e-TEK Labs products */ -#define USB_PRODUCT_ETEK_1COM 0x8007 /* Serial port */ +/* Inside Out Networks products */ +#define USB_PRODUCT_INSIDEOUT_EDGEPORT4 0x0001 /* EdgePort/4 serial ports */ -/* EIZO products */ -#define USB_PRODUCT_EIZO_HUB 0x0000 /* hub */ -#define USB_PRODUCT_EIZO_MONITOR 0x0001 /* monitor */ +/* In-System products */ +#define USB_PRODUCT_INSYSTEM_F5U002 0x0002 /* Parallel printer adapter */ +#define USB_PRODUCT_INSYSTEM_ISD110 0x0200 /* IDE adapter */ -/* Agiler products */ -#define USB_PRODUCT_ELECOM_MOUSE29UO 0x0002 /* mouse 29UO */ +/* Intel products */ +#define USB_PRODUCT_INTEL_TESTBOARD 0x9890 /* 82930 test board */ -/* Rockfire products */ -#define USB_PRODUCT_ROCKFIRE_GAMEPAD 0x2033 /* gamepad 203USB */ +/* I/O DATA products */ +#define USB_PRODUCT_IODATA_USBETTX 0x0904 /* Iomega products */ #define USB_PRODUCT_IOMEGA_ZIP100 0x0001 /* Zip 100 */ -/* OmniVision Technologies Inc. products */ -#define USB_PRODUCT_OMNIVISION_OV511 0x0511 /* OV511 Camera */ +/* Kawasaki products */ +#define USB_PRODUCT_KLSI_DUH3E10BT 0x0008 /* USB ethernet controller engine */ -/* In-System products */ -#define USB_PRODUCT_INSYSTEM_F5U002 0x0002 /* Parallel printer adapter */ -#define USB_PRODUCT_INSYSTEM_ISD110 0x0200 /* IDE adapter */ +/* Kawatsu products */ +#define USB_PRODUCT_KAWATSU_MH4000P 0x0003 /* MiniHub 4000P */ -/* Qtronix products */ -#define USB_PRODUCT_QTRONIX_980N 0x2011 /* Scorpion-980N keyboard */ +/* Kensington products */ +#define USB_PRODUCT_KENSINGTON_ORBIT 0x1003 /* Orbit USB/PS2 trackball */ +#define USB_PRODUCT_KENSINGTON_TURBOBALL 0x1005 /* TurboBall */ -/* Elsa products */ -#define USB_PRODUCT_ELSA_MODEM1 0x2265 /* ELSA Modem Board */ +/* Kodak products */ +#define USB_PRODUCT_KODAK_DC220 0x0100 /* Digital Science DC220 */ +#define USB_PRODUCT_KODAK_DC260 0x0110 /* Digital Science DC260 */ +#define USB_PRODUCT_KODAK_DC265 0x0111 /* Digital Science DC265 */ +#define USB_PRODUCT_KODAK_DC290 0x0112 /* Digital Science DC290 */ +#define USB_PRODUCT_KODAK_DC240 0x0120 /* Digital Science DC240 */ +#define USB_PRODUCT_KODAK_DC280 0x0130 /* Digital Science DC280 */ + +/* Konica Corp. Products */ +#define USB_PRODUCT_KONICA_CAMERA 0x0720 /* Digital Color Camera */ + +/* KYE products */ +#define USB_PRODUCT_KYE_NICHE 0x0001 /* Niche mouse */ +#define USB_PRODUCT_KYE_NETSCROLL 0x0003 /* Genius NetScroll mouse */ +#define USB_PRODUCT_KYE_FLIGHT2000 0x1004 /* Flight 2000 joystick */ + +/* Lexmark products */ +#define USB_PRODUCT_LEXMARK_S2450 0x0009 /* Optra S 2450 */ + +/* Linksys products */ +#define USB_PRODUCT_LINKSYS_USB10T 0x2202 /* USB10T Ethernet */ +#define USB_PRODUCT_LINKSYS_USB100TX 0x2203 /* USB100TX Ethernet */ /* Logitech products */ #define USB_PRODUCT_LOGITECH_M2452 0x0203 /* M2452 keyboard */ #define USB_PRODUCT_LOGITECH_M4848 0x0301 /* M4848 mouse */ #define USB_PRODUCT_LOGITECH_QUICKCAM 0x0801 /* QuickCam */ #define USB_PRODUCT_LOGITECH_QUICKCAMPRO 0x0810 /* QuickCam Pro */ +#define USB_PRODUCT_LOGITECH_N43 0xc000 /* N43 */ #define USB_PRODUCT_LOGITECH_N48 0xc001 /* N48 mouse */ #define USB_PRODUCT_LOGITECH_MBA47 0xc002 /* M-BA47 mouse */ +#define USB_PRODUCT_LOGITECH_WMMOUSE 0xc004 /* WingMan Gaming Mouse */ +#define USB_PRODUCT_LOGITECH_WMPAD 0xc208 /* WingMan GamePad Extreme */ +#define USB_PRODUCT_LOGITECH_WMJOY 0xc281 /* WingMan Force joystick */ -/* Kawasaki products */ -#define USB_PRODUCT_KLSI_USB101 0x0008 /* USB ethernet controller engine */ - -/* P.I. Engineering products */ -#define USB_PRODUCT_PIENGINEERING_PS2USB 0x020b /* PS2 to Mac USB Adapter */ - -/* Chic Technology products */ -#define USB_PRODUCT_CHIC_MOUSE1 0x0001 /* mouse */ +/* Lucent products */ +#define USB_PRODUCT_LUCENT_EVALKIT 0x1001 /* USS-720 evaluation kit */ /* Macally products */ #define USB_PRODUCT_MACALLY_MOUSE1 0x0101 /* mouse */ -/* Linksys products */ -#define USB_PRODUCT_LINKSYS_USB10T 0x2202 /* USB10T Ethernet */ -#define USB_PRODUCT_LINKSYS_USB100TX 0x2203 /* USB100TX Ethernet */ +/* Melco Inc products */ +#define USB_PRODUCT_MELCO_LUATX 0x0001 /* LU-ATX Ethernet */ + +/* Microsoft products */ +#define USB_PRODUCT_MICROSOFT_SIDEPREC 0x0008 /* SideWinder Precision Pro */ +#define USB_PRODUCT_MICROSOFT_INTELLIMOUSE 0x0009 /* IntelliMouse */ +#define USB_PRODUCT_MICROSOFT_NATURALKBD 0x000b /* Natural Keyboard Elite */ +#define USB_PRODUCT_MICROSOFT_DDS80 0x0014 /* Digital Sound System 80 */ +#define USB_PRODUCT_MICROSOFT_SIDEWINDER 0x001a /* Sidewinder Precision Racing Wheel */ +#define USB_PRODUCT_MICROSOFT_INTELLIEYE 0x0025 /* IntelliEye mouse */ +#define USB_PRODUCT_MICROSOFT_INETPRO 0x002b /* Internet Keyboard Pro */ + +/* Midiman products */ +#define USB_PRODUCT_MIDIMAN_MIDISPORT2X2 0x1001 /* Midisport 2x2 */ + +/* Motorola products */ +#define USB_PRODUCT_MOTOROLA_MC141555 0x1555 /* MC141555 hub controller */ /* MultiTech products */ #define USB_PRODUCT_MULTITECH_ATLAS 0xf101 /* MT5634ZBA-USB modem */ -/* ADS products */ -#define USB_PRODUCT_ADS_UBS10BT 0x0008 /* Ethernet adapter */ +/* Mustek products */ +#define USB_PRODUCT_MUSTEK_MDC800 0xa800 /* MDC-800 digital camera */ -/* SMC products */ -#define USB_PRODUCT_SMC_2102USB 0x0100 /* 10Mbps ethernet adapter */ -#define USB_PRODUCT_SMC_2202USB 0x0200 /* 10/100 ethernet adapter */ +/* NEC products */ +#define USB_PRODUCT_NEC_HUB 0x55aa /* hub */ +#define USB_PRODUCT_NEC_HUB_B 0x55ab /* hub */ -/* Entrega products */ -#define USB_PRODUCT_ENTREGA_1S 0x0001 /* 1S serial connector */ -#define USB_PRODUCT_ENTREGA_2S 0x0002 /* 2S serial connector */ -#define USB_PRODUCT_ENTREGA_1S25 0x0003 /* 1S25 serial connector */ -#define USB_PRODUCT_ENTREGA_4S 0x0004 /* 4S serial connector */ -#define USB_PRODUCT_ENTREGA_E45 0x0005 /* E45 Ethernet adapter */ -#define USB_PRODUCT_ENTREGA_CENTRONICS 0x0006 /* Centronics connector */ -#define USB_PRODUCT_ENTREGA_1S9 0x0093 /* 1S9 serial connector */ -#define USB_PRODUCT_ENTREGA_EZUSB 0x8000 /* EZ-USB */ -/*product ENTREGA SERIAL 0x8001 DB25 Serial connector*/ -/*product ENTREGA SERIAL_DB9 0x8093 DB9 Serial connector*/ +/* NetChip Technology Products */ +#define USB_PRODUCT_NETCHIP_TURBOCONNECT 0x1080 /* Turbo-Connect */ -/* D-Link products */ -#define USB_PRODUCT_DLINK_DSB650C 0x4000 /* 10Mbps ethernet adapter */ +/* Netgear products */ +#define USB_PRODUCT_NETGEAR_EA101 0x1001 /* Ethernet adapter */ -/* Midiman products */ -#define USB_PRODUCT_MIDIMAN_MIDISPORT2X2 0x1001 /* Midisport 2x2 */ +/* OmniVision Technologies Inc. products */ +#define USB_PRODUCT_OMNIVISION_OV511 0x0511 /* OV511 Camera */ + +/* Palm Computing, Inc. */ +#define USB_PRODUCT_PALM_SERIAL 0x0080 /* USB Serial Adaptor */ + +/* Peracom products */ +#define USB_PRODUCT_PERACOM_SERIAL1 0x0001 /* Serial Converter */ +#define USB_PRODUCT_PERACOM_ENET 0x0002 /* Ethernet adapter */ +#define USB_PRODUCT_PERACOM_ENET2 0x0005 /* Ethernet adapter */ + +/* Philips products */ +#define USB_PRODUCT_PHILIPS_DSS350 0x0101 /* DSS 350 Digital Speaker System */ +#define USB_PRODUCT_PHILIPS_DSS 0x0104 /* DSS XXX Digital Speaker System */ +#define USB_PRODUCT_PHILIPS_HUB 0x0201 /* hub */ +#define USB_PRODUCT_PHILIPS_DSS150 0x0471 /* DSS 150 Digital Speaker System */ + +/* P.I. Engineering products */ +#define USB_PRODUCT_PIENGINEERING_PS2USB 0x020b /* PS2 to Mac USB Adapter */ + +/* PLX products */ +#define USB_PRODUCT_PLX_TESTBOARD 0x9060 /* test board */ + +/* Primax products */ +#define USB_PRODUCT_PRIMAX_COMFORT 0x4d01 /* Comfort */ +#define USB_PRODUCT_PRIMAX_MOUSEINABOX 0x4d02 /* Mouse-in-a-Box */ +#define USB_PRODUCT_PRIMAX_PCGAUMS1 0x4d04 /* Sony PCGA-UMS1 */ + +/* Quickshot products */ +#define USB_PRODUCT_QUICKSHOT_STRIKEPAD 0x6238 /* USB StrikePad */ + +/* Rockfire products */ +#define USB_PRODUCT_ROCKFIRE_GAMEPAD 0x2033 /* gamepad 203USB */ + +/* Qtronix products */ +#define USB_PRODUCT_QTRONIX_980N 0x2011 /* Scorpion-980N keyboard */ /* SanDisk products */ #define USB_PRODUCT_SANDISK_IMAGEMATE 0x0001 /* USB ImageMate */ -/* Corega products */ -#define USB_PRODUCT_COREGA_ETHER_USB_T 0x0001 /* Ether USB-T */ +/* Shuttle Technology products */ +#define USB_PRODUCT_SHUTTLE_EUSB 0x0001 /* E-USB Bridge */ /* SIIG products */ #define USB_PRODUCT_SIIG_DIGIFILMREADER 0x0004 /* DigiFilm-Combo Reader */ -/* Handspring Inc. */ -#define USB_PRODUCT_HANDSPRING_VISOR 0x0100 /* Handspring Visor */ +/* Sirius Technologies products */ +#define USB_PRODUCT_SIRIUS_ROADSTER 0x0001 /* NetComm Roadster II 56 USB */ -/* Netgear products */ -#define USB_PRODUCT_NETGEAR_EA101 0x1001 /* Ethernet adapter */ +/* SMC products */ +#define USB_PRODUCT_SMC_2102USB 0x0100 /* 10Mbps ethernet adapter */ +#define USB_PRODUCT_SMC_2202USB 0x0200 /* 10/100 ethernet adapter */ -/* ActiveWire Inc. products */ -#define USB_PRODUCT_ACTIVEWIRE_IOBOARD 0x0100 /* I/O Board */ -#define USB_PRODUCT_ACTIVEWIRE_IOBOARD_FW1 0x0101 /* I/O Board, rev. 1 firmware */ +/* SOLID YEAR products */ +#define USB_PRODUCT_SOLIDYEAR_KEYBOARD 0x2101 /* Solid Year USB keyboard */ -/* Billionton products */ -#define USB_PRODUCT_BILLIONTON_USB100 0x0986 /* USB100N 10/100 FastEthernet Adapter */ +/* STMicroelectronics products */ +#define USB_PRODUCT_STMICRO_COMMUNICATOR 0x7554 /* USB Communicator */ -/* Motorola products */ -#define USB_PRODUCT_MOTOROLA_MC141555 0x1555 /* MC141555 hub controller */ +/* Sun Microsystems products */ +#define USB_PRODUCT_SUN_KEYBOARD 0x0005 /* Type 6 USB */ +/* XXX The above is a North American PC style keyboard possibly */ -/* PLX products */ -#define USB_PRODUCT_PLX_TESTBOARD 0x9060 /* test board */ +/* Telex Communications products */ +#define USB_PRODUCT_TELEX_MIC1 0x0001 /* Enhanced USB Microphone */ -/* Inside Out Networks products */ -#define USB_PRODUCT_INSIDEOUT_EDGEPORT4 0x0001 /* EdgePort/4 serial ports */ +/* Texas Intel products */ +#define USB_PRODUCT_TI_UTUSB41 0x1446 /* UT-USB41 hub */ -/* Intel products */ -#define USB_PRODUCT_INTEL_TESTBOARD 0x9890 /* 82930 test board */ +/* Thrustmaster products */ +#define USB_PRODUCT_THRUST_FUSION_PAD 0xa0a3 /* Fusion Digital Gamepad */ + +/* Universal Access products */ +#define USB_PRODUCT_UNIACCESS_PANACHE 0x0101 /* Panache Surf USB ISDN Adapter */ + +/* Vision products */ +#define USB_PRODUCT_VISION_VC6452V002 0x0002 /* VC6452V002 Camera */ + +/* Wacom products */ +#define USB_PRODUCT_WACOM_CT0405U 0x0000 /* CT-0405-U Tablet */ +#define USB_PRODUCT_WACOM_GRAPHIRE 0x0010 /* Graphire */ +#define USB_PRODUCT_WACOM_INTUOSA5 0x0021 /* Intuos A5 */ + +/* Y-E data products */ +#define USB_PRODUCT_YEDATA_FLASHBUSTERU 0x0000 /* Flashbuster-U */ + +/* Zoom Telephonics Inc. products */ +#define USB_PRODUCT_ZOOM_2986L 0x9700 /* 2986L Fax modem */ diff --git a/sys/dev/usb/usbdevs_data.h b/sys/dev/usb/usbdevs_data.h index e7fdef6522c..7029f0b0882 100644 --- a/sys/dev/usb/usbdevs_data.h +++ b/sys/dev/usb/usbdevs_data.h @@ -1,12 +1,11 @@ -/* $OpenBSD: usbdevs_data.h,v 1.13 2000/03/26 19:30:40 aaron Exp $ */ +/* $OpenBSD: usbdevs_data.h,v 1.14 2000/03/28 19:37:52 aaron Exp $ */ /* * THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. * * generated from: - * OpenBSD: usbdevs,v 1.14 2000/03/26 19:29:17 aaron Exp + * NetBSD: usbdevs,v 1.87 2000/03/26 15:08:02 augustss Exp */ -/* $NetBSD: usbdevs,v 1.56 1999/10/28 06:41:13 augustss Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -47,148 +46,148 @@ struct usb_knowndev usb_knowndevs[] = { { - USB_VENDOR_AOX, USB_PRODUCT_AOX_USB101, + USB_VENDOR_3COM, USB_PRODUCT_3COM_HOMECONN, 0, - "Aox Inc.", - "USB ethernet controller engine", + "3Com Corp.", + "HomeConnect USB Camera", }, { - USB_VENDOR_HP, USB_PRODUCT_HP_4100C, + USB_VENDOR_3COM, USB_PRODUCT_3COM_3C19250, 0, - "Hewlett Packard", - "Scanjet 4100C", + "3Com Corp.", + "3C19250 Ethernet adapter", }, { - USB_VENDOR_HP, USB_PRODUCT_HP_6300C, + USB_VENDOR_3COM, USB_PRODUCT_3COM_USR56K, 0, - "Hewlett Packard", - "Scanjet 6300C", + "3Com Corp.", + "U.S.Robotics 56000 Voice Faxmodem Pro", }, { - USB_VENDOR_NEC, USB_PRODUCT_NEC_HUB, + USB_VENDOR_3COM, USB_PRODUCT_3COM_3C460, 0, - "NEC", - "hub", + "3Com Corp.", + "HomeConnect Ethernet USB Adapter", }, { - USB_VENDOR_NEC, USB_PRODUCT_NEC_HUB_B, + USB_VENDOR_3COMUSR, USB_PRODUCT_3COMUSR_OFFICECONN, 0, - "NEC", - "hub", + "U.S. Robotics", + "3Com OfficeConnect Analog Modem", }, { - USB_VENDOR_KODAK, USB_PRODUCT_KODAK_DC260, + USB_VENDOR_3COMUSR, USB_PRODUCT_3COMUSR_USRISDN, 0, - "Eastman Kodak Corp.", - "Digital Science DC260", + "U.S. Robotics", + "3Com U.S. Robotics Pro ISDN TA", }, { - USB_VENDOR_KODAK, USB_PRODUCT_KODAK_DC240, + USB_VENDOR_3COMUSR, USB_PRODUCT_3COMUSR_HOMECONN, 0, - "Eastman Kodak Corp.", - "Digital Science DC240", + "U.S. Robotics", + "3Com HomeConnect camera", }, { - USB_VENDOR_KODAK, USB_PRODUCT_KODAK_DC280, + USB_VENDOR_3COMUSR, USB_PRODUCT_3COMUSR_USR56K, 0, - "Eastman Kodak Corp.", - "Digital Science DC280", + "U.S. Robotics", + "U.S.Robotics 56000 Voice Faxmodem Pro", }, { - USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUATX, + USB_VENDOR_ACER, USB_PRODUCT_ACER_ACERSCAN_C310U, 0, - "Melco Inc.", - "LUA-TX Ethernet", + "Acer Peripheral Inc.", + "Acerscan C310U", }, { - USB_VENDOR_CATC, USB_PRODUCT_CATC_CHIEF, + USB_VENDOR_ACTIVEWIRE, USB_PRODUCT_ACTIVEWIRE_IOBOARD, 0, - "Computer Access Technology Corp.", - "USB Chief Bus & Protocol Analyzer", + "ActiveWire Inc.", + "I/O Board", }, { - USB_VENDOR_CATC, USB_PRODUCT_CATC_ANDROMEDA, + USB_VENDOR_ACTIVEWIRE, USB_PRODUCT_ACTIVEWIRE_IOBOARD_FW1, 0, - "Computer Access Technology Corp.", - "Andromeda hub", + "ActiveWire Inc.", + "I/O Board, rev. 1 firmware", }, { - USB_VENDOR_GRAVIS, USB_PRODUCT_GRAVIS_GAMEPADPRO, + USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUS, 0, - "Advanced Gravis Computer Tech. Ltd.", - "GamePad Pro", + "ADMtek Inc.", + "AN986 USB Ethernet adapter", }, { - USB_VENDOR_LEXMARK, USB_PRODUCT_LEXMARK_S2450, + USB_VENDOR_ADS, USB_PRODUCT_ADS_UBS10BT, 0, - "Lexmark International Inc.", - "Optra S 2450", + "ADS Technologies", + "UBS-10BT Ethernet adapter", }, { - USB_VENDOR_THRUST, USB_PRODUCT_THRUST_FUSION_PAD, + USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_MOUSE29UO, 0, - "Thrustmaster", - "Fusion Digital Gamepad", + "Elecom Corp. Ltd.", + "mouse 29UO", }, { - USB_VENDOR_TI, USB_PRODUCT_TI_UTUSB41, + USB_VENDOR_AKS, USB_PRODUCT_AKS_USBHASP, 0, - "Texas Instruments", - "UT-USB41 hub", + "Fast Security AG", + "USB-HASP 0.06", }, { - USB_VENDOR_KYE, USB_PRODUCT_KYE_NICHE, + USB_VENDOR_ALTEC, USB_PRODUCT_ALTEC_ADA70, 0, - "KYE Systems Corp.", - "Niche mouse", + "Altec Lansing", + "ADA70 Speakers", }, { - USB_VENDOR_KYE, USB_PRODUCT_KYE_FLIGHT2000, + USB_VENDOR_ALTEC, USB_PRODUCT_ALTEC_ASC495, 0, - "KYE Systems Corp.", - "Flight 2000 joystick", + "Altec Lansing", + "ASC495 Speakers", }, { - USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_INTELLIMOUSE, + USB_VENDOR_APC, USB_PRODUCT_APC_UPSPRO500, 0, - "Microsoft", - "IntelliMouse", + "American Power Conversion", + "Back-UPS Pro 500", }, { - USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_NATURALKBD, + USB_VENDOR_ANCHOR, USB_PRODUCT_ANCHOR_EZUSB, 0, - "Microsoft", - "Natural Keyboard Elite", + "Anchor Chips Inc.", + "EZUSB", }, { - USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_DDS80, + USB_VENDOR_AOX, USB_PRODUCT_AOX_USB101, 0, - "Microsoft", - "Digital Sound System 80", + "Aox Inc.", + "USB ethernet controller engine", }, { - USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_COMFORT, + USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC1284, 0, - "Primax Electronics", - "Comfort", + "ATEN International Corp. Ltd.", + "Parallel printer adapter", }, { - USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_MOUSEINABOX, + USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC10T, 0, - "Primax Electronics", - "Mouse-in-a-Box", + "ATEN International Corp. Ltd.", + "10Mbps ethernet adapter", }, { - USB_VENDOR_CHERRY, USB_PRODUCT_CHERRY_MY3000KBD, + USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USB100, 0, - "Cherry Mikroschalter GmbH", - "My3000 keyboard", + "Billionton Systems Inc.", + "USB100N 10/100 FastEthernet Adapter", }, { - USB_VENDOR_CHERRY, USB_PRODUCT_CHERRY_MY3000HUB, + USB_VENDOR_BROTHER, USB_PRODUCT_BROTHER_HL1050, 0, - "Cherry Mikroschalter GmbH", - "My3000 hub", + "Brother Industries Corp.", + "HL-1050 laser printer", }, { USB_VENDOR_BTC, USB_PRODUCT_BTC_BTC7932, @@ -197,268 +196,310 @@ struct usb_knowndev usb_knowndevs[] = { "Keyboard with mouse port", }, { - USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_DSS350, + USB_VENDOR_CANON, USB_PRODUCT_CANON_S10, 0, - "Philips", - "DSS 350 Digital Speaker System", + "Canon Inc.", + "PowerShot S10", }, { - USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_DSS, + USB_VENDOR_CATC, USB_PRODUCT_CATC_NETMATE, 0, - "Philips", - "DSS XXX Digital Speaker System", + "Computer Access Technology Corp.", + "Netmate ethernet adapter", }, { - USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_HUB, + USB_VENDOR_CATC, USB_PRODUCT_CATC_NETMATE2, 0, - "Philips", - "hub", + "Computer Access Technology Corp.", + "Netmate2 ethernet adapter", }, { - USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_DSS150, + USB_VENDOR_CATC, USB_PRODUCT_CATC_CHIEF, 0, - "Philips", - "DSS XXX Digital Speaker System", + "Computer Access Technology Corp.", + "USB Chief Bus & Protocol Analyzer", }, { - USB_VENDOR_CONNECTIX, USB_PRODUCT_CONNECTIX_QUICKCAM, + USB_VENDOR_CATC, USB_PRODUCT_CATC_ANDROMEDA, 0, - "Connectix Corp.", - "QuickCam", + "Computer Access Technology Corp.", + "Andromeda hub", }, { - USB_VENDOR_LUCENT, USB_PRODUCT_LUCENT_EVALKIT, + USB_VENDOR_CHERRY, USB_PRODUCT_CHERRY_MY3000KBD, 0, - "Lucent", - "USS-720 evaluation kit", + "Cherry Mikroschalter GmbH", + "My3000 keyboard", }, { - USB_VENDOR_STMICRO, USB_PRODUCT_STMICRO_COMMUNICATOR, + USB_VENDOR_CHERRY, USB_PRODUCT_CHERRY_MY3000HUB, 0, - "STMicroelectronics", - "USB Communicator", + "Cherry Mikroschalter GmbH", + "My3000 hub", }, { - USB_VENDOR_ACER, USB_PRODUCT_ACER_ACERSCAN_C310U, + USB_VENDOR_CHIC, USB_PRODUCT_CHIC_MOUSE1, 0, - "Acer Peripheral Inc.", - "Acerscan C310U", + "Chic Technology", + "mouse", }, { - USB_VENDOR_CANON, USB_PRODUCT_CANON_S10, + USB_VENDOR_CHIC, USB_PRODUCT_CHIC_CYPRESS, 0, - "Canon Inc.", - "PowerShot S10", + "Chic Technology", + "Cypress USB Mouse", }, { - USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_MOUSE, + USB_VENDOR_CHICONY, USB_PRODUCT_CHICONY_KB8933, 0, - "Cypress Semiconductor", - "mouse", + "Chicony Electronics Co., Ltd.", + "KB-8933 keyboard", }, { - USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_THERMO, + USB_VENDOR_CONNECTIX, USB_PRODUCT_CONNECTIX_QUICKCAM, 0, - "Cypress Semiconductor", - "thermometer", + "Connectix Corp.", + "QuickCam", }, { - USB_VENDOR_EPSON, USB_PRODUCT_EPSON_PRINTER3, + USB_VENDOR_COREGA, USB_PRODUCT_COREGA_ETHER_USB_T, 0, - "Seiko Epson Corp.", - "ISD USB Smart Cable", + "Corega", + "Ether USB-T", }, { - USB_VENDOR_3COM, USB_PRODUCT_3COM_HOMECONN, + USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB_TX, 0, - "U.S. Robotics", - "HomeConnect USB Camera", + "Corega", + "FEther USB-TX", }, { - USB_VENDOR_3COM, USB_PRODUCT_3COM_3C19250, + USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_MOUSE, 0, - "U.S. Robotics", - "3C19250 Ethernet adapter", + "Cypress Semiconductor", + "mouse", }, { - USB_VENDOR_3COM, USB_PRODUCT_3COM_3C460, + USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_THERMO, 0, - "U.S. Robotics", - "HomeConnect Ethernet USB Adapter", + "Cypress Semiconductor", + "thermometer", }, { - USB_VENDOR_3COM, USB_PRODUCT_3COM_USR56K, + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650C, 0, - "U.S. Robotics", - "U.S.Robotics 56000 Voice Faxmodem Pro", + "D-Link Corp", + "10Mbps ethernet adapter", }, { - USB_VENDOR_KONICA, USB_PRODUCT_KONICA_CAMERA, + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX, 0, - "Konica Corp.", - "Digital Color Camera", + "D-Link Corp", + "10/100 ethernet adapter", }, { - USB_VENDOR_ALTEC, USB_PRODUCT_ALTEC_ADA70, + USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX_PNA, 0, - "Altec Lansing", - "ADA70 Speakers", + "D-Link Corp", + "1/10/100 ethernet adapter", }, { - USB_VENDOR_ALTEC, USB_PRODUCT_ALTEC_ASC495, + USB_VENDOR_DALLAS, USB_PRODUCT_DALLAS_J6502, 0, - "Altec Lansing", - "ASC495 Speakers", + "Dallas Semiconductor", + "J-6502 speakers", }, { - USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSB, + USB_VENDOR_DIAMOND, USB_PRODUCT_DIAMOND_RIO500USB, 0, - "Shuttle Technology", - "E-USB Bridge", + "Diamond", + "Rio 500 USB", }, { - USB_VENDOR_CHICONY, USB_PRODUCT_CHICONY_KB8933, + USB_VENDOR_DIGI, USB_PRODUCT_DIGI_ACCELEPORT2, 0, - "Chicony Electronics Co., Ltd.", - "KB-8933 keyboard", + "Digi International", + "AccelePort USB 2", }, { - USB_VENDOR_BROTHER, USB_PRODUCT_BROTHER_HL1050, + USB_VENDOR_DIGI, USB_PRODUCT_DIGI_ACCELEPORT4, 0, - "Brother Industries Corp.", - "HL-1050 laser printer", + "Digi International", + "AccelePort USB 4", }, { - USB_VENDOR_DALLAS, USB_PRODUCT_DALLAS_J6502, + USB_VENDOR_DIGI, USB_PRODUCT_DIGI_ACCELEPORT8, 0, - "Dallas Semiconductor", - "J-6502 speakers", + "Digi International", + "AccelePort USB 8", }, { - USB_VENDOR_KAWATSU, USB_PRODUCT_KAWATSU_MH4000P, + USB_VENDOR_EIZO, USB_PRODUCT_EIZO_HUB, 0, - "Kawatsu Semiconductor, Inc.", - "MiniHub 4000P", + "EIZO", + "hub", }, { - USB_VENDOR_APC, USB_PRODUCT_APC_UPSPRO500, + USB_VENDOR_EIZO, USB_PRODUCT_EIZO_MONITOR, 0, - "American Power Conversion", - "Back-UPS Pro 500", + "EIZO", + "monitor", }, { - USB_VENDOR_AKS, USB_PRODUCT_AKS_USBHASP, + USB_VENDOR_ELSA, USB_PRODUCT_ELSA_MODEM1, 0, - "Fast Security AG", - "USB-HASP 0.06", + "ELSA Gmbh", + "ELSA Modem Board", }, { - USB_VENDOR_UNIACCESS, USB_PRODUCT_UNIACCESS_PANACHE, + USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_1S, 0, - "Universal Access", - "Panache Surf USB ISDN Adapter", + "Entrega", + "1S serial connector", }, { - USB_VENDOR_ANCHOR, USB_PRODUCT_ANCHOR_EZUSB, + USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_2S, 0, - "Anchor Chips Inc.", - "EZUSB", + "Entrega", + "2S serial connector", }, { - USB_VENDOR_VISION, USB_PRODUCT_VISION_VC6452V002, + USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_1S25, 0, - "VLSI Vision Ltd.", - "VC6452V002 Camera", + "Entrega", + "1S25 serial connector", }, { - USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC1284, + USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_4S, 0, - "ATEN International Corp. Ltd.", - "Parallel printer adapter", + "Entrega", + "4S serial connector", }, { - USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC10T, + USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_E45, 0, - "ATEN International Corp. Ltd.", - "Ethernet adapter", + "Entrega", + "E45 Ethernet adapter", }, { - USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_MDC800, + USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_CENTRONICS, 0, - "Mustek Systems Inc.", - "MDC-800 digital camera", + "Entrega", + "Centronics connector", }, { - USB_VENDOR_TELEX, USB_PRODUCT_TELEX_MIC1, + USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_1S9, 0, - "Telex Communications Inc.", - "Enhanced USB Microphone", + "Entrega", + "1S9 serial connector", }, { - USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_SERIAL1, + USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_EZUSB, 0, - "Peracom Networks Inc.", - "Serial Converter", + "Entrega", + "EZ-USB", }, { - USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_ENET, + USB_VENDOR_ETEK, USB_PRODUCT_ETEK_1COM, 0, - "Peracom Networks Inc.", - "Ethernet adapter", + "e-TEK Labs", + "Serial port", }, { - USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_ENET2, + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_PRINTER2, 0, - "Peracom Networks Inc.", - "Ethernet adapter", + "Seiko Epson Corp.", + "ISD USB Smart Cable for Mac", }, { - USB_VENDOR_WACOM, USB_PRODUCT_WACOM_CT0405U, + USB_VENDOR_EPSON, USB_PRODUCT_EPSON_PRINTER3, 0, - "WACOM Corp. Ltd.", - "CT-0405-U Tablet", + "Seiko Epson Corp.", + "ISD USB Smart Cable", }, { - USB_VENDOR_ETEK, USB_PRODUCT_ETEK_1COM, + USB_VENDOR_GRAVIS, USB_PRODUCT_GRAVIS_GAMEPADPRO, 0, - "e-TEK Labs", - "Serial port", + "Advanced Gravis Computer Tech. Ltd.", + "GamePad Pro", }, { - USB_VENDOR_EIZO, USB_PRODUCT_EIZO_HUB, + USB_VENDOR_FUTURE, USB_PRODUCT_FUTURE_SERIAL, 0, - "EIZO", - "hub", + "Future Technology Devices", + "Serial converter", }, { - USB_VENDOR_EIZO, USB_PRODUCT_EIZO_MONITOR, + USB_VENDOR_HANDSPRING, USB_PRODUCT_HANDSPRING_VISOR, 0, - "EIZO", - "monitor", + "Handspring Inc.", + "Handspring Visor", }, { - USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_MOUSE29UO, + USB_VENDOR_HP, USB_PRODUCT_HP_4100C, 0, - "Elecom Corp. Ltd.", - "mouse 29UO", + "Hewlett Packard", + "Scanjet 4100C", }, { - USB_VENDOR_ROCKFIRE, USB_PRODUCT_ROCKFIRE_GAMEPAD, + USB_VENDOR_HP, USB_PRODUCT_HP_S20, 0, - "Rockfire", - "gamepad 203USB", + "Hewlett Packard", + "Photosmart S20", }, { - USB_VENDOR_IOMEGA, USB_PRODUCT_IOMEGA_ZIP100, + USB_VENDOR_HP, USB_PRODUCT_HP_4200C, 0, - "Iomega Corp.", - "Zip 100", + "Hewlett Packard", + "ScanJet 4200C", }, { - USB_VENDOR_OMNIVISION, USB_PRODUCT_OMNIVISION_OV511, + USB_VENDOR_HP, USB_PRODUCT_HP_6200C, 0, - "OmniVision", - "OV511 Camera", + "Hewlett Packard", + "ScanJet 6200C", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_S20b, + 0, + "Hewlett Packard", + "PhotoSmart S20", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_3300C, + 0, + "Hewlett Packard", + "ScanJet 3300C", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_5200, + 0, + "Hewlett Packard", + "Scanjet 5200", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_6300C, + 0, + "Hewlett Packard", + "Scanjet 6300C", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_970CSE, + 0, + "Hewlett Packard", + "Deskjet 970Cse", + }, + { + USB_VENDOR_HP, USB_PRODUCT_HP_P1100, + 0, + "Hewlett Packard", + "Photosmart P1100", + }, + { + USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORT4, + 0, + "Inside Out Networks", + "EdgePort/4 serial ports", }, { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_F5U002, @@ -473,16 +514,124 @@ struct usb_knowndev usb_knowndevs[] = { "IDE adapter", }, { - USB_VENDOR_QTRONIX, USB_PRODUCT_QTRONIX_980N, + USB_VENDOR_INTEL, USB_PRODUCT_INTEL_TESTBOARD, 0, - "Qtronix Corp", - "Scorpion-980N keyboard", + "Intel", + "82930 test board", }, { - USB_VENDOR_ELSA, USB_PRODUCT_ELSA_MODEM1, + USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBETTX, 0, - "ELSA Gmbh", - "ELSA Modem Board", + "I/O DATA", + "", + }, + { + USB_VENDOR_IOMEGA, USB_PRODUCT_IOMEGA_ZIP100, + 0, + "Iomega Corp.", + "Zip 100", + }, + { + USB_VENDOR_KLSI, USB_PRODUCT_KLSI_DUH3E10BT, + 0, + "Kawasaki LSI", + "USB ethernet controller engine", + }, + { + USB_VENDOR_KAWATSU, USB_PRODUCT_KAWATSU_MH4000P, + 0, + "Kawatsu Semiconductor, Inc.", + "MiniHub 4000P", + }, + { + USB_VENDOR_KENSINGTON, USB_PRODUCT_KENSINGTON_ORBIT, + 0, + "Kensington", + "Orbit USB/PS2 trackball", + }, + { + USB_VENDOR_KENSINGTON, USB_PRODUCT_KENSINGTON_TURBOBALL, + 0, + "Kensington", + "TurboBall", + }, + { + USB_VENDOR_KODAK, USB_PRODUCT_KODAK_DC220, + 0, + "Eastman Kodak Corp.", + "Digital Science DC220", + }, + { + USB_VENDOR_KODAK, USB_PRODUCT_KODAK_DC260, + 0, + "Eastman Kodak Corp.", + "Digital Science DC260", + }, + { + USB_VENDOR_KODAK, USB_PRODUCT_KODAK_DC265, + 0, + "Eastman Kodak Corp.", + "Digital Science DC265", + }, + { + USB_VENDOR_KODAK, USB_PRODUCT_KODAK_DC290, + 0, + "Eastman Kodak Corp.", + "Digital Science DC290", + }, + { + USB_VENDOR_KODAK, USB_PRODUCT_KODAK_DC240, + 0, + "Eastman Kodak Corp.", + "Digital Science DC240", + }, + { + USB_VENDOR_KODAK, USB_PRODUCT_KODAK_DC280, + 0, + "Eastman Kodak Corp.", + "Digital Science DC280", + }, + { + USB_VENDOR_KONICA, USB_PRODUCT_KONICA_CAMERA, + 0, + "Konica Corp.", + "Digital Color Camera", + }, + { + USB_VENDOR_KYE, USB_PRODUCT_KYE_NICHE, + 0, + "KYE Systems Corp.", + "Niche mouse", + }, + { + USB_VENDOR_KYE, USB_PRODUCT_KYE_NETSCROLL, + 0, + "KYE Systems Corp.", + "Genius NetScroll mouse", + }, + { + USB_VENDOR_KYE, USB_PRODUCT_KYE_FLIGHT2000, + 0, + "KYE Systems Corp.", + "Flight 2000 joystick", + }, + { + USB_VENDOR_LEXMARK, USB_PRODUCT_LEXMARK_S2450, + 0, + "Lexmark International Inc.", + "Optra S 2450", + }, + { + USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10T, + 0, + "Linksys Inc.", + "USB10T Ethernet", + }, + { + USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB100TX, + 0, + "Linksys Inc.", + "USB100TX Ethernet", }, { USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_M2452, @@ -491,226 +640,382 @@ struct usb_knowndev usb_knowndevs[] = { "M2452 keyboard", }, { - USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_M4848, + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_M4848, + 0, + "Logitech Inc.", + "M4848 mouse", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAM, + 0, + "Logitech Inc.", + "QuickCam", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMPRO, + 0, + "Logitech Inc.", + "QuickCam Pro", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_N43, + 0, + "Logitech Inc.", + "N43", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_N48, + 0, + "Logitech Inc.", + "N48 mouse", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_MBA47, + 0, + "Logitech Inc.", + "M-BA47 mouse", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_WMMOUSE, + 0, + "Logitech Inc.", + "WingMan Gaming Mouse", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_WMPAD, + 0, + "Logitech Inc.", + "WingMan GamePad Extreme", + }, + { + USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_WMJOY, + 0, + "Logitech Inc.", + "WingMan Force joystick", + }, + { + USB_VENDOR_LUCENT, USB_PRODUCT_LUCENT_EVALKIT, + 0, + "Lucent", + "USS-720 evaluation kit", + }, + { + USB_VENDOR_MACALLY, USB_PRODUCT_MACALLY_MOUSE1, + 0, + "Macally", + "mouse", + }, + { + USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUATX, + 0, + "Melco Inc.", + "LU-ATX Ethernet", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_SIDEPREC, + 0, + "Microsoft", + "SideWinder Precision Pro", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_INTELLIMOUSE, + 0, + "Microsoft", + "IntelliMouse", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_NATURALKBD, + 0, + "Microsoft", + "Natural Keyboard Elite", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_DDS80, + 0, + "Microsoft", + "Digital Sound System 80", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_SIDEWINDER, + 0, + "Microsoft", + "Sidewinder Precision Racing Wheel", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_INTELLIEYE, + 0, + "Microsoft", + "IntelliEye mouse", + }, + { + USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_INETPRO, + 0, + "Microsoft", + "Internet Keyboard Pro", + }, + { + USB_VENDOR_MIDIMAN, USB_PRODUCT_MIDIMAN_MIDISPORT2X2, + 0, + "Midiman", + "Midisport 2x2", + }, + { + USB_VENDOR_MOTOROLA, USB_PRODUCT_MOTOROLA_MC141555, + 0, + "Motorola", + "MC141555 hub controller", + }, + { + USB_VENDOR_MULTITECH, USB_PRODUCT_MULTITECH_ATLAS, + 0, + "MultiTech", + "MT5634ZBA-USB modem", + }, + { + USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_MDC800, + 0, + "Mustek Systems Inc.", + "MDC-800 digital camera", + }, + { + USB_VENDOR_NEC, USB_PRODUCT_NEC_HUB, + 0, + "NEC", + "hub", + }, + { + USB_VENDOR_NEC, USB_PRODUCT_NEC_HUB_B, + 0, + "NEC", + "hub", + }, + { + USB_VENDOR_NETCHIP, USB_PRODUCT_NETCHIP_TURBOCONNECT, 0, - "Logitech Inc.", - "M4848 mouse", + "NetChip Technology", + "Turbo-Connect", }, { - USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAM, + USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_EA101, 0, - "Logitech Inc.", - "QuickCam", + "BayNETGEAR Inc.", + "Ethernet adapter", }, { - USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMPRO, + USB_VENDOR_OMNIVISION, USB_PRODUCT_OMNIVISION_OV511, 0, - "Logitech Inc.", - "QuickCam Pro", + "OmniVision", + "OV511 Camera", }, { - USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_N48, + USB_VENDOR_PALM, USB_PRODUCT_PALM_SERIAL, 0, - "Logitech Inc.", - "N48 mouse", + "Palm Computing, Inc.", + "USB Serial Adaptor", }, { - USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_MBA47, + USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_SERIAL1, 0, - "Logitech Inc.", - "M-BA47 mouse", + "Peracom Networks Inc.", + "Serial Converter", }, { - USB_VENDOR_KLSI, USB_PRODUCT_KLSI_USB101, + USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_ENET, 0, - "Kawasaki LSI", - "USB ethernet controller engine", + "Peracom Networks Inc.", + "Ethernet adapter", }, { - USB_VENDOR_PIENGINEERING, USB_PRODUCT_PIENGINEERING_PS2USB, + USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_ENET2, 0, - "P.I. Engineering", - "PS2 to Mac USB Adapter", + "Peracom Networks Inc.", + "Ethernet adapter", }, { - USB_VENDOR_CHIC, USB_PRODUCT_CHIC_MOUSE1, + USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_DSS350, 0, - "Chic Technology", - "mouse", + "Philips", + "DSS 350 Digital Speaker System", }, { - USB_VENDOR_MACALLY, USB_PRODUCT_MACALLY_MOUSE1, + USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_DSS, 0, - "Macally", - "mouse", + "Philips", + "DSS XXX Digital Speaker System", }, { - USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10T, + USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_HUB, 0, - "Linksys Inc.", - "USB10T Ethernet", + "Philips", + "hub", }, { - USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB100TX, + USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_DSS150, 0, - "Linksys Inc.", - "USB100TX Ethernet", + "Philips", + "DSS 150 Digital Speaker System", }, { - USB_VENDOR_MULTITECH, USB_PRODUCT_MULTITECH_ATLAS, + USB_VENDOR_PIENGINEERING, USB_PRODUCT_PIENGINEERING_PS2USB, 0, - "MultiTech", - "MT5634ZBA-USB modem", + "P.I. Engineering", + "PS2 to Mac USB Adapter", }, { - USB_VENDOR_ADS, USB_PRODUCT_ADS_UBS10BT, + USB_VENDOR_PLX, USB_PRODUCT_PLX_TESTBOARD, 0, - "ADS Technologies", - "Ethernet adapter", + "PLX", + "test board", }, { - USB_VENDOR_SMC, USB_PRODUCT_SMC_2102USB, + USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_COMFORT, 0, - "Standard Microsystems Corp", - "10Mbps ethernet adapter", + "Primax Electronics", + "Comfort", }, { - USB_VENDOR_SMC, USB_PRODUCT_SMC_2202USB, + USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_MOUSEINABOX, 0, - "Standard Microsystems Corp", - "10/100 ethernet adapter", + "Primax Electronics", + "Mouse-in-a-Box", }, { - USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_1S, + USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_PCGAUMS1, 0, - "Entrega", - "1S serial connector", + "Primax Electronics", + "Sony PCGA-UMS1", }, { - USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_2S, + USB_VENDOR_QUICKSHOT, USB_PRODUCT_QUICKSHOT_STRIKEPAD, 0, - "Entrega", - "2S serial connector", + "Quickshot", + "USB StrikePad", }, { - USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_1S25, + USB_VENDOR_ROCKFIRE, USB_PRODUCT_ROCKFIRE_GAMEPAD, 0, - "Entrega", - "1S25 serial connector", + "Rockfire", + "gamepad 203USB", }, { - USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_4S, + USB_VENDOR_QTRONIX, USB_PRODUCT_QTRONIX_980N, 0, - "Entrega", - "4S serial connector", + "Qtronix Corp", + "Scorpion-980N keyboard", }, { - USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_E45, + USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_IMAGEMATE, 0, - "Entrega", - "E45 Ethernet adapter", + "SanDisk Corp", + "USB ImageMate", }, { - USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_CENTRONICS, + USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSB, 0, - "Entrega", - "Centronics connector", + "Shuttle Technology", + "E-USB Bridge", }, { - USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_1S9, + USB_VENDOR_SIIG, USB_PRODUCT_SIIG_DIGIFILMREADER, 0, - "Entrega", - "1S9 serial connector", + "SIIG", + "DigiFilm-Combo Reader", }, { - USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_EZUSB, + USB_VENDOR_SIRIUS, USB_PRODUCT_SIRIUS_ROADSTER, 0, - "Entrega", - "EZ-USB", + "Sirius Technologies", + "NetComm Roadster II 56 USB", }, { - USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650C, + USB_VENDOR_SMC, USB_PRODUCT_SMC_2102USB, 0, - "D-Link Corp", + "Standard Microsystems Corp", "10Mbps ethernet adapter", }, { - USB_VENDOR_MIDIMAN, USB_PRODUCT_MIDIMAN_MIDISPORT2X2, + USB_VENDOR_SMC, USB_PRODUCT_SMC_2202USB, 0, - "Midiman", - "Midisport 2x2", + "Standard Microsystems Corp", + "10/100 ethernet adapter", }, { - USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_IMAGEMATE, + USB_VENDOR_SOLIDYEAR, USB_PRODUCT_SOLIDYEAR_KEYBOARD, 0, - "SanDisk Corp", - "USB ImageMate", + "Solid Year", + "Solid Year USB keyboard", }, { - USB_VENDOR_COREGA, USB_PRODUCT_COREGA_ETHER_USB_T, + USB_VENDOR_STMICRO, USB_PRODUCT_STMICRO_COMMUNICATOR, 0, - "Corega", - "Ether USB-T", + "STMicroelectronics", + "USB Communicator", }, { - USB_VENDOR_SIIG, USB_PRODUCT_SIIG_DIGIFILMREADER, + USB_VENDOR_SUN, USB_PRODUCT_SUN_KEYBOARD, 0, - "SIIG", - "DigiFilm-Combo Reader", + "Sun Microsystems", + "Type 6 USB", }, { - USB_VENDOR_HANDSPRING, USB_PRODUCT_HANDSPRING_VISOR, + USB_VENDOR_TELEX, USB_PRODUCT_TELEX_MIC1, 0, - "Handspring Inc.", - "Handspring Visor", + "Telex Communications Inc.", + "Enhanced USB Microphone", }, { - USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_EA101, + USB_VENDOR_TI, USB_PRODUCT_TI_UTUSB41, 0, - "BayNETGEAR Inc.", - "Ethernet adapter", + "Texas Instruments", + "UT-USB41 hub", }, { - USB_VENDOR_ACTIVEWIRE, USB_PRODUCT_ACTIVEWIRE_IOBOARD, + USB_VENDOR_THRUST, USB_PRODUCT_THRUST_FUSION_PAD, 0, - "ActiveWire Inc.", - "I/O Board", + "Thrustmaster", + "Fusion Digital Gamepad", }, { - USB_VENDOR_ACTIVEWIRE, USB_PRODUCT_ACTIVEWIRE_IOBOARD_FW1, + USB_VENDOR_UNIACCESS, USB_PRODUCT_UNIACCESS_PANACHE, 0, - "ActiveWire Inc.", - "I/O Board, rev. 1 firmware", + "Universal Access", + "Panache Surf USB ISDN Adapter", }, { - USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USB100, + USB_VENDOR_VISION, USB_PRODUCT_VISION_VC6452V002, 0, - "Billionton Systems Inc.", - "USB100N 10/100 FastEthernet Adapter", + "VLSI Vision Ltd.", + "VC6452V002 Camera", }, { - USB_VENDOR_MOTOROLA, USB_PRODUCT_MOTOROLA_MC141555, + USB_VENDOR_WACOM, USB_PRODUCT_WACOM_CT0405U, 0, - "Motorola", - "MC141555 hub controller", + "WACOM Corp. Ltd.", + "CT-0405-U Tablet", }, { - USB_VENDOR_PLX, USB_PRODUCT_PLX_TESTBOARD, + USB_VENDOR_WACOM, USB_PRODUCT_WACOM_GRAPHIRE, 0, - "PLX", - "test board", + "WACOM Corp. Ltd.", + "Graphire", }, { - USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORT4, + USB_VENDOR_WACOM, USB_PRODUCT_WACOM_INTUOSA5, 0, - "Inside Out Networks", - "EdgePort/4 serial ports", + "WACOM Corp. Ltd.", + "Intuos A5", }, { - USB_VENDOR_INTEL, USB_PRODUCT_INTEL_TESTBOARD, + USB_VENDOR_YEDATA, USB_PRODUCT_YEDATA_FLASHBUSTERU, 0, - "Intel", - "82930 test board", + "Y-E Data", + "Flashbuster-U", + }, + { + USB_VENDOR_ZOOM, USB_PRODUCT_ZOOM_2986L, + 0, + "Zoom Telephonics Inc.", + "2986L Fax modem", }, { USB_VENDOR_AOX, 0, @@ -724,6 +1029,12 @@ struct usb_knowndev usb_knowndevs[] = { "Hewlett Packard", NULL, }, + { + USB_VENDOR_FUTURE, 0, + USB_KNOWNDEV_NOPROD, + "Future Technology Devices", + NULL, + }, { USB_VENDOR_NEC, 0, USB_KNOWNDEV_NOPROD, @@ -754,6 +1065,12 @@ struct usb_knowndev usb_knowndevs[] = { "Advanced Gravis Computer Tech. Ltd.", NULL, }, + { + USB_VENDOR_SUN, 0, + USB_KNOWNDEV_NOPROD, + "Sun Microsystems", + NULL, + }, { USB_VENDOR_LEXMARK, 0, USB_KNOWNDEV_NOPROD, @@ -826,6 +1143,12 @@ struct usb_knowndev usb_knowndevs[] = { "Connectix Corp.", NULL, }, + { + USB_VENDOR_KENSINGTON, 0, + USB_KNOWNDEV_NOPROD, + "Kensington", + NULL, + }, { USB_VENDOR_LUCENT, 0, USB_KNOWNDEV_NOPROD, @@ -863,7 +1186,13 @@ struct usb_knowndev usb_knowndevs[] = { NULL, }, { - USB_VENDOR_3COM, 0, + USB_VENDOR_IODATA, 0, + USB_KNOWNDEV_NOPROD, + "I/O DATA", + NULL, + }, + { + USB_VENDOR_3COMUSR, 0, USB_KNOWNDEV_NOPROD, "U.S. Robotics", NULL, @@ -904,6 +1233,12 @@ struct usb_knowndev usb_knowndevs[] = { "Dallas Semiconductor", NULL, }, + { + USB_VENDOR_3COM, 0, + USB_KNOWNDEV_NOPROD, + "3Com Corp.", + NULL, + }, { USB_VENDOR_BELKIN, 0, USB_KNOWNDEV_NOPROD, @@ -922,6 +1257,12 @@ struct usb_knowndev usb_knowndevs[] = { "American Power Conversion", NULL, }, + { + USB_VENDOR_NETCHIP, 0, + USB_KNOWNDEV_NOPROD, + "NetChip Technology", + NULL, + }, { USB_VENDOR_AKS, 0, USB_KNOWNDEV_NOPROD, @@ -994,6 +1335,18 @@ struct usb_knowndev usb_knowndevs[] = { "Elecom Corp. Ltd.", NULL, }, + { + USB_VENDOR_YEDATA, 0, + USB_KNOWNDEV_NOPROD, + "Y-E Data", + NULL, + }, + { + USB_VENDOR_QUICKSHOT, 0, + USB_KNOWNDEV_NOPROD, + "Quickshot", + NULL, + }, { USB_VENDOR_ROCKFIRE, 0, USB_KNOWNDEV_NOPROD, @@ -1024,6 +1377,12 @@ struct usb_knowndev usb_knowndevs[] = { "Apple Computer", NULL, }, + { + USB_VENDOR_DIGI, 0, + USB_KNOWNDEV_NOPROD, + "Digi International", + NULL, + }, { USB_VENDOR_QTRONIX, 0, USB_KNOWNDEV_NOPROD, @@ -1060,6 +1419,12 @@ struct usb_knowndev usb_knowndevs[] = { "Chic Technology", NULL, }, + { + USB_VENDOR_SOLIDYEAR, 0, + USB_KNOWNDEV_NOPROD, + "Solid Year", + NULL, + }, { USB_VENDOR_MACALLY, 0, USB_KNOWNDEV_NOPROD, @@ -1084,6 +1449,12 @@ struct usb_knowndev usb_knowndevs[] = { "ADS Technologies", NULL, }, + { + USB_VENDOR_SIRIUS, 0, + USB_KNOWNDEV_NOPROD, + "Sirius Technologies", + NULL, + }, { USB_VENDOR_SMC, 0, USB_KNOWNDEV_NOPROD, @@ -1102,6 +1473,12 @@ struct usb_knowndev usb_knowndevs[] = { "SanDisk Corp", NULL, }, + { + USB_VENDOR_ADMTEK, 0, + USB_KNOWNDEV_NOPROD, + "ADMtek Inc.", + NULL, + }, { USB_VENDOR_COREGA, 0, USB_KNOWNDEV_NOPROD, @@ -1114,12 +1491,30 @@ struct usb_knowndev usb_knowndevs[] = { "SIIG", NULL, }, + { + USB_VENDOR_ZOOM, 0, + USB_KNOWNDEV_NOPROD, + "Zoom Telephonics Inc.", + NULL, + }, { USB_VENDOR_HANDSPRING, 0, USB_KNOWNDEV_NOPROD, "Handspring Inc.", NULL, }, + { + USB_VENDOR_PALM, 0, + USB_KNOWNDEV_NOPROD, + "Palm Computing, Inc.", + NULL, + }, + { + USB_VENDOR_DIAMOND, 0, + USB_KNOWNDEV_NOPROD, + "Diamond", + NULL, + }, { USB_VENDOR_NETGEAR, 0, USB_KNOWNDEV_NOPROD, diff --git a/sys/dev/usb/usbdi.c b/sys/dev/usb/usbdi.c index 2765d7b4b07..eddcf375d01 100644 --- a/sys/dev/usb/usbdi.c +++ b/sys/dev/usb/usbdi.c @@ -1,5 +1,6 @@ -/* $OpenBSD: usbdi.c,v 1.8 2000/03/26 08:39:46 aaron Exp $ */ -/* $NetBSD: usbdi.c,v 1.65 2000/03/08 15:34:10 augustss Exp $ */ +/* $OpenBSD: usbdi.c,v 1.9 2000/03/28 19:37:52 aaron Exp $ */ +/* $NetBSD: usbdi.c,v 1.68 2000/03/25 18:02:33 augustss Exp $ */ +/* $FreeBSD: src/sys/dev/usb/usbdi.c,v 1.28 1999/11/17 22:33:49 n_hibma Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -77,11 +78,11 @@ extern int usbdebug; #endif static usbd_status usbd_ar_pipe __P((usbd_pipe_handle pipe)); -void usbd_do_request_async_cb - __P((usbd_xfer_handle, usbd_private_handle, usbd_status)); -void usbd_start_next __P((usbd_pipe_handle pipe)); -usbd_status usbd_open_pipe_ival - __P((usbd_interface_handle, u_int8_t, u_int8_t, usbd_pipe_handle *, int)); +static void usbd_do_request_async_cb + __P((usbd_xfer_handle, usbd_private_handle, usbd_status)); +static void usbd_start_next __P((usbd_pipe_handle pipe)); +static usbd_status usbd_open_pipe_ival + __P((usbd_interface_handle, u_int8_t, u_int8_t, usbd_pipe_handle *, int)); static int usbd_nbuses = 0; @@ -134,18 +135,18 @@ usbd_open_pipe(iface, address, flags, pipe) u_int8_t flags; usbd_pipe_handle *pipe; { - return (usbd_open_pipe_ival(iface, address, flags, pipe, + return (usbd_open_pipe_ival(iface, address, flags, pipe, USBD_DEFAULT_INTERVAL)); } -usbd_status +usbd_status usbd_open_pipe_ival(iface, address, flags, pipe, ival) usbd_interface_handle iface; u_int8_t address; u_int8_t flags; usbd_pipe_handle *pipe; int ival; -{ +{ usbd_pipe_handle p; struct usbd_endpoint *ep; usbd_status err; @@ -192,7 +193,7 @@ usbd_open_pipe_intr(iface, address, flags, pipe, priv, buffer, len, cb, ival) DPRINTFN(3,("usbd_open_pipe_intr: address=0x%x flags=0x%x len=%d\n", address, flags, len)); - err = usbd_open_pipe_ival(iface, address, USBD_EXCLUSIVE_USE, + err = usbd_open_pipe_ival(iface, address, USBD_EXCLUSIVE_USE, &ipipe, ival); if (err) return (err); @@ -202,7 +203,7 @@ usbd_open_pipe_intr(iface, address, flags, pipe, priv, buffer, len, cb, ival) goto bad1; } usbd_setup_xfer(xfer, ipipe, priv, buffer, len, flags, - USBD_NO_TIMEOUT, cb); + USBD_NO_TIMEOUT, cb); ipipe->intrxfer = xfer; ipipe->repeat = 1; err = usbd_transfer(xfer); @@ -212,7 +213,7 @@ usbd_open_pipe_intr(iface, address, flags, pipe, priv, buffer, len, cb, ival) return (USBD_NORMAL_COMPLETION); bad2: - ipipe->intrxfer = 0; + ipipe->intrxfer = NULL; ipipe->repeat = 0; usbd_free_xfer(xfer); bad1: @@ -238,6 +239,12 @@ usbd_close_pipe(pipe) LIST_REMOVE(pipe, next); pipe->endpoint->refcnt--; pipe->methods->close(pipe); +#if defined(__NetBSD__) && defined(DIAGNOSTIC) + if (callout_pending(&pipe->abort_handle)) { + callout_stop(&pipe->abort_handle); + printf("usbd_close_pipe: abort_handle pending"); + } +#endif if (pipe->intrxfer != NULL) usbd_free_xfer(pipe->intrxfer); free(pipe, M_USB); @@ -381,9 +388,10 @@ usbd_alloc_xfer(dev) usbd_xfer_handle xfer; xfer = dev->bus->methods->allocx(dev->bus); - if (!xfer) + if (xfer == NULL) return (NULL); xfer->device = dev; + usb_callout_init(xfer->timeout_handle); DPRINTFN(5,("usbd_alloc_xfer() = %p\n", xfer)); return (xfer); } @@ -395,6 +403,12 @@ usbd_free_xfer(xfer) DPRINTFN(5,("usbd_free_xfer: %p\n", xfer)); if (xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF)) usbd_free_buffer(xfer); +#if defined(__NetBSD__) && defined(DIAGNOSTIC) + if (callout_pending(&xfer->timeout_handle)) { + callout_stop(&xfer->timeout_handle); + printf("usbd_free_xfer: timout_handle pending"); + } +#endif xfer->device->bus->methods->freex(xfer->device->bus, xfer); return (USBD_NORMAL_COMPLETION); } @@ -777,8 +791,8 @@ usb_transfer_complete(xfer) SPLUSBCHECK; - DPRINTFN(5, ("usb_transfer_complete: pipe=%p xfer=%p status=%d actlen=%d\n", - pipe, xfer, xfer->status, xfer->actlen)); + DPRINTFN(5, ("usb_transfer_complete: pipe=%p xfer=%p status=%d " + "actlen=%d\n", pipe, xfer, xfer->status, xfer->actlen)); #ifdef DIAGNOSTIC if (pipe == NULL) { @@ -821,7 +835,7 @@ usb_transfer_complete(xfer) #endif SIMPLEQ_REMOVE_HEAD(&pipe->queue, xfer, next); } - DPRINTFN(5,("usb_transfer_complete: repeat=%d new head=%p\n", + DPRINTFN(5,("usb_transfer_complete: repeat=%d new head=%p\n", repeat, SIMPLEQ_FIRST(&pipe->queue))); /* Count completed transfers. */ @@ -829,10 +843,10 @@ usb_transfer_complete(xfer) [pipe->endpoint->edesc->bmAttributes & UE_XFERTYPE]; xfer->done = 1; - if (xfer->status && xfer->actlen < xfer->length && + if (!xfer->status && xfer->actlen < xfer->length && !(xfer->flags & USBD_SHORT_XFER_OK)) { - DPRINTFN(-1, ("usbd_transfer_cb: short xfer %d<%d (bytes)\n", - xfer->actlen, xfer->length)); + DPRINTFN(-1,("usbd_transfer_cb: short transfer %d<%d\n", + xfer->actlen, xfer->length)); xfer->status = USBD_SHORT_XFER; } @@ -854,8 +868,8 @@ usb_transfer_complete(xfer) if (!repeat) { /* XXX should we stop the queue on all errors? */ if ((xfer->status == USBD_CANCELLED || - xfer->status == USBD_TIMEOUT) && - pipe->iface != NULL) /* not control pipe */ + xfer->status == USBD_TIMEOUT) && + pipe->iface != NULL) /* not control pipe */ pipe->running = 0; else usbd_start_next(pipe); @@ -943,7 +957,7 @@ usbd_do_request_flags(dev, req, data, flags, actlen) #ifdef DIAGNOSTIC #if defined(__i386__) && defined(__FreeBSD__) KASSERT(intr_nesting_level == 0, - ("usbd_do_request: in interrupt context")); + ("usbd_do_request: in interrupt context")); #endif if (dev->bus->intr_context) { printf("usbd_do_request: not in process context\n"); @@ -1048,9 +1062,8 @@ usbd_do_request_async(dev, req, data) xfer = usbd_alloc_xfer(dev); if (xfer == NULL) return (USBD_NOMEM); - usbd_setup_default_xfer(xfer, dev, 0, USBD_DEFAULT_TIMEOUT, req, data, - UGETW(req->wLength), 0, - usbd_do_request_async_cb); + usbd_setup_default_xfer(xfer, dev, 0, USBD_DEFAULT_TIMEOUT, req, + data, UGETW(req->wLength), 0, usbd_do_request_async_cb); err = usbd_transfer(xfer); if (err != USBD_IN_PROGRESS) { usbd_free_xfer(xfer); @@ -1109,14 +1122,14 @@ usbd_get_endpoint_descriptor(iface, address) /* * usbd_ratecheck() can limit the number of error messages that occurs. * When a device is unplugged it may take up to 0.25s for the hub driver - * to notice it. If the driver continuously tries to do I/O operations + * to notice it. If the driver continuosly tries to do I/O operations * this can generate a large number of messages. */ int usbd_ratecheck(last) struct timeval *last; { - struct timeval errinterval = { 0, 250000 }; /* 0.25s */ + static struct timeval errinterval = { 0, 250000 }; /* 0.25 s*/ return (ratecheck(last, &errinterval)); } @@ -1127,7 +1140,7 @@ usbd_driver_load(module_t mod, int what, void *arg) { /* XXX should implement something like a function that removes all generic devices */ - return 0; + return (0); } #endif diff --git a/sys/dev/usb/usbdi.h b/sys/dev/usb/usbdi.h index 29f969c58cc..8447a6b4fdc 100644 --- a/sys/dev/usb/usbdi.h +++ b/sys/dev/usb/usbdi.h @@ -1,5 +1,6 @@ -/* $OpenBSD: usbdi.h,v 1.7 2000/03/26 08:39:46 aaron Exp $ */ -/* $NetBSD: usbdi.h,v 1.31 2000/03/02 12:37:51 augustss Exp $ */ +/* $OpenBSD: usbdi.h,v 1.8 2000/03/28 19:37:52 aaron Exp $ */ +/* $NetBSD: usbdi.h,v 1.41 2000/03/02 12:37:51 augustss Exp $ */ +/* $FreeBSD: src/sys/dev/usb/usbdi.h,v 1.18 1999/11/17 22:33:49 n_hibma Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -77,7 +78,7 @@ typedef void (*usbd_callback) __P((usbd_xfer_handle, usbd_private_handle, #define USBD_EXCLUSIVE_USE 0x01 /* Use default (specified by ep. desc.) interval on interrupt pipe */ -#define USBD_DEFAULT_INTERVAL (-1) +#define USBD_DEFAULT_INTERVAL (-1) /* Request flags */ #define USBD_NO_COPY 0x01 /* do not copy data to DMA buffer */ @@ -100,7 +101,7 @@ usbd_status usbd_open_pipe u_int8_t flags, usbd_pipe_handle *pipe)); usbd_status usbd_close_pipe __P((usbd_pipe_handle pipe)); usbd_status usbd_transfer __P((usbd_xfer_handle req)); -usbd_xfer_handle usbd_alloc_xfer __P((usbd_device_handle)); +usbd_xfer_handle usbd_alloc_xfer __P((usbd_device_handle)); usbd_status usbd_free_xfer __P((usbd_xfer_handle xfer)); void usbd_setup_xfer __P((usbd_xfer_handle xfer, usbd_pipe_handle pipe, @@ -112,7 +113,7 @@ void usbd_setup_default_xfer usbd_private_handle priv, u_int32_t timeout, usb_device_request_t *req, void *buffer, u_int32_t length, u_int16_t flags, usbd_callback)); -void usbd_setup_isoc_xfer +void usbd_setup_isoc_xfer __P((usbd_xfer_handle xfer, usbd_pipe_handle pipe, usbd_private_handle priv, u_int16_t *frlengths, u_int32_t nframes, u_int16_t flags, usbd_callback)); @@ -261,4 +262,3 @@ int usbd_driver_load __P((module_t mod, int what, void *arg)); #define splhardusb splbio #define IPL_USB IPL_BIO /* XXX */ - diff --git a/sys/dev/usb/usbdi_util.c b/sys/dev/usb/usbdi_util.c index 152e81db2fa..10354e0f269 100644 --- a/sys/dev/usb/usbdi_util.c +++ b/sys/dev/usb/usbdi_util.c @@ -1,5 +1,6 @@ -/* $OpenBSD: usbdi_util.c,v 1.6 2000/03/26 08:39:46 aaron Exp $ */ +/* $OpenBSD: usbdi_util.c,v 1.7 2000/03/28 19:37:52 aaron Exp $ */ /* $NetBSD: usbdi_util.c,v 1.28 2000/02/22 11:25:06 augustss Exp $ */ +/* $FreeBSD: src/sys/dev/usb/usbdi_util.c,v 1.14 1999/11/17 22:33:50 n_hibma Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -93,12 +94,12 @@ usbd_get_config_desc(dev, confidx, d) usbd_status err; DPRINTFN(3,("usbd_get_config_desc: confidx=%d\n", confidx)); - err = usbd_get_desc(dev, UDESC_CONFIG, confidx, + err = usbd_get_desc(dev, UDESC_CONFIG, confidx, USB_CONFIG_DESCRIPTOR_SIZE, d); if (err) return (err); if (d->bDescriptorType != UDESC_CONFIG) { - DPRINTFN(-1,("usbd_get_config_desc: confidx=%d, bad desc ", + DPRINTFN(-1,("usbd_get_config_desc: confidx=%d, bad desc " "len=%d type=%d\n", confidx, d->bLength, d->bDescriptorType)); return (USBD_INVAL); @@ -484,7 +485,7 @@ usbd_get_config(dev, conf) return (usbd_do_request(dev, &req, conf)); } -static void usbd_bulk_transfer_cb __P((usbd_xfer_handle xfer, +static void usbd_bulk_transfer_cb __P((usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)); static void usbd_bulk_transfer_cb(xfer, priv, status) @@ -526,7 +527,7 @@ usbd_bulk_transfer(xfer, pipe, flags, timeout, buf, size, lbl) } usbd_get_xfer_status(xfer, NULL, NULL, size, &err); DPRINTFN(1,("usbd_bulk_transfer: transferred %d\n", *size)); - if (err != USBD_NORMAL_COMPLETION) { + if (err) { DPRINTF(("usbd_bulk_transfer: error=%d\n", err)); usbd_clear_endpoint_stall(pipe); } diff --git a/sys/dev/usb/usbdi_util.h b/sys/dev/usb/usbdi_util.h index 098316bac4d..d5dab901244 100644 --- a/sys/dev/usb/usbdi_util.h +++ b/sys/dev/usb/usbdi_util.h @@ -1,5 +1,6 @@ -/* $OpenBSD: usbdi_util.h,v 1.4 2000/03/26 08:39:46 aaron Exp $ */ +/* $OpenBSD: usbdi_util.h,v 1.5 2000/03/28 19:37:53 aaron Exp $ */ /* $NetBSD: usbdi_util.h,v 1.19 1999/11/18 23:32:37 augustss Exp $ */ +/* $FreeBSD: src/sys/dev/usb/usbdi_util.h,v 1.9 1999/11/17 22:33:50 n_hibma Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. diff --git a/sys/dev/usb/usbdivar.h b/sys/dev/usb/usbdivar.h index ad013bedc34..2d23ef4af1f 100644 --- a/sys/dev/usb/usbdivar.h +++ b/sys/dev/usb/usbdivar.h @@ -1,5 +1,6 @@ -/* $OpenBSD: usbdivar.h,v 1.7 2000/03/26 08:39:46 aaron Exp $ */ -/* $NetBSD: usbdivar.h,v 1.47 2000/02/22 11:30:56 augustss Exp $ */ +/* $OpenBSD: usbdivar.h,v 1.8 2000/03/28 19:37:53 aaron Exp $ */ +/* $NetBSD: usbdivar.h,v 1.52 2000/03/25 18:02:33 augustss Exp $ */ +/* $FreeBSD: src/sys/dev/usb/usbdivar.h,v 1.11 1999/11/17 22:33:51 n_hibma Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -38,6 +39,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#if defined(__NetBSD__) || defined(__FreeBSD__) +#include +#else +#include +#endif + /* From usb_mem.h */ DECLARE_USB_DMA_T; @@ -105,11 +112,11 @@ struct usbd_bus { struct usb_device_stats stats; int intr_context; u_int no_intrs; - int usbrev; /* USB revision */ -#define USBREV_UNKNOWN 0 -#define USBREV_PRE_1_0 1 -#define USBREV_1_0 2 -#define USBREV_1_1 3 + int usbrev; /* USB revision */ +#define USBREV_UNKNOWN 0 +#define USBREV_PRE_1_0 1 +#define USBREV_1_0 2 +#define USBREV_1_1 3 #define USBREV_STR { "unknown", "pre 1.0", "1.0", "1.1" } #if defined(__NetBSD__) || defined(__OpenBSD__) @@ -118,26 +125,26 @@ struct usbd_bus { }; struct usbd_device { - struct usbd_bus *bus; /* our controller */ - struct usbd_pipe *default_pipe; /* pipe 0 */ - u_int8_t address; /* device address */ - u_int8_t config; /* current configuration # */ - u_int8_t depth; /* distance from root hub */ - u_int8_t lowspeed; /* lowspeed flag */ - u_int8_t self_powered; /* flag for self powered */ - u_int16_t power; /* mA the device uses */ - int16_t langid; /* language for strings */ + struct usbd_bus *bus; /* our controller */ + struct usbd_pipe *default_pipe; /* pipe 0 */ + u_int8_t address; /* device addess */ + u_int8_t config; /* current configuration # */ + u_int8_t depth; /* distance from root hub */ + u_int8_t lowspeed; /* lowspeed flag */ + u_int8_t self_powered; /* flag for self powered */ + u_int16_t power; /* mA the device uses */ + int16_t langid; /* language for strings */ #define USBD_NOLANG (-1) - usb_event_cookie_t cookie; /* unique connection id */ - struct usbd_port *powersrc; /* upstream hub port, or 0 */ - struct usbd_endpoint def_ep; /* for pipe 0 */ - usb_endpoint_descriptor_t def_ep_desc; /* for pipe 0 */ - struct usbd_interface *ifaces; /* array of all interfaces */ - usb_device_descriptor_t ddesc; /* device descriptor */ - usb_config_descriptor_t *cdesc; /* full config descr */ - struct usbd_quirks *quirks; /* device quirks, always set */ - struct usbd_hub *hub; /* only if this is a hub */ - device_ptr_t *subdevs; /* sub-devices, 0 terminated */ + usb_event_cookie_t cookie; /* unique connection id */ + struct usbd_port *powersrc; /* upstream hub port, or 0 */ + struct usbd_endpoint def_ep; /* for pipe 0 */ + usb_endpoint_descriptor_t def_ep_desc; /* for pipe 0 */ + struct usbd_interface *ifaces; /* array of all interfaces */ + usb_device_descriptor_t ddesc; /* device descriptor */ + usb_config_descriptor_t *cdesc; /* full config descr */ + struct usbd_quirks *quirks; /* device quirks, always set */ + struct usbd_hub *hub; /* only if this is a hub */ + device_ptr_t *subdevs; /* sub-devices, 0 terminated */ }; struct usbd_interface { @@ -163,6 +170,8 @@ struct usbd_pipe { char repeat; int interval; + usb_callout_t abort_handle; + /* Filled by HC driver. */ struct usbd_pipe_methods *methods; }; @@ -178,6 +187,11 @@ struct usbd_xfer { usbd_status status; usbd_callback callback; __volatile char done; +#ifdef DIAGNOSTIC + u_int32_t busy_free; +#define XFER_FREE 0x46524545 +#define XFER_BUSY 0x42555357 +#endif /* For control pipe */ usb_device_request_t request; @@ -198,11 +212,8 @@ struct usbd_xfer { SIMPLEQ_ENTRY(usbd_xfer) next; void *hcpriv; /* private use by the HC driver */ - int hcprivint; -#if defined(__FreeBSD__) - struct callout_handle timo_handle; -#endif + usb_callout_t timeout_handle; }; void usbd_init __P((void)); @@ -243,7 +254,7 @@ void usb_schedsoftintr __P((struct usbd_bus *)); extern int cold; \ if (!cold && _s != _su) printf("SPLUSBCHECK failed 0x%x!=0x%x, %s:%d\n", \ _s, _su, __FILE__, __LINE__); \ - splx(_s); \ + splx(_s); \ } while (0) #else #define SPLUSBCHECK diff --git a/sys/dev/usb/usbhid.h b/sys/dev/usb/usbhid.h index 783fe75d397..945fa76ccd4 100644 --- a/sys/dev/usb/usbhid.h +++ b/sys/dev/usb/usbhid.h @@ -1,5 +1,6 @@ -/* $OpenBSD: usbhid.h,v 1.1 1999/08/13 05:28:05 fgsch Exp $ */ -/* $NetBSD: usbhid.h,v 1.5 1999/05/13 23:29:11 augustss Exp $ */ +/* $OpenBSD: usbhid.h,v 1.2 2000/03/28 19:37:53 aaron Exp $ */ +/* $NetBSD: usbhid.h,v 1.6 1999/11/18 23:32:37 augustss Exp $ */ +/* $FreeBSD: src/sys/dev/usb/usbhid.h,v 1.7 1999/11/17 22:33:51 n_hibma Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc.