summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/if_ndis/if_ndis.c4
-rw-r--r--sys/dev/if_ndis/if_ndis_pccard.c4
-rw-r--r--sys/dev/if_ndis/if_ndis_pci.c4
-rw-r--r--sys/dev/if_ndis/if_ndis_usb.c8
-rw-r--r--sys/dev/usb/FILES52
-rw-r--r--sys/dev/usb/dsbr100io.h39
-rw-r--r--sys/dev/usb/ehci.c3932
-rw-r--r--sys/dev/usb/ehci_ddb.c255
-rw-r--r--sys/dev/usb/ehci_ixp4xx.c360
-rw-r--r--sys/dev/usb/ehci_mbus.c396
-rw-r--r--sys/dev/usb/ehci_pci.c636
-rw-r--r--sys/dev/usb/ehcireg.h344
-rw-r--r--sys/dev/usb/ehcivar.h278
-rw-r--r--sys/dev/usb/hid.c469
-rw-r--r--sys/dev/usb/hid.h91
-rw-r--r--sys/dev/usb/if_aue.c1498
-rw-r--r--sys/dev/usb/if_auereg.h294
-rw-r--r--sys/dev/usb/if_axe.c1428
-rw-r--r--sys/dev/usb/if_axereg.h254
-rw-r--r--sys/dev/usb/if_cdce.c771
-rw-r--r--sys/dev/usb/if_cdcereg.h79
-rw-r--r--sys/dev/usb/if_cue.c1074
-rw-r--r--sys/dev/usb/if_cuereg.h168
-rw-r--r--sys/dev/usb/if_kue.c1024
-rw-r--r--sys/dev/usb/if_kuereg.h161
-rw-r--r--sys/dev/usb/if_rue.c1393
-rw-r--r--sys/dev/usb/if_ruereg.h226
-rw-r--r--sys/dev/usb/if_rum.c2560
-rw-r--r--sys/dev/usb/if_rumreg.h235
-rw-r--r--sys/dev/usb/if_rumvar.h161
-rw-r--r--sys/dev/usb/if_udav.c1962
-rw-r--r--sys/dev/usb/if_udavreg.h210
-rw-r--r--sys/dev/usb/if_upgt.c2375
-rw-r--r--sys/dev/usb/if_upgtvar.h462
-rw-r--r--sys/dev/usb/if_ural.c2505
-rw-r--r--sys/dev/usb/if_uralreg.h210
-rw-r--r--sys/dev/usb/if_uralvar.h157
-rw-r--r--sys/dev/usb/if_urtw.c3324
-rw-r--r--sys/dev/usb/if_urtwreg.h256
-rw-r--r--sys/dev/usb/if_urtwvar.h151
-rw-r--r--sys/dev/usb/if_zyd.c3126
-rw-r--r--sys/dev/usb/if_zydfw.h1144
-rw-r--r--sys/dev/usb/if_zydreg.h1322
-rw-r--r--sys/dev/usb/kue_fw.h685
-rw-r--r--sys/dev/usb/ohci.c3638
-rw-r--r--sys/dev/usb/ohci_pci.c411
-rw-r--r--sys/dev/usb/ohcireg.h250
-rw-r--r--sys/dev/usb/ohcivar.h164
-rw-r--r--sys/dev/usb/rio500_usb.h48
-rw-r--r--sys/dev/usb/rt2573_ucode.h213
-rw-r--r--sys/dev/usb/sl811hs.c1654
-rw-r--r--sys/dev/usb/sl811hsreg.h126
-rw-r--r--sys/dev/usb/sl811hsvar.h107
-rw-r--r--sys/dev/usb/slhci_pccard.c206
-rw-r--r--sys/dev/usb/u3g.c799
-rw-r--r--sys/dev/usb/uark.c339
-rw-r--r--sys/dev/usb/ubsa.c742
-rw-r--r--sys/dev/usb/ubser.c882
-rw-r--r--sys/dev/usb/ubser.h43
-rw-r--r--sys/dev/usb/uchcom.c1036
-rw-r--r--sys/dev/usb/ucom.c829
-rw-r--r--sys/dev/usb/ucomvar.h169
-rw-r--r--sys/dev/usb/ucycom.c543
-rw-r--r--sys/dev/usb/udbp.c860
-rw-r--r--sys/dev/usb/udbp.h80
-rw-r--r--sys/dev/usb/ufm.c376
-rw-r--r--sys/dev/usb/ufoma.c1192
-rw-r--r--sys/dev/usb/uftdi.c793
-rw-r--r--sys/dev/usb/uftdireg.h338
-rw-r--r--sys/dev/usb/ugen.c1590
-rw-r--r--sys/dev/usb/ugraphire_rdesc.h176
-rw-r--r--sys/dev/usb/uhci.c3704
-rw-r--r--sys/dev/usb/uhci_pci.c524
-rw-r--r--sys/dev/usb/uhcireg.h193
-rw-r--r--sys/dev/usb/uhcivar.h206
-rw-r--r--sys/dev/usb/uhid.c755
-rw-r--r--sys/dev/usb/uhub.c703
-rw-r--r--sys/dev/usb/uipaq.c822
-rw-r--r--sys/dev/usb/ukbd.c1538
-rw-r--r--sys/dev/usb/ulpt.c815
-rw-r--r--sys/dev/usb/umass.c3611
-rw-r--r--sys/dev/usb/umct.c511
-rw-r--r--sys/dev/usb/umodem.c821
-rw-r--r--sys/dev/usb/ums.c972
-rw-r--r--sys/dev/usb/uplcom.c990
-rw-r--r--sys/dev/usb/urio.c518
-rw-r--r--sys/dev/usb/usb.c939
-rw-r--r--sys/dev/usb/usb.h708
-rw-r--r--sys/dev/usb/usb_ethersubr.c283
-rw-r--r--sys/dev/usb/usb_ethersubr.h91
-rw-r--r--sys/dev/usb/usb_if.m42
-rw-r--r--sys/dev/usb/usb_mem.c297
-rw-r--r--sys/dev/usb/usb_mem.h58
-rw-r--r--sys/dev/usb/usb_port.h200
-rw-r--r--sys/dev/usb/usb_quirks.c153
-rw-r--r--sys/dev/usb/usb_quirks.h64
-rw-r--r--sys/dev/usb/usb_subr.c1388
-rw-r--r--sys/dev/usb/usbcdc.h188
-rw-r--r--sys/dev/usb/usbdevs2527
-rw-r--r--sys/dev/usb/usbdi.c1383
-rw-r--r--sys/dev/usb/usbdi.h289
-rw-r--r--sys/dev/usb/usbdi_util.c539
-rw-r--r--sys/dev/usb/usbdi_util.h98
-rw-r--r--sys/dev/usb/usbdivar.h322
-rw-r--r--sys/dev/usb/usbhid.h185
-rw-r--r--sys/dev/usb/uscanner.c723
-rw-r--r--sys/dev/usb/uslcom.c419
-rw-r--r--sys/dev/usb/uvisor.c639
-rw-r--r--sys/dev/usb/uvscom.c906
-rw-r--r--sys/dev/usb/uxb360gp_rdesc.h124
110 files changed, 10 insertions, 82929 deletions
diff --git a/sys/dev/if_ndis/if_ndis.c b/sys/dev/if_ndis/if_ndis.c
index 0005db4..d20308f 100644
--- a/sys/dev/if_ndis/if_ndis.c
+++ b/sys/dev/if_ndis/if_ndis.c
@@ -74,8 +74,8 @@ __FBSDID("$FreeBSD$");
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
+#include <legacy/dev/usb/usb.h>
+#include <legacy/dev/usb/usbdi.h>
#include <compat/ndis/pe_var.h>
#include <compat/ndis/cfg_var.h>
diff --git a/sys/dev/if_ndis/if_ndis_pccard.c b/sys/dev/if_ndis/if_ndis_pccard.c
index 7eb4cd6..d84550a 100644
--- a/sys/dev/if_ndis/if_ndis_pccard.c
+++ b/sys/dev/if_ndis/if_ndis_pccard.c
@@ -53,8 +53,8 @@ __FBSDID("$FreeBSD$");
#include <net80211/ieee80211_var.h>
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
+#include <legacy/dev/usb/usb.h>
+#include <legacy/dev/usb/usbdi.h>
#include <compat/ndis/pe_var.h>
#include <compat/ndis/cfg_var.h>
diff --git a/sys/dev/if_ndis/if_ndis_pci.c b/sys/dev/if_ndis/if_ndis_pci.c
index c03c502..afadd8a 100644
--- a/sys/dev/if_ndis/if_ndis_pci.c
+++ b/sys/dev/if_ndis/if_ndis_pci.c
@@ -54,8 +54,8 @@ __FBSDID("$FreeBSD$");
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
+#include <legacy/dev/usb/usb.h>
+#include <legacy/dev/usb/usbdi.h>
#include <compat/ndis/pe_var.h>
#include <compat/ndis/cfg_var.h>
diff --git a/sys/dev/if_ndis/if_ndis_usb.c b/sys/dev/if_ndis/if_ndis_usb.c
index b206982..1de308d 100644
--- a/sys/dev/if_ndis/if_ndis_usb.c
+++ b/sys/dev/if_ndis/if_ndis_usb.c
@@ -52,10 +52,10 @@ __FBSDID("$FreeBSD$");
#include <sys/bus.h>
#include <machine/bus.h>
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include <dev/usb/usbdivar.h>
+#include <legacy/dev/usb/usb.h>
+#include <legacy/dev/usb/usbdi.h>
+#include <legacy/dev/usb/usbdi_util.h>
+#include <legacy/dev/usb/usbdivar.h>
#include "usbdevs.h"
#include <net80211/ieee80211_var.h>
diff --git a/sys/dev/usb/FILES b/sys/dev/usb/FILES
deleted file mode 100644
index 5a77cbd..0000000
--- a/sys/dev/usb/FILES
+++ /dev/null
@@ -1,52 +0,0 @@
-$FreeBSD$
-
-A small roadmap of the USB files:
-
-FILES this file
-dsbr100io.h API for ufm.c
-ehci.c Host controller driver for EHCI
-ehcireg.h Hardware definitions for EHCI
-ehcivar.h API for ehci.c
-hid.c subroutines to parse and access HID data
-hid.h API for hid.c
-if_aue.c USB Pegasus Ethernet driver
-if_auereg.h and definitions for it
-if_axe.c USB ASIX Electronics Ethernet driver
-if_axereg.h and definitions for it
-if_cue.c USB CATC Ethernet driver
-if_cuereg.h and definitions for it
-if_kue.c USB Kawasaki Ethernet driver
-if_kuereg.h and definitions for it
-ohci.c Host controller driver for OHCI
-ohcireg.h Hardware definitions for OHCI
-ohcivar.h API for ohci.c
-ufm.c USB fm radio driver
-[Merged] ugen.c generic driver that can handle access to any USB device
-uhci.c Host controller driver for UHCI
-uhcireg.h Hardware definitions for UHCI
-uhcivar.h API for uhci.c
-uhid.c USB HID class driver
-uhub.c USB hub driver
-ukbd.c USB keyboard driver
-ulpt.c USB printer class driver
-umass.c USB mass storage driver
-umodem.c USB modem (CDC ACM) driver
-ums.c USB mouse driver
-urio.c USB Diamond Rio500 driver
-usb.c usb (bus) device driver
-usb.h general USB defines
-usb_mem.c memory allocation for DMAable memory
-usb_mem.h API for usb_mem.c
-usb_port.h compatibility defines for different OSs
-usb_quirks.c table of non-conforming USB devices and their problems
-usb_quirks.h API for usb_quirks.c
-usb_subr.c various subroutines used by USB code
-usbcdc.h USB CDC class definitions
-usbdevs data base of known device
-usbdi.c implementation of the USBDI API, which all drivers use
-usbdi.h API for usbdi.c
-usbdi_util.c utilities built on top of usbdi.h
-usbdi_util.h API for usbdi_util.c
-usbdivar.h internal defines and structures for usbdi.c
-uscanner.c minimal USB scanner driver
-usbhid.h USB HID class definitions
diff --git a/sys/dev/usb/dsbr100io.h b/sys/dev/usb/dsbr100io.h
deleted file mode 100644
index f1c8a97..0000000
--- a/sys/dev/usb/dsbr100io.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*-
- * Copyright (c) 2001 M. Warner Losh
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- * This code is based on ugen.c and ulpt.c developed by Lennart Augustsson.
- * This code includes software developed by the NetBSD Foundation, Inc. and
- * its contributors.
- */
-
-/* $FreeBSD$ */
-
-#include <sys/ioccom.h>
-
-#define FM_SET_FREQ _IOWR('U', 200, int)
-#define FM_GET_FREQ _IOWR('U', 201, int)
-#define FM_START _IOWR('U', 202, int)
-#define FM_STOP _IOWR('U', 203, int)
-#define FM_GET_STAT _IOWR('U', 204, int)
diff --git a/sys/dev/usb/ehci.c b/sys/dev/usb/ehci.c
deleted file mode 100644
index c159600..0000000
--- a/sys/dev/usb/ehci.c
+++ /dev/null
@@ -1,3932 +0,0 @@
-/* $NetBSD: ehci.c,v 1.91 2005/02/27 00:27:51 perry Exp $ */
-
-/*-
- * Copyright (c) 2004 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) and by Charles M. Hannum.
- *
- * 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.
- */
-
-/*
- * USB Enhanced Host Controller Driver, a.k.a. USB 2.0 controller.
- *
- * The EHCI 1.0 spec can be found at
- * http://developer.intel.com/technology/usb/download/ehci-r10.pdf
- * and the USB 2.0 spec at
- * http://www.usb.org/developers/docs/usb_20.zip
- *
- */
-
-/*
- * TODO:
- * 1) The EHCI driver lacks support for isochronous transfers, so
- * devices using them don't work.
- *
- * 2) Interrupt transfer scheduling does not manage the time available
- * in each frame, so it is possible for the transfers to overrun
- * the end of the frame.
- *
- * 3) Command failures are not recovered correctly.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/malloc.h>
-#include <sys/kernel.h>
-#include <sys/endian.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/lock.h>
-#include <sys/lockmgr.h>
-#if defined(DIAGNOSTIC) && defined(__i386__) && defined(__FreeBSD__)
-#include <machine/cpu.h>
-#endif
-#include <sys/proc.h>
-#include <sys/queue.h>
-#include <sys/sysctl.h>
-
-#include <machine/bus.h>
-#include <machine/endian.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdivar.h>
-#include <dev/usb/usb_mem.h>
-#include <dev/usb/usb_quirks.h>
-
-#include <dev/usb/ehcireg.h>
-#include <dev/usb/ehcivar.h>
-
-#define delay(d) DELAY(d)
-
-#ifdef USB_DEBUG
-#define EHCI_DEBUG USB_DEBUG
-#define DPRINTF(x) do { if (ehcidebug) printf x; } while (0)
-#define DPRINTFN(n,x) do { if (ehcidebug>(n)) printf x; } while (0)
-int ehcidebug = 0;
-SYSCTL_NODE(_hw_usb, OID_AUTO, ehci, CTLFLAG_RW, 0, "USB ehci");
-SYSCTL_INT(_hw_usb_ehci, OID_AUTO, debug, CTLFLAG_RW,
- &ehcidebug, 0, "ehci debug level");
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-struct ehci_pipe {
- struct usbd_pipe pipe;
-
- ehci_soft_qh_t *sqh;
- union {
- ehci_soft_qtd_t *qtd;
- /* ehci_soft_itd_t *itd; */
- } tail;
- union {
- /* Control pipe */
- struct {
- usb_dma_t reqdma;
- u_int length;
- /*ehci_soft_qtd_t *setup, *data, *stat;*/
- } ctl;
- /* Interrupt pipe */
- struct {
- u_int length;
- } intr;
- /* Bulk pipe */
- struct {
- u_int length;
- } bulk;
- /* Iso pipe */
- struct {
- u_int next_frame;
- u_int cur_xfers;
- } isoc;
- } u;
-};
-
-static usbd_status ehci_open(usbd_pipe_handle);
-static void ehci_poll(struct usbd_bus *);
-static void ehci_softintr(void *);
-static int ehci_intr1(ehci_softc_t *);
-static void ehci_waitintr(ehci_softc_t *, usbd_xfer_handle);
-static void ehci_check_intr(ehci_softc_t *, struct ehci_xfer *);
-static void ehci_check_qh_intr(ehci_softc_t *, struct ehci_xfer *);
-static void ehci_check_itd_intr(ehci_softc_t *, struct ehci_xfer *);
-static void ehci_idone(struct ehci_xfer *);
-static void ehci_timeout(void *);
-static void ehci_timeout_task(void *);
-static void ehci_intrlist_timeout(void *);
-
-static usbd_status ehci_allocm(struct usbd_bus *, usb_dma_t *, u_int32_t);
-static void ehci_freem(struct usbd_bus *, usb_dma_t *);
-
-static usbd_xfer_handle ehci_allocx(struct usbd_bus *);
-static void ehci_freex(struct usbd_bus *, usbd_xfer_handle);
-
-static usbd_status ehci_root_ctrl_transfer(usbd_xfer_handle);
-static usbd_status ehci_root_ctrl_start(usbd_xfer_handle);
-static void ehci_root_ctrl_abort(usbd_xfer_handle);
-static void ehci_root_ctrl_close(usbd_pipe_handle);
-static void ehci_root_ctrl_done(usbd_xfer_handle);
-
-static usbd_status ehci_root_intr_transfer(usbd_xfer_handle);
-static usbd_status ehci_root_intr_start(usbd_xfer_handle);
-static void ehci_root_intr_abort(usbd_xfer_handle);
-static void ehci_root_intr_close(usbd_pipe_handle);
-static void ehci_root_intr_done(usbd_xfer_handle);
-
-static usbd_status ehci_device_ctrl_transfer(usbd_xfer_handle);
-static usbd_status ehci_device_ctrl_start(usbd_xfer_handle);
-static void ehci_device_ctrl_abort(usbd_xfer_handle);
-static void ehci_device_ctrl_close(usbd_pipe_handle);
-static void ehci_device_ctrl_done(usbd_xfer_handle);
-
-static usbd_status ehci_device_bulk_transfer(usbd_xfer_handle);
-static usbd_status ehci_device_bulk_start(usbd_xfer_handle);
-static void ehci_device_bulk_abort(usbd_xfer_handle);
-static void ehci_device_bulk_close(usbd_pipe_handle);
-static void ehci_device_bulk_done(usbd_xfer_handle);
-
-static usbd_status ehci_device_intr_transfer(usbd_xfer_handle);
-static usbd_status ehci_device_intr_start(usbd_xfer_handle);
-static void ehci_device_intr_abort(usbd_xfer_handle);
-static void ehci_device_intr_close(usbd_pipe_handle);
-static void ehci_device_intr_done(usbd_xfer_handle);
-
-static usbd_status ehci_device_isoc_transfer(usbd_xfer_handle);
-static usbd_status ehci_device_isoc_start(usbd_xfer_handle);
-static void ehci_device_isoc_abort(usbd_xfer_handle);
-static void ehci_device_isoc_close(usbd_pipe_handle);
-static void ehci_device_isoc_done(usbd_xfer_handle);
-
-static void ehci_device_clear_toggle(usbd_pipe_handle pipe);
-static void ehci_noop(usbd_pipe_handle pipe);
-
-static int ehci_str(usb_string_descriptor_t *, int, char *);
-static void ehci_pcd(ehci_softc_t *, usbd_xfer_handle);
-static void ehci_disown(ehci_softc_t *, int, int);
-
-static ehci_soft_qh_t *ehci_alloc_sqh(ehci_softc_t *);
-static void ehci_free_sqh(ehci_softc_t *, ehci_soft_qh_t *);
-
-static ehci_soft_qtd_t *ehci_alloc_sqtd(ehci_softc_t *);
-static void ehci_free_sqtd(ehci_softc_t *, ehci_soft_qtd_t *);
-static usbd_status ehci_alloc_sqtd_chain(struct ehci_pipe *,
- ehci_softc_t *, int, int, usbd_xfer_handle,
- ehci_soft_qtd_t *, ehci_soft_qtd_t *,
- ehci_soft_qtd_t **, ehci_soft_qtd_t **);
-static void ehci_free_sqtd_chain(ehci_softc_t *, ehci_soft_qh_t *,
- ehci_soft_qtd_t *, ehci_soft_qtd_t *);
-
-static ehci_soft_itd_t *ehci_alloc_itd(ehci_softc_t *);
-static void ehci_free_itd(ehci_softc_t *, ehci_soft_itd_t *);
-static void ehci_rem_free_itd_chain(ehci_softc_t *,
- struct ehci_xfer *);
-static void ehci_abort_isoc_xfer(usbd_xfer_handle, usbd_status);
-
-static usbd_status ehci_device_request(usbd_xfer_handle xfer);
-
-static usbd_status ehci_device_setintr(ehci_softc_t *, ehci_soft_qh_t *,
- int ival);
-
-static void ehci_add_qh(ehci_softc_t *, ehci_soft_qh_t *,
- ehci_soft_qh_t *);
-static void ehci_rem_qh(ehci_softc_t *, ehci_soft_qh_t *,
- ehci_soft_qh_t *);
-static void ehci_activate_qh(ehci_softc_t *sc, ehci_soft_qh_t *,
- ehci_soft_qtd_t *);
-static void ehci_sync_hc(ehci_softc_t *);
-
-static void ehci_close_pipe(usbd_pipe_handle, ehci_soft_qh_t *);
-static void ehci_abort_xfer(usbd_xfer_handle, usbd_status);
-
-ehci_softc_t *theehci;
-
-#define EHCI_NULL(sc) htohc32(sc, EHCI_LINK_TERMINATE)
-
-#define EHCI_INTR_ENDPT 1
-
-#define ehci_add_intr_list(sc, ex) \
- LIST_INSERT_HEAD(&(sc)->sc_intrhead, (ex), inext);
-#define ehci_del_intr_list(ex) \
- do { \
- LIST_REMOVE((ex), inext); \
- (ex)->inext.le_prev = NULL; \
- } while (0)
-#define ehci_active_intr_list(ex) ((ex)->inext.le_prev != NULL)
-
-static struct usbd_bus_methods ehci_bus_methods = {
- ehci_open,
- ehci_softintr,
- ehci_poll,
- ehci_allocm,
- ehci_freem,
- ehci_allocx,
- ehci_freex,
-};
-
-static struct usbd_pipe_methods ehci_root_ctrl_methods = {
- ehci_root_ctrl_transfer,
- ehci_root_ctrl_start,
- ehci_root_ctrl_abort,
- ehci_root_ctrl_close,
- ehci_noop,
- ehci_root_ctrl_done,
-};
-
-static struct usbd_pipe_methods ehci_root_intr_methods = {
- ehci_root_intr_transfer,
- ehci_root_intr_start,
- ehci_root_intr_abort,
- ehci_root_intr_close,
- ehci_noop,
- ehci_root_intr_done,
-};
-
-static struct usbd_pipe_methods ehci_device_ctrl_methods = {
- ehci_device_ctrl_transfer,
- ehci_device_ctrl_start,
- ehci_device_ctrl_abort,
- ehci_device_ctrl_close,
- ehci_noop,
- ehci_device_ctrl_done,
-};
-
-static struct usbd_pipe_methods ehci_device_intr_methods = {
- ehci_device_intr_transfer,
- ehci_device_intr_start,
- ehci_device_intr_abort,
- ehci_device_intr_close,
- ehci_device_clear_toggle,
- ehci_device_intr_done,
-};
-
-static struct usbd_pipe_methods ehci_device_bulk_methods = {
- ehci_device_bulk_transfer,
- ehci_device_bulk_start,
- ehci_device_bulk_abort,
- ehci_device_bulk_close,
- ehci_device_clear_toggle,
- ehci_device_bulk_done,
-};
-
-static struct usbd_pipe_methods ehci_device_isoc_methods = {
- ehci_device_isoc_transfer,
- ehci_device_isoc_start,
- ehci_device_isoc_abort,
- ehci_device_isoc_close,
- ehci_noop,
- ehci_device_isoc_done,
-};
-
-usbd_status
-ehci_reset(ehci_softc_t *sc)
-{
- u_int32_t hcr;
- u_int i;
-
- EOWRITE4(sc, EHCI_USBCMD, EHCI_CMD_HCRESET);
- for (i = 0; i < 100; i++) {
- usb_delay_ms(&sc->sc_bus, 1);
- hcr = EOREAD4(sc, EHCI_USBCMD) & EHCI_CMD_HCRESET;
- if (!hcr) {
- if (sc->sc_flags & (EHCI_SCFLG_SETMODE | EHCI_SCFLG_BIGEMMIO)) {
- /*
- * Force USBMODE as requested. Controllers
- * may have multiple operating modes.
- */
- uint32_t usbmode = EOREAD4(sc, EHCI_USBMODE);
- if (sc->sc_flags & EHCI_SCFLG_SETMODE) {
- usbmode = (usbmode &~ EHCI_UM_CM) | EHCI_UM_CM_HOST;
- device_printf(sc->sc_bus.bdev,
- "set host controller mode\n");
- }
- if (sc->sc_flags & EHCI_SCFLG_BIGEMMIO) {
- usbmode = (usbmode &~ EHCI_UM_ES) | EHCI_UM_ES_BE;
- device_printf(sc->sc_bus.bdev,
- "set big-endian mode\n");
- }
- EOWRITE4(sc, EHCI_USBMODE, usbmode);
- }
- return (USBD_NORMAL_COMPLETION);
- }
- }
- printf("%s: reset timeout\n", device_get_nameunit(sc->sc_bus.bdev));
- return (USBD_IOERROR);
-}
-
-static usbd_status
-ehci_hcreset(ehci_softc_t *sc)
-{
- u_int32_t hcr;
- u_int i;
-
- EOWRITE4(sc, EHCI_USBCMD, 0); /* Halt controller */
- for (i = 0; i < 100; i++) {
- usb_delay_ms(&sc->sc_bus, 1);
- hcr = EOREAD4(sc, EHCI_USBSTS) & EHCI_STS_HCH;
- if (hcr)
- break;
- }
- if (!hcr)
- /*
- * Fall through and try reset anyway even though
- * Table 2-9 in the EHCI spec says this will result
- * in undefined behavior.
- */
- device_printf(sc->sc_bus.bdev, "stop timeout\n");
-
- return ehci_reset(sc);
-}
-
-usbd_status
-ehci_init(ehci_softc_t *sc)
-{
- u_int32_t version, sparams, cparams, hcr;
- u_int i;
- usbd_status err;
- ehci_soft_qh_t *sqh;
- u_int ncomp;
- int lev;
-
- DPRINTF(("ehci_init: start\n"));
-#ifdef EHCI_DEBUG
- theehci = sc;
-#endif
-
- /* NB: must handle byte-order manually before ehci_hcreset */
-
- sc->sc_offs = EREAD1(sc, EHCI_CAPLENGTH);
-
- version = EREAD2(sc, EHCI_HCIVERSION);
- device_printf(sc->sc_bus.bdev, "EHCI version %x.%x\n",
- version >> 8, version & 0xff);
-
- sparams = EREAD4(sc, EHCI_HCSPARAMS);
- DPRINTF(("ehci_init: sparams=0x%x\n", sparams));
- sc->sc_npcomp = EHCI_HCS_N_PCC(sparams);
- ncomp = EHCI_HCS_N_CC(sparams);
- if (ncomp != sc->sc_ncomp) {
- printf("%s: wrong number of companions (%d != %d)\n",
- device_get_nameunit(sc->sc_bus.bdev),
- ncomp, sc->sc_ncomp);
- if (ncomp < sc->sc_ncomp)
- sc->sc_ncomp = ncomp;
- }
- if (sc->sc_ncomp > 0) {
- printf("%s: companion controller%s, %d port%s each:",
- device_get_nameunit(sc->sc_bus.bdev), sc->sc_ncomp!=1 ? "s" : "",
- EHCI_HCS_N_PCC(sparams),
- EHCI_HCS_N_PCC(sparams)!=1 ? "s" : "");
- for (i = 0; i < sc->sc_ncomp; i++)
- printf(" %s", device_get_nameunit(sc->sc_comps[i]->bdev));
- printf("\n");
- }
- sc->sc_noport = EHCI_HCS_N_PORTS(sparams);
- cparams = EREAD4(sc, EHCI_HCCPARAMS);
- DPRINTF(("ehci_init: cparams=0x%x\n", cparams));
-
- if (EHCI_HCC_64BIT(cparams)) {
- /* MUST clear segment register if 64 bit capable. */
- EWRITE4(sc, EHCI_CTRLDSSEGMENT, 0);
- }
-
- sc->sc_bus.usbrev = USBREV_2_0;
-
- /* Reset the controller */
- DPRINTF(("%s: resetting\n", device_get_nameunit(sc->sc_bus.bdev)));
- err = ehci_hcreset(sc);
- if (err != USBD_NORMAL_COMPLETION)
- return (err);
-
- /* frame list size at default, read back what we got and use that */
- switch (EHCI_CMD_FLS(EOREAD4(sc, EHCI_USBCMD))) {
- case 0: sc->sc_flsize = 1024; break;
- case 1: sc->sc_flsize = 512; break;
- case 2: sc->sc_flsize = 256; break;
- case 3: return (USBD_IOERROR);
- }
- err = usb_allocmem(&sc->sc_bus, sc->sc_flsize * sizeof(ehci_link_t),
- EHCI_FLALIGN_ALIGN, &sc->sc_fldma);
- if (err)
- return (err);
- DPRINTF(("%s: flsize=%d\n", device_get_nameunit(sc->sc_bus.bdev),sc->sc_flsize));
- sc->sc_flist = KERNADDR(&sc->sc_fldma, 0);
-
- for (i = 0; i < sc->sc_flsize; i++) {
- sc->sc_flist[i] = EHCI_NULL(sc);
- }
-
- EOWRITE4(sc, EHCI_PERIODICLISTBASE, DMAADDR(&sc->sc_fldma, 0));
-
- sc->sc_softitds = malloc(sc->sc_flsize * sizeof(ehci_soft_itd_t *),
- M_USB, M_NOWAIT | M_ZERO);
- if (sc->sc_softitds == NULL)
- return (ENOMEM);
- LIST_INIT(&sc->sc_freeitds);
-
- /* Set up the bus struct. */
- sc->sc_bus.methods = &ehci_bus_methods;
- sc->sc_bus.pipe_size = sizeof(struct ehci_pipe);
-
- sc->sc_eintrs = EHCI_NORMAL_INTRS;
-
- /*
- * Allocate the interrupt dummy QHs. These are arranged to give
- * poll intervals that are powers of 2 times 1ms.
- */
- for (i = 0; i < EHCI_INTRQHS; i++) {
- sqh = ehci_alloc_sqh(sc);
- if (sqh == NULL) {
- err = USBD_NOMEM;
- goto bad1;
- }
- sc->sc_islots[i].sqh = sqh;
- }
- lev = 0;
- for (i = 0; i < EHCI_INTRQHS; i++) {
- if (i == EHCI_IQHIDX(lev + 1, 0))
- lev++;
- sqh = sc->sc_islots[i].sqh;
- if (i == 0) {
- /* The last (1ms) QH terminates. */
- sqh->qh.qh_link = EHCI_NULL(sc);
- sqh->next = NULL;
- } else {
- /* Otherwise the next QH has half the poll interval */
- sqh->next =
- sc->sc_islots[EHCI_IQHIDX(lev - 1, i + 1)].sqh;
- sqh->qh.qh_link = htohc32(sc, sqh->next->physaddr |
- EHCI_LINK_QH);
- }
- sqh->qh.qh_endp = htohc32(sc, EHCI_QH_SET_EPS(EHCI_QH_SPEED_HIGH));
- sqh->qh.qh_endphub = htohc32(sc, EHCI_QH_SET_MULT(1));
- sqh->qh.qh_curqtd = EHCI_NULL(sc);
- sqh->qh.qh_qtd.qtd_next = EHCI_NULL(sc);
- sqh->qh.qh_qtd.qtd_altnext = EHCI_NULL(sc);
- sqh->qh.qh_qtd.qtd_status = htohc32(sc, EHCI_QTD_HALTED);
- }
- /* Point the frame list at the last level (128ms). */
- for (i = 0; i < sc->sc_flsize; i++) {
- sc->sc_flist[i] = htohc32(sc, EHCI_LINK_QH |
- sc->sc_islots[EHCI_IQHIDX(EHCI_IPOLLRATES - 1, i)].sqh->physaddr);
- }
-
- /* Allocate dummy QH that starts the async list. */
- sqh = ehci_alloc_sqh(sc);
- if (sqh == NULL) {
- err = USBD_NOMEM;
- goto bad1;
- }
- /* Fill the QH */
- sqh->qh.qh_endp =
- htohc32(sc, EHCI_QH_SET_EPS(EHCI_QH_SPEED_HIGH) | EHCI_QH_HRECL);
- sqh->qh.qh_link =
- htohc32(sc, sqh->physaddr | EHCI_LINK_QH);
- sqh->qh.qh_curqtd = EHCI_NULL(sc);
- sqh->prev = sqh; /*It's a circular list.. */
- sqh->next = sqh;
- /* Fill the overlay qTD */
- sqh->qh.qh_qtd.qtd_next = EHCI_NULL(sc);
- sqh->qh.qh_qtd.qtd_altnext = EHCI_NULL(sc);
- sqh->qh.qh_qtd.qtd_status = htohc32(sc, 0);
-#ifdef EHCI_DEBUG
- if (ehcidebug) {
- ehci_dump_sqh(sc, sqh);
- }
-#endif
-
- /* Point to async list */
- sc->sc_async_head = sqh;
- EOWRITE4(sc, EHCI_ASYNCLISTADDR, sqh->physaddr | EHCI_LINK_QH);
-
- callout_init(&sc->sc_tmo_intrlist, 0);
-
- lockinit(&sc->sc_doorbell_lock, PZERO, "ehcidb", 0, 0);
-
- /* Enable interrupts */
- EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs);
-
- /* Turn on controller */
- EOWRITE4(sc, EHCI_USBCMD,
- EHCI_CMD_ITC_2 | /* 2 microframes interrupt delay */
- (EOREAD4(sc, EHCI_USBCMD) & EHCI_CMD_FLS_M) |
- EHCI_CMD_ASE |
- EHCI_CMD_PSE |
- EHCI_CMD_RS);
-
- /* Take over port ownership */
- EOWRITE4(sc, EHCI_CONFIGFLAG, EHCI_CONF_CF);
-
- for (i = 0; i < 100; i++) {
- usb_delay_ms(&sc->sc_bus, 1);
- hcr = EOREAD4(sc, EHCI_USBSTS) & EHCI_STS_HCH;
- if (!hcr)
- break;
- }
- if (hcr) {
- printf("%s: run timeout\n", device_get_nameunit(sc->sc_bus.bdev));
- return (USBD_IOERROR);
- }
-
- return (USBD_NORMAL_COMPLETION);
-
-#if 0
- bad2:
- ehci_free_sqh(sc, sc->sc_async_head);
-#endif
- bad1:
- usb_freemem(&sc->sc_bus, &sc->sc_fldma);
- return (err);
-}
-
-int
-ehci_intr(void *v)
-{
- ehci_softc_t *sc = v;
-
- if (sc == NULL || sc->sc_dying)
- return (0);
-
- /* If we get an interrupt while polling, then just ignore it. */
- if (sc->sc_bus.use_polling) {
- u_int32_t intrs = EHCI_STS_INTRS(EOREAD4(sc, EHCI_USBSTS));
-
- if (intrs)
- EOWRITE4(sc, EHCI_USBSTS, intrs); /* Acknowledge */
-#ifdef DIAGNOSTIC
- DPRINTFN(16, ("ehci_intr: ignored interrupt while polling\n"));
-#endif
- return (0);
- }
-
- return (ehci_intr1(sc));
-}
-
-static int
-ehci_intr1(ehci_softc_t *sc)
-{
- u_int32_t intrs, eintrs;
-
- DPRINTFN(20,("ehci_intr1: enter\n"));
-
- /* In case the interrupt occurs before initialization has completed. */
- if (sc == NULL) {
-#ifdef DIAGNOSTIC
- printf("ehci_intr1: sc == NULL\n");
-#endif
- return (0);
- }
-
- intrs = EHCI_STS_INTRS(EOREAD4(sc, EHCI_USBSTS));
- if (!intrs)
- return (0);
-
- eintrs = intrs & sc->sc_eintrs;
- DPRINTFN(7, ("ehci_intr1: sc=%p intrs=0x%x(0x%x) eintrs=0x%x\n",
- sc, (u_int)intrs, EOREAD4(sc, EHCI_USBSTS),
- (u_int)eintrs));
- if (!eintrs)
- return (0);
-
- EOWRITE4(sc, EHCI_USBSTS, intrs); /* Acknowledge */
- sc->sc_bus.intr_context++;
- sc->sc_bus.no_intrs++;
- if (eintrs & EHCI_STS_IAA) {
- DPRINTF(("ehci_intr1: door bell\n"));
- wakeup(&sc->sc_async_head);
- eintrs &= ~EHCI_STS_IAA;
- }
- if (eintrs & (EHCI_STS_INT | EHCI_STS_ERRINT)) {
- DPRINTFN(5,("ehci_intr1: %s %s\n",
- eintrs & EHCI_STS_INT ? "INT" : "",
- eintrs & EHCI_STS_ERRINT ? "ERRINT" : ""));
- usb_schedsoftintr(&sc->sc_bus);
- eintrs &= ~(EHCI_STS_INT | EHCI_STS_ERRINT);
- }
- if (eintrs & EHCI_STS_HSE) {
- printf("%s: unrecoverable error, controller halted\n",
- device_get_nameunit(sc->sc_bus.bdev));
- /* XXX what else */
- }
- if (eintrs & EHCI_STS_PCD) {
- ehci_pcd(sc, sc->sc_intrxfer);
- eintrs &= ~EHCI_STS_PCD;
- }
-
- sc->sc_bus.intr_context--;
-
- if (eintrs != 0) {
- /* Block unprocessed interrupts. */
- sc->sc_eintrs &= ~eintrs;
- EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs);
- printf("%s: blocking intrs 0x%x\n",
- device_get_nameunit(sc->sc_bus.bdev), eintrs);
- }
-
- return (1);
-}
-
-/*
- * XXX write back xfer data for architectures with a write-back
- * data cache; this is a hack because usb is mis-architected
- * in blindly mixing bus_dma w/ PIO.
- */
-static __inline void
-hacksync(usbd_xfer_handle xfer)
-{
- bus_dma_tag_t tag;
- struct usb_dma_mapping *dmap;
-
- if (xfer->length == 0)
- return;
- tag = xfer->pipe->device->bus->buffer_dmatag;
- dmap = &xfer->dmamap;
- bus_dmamap_sync(tag, dmap->map, BUS_DMASYNC_PREWRITE);
-}
-
-void
-ehci_pcd(ehci_softc_t *sc, usbd_xfer_handle xfer)
-{
- usbd_pipe_handle pipe;
- u_char *p;
- int i, m;
-
- if (xfer == NULL) {
- /* Just ignore the change. */
- return;
- }
-
- pipe = xfer->pipe;
-
- p = xfer->buffer;
- m = min(sc->sc_noport, xfer->length * 8 - 1);
- memset(p, 0, xfer->length);
- for (i = 1; i <= m; i++) {
- /* Pick out CHANGE bits from the status reg. */
- if (EOREAD4(sc, EHCI_PORTSC(i)) & EHCI_PS_CLEAR)
- p[i/8] |= 1 << (i%8);
- }
- DPRINTF(("ehci_pcd: change=0x%02x\n", *p));
- xfer->actlen = xfer->length;
- xfer->status = USBD_NORMAL_COMPLETION;
-
- hacksync(xfer); /* XXX to compensate for usb_transfer_complete */
- usb_transfer_complete(xfer);
-}
-
-void
-ehci_softintr(void *v)
-{
- ehci_softc_t *sc = v;
- struct ehci_xfer *ex, *nextex;
-
- DPRINTFN(10,("%s: ehci_softintr (%d)\n", device_get_nameunit(sc->sc_bus.bdev),
- sc->sc_bus.intr_context));
-
- sc->sc_bus.intr_context++;
-
- /*
- * The only explanation I can think of for why EHCI is as brain dead
- * as UHCI interrupt-wise is that Intel was involved in both.
- * An interrupt just tells us that something is done, we have no
- * clue what, so we need to scan through all active transfers. :-(
- */
- for (ex = LIST_FIRST(&sc->sc_intrhead); ex; ex = nextex) {
- nextex = LIST_NEXT(ex, inext);
- ehci_check_intr(sc, ex);
- }
-
- /* Schedule a callout to catch any dropped transactions. */
- if ((sc->sc_flags & EHCI_SCFLG_LOSTINTRBUG) &&
- !LIST_EMPTY(&sc->sc_intrhead))
- callout_reset(&sc->sc_tmo_intrlist, hz / 5,
- ehci_intrlist_timeout, sc);
-
-#ifdef USB_USE_SOFTINTR
- if (sc->sc_softwake) {
- sc->sc_softwake = 0;
- wakeup(&sc->sc_softwake);
- }
-#endif /* USB_USE_SOFTINTR */
-
- sc->sc_bus.intr_context--;
-}
-
-/* Check for an interrupt. */
-void
-ehci_check_intr(ehci_softc_t *sc, struct ehci_xfer *ex)
-{
- int attr;
-
- DPRINTFN(/*15*/2, ("ehci_check_intr: ex=%p\n", ex));
-
- attr = ex->xfer.pipe->endpoint->edesc->bmAttributes;
- if (UE_GET_XFERTYPE(attr) == UE_ISOCHRONOUS)
- ehci_check_itd_intr(sc, ex);
- else
- ehci_check_qh_intr(sc, ex);
-}
-
-void
-ehci_check_qh_intr(ehci_softc_t *sc, struct ehci_xfer *ex)
-{
- ehci_soft_qtd_t *sqtd, *lsqtd;
- u_int32_t status;
-
- if (ex->sqtdstart == NULL) {
- printf("ehci_check_qh_intr: not valid sqtd\n");
- return;
- }
- lsqtd = ex->sqtdend;
-#ifdef DIAGNOSTIC
- if (lsqtd == NULL) {
- printf("ehci_check_qh_intr: lsqtd==0\n");
- return;
- }
-#endif
- /*
- * If the last TD is still active we need to check whether there
- * is a an error somewhere in the middle, or whether there was a
- * short packet (SPD and not ACTIVE).
- */
- if (hc32toh(sc, lsqtd->qtd.qtd_status) & EHCI_QTD_ACTIVE) {
- DPRINTFN(12, ("ehci_check_intr: active ex=%p\n", ex));
- for (sqtd = ex->sqtdstart; sqtd != lsqtd; sqtd=sqtd->nextqtd) {
- status = hc32toh(sc, sqtd->qtd.qtd_status);
- /* If there's an active QTD the xfer isn't done. */
- if (status & EHCI_QTD_ACTIVE)
- break;
- /* Any kind of error makes the xfer done. */
- if (status & EHCI_QTD_HALTED)
- goto done;
- /* We want short packets, and it is short: it's done */
- if (EHCI_QTD_GET_BYTES(status) != 0)
- goto done;
- }
- DPRINTFN(12, ("ehci_check_intr: ex=%p std=%p still active\n",
- ex, ex->sqtdstart));
- return;
- }
- done:
- DPRINTFN(12, ("ehci_check_intr: ex=%p done\n", ex));
- callout_stop(&ex->xfer.timeout_handle);
- usb_rem_task(ex->xfer.pipe->device, &ex->abort_task);
- ehci_idone(ex);
-}
-
-void
-ehci_check_itd_intr(ehci_softc_t *sc, struct ehci_xfer *ex)
-{
- ehci_soft_itd_t *itd;
- int i;
-
- if (ex->itdstart == NULL) {
- printf("ehci_check_itd_intr: not valid itd\n");
- return;
- }
-
- itd = ex->itdend;
-#ifdef DIAGNOSTIC
- if (itd == NULL) {
- printf("ehci_check_itd_intr: itdend == 0\n");
- return;
- }
-#endif
-
- /*
- * Step 1, check no active transfers in last itd, meaning we're finished
- */
- for (i = 0; i < 8; i++) {
- if (hc32toh(sc, itd->itd.itd_ctl[i]) & EHCI_ITD_ACTIVE)
- break;
- }
-
- if (i == 8) {
- goto done; /* All 8 descriptors inactive, it's done */
- }
-
- /*
- * Step 2, check for errors in status bits, throughout chain...
- */
-
- DPRINTFN(12, ("ehci_check_itd_intr: active ex=%p\n", ex));
-
- for (itd = ex->itdstart; itd != ex->itdend; itd = itd->xfer_next) {
- for (i = 0; i < 8; i++) {
- if (hc32toh(sc, itd->itd.itd_ctl[i]) & (EHCI_ITD_BUF_ERR |
- EHCI_ITD_BABBLE | EHCI_ITD_ERROR))
- break;
- }
- if (i != 8) { /* Error in one of the itds */
- goto done;
- }
- } /* itd search loop */
-
- DPRINTFN(12, ("ehci_check_itd_intr: ex %p itd %p still active\n", ex,
- ex->itdstart));
- return;
-done:
- DPRINTFN(12, ("ehci_check_itd_intr: ex=%p done\n", ex));
- callout_stop(&ex->xfer.timeout_handle);
- usb_rem_task(ex->xfer.pipe->device, &ex->abort_task);
- ehci_idone(ex);
-}
-
-void
-ehci_idone(struct ehci_xfer *ex)
-{
- usbd_xfer_handle xfer = &ex->xfer;
- struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
- ehci_softc_t *sc = (ehci_softc_t *)epipe->pipe.device->bus;
- ehci_soft_qtd_t *sqtd, *lsqtd;
- u_int32_t status = 0, nstatus = 0;
- ehci_physaddr_t nextphys, altnextphys;
- int actlen, cerr;
-
- DPRINTFN(/*12*/2, ("ehci_idone: ex=%p\n", ex));
-#ifdef DIAGNOSTIC
- {
- int s = splhigh();
- if (ex->isdone) {
- splx(s);
-#ifdef EHCI_DEBUG
- printf("ehci_idone: ex is done!\n ");
- ehci_dump_exfer(ex);
-#else
- printf("ehci_idone: ex=%p is done!\n", ex);
-#endif
- return;
- }
- ex->isdone = 1;
- splx(s);
- }
-#endif
-
- if (xfer->status == USBD_CANCELLED ||
- xfer->status == USBD_TIMEOUT) {
- DPRINTF(("ehci_idone: aborted xfer=%p\n", xfer));
- return;
- }
-
-#ifdef EHCI_DEBUG
- DPRINTFN(/*10*/2, ("ehci_idone: xfer=%p, pipe=%p ready\n", xfer, epipe));
- if (ehcidebug > 10)
- ehci_dump_sqtds(sc, ex->sqtdstart);
-#endif
-
- /*
- * Make sure that the QH overlay qTD does not reference any
- * of the qTDs we are about to free. This is probably only
- * necessary if the transfer is marked as HALTED.
- */
- nextphys = EHCI_LINK_ADDR(hc32toh(sc, epipe->sqh->qh.qh_qtd.qtd_next));
- altnextphys =
- EHCI_LINK_ADDR(hc32toh(sc, epipe->sqh->qh.qh_qtd.qtd_altnext));
- for (sqtd = ex->sqtdstart; sqtd != ex->sqtdend->nextqtd;
- sqtd = sqtd->nextqtd) {
- if (sqtd->physaddr == nextphys) {
- epipe->sqh->qh.qh_qtd.qtd_next =
- htohc32(sc, ex->sqtdend->nextqtd->physaddr);
- DPRINTFN(4, ("ehci_idone: updated overlay next ptr\n"));
-
- }
- if (sqtd->physaddr == altnextphys) {
- DPRINTFN(4,
- ("ehci_idone: updated overlay altnext ptr\n"));
- epipe->sqh->qh.qh_qtd.qtd_altnext =
- htohc32(sc, ex->sqtdend->nextqtd->physaddr);
- }
- }
-
- /* The transfer is done, compute actual length and status. */
- if (UE_GET_XFERTYPE(xfer->pipe->endpoint->edesc->bmAttributes)
- == UE_ISOCHRONOUS) {
- /* Isoc transfer */
- struct ehci_soft_itd *itd;
- int i, nframes, len, uframes;
-
- nframes = 0;
- actlen = 0;
-
- switch (xfer->pipe->endpoint->edesc->bInterval) {
- case 0:
- panic("ehci: isoc xfer suddenly has 0 bInterval, "
- "invalid\n");
- case 1:
- uframes = 1;
- break;
- case 2:
- uframes = 2;
- break;
- case 3:
- uframes = 4;
- break;
- default:
- uframes = 8;
- break;
- }
-
- for (itd = ex->itdstart; itd != NULL; itd = itd->xfer_next) {
- for (i = 0; i < 8; i += uframes) {
- /* XXX - driver didn't fill in the frame full
- * of uframes. This leads to scheduling
- * inefficiencies, but working around
- * this doubles complexity of tracking
- * an xfer.
- */
- if (nframes >= xfer->nframes)
- break;
-
- status = hc32toh(sc, itd->itd.itd_ctl[i]);
- len = EHCI_ITD_GET_LEN(status);
- xfer->frlengths[nframes++] = len;
- actlen += len;
- }
- if (nframes >= xfer->nframes)
- break;
- }
- xfer->actlen = actlen;
- xfer->status = USBD_NORMAL_COMPLETION;
-
- goto end;
- }
-
- /* Continue processing xfers using queue heads */
-
- lsqtd = ex->sqtdend;
- actlen = 0;
- for (sqtd = ex->sqtdstart; sqtd != lsqtd->nextqtd;
- sqtd =sqtd->nextqtd) {
- nstatus = hc32toh(sc, sqtd->qtd.qtd_status);
- if (nstatus & EHCI_QTD_ACTIVE)
- break;
-
- status = nstatus;
- /* halt is ok if descriptor is last, and complete */
- if (sqtd == lsqtd && EHCI_QTD_GET_BYTES(status) == 0)
- status &= ~EHCI_QTD_HALTED;
- if (EHCI_QTD_GET_PID(status) != EHCI_QTD_PID_SETUP)
- actlen += sqtd->len - EHCI_QTD_GET_BYTES(status);
- }
-
- cerr = EHCI_QTD_GET_CERR(status);
- DPRINTFN(/*10*/2, ("ehci_idone: len=%d, actlen=%d, cerr=%d, "
- "status=0x%x\n", xfer->length, actlen, cerr, status));
- xfer->actlen = actlen;
- if ((status & EHCI_QTD_HALTED) != 0) {
- DPRINTFN(2,
- ("ehci_idone: error, addr=%d, endpt=0x%02x, status %b\n",
- xfer->pipe->device->address,
- xfer->pipe->endpoint->edesc->bEndpointAddress,
- status, EHCI_QTD_STATUS_BITS));
- if ((status & EHCI_QTD_BABBLE) == 0 && cerr > 0)
- xfer->status = USBD_STALLED;
- else
- xfer->status = USBD_IOERROR; /* more info XXX */
- } else {
- xfer->status = USBD_NORMAL_COMPLETION;
- }
-#ifdef EHCI_DEBUG
- if (ehcidebug > 2) {
- ehci_dump_sqh(sc, epipe->sqh);
- ehci_dump_sqtds(sc, ex->sqtdstart);
- }
-#endif
-end:
- /* XXX transfer_complete memcpys out transfer data (for in endpoints)
- * during this call, before methods->done is called: dma sync required
- * beforehand?
- */
- usb_transfer_complete(xfer);
- DPRINTFN(/*12*/2, ("ehci_idone: ex=%p done\n", ex));
-}
-
-/*
- * Wait here until controller claims to have an interrupt.
- * Then call ehci_intr and return. Use timeout to avoid waiting
- * too long.
- */
-void
-ehci_waitintr(ehci_softc_t *sc, usbd_xfer_handle xfer)
-{
- int timo = xfer->timeout;
- int usecs;
- u_int32_t intrs;
-
- xfer->status = USBD_IN_PROGRESS;
- for (usecs = timo * 1000000 / hz; usecs > 0; usecs -= 1000) {
- usb_delay_ms(&sc->sc_bus, 1);
- if (sc->sc_dying)
- break;
- intrs = EHCI_STS_INTRS(EOREAD4(sc, EHCI_USBSTS)) &
- sc->sc_eintrs;
- DPRINTFN(15,("ehci_waitintr: 0x%04x\n", intrs));
-#ifdef EHCI_DEBUG
- if (ehcidebug > 15)
- ehci_dump_regs(sc);
-#endif
- if (intrs) {
- ehci_intr1(sc);
- if (xfer->status != USBD_IN_PROGRESS)
- return;
- }
- }
-
- /* Timeout */
- DPRINTF(("ehci_waitintr: timeout\n"));
- xfer->status = USBD_TIMEOUT;
- usb_transfer_complete(xfer);
- /* XXX should free TD */
-}
-
-void
-ehci_poll(struct usbd_bus *bus)
-{
- ehci_softc_t *sc = (ehci_softc_t *)bus;
-#ifdef EHCI_DEBUG
- static int last;
- int new;
- new = EHCI_STS_INTRS(EOREAD4(sc, EHCI_USBSTS));
- if (new != last) {
- DPRINTFN(10,("ehci_poll: intrs=0x%04x\n", new));
- last = new;
- }
-#endif
-
- if (EOREAD4(sc, EHCI_USBSTS) & sc->sc_eintrs)
- ehci_intr1(sc);
-}
-
-int
-ehci_detach(struct ehci_softc *sc, int flags)
-{
- int rv = 0;
-
- sc->sc_dying = 1;
-
- EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs);
- (void) ehci_hcreset(sc);
- callout_stop(&sc->sc_tmo_intrlist);
-
- usb_delay_ms(&sc->sc_bus, 300); /* XXX let stray task complete */
-
- usb_freemem(&sc->sc_bus, &sc->sc_fldma);
- /* XXX free other data structures XXX */
-
- return (rv);
-}
-
-/*
- * 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
- * are almost suspended anyway.
- */
-void
-ehci_power(int why, void *v)
-{
- ehci_softc_t *sc = v;
- u_int32_t cmd, hcr;
- int s, i;
-
-#ifdef EHCI_DEBUG
- DPRINTF(("ehci_power: sc=%p, why=%d\n", sc, why));
- if (ehcidebug > 0)
- ehci_dump_regs(sc);
-#endif
-
- s = splhardusb();
- switch (why) {
- case PWR_SUSPEND:
- case PWR_STANDBY:
- sc->sc_bus.use_polling++;
-
- for (i = 1; i <= sc->sc_noport; i++) {
- cmd = EOREAD4(sc, EHCI_PORTSC(i));
- if ((cmd & EHCI_PS_PO) == 0 &&
- (cmd & EHCI_PS_PE) == EHCI_PS_PE)
- EOWRITE4(sc, EHCI_PORTSC(i),
- cmd | EHCI_PS_SUSP);
- }
-
- sc->sc_cmd = EOREAD4(sc, EHCI_USBCMD);
-
- cmd = sc->sc_cmd & ~(EHCI_CMD_ASE | EHCI_CMD_PSE);
- EOWRITE4(sc, EHCI_USBCMD, cmd);
-
- for (i = 0; i < 100; i++) {
- hcr = EOREAD4(sc, EHCI_USBSTS) &
- (EHCI_STS_ASS | EHCI_STS_PSS);
- if (hcr == 0)
- break;
-
- usb_delay_ms(&sc->sc_bus, 1);
- }
- if (hcr != 0) {
- printf("%s: reset timeout\n",
- device_get_nameunit(sc->sc_bus.bdev));
- }
-
- cmd &= ~EHCI_CMD_RS;
- EOWRITE4(sc, EHCI_USBCMD, cmd);
-
- for (i = 0; i < 100; i++) {
- hcr = EOREAD4(sc, EHCI_USBSTS) & EHCI_STS_HCH;
- if (hcr == EHCI_STS_HCH)
- break;
-
- usb_delay_ms(&sc->sc_bus, 1);
- }
- if (hcr != EHCI_STS_HCH) {
- printf("%s: config timeout\n",
- device_get_nameunit(sc->sc_bus.bdev));
- }
-
- sc->sc_bus.use_polling--;
- break;
-
- case PWR_RESUME:
- sc->sc_bus.use_polling++;
-
- /* restore things in case the bios sucks */
- EOWRITE4(sc, EHCI_CTRLDSSEGMENT, 0);
- EOWRITE4(sc, EHCI_PERIODICLISTBASE, DMAADDR(&sc->sc_fldma, 0));
- EOWRITE4(sc, EHCI_ASYNCLISTADDR,
- sc->sc_async_head->physaddr | EHCI_LINK_QH);
- EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs);
-
- hcr = 0;
- for (i = 1; i <= sc->sc_noport; i++) {
- cmd = EOREAD4(sc, EHCI_PORTSC(i));
- if ((cmd & EHCI_PS_PO) == 0 &&
- (cmd & EHCI_PS_SUSP) == EHCI_PS_SUSP) {
- EOWRITE4(sc, EHCI_PORTSC(i),
- cmd | EHCI_PS_FPR);
- hcr = 1;
- }
- }
-
- if (hcr) {
- usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT);
-
- for (i = 1; i <= sc->sc_noport; i++) {
- cmd = EOREAD4(sc, EHCI_PORTSC(i));
- if ((cmd & EHCI_PS_PO) == 0 &&
- (cmd & EHCI_PS_SUSP) == EHCI_PS_SUSP)
- EOWRITE4(sc, EHCI_PORTSC(i),
- cmd & ~EHCI_PS_FPR);
- }
- }
-
- EOWRITE4(sc, EHCI_USBCMD, sc->sc_cmd);
-
- for (i = 0; i < 100; i++) {
- hcr = EOREAD4(sc, EHCI_USBSTS) & EHCI_STS_HCH;
- if (hcr != EHCI_STS_HCH)
- break;
-
- usb_delay_ms(&sc->sc_bus, 1);
- }
- if (hcr == EHCI_STS_HCH) {
- printf("%s: config timeout\n",
- device_get_nameunit(sc->sc_bus.bdev));
- }
-
- usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT);
-
- sc->sc_bus.use_polling--;
- break;
- case PWR_SOFTSUSPEND:
- case PWR_SOFTSTANDBY:
- case PWR_SOFTRESUME:
- break;
- }
- splx(s);
-
-#ifdef EHCI_DEBUG
- DPRINTF(("ehci_power: sc=%p\n", sc));
- if (ehcidebug > 0)
- ehci_dump_regs(sc);
-#endif
-}
-
-/*
- * Shut down the controller when the system is going down.
- */
-void
-ehci_shutdown(void *v)
-{
- ehci_softc_t *sc = v;
-
- DPRINTF(("ehci_shutdown: stopping the HC\n"));
- (void) ehci_hcreset(sc);
-}
-
-usbd_status
-ehci_allocm(struct usbd_bus *bus, usb_dma_t *dma, u_int32_t size)
-{
- usbd_status err;
-
- err = usb_allocmem(bus, size, 0, dma);
-#ifdef EHCI_DEBUG
- if (err)
- printf("ehci_allocm: usb_allocmem()=%d\n", err);
-#endif
- return (err);
-}
-
-void
-ehci_freem(struct usbd_bus *bus, usb_dma_t *dma)
-{
- usb_freemem(bus, dma);
-}
-
-usbd_xfer_handle
-ehci_allocx(struct usbd_bus *bus)
-{
- struct ehci_softc *sc = (struct ehci_softc *)bus;
- usbd_xfer_handle xfer;
-
- xfer = STAILQ_FIRST(&sc->sc_free_xfers);
- if (xfer != NULL) {
- STAILQ_REMOVE_HEAD(&sc->sc_free_xfers, next);
-#ifdef DIAGNOSTIC
- if (xfer->busy_free != XFER_FREE) {
- printf("ehci_allocx: xfer=%p not free, 0x%08x\n", xfer,
- xfer->busy_free);
- }
-#endif
- } else {
- xfer = malloc(sizeof(struct ehci_xfer), M_USB, M_NOWAIT);
- }
- if (xfer != NULL) {
- memset(xfer, 0, sizeof(struct ehci_xfer));
- usb_init_task(&EXFER(xfer)->abort_task, ehci_timeout_task,
- xfer);
- EXFER(xfer)->ehci_xfer_flags = 0;
-#ifdef DIAGNOSTIC
- EXFER(xfer)->isdone = 1;
- xfer->busy_free = XFER_BUSY;
-#endif
- }
- return (xfer);
-}
-
-void
-ehci_freex(struct usbd_bus *bus, usbd_xfer_handle xfer)
-{
- struct ehci_softc *sc = (struct ehci_softc *)bus;
-
-#ifdef DIAGNOSTIC
- if (xfer->busy_free != XFER_BUSY) {
- printf("ehci_freex: xfer=%p not busy, 0x%08x\n", xfer,
- xfer->busy_free);
- return;
- }
- xfer->busy_free = XFER_FREE;
- if (!EXFER(xfer)->isdone) {
- printf("ehci_freex: !isdone\n");
- return;
- }
-#endif
- STAILQ_INSERT_HEAD(&sc->sc_free_xfers, xfer, next);
-}
-
-static void
-ehci_device_clear_toggle(usbd_pipe_handle pipe)
-{
- struct ehci_pipe *epipe = (struct ehci_pipe *)pipe;
- ehci_softc_t *sc = (ehci_softc_t *)epipe->pipe.device->bus;
-
- DPRINTF(("ehci_device_clear_toggle: epipe=%p status=0x%x\n",
- epipe, epipe->sqh->qh.qh_qtd.qtd_status));
-#ifdef USB_DEBUG
- if (ehcidebug)
- usbd_dump_pipe(pipe);
-#endif
- KASSERT((epipe->sqh->qh.qh_qtd.qtd_status &
- htohc32(sc, EHCI_QTD_ACTIVE)) == 0,
- ("ehci_device_clear_toggle: queue active"));
- epipe->sqh->qh.qh_qtd.qtd_status &= htohc32(sc, ~EHCI_QTD_TOGGLE_MASK);
-}
-
-static void
-ehci_noop(usbd_pipe_handle pipe)
-{
-}
-
-usbd_status
-ehci_open(usbd_pipe_handle pipe)
-{
- usbd_device_handle dev = pipe->device;
- ehci_softc_t *sc = (ehci_softc_t *)dev->bus;
- usb_endpoint_descriptor_t *ed = pipe->endpoint->edesc;
- u_int8_t addr = dev->address;
- u_int8_t xfertype = ed->bmAttributes & UE_XFERTYPE;
- struct ehci_pipe *epipe = (struct ehci_pipe *)pipe;
- ehci_soft_qh_t *sqh;
- usbd_status err;
- int s;
- int ival, speed, naks;
- int hshubaddr, hshubport;
-
- DPRINTFN(1, ("ehci_open: pipe=%p, xfertype=%d, addr=%d, endpt=%d (%d)\n",
- pipe, addr, ed->bEndpointAddress, sc->sc_addr, xfertype));
-
- if (dev->myhsport) {
- hshubaddr = dev->myhsport->parent->address;
- hshubport = dev->myhsport->portno;
- } else {
- hshubaddr = 0;
- hshubport = 0;
- }
-
- if (sc->sc_dying)
- return (USBD_IOERROR);
-
- if (addr == sc->sc_addr) {
- switch (ed->bEndpointAddress) {
- case USB_CONTROL_ENDPOINT:
- pipe->methods = &ehci_root_ctrl_methods;
- break;
- case UE_DIR_IN | EHCI_INTR_ENDPT:
- pipe->methods = &ehci_root_intr_methods;
- break;
- default:
- DPRINTF(("ehci_open: bad bEndpointAddress 0x%02x\n",
- ed->bEndpointAddress));
- return (USBD_INVAL);
- }
- return (USBD_NORMAL_COMPLETION);
- }
-
- /* XXX All this stuff is only valid for async. */
- switch (dev->speed) {
- case USB_SPEED_LOW: speed = EHCI_QH_SPEED_LOW; break;
- case USB_SPEED_FULL: speed = EHCI_QH_SPEED_FULL; break;
- case USB_SPEED_HIGH: speed = EHCI_QH_SPEED_HIGH; break;
- default: panic("ehci_open: bad device speed %d", dev->speed);
- }
- if (speed != EHCI_QH_SPEED_HIGH && xfertype == UE_ISOCHRONOUS) {
- printf("%s: *** Error: opening low/full speed isoc device on"
- "ehci, this does not work yet. Feel free to implement\n",
- device_get_nameunit(sc->sc_bus.bdev));
- DPRINTFN(1,("ehci_open: hshubaddr=%d hshubport=%d\n",
- hshubaddr, hshubport));
- return USBD_INVAL;
- }
-
- naks = 8; /* XXX */
- /* Allocate sqh for everything, save isoc xfers */
- if (xfertype != UE_ISOCHRONOUS) {
- sqh = ehci_alloc_sqh(sc);
- if (sqh == NULL)
- goto bad0;
- /* qh_link filled when the QH is added */
- sqh->qh.qh_endp = htohc32(sc,
- EHCI_QH_SET_ADDR(addr) |
- EHCI_QH_SET_ENDPT(UE_GET_ADDR(ed->bEndpointAddress)) |
- EHCI_QH_SET_EPS(speed) |
- (xfertype == UE_CONTROL ? EHCI_QH_DTC : 0) |
- EHCI_QH_SET_MPL(UGETW(ed->wMaxPacketSize)) |
- (speed != EHCI_QH_SPEED_HIGH && xfertype == UE_CONTROL ?
- EHCI_QH_CTL : 0) |
- EHCI_QH_SET_NRL(naks)
- );
- sqh->qh.qh_endphub = htohc32(sc,
- EHCI_QH_SET_MULT(1) |
- EHCI_QH_SET_HUBA(hshubaddr) |
- EHCI_QH_SET_PORT(hshubport) |
- EHCI_QH_SET_CMASK(0x1c) |
- EHCI_QH_SET_SMASK(xfertype == UE_INTERRUPT ? 0x01 : 0)
- );
- sqh->qh.qh_curqtd = EHCI_NULL(sc);
- /* The overlay qTD was already set up by ehci_alloc_sqh(). */
- sqh->qh.qh_qtd.qtd_status =
- htohc32(sc, EHCI_QTD_SET_TOGGLE(pipe->endpoint->savedtoggle));
- epipe->sqh = sqh;
- } else {
- sqh = NULL;
- }
-
- switch (xfertype) {
- case UE_CONTROL:
- err = usb_allocmem(&sc->sc_bus, sizeof(usb_device_request_t),
- 0, &epipe->u.ctl.reqdma);
-#ifdef EHCI_DEBUG
- if (err)
- printf("ehci_open: usb_allocmem()=%d\n", err);
-#endif
- if (err)
- goto bad1;
- pipe->methods = &ehci_device_ctrl_methods;
- s = splusb();
- ehci_add_qh(sc, sqh, sc->sc_async_head);
- splx(s);
- break;
- case UE_BULK:
- pipe->methods = &ehci_device_bulk_methods;
- s = splusb();
- ehci_add_qh(sc, sqh, sc->sc_async_head);
- splx(s);
- break;
- case UE_INTERRUPT:
- pipe->methods = &ehci_device_intr_methods;
- ival = pipe->interval;
- if (ival == USBD_DEFAULT_INTERVAL)
- ival = ed->bInterval;
- return (ehci_device_setintr(sc, sqh, ival));
- case UE_ISOCHRONOUS:
- pipe->methods = &ehci_device_isoc_methods;
- if (ed->bInterval == 0 || ed->bInterval > 16) {
- printf("ehci: opening pipe with invalid bInterval\n");
- err = USBD_INVAL;
- goto bad1;
- }
- if (UGETW(ed->wMaxPacketSize) == 0) {
- printf("ehci: zero length endpoint open request\n");
- err = USBD_INVAL;
- goto bad1;
- }
- epipe->u.isoc.next_frame = 0;
- epipe->u.isoc.cur_xfers = 0;
- break;
- default:
- DPRINTF(("ehci: bad xfer type %d\n", xfertype));
- return (USBD_INVAL);
- }
- return (USBD_NORMAL_COMPLETION);
-
- bad1:
- if (sqh != NULL)
- ehci_free_sqh(sc, sqh);
- return (err);
- bad0:
- return (USBD_NOMEM);
-}
-
-/*
- * Add an ED to the schedule. Called at splusb().
- * If in the async schedule, it will always have a next.
- * If in the intr schedule it may not.
- */
-void
-ehci_add_qh(ehci_softc_t *sc, ehci_soft_qh_t *sqh, ehci_soft_qh_t *head)
-{
- SPLUSBCHECK;
-
- sqh->next = head->next;
- sqh->prev = head;
- sqh->qh.qh_link = head->qh.qh_link;
- head->next = sqh;
- if (sqh->next)
- sqh->next->prev = sqh;
- head->qh.qh_link = htohc32(sc, sqh->physaddr | EHCI_LINK_QH);
-
-#ifdef EHCI_DEBUG
- if (ehcidebug > 5) {
- printf("ehci_add_qh:\n");
- ehci_dump_sqh(sc, sqh);
- }
-#endif
-}
-
-/*
- * Remove an ED from the schedule. Called at splusb().
- * Will always have a 'next' if it's in the async list as it's circular.
- */
-void
-ehci_rem_qh(ehci_softc_t *sc, ehci_soft_qh_t *sqh, ehci_soft_qh_t *head)
-{
- SPLUSBCHECK;
- /* XXX */
- sqh->prev->qh.qh_link = sqh->qh.qh_link;
- sqh->prev->next = sqh->next;
- if (sqh->next)
- sqh->next->prev = sqh->prev;
- ehci_sync_hc(sc);
-}
-
-/* Restart a QH following the addition of a qTD. */
-void
-ehci_activate_qh(ehci_softc_t *sc, ehci_soft_qh_t *sqh, ehci_soft_qtd_t *sqtd)
-{
- KASSERT((sqtd->qtd.qtd_status & htohc32(sc, EHCI_QTD_ACTIVE)) == 0,
- ("ehci_activate_qh: already active"));
-
- /*
- * When a QH is idle, the overlay qTD should be marked as not
- * halted and not active. This causes the host controller to
- * retrieve the real qTD on each pass (rather than just examinig
- * the overlay), so it will notice when we activate the qTD.
- */
- if (sqtd == sqh->sqtd) {
- /* Check that the hardware is in the state we expect. */
- if (EHCI_LINK_ADDR(hc32toh(sc, sqh->qh.qh_qtd.qtd_next)) !=
- sqtd->physaddr) {
-#ifdef EHCI_DEBUG
- printf("ehci_activate_qh: unexpected next ptr\n");
- ehci_dump_sqh(sc, sqh);
- ehci_dump_sqtds(sc, sqh->sqtd);
-#endif
- sqh->qh.qh_qtd.qtd_next = htohc32(sc, sqtd->physaddr);
- sqh->qh.qh_qtd.qtd_altnext = EHCI_NULL(sc);
- }
- /* Ensure the flags are correct. */
- sqh->qh.qh_qtd.qtd_status &= htohc32(sc, EHCI_QTD_PINGSTATE |
- EHCI_QTD_TOGGLE_MASK);
- }
-
- /* Now activate the qTD. */
- sqtd->qtd.qtd_status |= htohc32(sc, EHCI_QTD_ACTIVE);
-}
-
-/*
- * Ensure that the HC has released all references to the QH. We do this
- * by asking for a Async Advance Doorbell interrupt and then we wait for
- * the interrupt.
- * To make this easier we first obtain exclusive use of the doorbell.
- */
-void
-ehci_sync_hc(ehci_softc_t *sc)
-{
- int s, error;
-
- if (sc->sc_dying) {
- DPRINTFN(2,("ehci_sync_hc: dying\n"));
- return;
- }
- DPRINTFN(2,("ehci_sync_hc: enter\n"));
- /* get doorbell */
- lockmgr(&sc->sc_doorbell_lock, LK_EXCLUSIVE, NULL);
- s = splhardusb();
- /* ask for doorbell */
- EOWRITE4(sc, EHCI_USBCMD, EOREAD4(sc, EHCI_USBCMD) | EHCI_CMD_IAAD);
- DPRINTFN(1,("ehci_sync_hc: cmd=0x%08x sts=0x%08x\n",
- EOREAD4(sc, EHCI_USBCMD), EOREAD4(sc, EHCI_USBSTS)));
- error = tsleep(&sc->sc_async_head, PZERO, "ehcidi", hz); /* bell wait */
- DPRINTFN(1,("ehci_sync_hc: cmd=0x%08x sts=0x%08x\n",
- EOREAD4(sc, EHCI_USBCMD), EOREAD4(sc, EHCI_USBSTS)));
- splx(s);
- /* release doorbell */
- lockmgr(&sc->sc_doorbell_lock, LK_RELEASE, NULL);
-#ifdef DIAGNOSTIC
- if (error)
- printf("ehci_sync_hc: tsleep() = %d\n", error);
-#endif
- DPRINTFN(2,("ehci_sync_hc: exit\n"));
-}
-
-/*Call at splusb*/
-void
-ehci_rem_free_itd_chain(ehci_softc_t *sc, struct ehci_xfer *exfer)
-{
- struct ehci_soft_itd *itd, *prev;
-
- prev = NULL;
-
- if (exfer->itdstart == NULL || exfer->itdend == NULL)
- panic("ehci isoc xfer being freed, but with no itd chain\n");
-
- for (itd = exfer->itdstart; itd != NULL; itd = itd->xfer_next) {
- prev = itd->u.frame_list.prev;
- /* Unlink itd from hardware chain, or frame array */
- if (prev == NULL) { /* We're at the table head */
- sc->sc_softitds[itd->slot] = itd->u.frame_list.next;
- sc->sc_flist[itd->slot] = itd->itd.itd_next;
-
- if (itd->u.frame_list.next != NULL)
- itd->u.frame_list.next->u.frame_list.prev =
- NULL;
- } else {
- /* XXX this part is untested... */
- prev->itd.itd_next = itd->itd.itd_next;
- prev->u.frame_list.next = itd->u.frame_list.next;
- if (itd->u.frame_list.next != NULL)
- itd->u.frame_list.next->u.frame_list.prev =
- prev;
- }
- }
-
- prev = NULL;
- for (itd = exfer->itdstart; itd != NULL; itd = itd->xfer_next) {
- if (prev != NULL)
- ehci_free_itd(sc, prev);
- prev = itd;
- }
- if (prev)
- ehci_free_itd(sc, prev);
- exfer->itdstart = NULL;
- exfer->itdend = NULL;
-}
-
-/***********/
-
-/*
- * Data structures and routines to emulate the root hub.
- */
-static usb_device_descriptor_t ehci_devd = {
- USB_DEVICE_DESCRIPTOR_SIZE,
- UDESC_DEVICE, /* type */
- {0x00, 0x02}, /* USB version */
- UDCLASS_HUB, /* class */
- UDSUBCLASS_HUB, /* subclass */
- UDPROTO_HSHUBSTT, /* protocol */
- 64, /* max packet */
- {0},{0},{0x00,0x01}, /* device id */
- 1,2,0, /* string indicies */
- 1 /* # of configurations */
-};
-
-static usb_device_qualifier_t ehci_odevd = {
- USB_DEVICE_DESCRIPTOR_SIZE,
- UDESC_DEVICE_QUALIFIER, /* type */
- {0x00, 0x02}, /* USB version */
- UDCLASS_HUB, /* class */
- UDSUBCLASS_HUB, /* subclass */
- UDPROTO_FSHUB, /* protocol */
- 64, /* max packet */
- 1, /* # of configurations */
- 0
-};
-
-static usb_config_descriptor_t ehci_confd = {
- USB_CONFIG_DESCRIPTOR_SIZE,
- UDESC_CONFIG,
- {USB_CONFIG_DESCRIPTOR_SIZE +
- USB_INTERFACE_DESCRIPTOR_SIZE +
- USB_ENDPOINT_DESCRIPTOR_SIZE},
- 1,
- 1,
- 0,
- UC_SELF_POWERED,
- 0 /* max power */
-};
-
-static usb_interface_descriptor_t ehci_ifcd = {
- USB_INTERFACE_DESCRIPTOR_SIZE,
- UDESC_INTERFACE,
- 0,
- 0,
- 1,
- UICLASS_HUB,
- UISUBCLASS_HUB,
- UIPROTO_HSHUBSTT,
- 0
-};
-
-static usb_endpoint_descriptor_t ehci_endpd = {
- USB_ENDPOINT_DESCRIPTOR_SIZE,
- UDESC_ENDPOINT,
- UE_DIR_IN | EHCI_INTR_ENDPT,
- UE_INTERRUPT,
- {8, 0}, /* max packet */
- 255
-};
-
-static usb_hub_descriptor_t ehci_hubd = {
- USB_HUB_DESCRIPTOR_SIZE,
- UDESC_HUB,
- 0,
- {0,0},
- 0,
- 0,
- {0},
-};
-
-static int
-ehci_str(usb_string_descriptor_t *p, int l, char *s)
-{
- int i;
-
- if (l == 0)
- return (0);
- p->bLength = 2 * strlen(s) + 2;
- if (l == 1)
- return (1);
- p->bDescriptorType = UDESC_STRING;
- l -= 2;
- for (i = 0; s[i] && l > 1; i++, l -= 2)
- USETW2(p->bString[i], 0, s[i]);
- return (2*i+2);
-}
-
-/*
- * Simulate a hardware hub by handling all the necessary requests.
- */
-static usbd_status
-ehci_root_ctrl_transfer(usbd_xfer_handle xfer)
-{
- usbd_status err;
-
- /* Insert last in queue. */
- err = usb_insert_transfer(xfer);
- if (err)
- return (err);
-
- /* Pipe isn't running, start first */
- return (ehci_root_ctrl_start(STAILQ_FIRST(&xfer->pipe->queue)));
-}
-
-static usbd_status
-ehci_root_ctrl_start(usbd_xfer_handle xfer)
-{
- ehci_softc_t *sc = (ehci_softc_t *)xfer->pipe->device->bus;
- usb_device_request_t *req;
- void *buf = NULL;
- int port, i;
- int s, len, value, index, l, totlen = 0;
- usb_port_status_t ps;
- usb_hub_descriptor_t hubd;
- usbd_status err;
- u_int32_t v;
-
- if (sc->sc_dying)
- return (USBD_IOERROR);
-
-#ifdef DIAGNOSTIC
- if (!(xfer->rqflags & URQ_REQUEST))
- /* XXX panic */
- return (USBD_INVAL);
-#endif
- req = &xfer->request;
-
- DPRINTFN(4,("ehci_root_ctrl_start: type=0x%02x request=%02x\n",
- req->bmRequestType, req->bRequest));
-
- len = UGETW(req->wLength);
- value = UGETW(req->wValue);
- index = UGETW(req->wIndex);
-
- if (len != 0)
- buf = xfer->buffer;
-
-#define C(x,y) ((x) | ((y) << 8))
- switch(C(req->bRequest, req->bmRequestType)) {
- case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE):
- case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE):
- case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT):
- /*
- * DEVICE_REMOTE_WAKEUP and ENDPOINT_HALT are no-ops
- * for the integrated root hub.
- */
- break;
- case C(UR_GET_CONFIG, UT_READ_DEVICE):
- if (len > 0) {
- *(u_int8_t *)buf = sc->sc_conf;
- totlen = 1;
- }
- break;
- case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
- DPRINTFN(8,("ehci_root_ctrl_start: wValue=0x%04x\n", value));
- switch(value >> 8) {
- case UDESC_DEVICE:
- if ((value & 0xff) != 0) {
- err = USBD_IOERROR;
- goto ret;
- }
- totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE);
- USETW(ehci_devd.idVendor, sc->sc_id_vendor);
- memcpy(buf, &ehci_devd, l);
- break;
- /*
- * We can't really operate at another speed, but the spec says
- * we need this descriptor.
- */
- case UDESC_DEVICE_QUALIFIER:
- if ((value & 0xff) != 0) {
- err = USBD_IOERROR;
- goto ret;
- }
- totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE);
- memcpy(buf, &ehci_odevd, l);
- break;
- /*
- * We can't really operate at another speed, but the spec says
- * we need this descriptor.
- */
- case UDESC_OTHER_SPEED_CONFIGURATION:
- case UDESC_CONFIG:
- if ((value & 0xff) != 0) {
- err = USBD_IOERROR;
- goto ret;
- }
- totlen = l = min(len, USB_CONFIG_DESCRIPTOR_SIZE);
- memcpy(buf, &ehci_confd, l);
- ((usb_config_descriptor_t *)buf)->bDescriptorType =
- value >> 8;
- buf = (char *)buf + l;
- len -= l;
- l = min(len, USB_INTERFACE_DESCRIPTOR_SIZE);
- totlen += l;
- memcpy(buf, &ehci_ifcd, l);
- buf = (char *)buf + l;
- len -= l;
- l = min(len, USB_ENDPOINT_DESCRIPTOR_SIZE);
- totlen += l;
- memcpy(buf, &ehci_endpd, l);
- break;
- case UDESC_STRING:
- if (len == 0)
- break;
- *(u_int8_t *)buf = 0;
- totlen = 1;
- switch (value & 0xff) {
- case 0: /* Language table */
- totlen = ehci_str(buf, len, "\001");
- break;
- case 1: /* Vendor */
- totlen = ehci_str(buf, len, sc->sc_vendor);
- break;
- case 2: /* Product */
- totlen = ehci_str(buf, len, "EHCI root hub");
- break;
- }
- break;
- default:
- err = USBD_IOERROR;
- goto ret;
- }
- break;
- case C(UR_GET_INTERFACE, UT_READ_INTERFACE):
- if (len > 0) {
- *(u_int8_t *)buf = 0;
- totlen = 1;
- }
- break;
- case C(UR_GET_STATUS, UT_READ_DEVICE):
- if (len > 1) {
- USETW(((usb_status_t *)buf)->wStatus,UDS_SELF_POWERED);
- totlen = 2;
- }
- break;
- case C(UR_GET_STATUS, UT_READ_INTERFACE):
- case C(UR_GET_STATUS, UT_READ_ENDPOINT):
- if (len > 1) {
- USETW(((usb_status_t *)buf)->wStatus, 0);
- totlen = 2;
- }
- break;
- case C(UR_SET_ADDRESS, UT_WRITE_DEVICE):
- if (value >= USB_MAX_DEVICES) {
- err = USBD_IOERROR;
- goto ret;
- }
- sc->sc_addr = value;
- break;
- case C(UR_SET_CONFIG, UT_WRITE_DEVICE):
- if (value != 0 && value != 1) {
- err = USBD_IOERROR;
- goto ret;
- }
- sc->sc_conf = value;
- break;
- case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE):
- break;
- case C(UR_SET_FEATURE, UT_WRITE_DEVICE):
- case C(UR_SET_FEATURE, UT_WRITE_INTERFACE):
- case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT):
- err = USBD_IOERROR;
- goto ret;
- case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE):
- break;
- case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT):
- break;
- /* Hub requests */
- case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE):
- break;
- case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER):
- DPRINTFN(8, ("ehci_root_ctrl_start: UR_CLEAR_PORT_FEATURE "
- "port=%d feature=%d\n",
- index, value));
- if (index < 1 || index > sc->sc_noport) {
- err = USBD_IOERROR;
- goto ret;
- }
- port = EHCI_PORTSC(index);
- v = EOREAD4(sc, port) &~ EHCI_PS_CLEAR;
- switch(value) {
- case UHF_PORT_ENABLE:
- EOWRITE4(sc, port, v &~ EHCI_PS_PE);
- break;
- case UHF_PORT_SUSPEND:
- EOWRITE4(sc, port, v &~ EHCI_PS_SUSP);
- break;
- case UHF_PORT_POWER:
- EOWRITE4(sc, port, v &~ EHCI_PS_PP);
- break;
- case UHF_PORT_TEST:
- DPRINTFN(2,("ehci_root_ctrl_start: clear port test "
- "%d\n", index));
- break;
- case UHF_PORT_INDICATOR:
- DPRINTFN(2,("ehci_root_ctrl_start: clear port ind "
- "%d\n", index));
- EOWRITE4(sc, port, v &~ EHCI_PS_PIC);
- break;
- case UHF_C_PORT_CONNECTION:
- EOWRITE4(sc, port, v | EHCI_PS_CSC);
- break;
- case UHF_C_PORT_ENABLE:
- EOWRITE4(sc, port, v | EHCI_PS_PEC);
- break;
- case UHF_C_PORT_SUSPEND:
- /* how? */
- break;
- case UHF_C_PORT_OVER_CURRENT:
- EOWRITE4(sc, port, v | EHCI_PS_OCC);
- break;
- case UHF_C_PORT_RESET:
- sc->sc_isreset = 0;
- break;
- default:
- err = USBD_IOERROR;
- goto ret;
- }
- break;
- case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE):
- if ((value & 0xff) != 0) {
- err = USBD_IOERROR;
- goto ret;
- }
- hubd = ehci_hubd;
- hubd.bNbrPorts = sc->sc_noport;
- v = EOREAD4(sc, EHCI_HCSPARAMS);
- USETW(hubd.wHubCharacteristics,
- EHCI_HCS_PPC(v) ? UHD_PWR_INDIVIDUAL : UHD_PWR_NO_SWITCH |
- EHCI_HCS_P_INDICATOR(EREAD4(sc, EHCI_HCSPARAMS))
- ? UHD_PORT_IND : 0);
- hubd.bPwrOn2PwrGood = 200; /* XXX can't find out? */
- for (i = 0, l = sc->sc_noport; l > 0; i++, l -= 8, v >>= 8)
- hubd.DeviceRemovable[i++] = 0; /* XXX can't find out? */
- hubd.bDescLength = USB_HUB_DESCRIPTOR_SIZE + i;
- l = min(len, hubd.bDescLength);
- totlen = l;
- memcpy(buf, &hubd, l);
- break;
- case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
- if (len != 4) {
- err = USBD_IOERROR;
- goto ret;
- }
- memset(buf, 0, len); /* ? XXX */
- totlen = len;
- break;
- case C(UR_GET_STATUS, UT_READ_CLASS_OTHER):
- DPRINTFN(8,("ehci_root_ctrl_start: get port status i=%d\n",
- index));
- if (index < 1 || index > sc->sc_noport) {
- err = USBD_IOERROR;
- goto ret;
- }
- if (len != 4) {
- err = USBD_IOERROR;
- goto ret;
- }
- v = EOREAD4(sc, EHCI_PORTSC(index));
- DPRINTFN(8,("ehci_root_ctrl_start: port status=0x%04x\n",
- v));
-
- i = UPS_HIGH_SPEED;
-
- if (sc->sc_flags & (EHCI_SCFLG_FORCESPEED | EHCI_SCFLG_TT)) {
- if ((v & 0xc000000) == 0x8000000)
- i = UPS_HIGH_SPEED;
- else if ((v & 0xc000000) == 0x4000000)
- i = UPS_LOW_SPEED;
- else
- i = 0;
- }
-
- if (v & EHCI_PS_CS) i |= UPS_CURRENT_CONNECT_STATUS;
- if (v & EHCI_PS_PE) i |= UPS_PORT_ENABLED;
- if (v & EHCI_PS_SUSP) i |= UPS_SUSPEND;
- if (v & EHCI_PS_OCA) i |= UPS_OVERCURRENT_INDICATOR;
- if (v & EHCI_PS_PR) i |= UPS_RESET;
- if (v & EHCI_PS_PP) i |= UPS_PORT_POWER;
- USETW(ps.wPortStatus, i);
- i = 0;
- if (v & EHCI_PS_CSC) i |= UPS_C_CONNECT_STATUS;
- if (v & EHCI_PS_PEC) i |= UPS_C_PORT_ENABLED;
- if (v & EHCI_PS_OCC) i |= UPS_C_OVERCURRENT_INDICATOR;
- if (sc->sc_isreset) i |= UPS_C_PORT_RESET;
- USETW(ps.wPortChange, i);
- l = min(len, sizeof ps);
- memcpy(buf, &ps, l);
- totlen = l;
- break;
- case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE):
- err = USBD_IOERROR;
- goto ret;
- case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE):
- break;
- case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER):
- if (index < 1 || index > sc->sc_noport) {
- err = USBD_IOERROR;
- goto ret;
- }
- port = EHCI_PORTSC(index);
- v = EOREAD4(sc, port) &~ EHCI_PS_CLEAR;
- switch(value) {
- case UHF_PORT_ENABLE:
- EOWRITE4(sc, port, v | EHCI_PS_PE);
- break;
- case UHF_PORT_SUSPEND:
- EOWRITE4(sc, port, v | EHCI_PS_SUSP);
- break;
- case UHF_PORT_RESET:
- DPRINTFN(5,("ehci_root_ctrl_start: reset port %d\n",
- index));
- if (EHCI_PS_IS_LOWSPEED(v) &&
- (sc->sc_flags & EHCI_SCFLG_TT) == 0) {
- /* Low speed device, give up ownership. */
- ehci_disown(sc, index, 1);
- break;
- }
- /* Start reset sequence. */
- v &= ~ (EHCI_PS_PE | EHCI_PS_PR);
- EOWRITE4(sc, port, v | EHCI_PS_PR);
- /* Wait for reset to complete. */
- usb_delay_ms(&sc->sc_bus, USB_PORT_ROOT_RESET_DELAY);
- if (sc->sc_dying) {
- err = USBD_IOERROR;
- goto ret;
- }
- /* Terminate reset sequence. */
- if (sc->sc_flags & EHCI_SCFLG_NORESTERM)
- ;
- else
- EOWRITE4(sc, port, v);
-
- /* Wait for HC to complete reset. */
- usb_delay_ms(&sc->sc_bus, EHCI_PORT_RESET_COMPLETE);
- if (sc->sc_dying) {
- err = USBD_IOERROR;
- goto ret;
- }
- v = EOREAD4(sc, port);
- DPRINTF(("ehci after reset, status=0x%08x\n", v));
- if (v & EHCI_PS_PR) {
- printf("%s: port reset timeout\n",
- device_get_nameunit(sc->sc_bus.bdev));
- return (USBD_TIMEOUT);
- }
- if (!(v & EHCI_PS_PE) &&
- (sc->sc_flags & EHCI_SCFLG_TT) == 0) {
- /* Not a high speed device, give up ownership.*/
- ehci_disown(sc, index, 0);
- break;
- }
- sc->sc_isreset = 1;
- DPRINTF(("ehci port %d reset, status = 0x%08x\n",
- index, v));
- break;
- case UHF_PORT_POWER:
- DPRINTFN(2,("ehci_root_ctrl_start: set port power "
- "%d\n", index));
- EOWRITE4(sc, port, v | EHCI_PS_PP);
- break;
- case UHF_PORT_TEST:
- DPRINTFN(2,("ehci_root_ctrl_start: set port test "
- "%d\n", index));
- break;
- case UHF_PORT_INDICATOR:
- DPRINTFN(2,("ehci_root_ctrl_start: set port ind "
- "%d\n", index));
- EOWRITE4(sc, port, v | EHCI_PS_PIC);
- break;
- default:
- err = USBD_IOERROR;
- goto ret;
- }
- break;
- case C(UR_CLEAR_TT_BUFFER, UT_WRITE_CLASS_OTHER):
- case C(UR_RESET_TT, UT_WRITE_CLASS_OTHER):
- case C(UR_GET_TT_STATE, UT_READ_CLASS_OTHER):
- case C(UR_STOP_TT, UT_WRITE_CLASS_OTHER):
- break;
- default:
- err = USBD_IOERROR;
- goto ret;
- }
- xfer->actlen = totlen;
- err = USBD_NORMAL_COMPLETION;
- ret:
- xfer->status = err;
- s = splusb();
- hacksync(xfer); /* XXX to compensate for usb_transfer_complete */
- usb_transfer_complete(xfer);
- splx(s);
- return (USBD_IN_PROGRESS);
-}
-
-void
-ehci_disown(ehci_softc_t *sc, int index, int lowspeed)
-{
- int port;
- u_int32_t v;
-
- DPRINTF(("ehci_disown: index=%d lowspeed=%d\n", index, lowspeed));
-#ifdef DIAGNOSTIC
- if (sc->sc_npcomp != 0) {
- int i = (index-1) / sc->sc_npcomp;
- if (i >= sc->sc_ncomp)
- printf("%s: strange port\n",
- device_get_nameunit(sc->sc_bus.bdev));
- else
- printf("%s: handing over %s speed device on "
- "port %d to %s\n",
- device_get_nameunit(sc->sc_bus.bdev),
- lowspeed ? "low" : "full",
- index, device_get_nameunit(sc->sc_comps[i]->bdev));
- } else {
- printf("%s: npcomp == 0\n", device_get_nameunit(sc->sc_bus.bdev));
- }
-#endif
- port = EHCI_PORTSC(index);
- v = EOREAD4(sc, port) &~ EHCI_PS_CLEAR;
- EOWRITE4(sc, port, v | EHCI_PS_PO);
-}
-
-/* Abort a root control request. */
-static void
-ehci_root_ctrl_abort(usbd_xfer_handle xfer)
-{
- /* Nothing to do, all transfers are synchronous. */
-}
-
-/* Close the root pipe. */
-static void
-ehci_root_ctrl_close(usbd_pipe_handle pipe)
-{
- DPRINTF(("ehci_root_ctrl_close\n"));
- /* Nothing to do. */
-}
-
-void
-ehci_root_intr_done(usbd_xfer_handle xfer)
-{
-}
-
-static usbd_status
-ehci_root_intr_transfer(usbd_xfer_handle xfer)
-{
- usbd_status err;
-
- /* Insert last in queue. */
- err = usb_insert_transfer(xfer);
- if (err)
- return (err);
-
- /* Pipe isn't running, start first */
- return (ehci_root_intr_start(STAILQ_FIRST(&xfer->pipe->queue)));
-}
-
-static usbd_status
-ehci_root_intr_start(usbd_xfer_handle xfer)
-{
- usbd_pipe_handle pipe = xfer->pipe;
- ehci_softc_t *sc = (ehci_softc_t *)pipe->device->bus;
-
- if (sc->sc_dying)
- return (USBD_IOERROR);
-
- sc->sc_intrxfer = xfer;
-
- return (USBD_IN_PROGRESS);
-}
-
-/* Abort a root interrupt request. */
-static void
-ehci_root_intr_abort(usbd_xfer_handle xfer)
-{
- int s;
-
- if (xfer->pipe->intrxfer == xfer) {
- DPRINTF(("ehci_root_intr_abort: remove\n"));
- xfer->pipe->intrxfer = NULL;
- }
- xfer->status = USBD_CANCELLED;
- s = splusb();
- usb_transfer_complete(xfer);
- splx(s);
-}
-
-/* Close the root pipe. */
-static void
-ehci_root_intr_close(usbd_pipe_handle pipe)
-{
- ehci_softc_t *sc = (ehci_softc_t *)pipe->device->bus;
-
- DPRINTF(("ehci_root_intr_close\n"));
-
- sc->sc_intrxfer = NULL;
-}
-
-void
-ehci_root_ctrl_done(usbd_xfer_handle xfer)
-{
-}
-
-/************************/
-
-ehci_soft_qh_t *
-ehci_alloc_sqh(ehci_softc_t *sc)
-{
- ehci_soft_qh_t *sqh;
- ehci_soft_qtd_t *sqtd;
- usbd_status err;
- int i, offs;
- usb_dma_t dma;
-
- if (sc->sc_freeqhs == NULL) {
- DPRINTFN(2, ("ehci_alloc_sqh: allocating chunk\n"));
- err = usb_allocmem(&sc->sc_bus, EHCI_SQH_SIZE * EHCI_SQH_CHUNK,
- EHCI_PAGE_SIZE, &dma);
-#ifdef EHCI_DEBUG
- if (err)
- printf("ehci_alloc_sqh: usb_allocmem()=%d\n", err);
-#endif
- if (err)
- return (NULL);
- for(i = 0; i < EHCI_SQH_CHUNK; i++) {
- offs = i * EHCI_SQH_SIZE;
- sqh = KERNADDR(&dma, offs);
- sqh->physaddr = DMAADDR(&dma, offs);
- sqh->next = sc->sc_freeqhs;
- sc->sc_freeqhs = sqh;
- }
- }
- /* Allocate the initial inactive sqtd. */
- sqtd = ehci_alloc_sqtd(sc);
- if (sqtd == NULL)
- return (NULL);
- sqtd->qtd.qtd_status = htohc32(sc, 0);
- sqtd->qtd.qtd_next = EHCI_NULL(sc);
- sqtd->qtd.qtd_altnext = EHCI_NULL(sc);
-
- sqh = sc->sc_freeqhs;
- sc->sc_freeqhs = sqh->next;
-
- /* The overlay QTD should begin zeroed. */
- sqh->qh.qh_qtd.qtd_next = htohc32(sc, sqtd->physaddr);
- sqh->qh.qh_qtd.qtd_altnext = EHCI_NULL(sc);
- sqh->qh.qh_qtd.qtd_status = 0;
- for (i = 0; i < EHCI_QTD_NBUFFERS; i++) {
- sqh->qh.qh_qtd.qtd_buffer[i] = 0;
- sqh->qh.qh_qtd.qtd_buffer_hi[i] = 0;
- }
- sqh->next = NULL;
- sqh->prev = NULL;
- sqh->sqtd = sqtd;
- sqh->inactivesqtd = sqtd;
- return (sqh);
-}
-
-void
-ehci_free_sqh(ehci_softc_t *sc, ehci_soft_qh_t *sqh)
-{
- ehci_free_sqtd(sc, sqh->inactivesqtd);
- sqh->next = sc->sc_freeqhs;
- sc->sc_freeqhs = sqh;
-}
-
-ehci_soft_qtd_t *
-ehci_alloc_sqtd(ehci_softc_t *sc)
-{
- ehci_soft_qtd_t *sqtd;
- usbd_status err;
- int i, offs;
- usb_dma_t dma;
- int s;
-
- if (sc->sc_freeqtds == NULL) {
- DPRINTFN(2, ("ehci_alloc_sqtd: allocating chunk\n"));
- err = usb_allocmem(&sc->sc_bus, EHCI_SQTD_SIZE*EHCI_SQTD_CHUNK,
- EHCI_PAGE_SIZE, &dma);
-#ifdef EHCI_DEBUG
- if (err)
- printf("ehci_alloc_sqtd: usb_allocmem()=%d\n", err);
-#endif
- if (err)
- return (NULL);
- s = splusb();
- for(i = 0; i < EHCI_SQTD_CHUNK; i++) {
- offs = i * EHCI_SQTD_SIZE;
- sqtd = KERNADDR(&dma, offs);
- sqtd->physaddr = DMAADDR(&dma, offs);
- sqtd->nextqtd = sc->sc_freeqtds;
- sc->sc_freeqtds = sqtd;
- }
- splx(s);
- }
-
- s = splusb();
- sqtd = sc->sc_freeqtds;
- sc->sc_freeqtds = sqtd->nextqtd;
- sqtd->qtd.qtd_next = EHCI_NULL(sc);
- sqtd->qtd.qtd_altnext = EHCI_NULL(sc);
- sqtd->qtd.qtd_status = 0;
- for (i = 0; i < EHCI_QTD_NBUFFERS; i++) {
- sqtd->qtd.qtd_buffer[i] = 0;
- sqtd->qtd.qtd_buffer_hi[i] = 0;
- }
- sqtd->nextqtd = NULL;
- sqtd->xfer = NULL;
- splx(s);
-
- return (sqtd);
-}
-
-void
-ehci_free_sqtd(ehci_softc_t *sc, ehci_soft_qtd_t *sqtd)
-{
- int s;
-
- s = splusb();
- sqtd->nextqtd = sc->sc_freeqtds;
- sc->sc_freeqtds = sqtd;
- splx(s);
-}
-
-usbd_status
-ehci_alloc_sqtd_chain(struct ehci_pipe *epipe, ehci_softc_t *sc,
- int alen, int rd, usbd_xfer_handle xfer, ehci_soft_qtd_t *start,
- ehci_soft_qtd_t *newinactive, ehci_soft_qtd_t **sp, ehci_soft_qtd_t **ep)
-{
- ehci_soft_qtd_t *next, *cur;
- ehci_physaddr_t dataphys, nextphys;
- u_int32_t qtdstatus;
- int adj, len, curlen, mps, offset, pagelen, seg, segoff;
- int i, iscontrol, forceshort;
- struct usb_dma_mapping *dma = &xfer->dmamap;
-
- DPRINTFN(alen<4*4096,("ehci_alloc_sqtd_chain: start len=%d\n", alen));
-
- offset = 0;
- len = alen;
- iscontrol = (epipe->pipe.endpoint->edesc->bmAttributes & UE_XFERTYPE) ==
- UE_CONTROL;
- qtdstatus = EHCI_QTD_ACTIVE |
- EHCI_QTD_SET_PID(rd ? EHCI_QTD_PID_IN : EHCI_QTD_PID_OUT) |
- EHCI_QTD_SET_CERR(3)
- /* IOC set below */
- /* BYTES set below */
- ;
- mps = UGETW(epipe->pipe.endpoint->edesc->wMaxPacketSize);
- forceshort = ((xfer->flags & USBD_FORCE_SHORT_XFER) || len == 0) &&
- len % mps == 0;
- /*
- * The control transfer data stage always starts with a toggle of 1.
- * For other transfers we let the hardware track the toggle state.
- */
- if (iscontrol)
- qtdstatus |= EHCI_QTD_SET_TOGGLE(1);
-
- if (start != NULL) {
- /*
- * If we are given a starting qTD, assume it is linked into
- * an active QH so be careful not to mark it active.
- */
- cur = start;
- *sp = cur;
- qtdstatus &= ~EHCI_QTD_ACTIVE;
- } else {
- cur = ehci_alloc_sqtd(sc);
- *sp = cur;
- if (cur == NULL)
- goto nomem;
- }
- seg = 0;
- segoff = 0;
- for (;;) {
- curlen = 0;
-
- /* The EHCI hardware can handle at most 5 pages. */
- for (i = 0; i < EHCI_QTD_NBUFFERS && curlen < len; i++) {
- KASSERT(seg < dma->nsegs,
- ("ehci_alloc_sqtd_chain: overrun"));
- dataphys = dma->segs[seg].ds_addr + segoff;
- pagelen = dma->segs[seg].ds_len - segoff;
- if (pagelen > len - curlen)
- pagelen = len - curlen;
- if (pagelen > EHCI_PAGE_SIZE -
- EHCI_PAGE_OFFSET(dataphys))
- pagelen = EHCI_PAGE_SIZE -
- EHCI_PAGE_OFFSET(dataphys);
- segoff += pagelen;
- if (segoff >= dma->segs[seg].ds_len) {
- KASSERT(segoff == dma->segs[seg].ds_len,
- ("ehci_alloc_sqtd_chain: overlap"));
- seg++;
- segoff = 0;
- }
-
- cur->qtd.qtd_buffer[i] = htohc32(sc, dataphys);
- cur->qtd.qtd_buffer_hi[i] = 0;
- curlen += pagelen;
-
- /*
- * Must stop if there is any gap before or after
- * the page boundary.
- */
- if (EHCI_PAGE_OFFSET(dataphys + pagelen) != 0)
- break;
- if (seg < dma->nsegs && EHCI_PAGE_OFFSET(segoff +
- dma->segs[seg].ds_addr) != 0)
- break;
- }
- /* Adjust down to a multiple of mps if not at the end. */
- if (curlen < len && curlen % mps != 0) {
- adj = curlen % mps;
- curlen -= adj;
- KASSERT(curlen > 0,
- ("ehci_alloc_sqtd_chain: need to copy"));
- segoff -= adj;
- if (segoff < 0) {
- seg--;
- segoff += dma->segs[seg].ds_len;
- }
- KASSERT(seg >= 0 && segoff >= 0,
- ("ehci_alloc_sqtd_chain: adjust to mps"));
- }
-
- len -= curlen;
-
- if (len != 0 || forceshort) {
- next = ehci_alloc_sqtd(sc);
- if (next == NULL)
- goto nomem;
- nextphys = htohc32(sc, next->physaddr);
- } else {
- next = NULL;
- nextphys = EHCI_NULL(sc);
- }
-
- cur->nextqtd = next;
- cur->qtd.qtd_next = nextphys;
- /* Make sure to stop after a short transfer. */
- cur->qtd.qtd_altnext = htohc32(sc, newinactive->physaddr);
- cur->qtd.qtd_status =
- htohc32(sc, qtdstatus | EHCI_QTD_SET_BYTES(curlen));
- cur->xfer = xfer;
- cur->len = curlen;
- DPRINTFN(10,("ehci_alloc_sqtd_chain: curlen=%d\n", curlen));
- if (iscontrol) {
- /*
- * adjust the toggle based on the number of packets
- * in this qtd
- */
- if ((((curlen + mps - 1) / mps) & 1) || curlen == 0)
- qtdstatus ^= EHCI_QTD_TOGGLE_MASK;
- }
- qtdstatus |= EHCI_QTD_ACTIVE;
- if (len == 0) {
- if (!forceshort)
- break;
- forceshort = 0;
- }
- DPRINTFN(10,("ehci_alloc_sqtd_chain: extend chain\n"));
- offset += curlen;
- cur = next;
- }
- cur->qtd.qtd_status |= htohc32(sc, EHCI_QTD_IOC);
- *ep = cur;
-
- DPRINTFN(10,("ehci_alloc_sqtd_chain: return sqtd=%p sqtdend=%p\n",
- *sp, *ep));
-
- return (USBD_NORMAL_COMPLETION);
-
- nomem:
- /* XXX free chain */
- DPRINTFN(-1,("ehci_alloc_sqtd_chain: no memory\n"));
- return (USBD_NOMEM);
-}
-
-/* Free the chain starting at sqtd and end at the qTD before sqtdend */
-static void
-ehci_free_sqtd_chain(ehci_softc_t *sc, ehci_soft_qh_t *sqh,
- ehci_soft_qtd_t *sqtd, ehci_soft_qtd_t *sqtdend)
-{
- ehci_soft_qtd_t *p, **prevp;
- int i;
-
- DPRINTFN(10,("ehci_free_sqtd_chain: sqtd=%p sqtdend=%p\n",
- sqtd, sqtdend));
-
- /* First unlink the chain from the QH's software qTD list. */
- prevp = &sqh->sqtd;
- for (p = sqh->sqtd; p != NULL; p = p->nextqtd) {
- if (p == sqtd) {
- *prevp = sqtdend;
- break;
- }
- prevp = &p->nextqtd;
- }
- KASSERT(p != NULL, ("ehci_free_sqtd_chain: chain not found"));
- for (i = 0; sqtd != sqtdend; sqtd = p, i++) {
- p = sqtd->nextqtd;
- ehci_free_sqtd(sc, sqtd);
- }
-}
-
-ehci_soft_itd_t *
-ehci_alloc_itd(ehci_softc_t *sc)
-{
- struct ehci_soft_itd *itd, *freeitd;
- usbd_status err;
- int i, s, offs, frindex, previndex;
- usb_dma_t dma;
-
- s = splusb();
-
- /* Find an itd that wasn't freed this frame or last frame. This can
- * discard itds that were freed before frindex wrapped around
- * XXX - can this lead to thrashing? Could fix by enabling wrap-around
- * interrupt and fiddling with list when that happens */
- frindex = (EOREAD4(sc, EHCI_FRINDEX) + 1) >> 3;
- previndex = (frindex != 0) ? frindex - 1 : sc->sc_flsize;
-
- freeitd = NULL;
- LIST_FOREACH(itd, &sc->sc_freeitds, u.free_list) {
- if (itd == NULL)
- break;
- if (itd->slot != frindex && itd->slot != previndex) {
- freeitd = itd;
- break;
- }
- }
-
- if (freeitd == NULL) {
- DPRINTFN(2, ("ehci_alloc_itd allocating chunk\n"));
- err = usb_allocmem(&sc->sc_bus, EHCI_ITD_SIZE * EHCI_ITD_CHUNK,
- EHCI_PAGE_SIZE, &dma);
-
- if (err) {
- DPRINTF(("ehci_alloc_itd, alloc returned %d\n", err));
- return NULL;
- }
-
- for (i = 0; i < EHCI_ITD_CHUNK; i++) {
- offs = i * EHCI_ITD_SIZE;
- itd = KERNADDR(&dma, offs);
- itd->physaddr = DMAADDR(&dma, offs);
- itd->dma = dma;
- itd->offs = offs;
- LIST_INSERT_HEAD(&sc->sc_freeitds, itd, u.free_list);
- }
- freeitd = LIST_FIRST(&sc->sc_freeitds);
- }
-
- itd = freeitd;
- LIST_REMOVE(itd, u.free_list);
- memset(&itd->itd, 0, sizeof(ehci_itd_t));
- itd->u.frame_list.next = NULL;
- itd->u.frame_list.prev = NULL;
- itd->xfer_next = NULL;
- itd->slot = 0;
- splx(s);
-
- return (itd);
-}
-
-void
-ehci_free_itd(ehci_softc_t *sc, ehci_soft_itd_t *itd)
-{
- int s;
-
- s = splusb();
- LIST_INSERT_AFTER(LIST_FIRST(&sc->sc_freeitds), itd, u.free_list);
- splx(s);
-}
-
-/****************/
-
-/*
- * Close a reqular pipe.
- * Assumes that there are no pending transactions.
- */
-void
-ehci_close_pipe(usbd_pipe_handle pipe, ehci_soft_qh_t *head)
-{
- struct ehci_pipe *epipe = (struct ehci_pipe *)pipe;
- ehci_softc_t *sc = (ehci_softc_t *)pipe->device->bus;
- ehci_soft_qh_t *sqh = epipe->sqh;
- int s;
-
- s = splusb();
- ehci_rem_qh(sc, sqh, head);
- splx(s);
- pipe->endpoint->savedtoggle =
- EHCI_QTD_GET_TOGGLE(hc32toh(sc, sqh->qh.qh_qtd.qtd_status));
- ehci_free_sqh(sc, epipe->sqh);
-}
-
-/*
- * Abort a device request.
- * If this routine is called at splusb() it guarantees that the request
- * will be removed from the hardware scheduling and that the callback
- * for it will be called with USBD_CANCELLED status.
- * It's impossible to guarantee that the requested transfer will not
- * have happened since the hardware runs concurrently.
- * If the transaction has already happened we rely on the ordinary
- * interrupt processing to process it.
- */
-void
-ehci_abort_xfer(usbd_xfer_handle xfer, usbd_status status)
-{
-#define exfer EXFER(xfer)
- struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
- ehci_softc_t *sc = (ehci_softc_t *)epipe->pipe.device->bus;
- ehci_soft_qh_t *sqh = epipe->sqh;
- ehci_soft_qtd_t *sqtd, *snext;
- ehci_physaddr_t cur, us, next;
- int s;
- int hit, i;
- /* int count = 0; */
- ehci_soft_qh_t *psqh;
-
- DPRINTF(("ehci_abort_xfer: xfer=%p pipe=%p\n", xfer, epipe));
-
- if (sc->sc_dying) {
- /* If we're dying, just do the software part. */
- s = splusb();
- xfer->status = status; /* make software ignore it */
- callout_stop(&xfer->timeout_handle);
- usb_rem_task(epipe->pipe.device, &exfer->abort_task);
- usb_transfer_complete(xfer);
- splx(s);
- return;
- }
-
- if (xfer->device->bus->intr_context)
- panic("ehci_abort_xfer: not in process context");
-
- /*
- * If an abort is already in progress then just wait for it to
- * complete and return.
- */
- if (exfer->ehci_xfer_flags & EHCI_XFER_ABORTING) {
- DPRINTFN(2, ("ehci_abort_xfer: already aborting\n"));
- /* No need to wait if we're aborting from a timeout. */
- if (status == USBD_TIMEOUT)
- return;
- /* Override the status which might be USBD_TIMEOUT. */
- xfer->status = status;
- DPRINTFN(2, ("ehci_abort_xfer: waiting for abort to finish\n"));
- exfer->ehci_xfer_flags |= EHCI_XFER_ABORTWAIT;
- while (exfer->ehci_xfer_flags & EHCI_XFER_ABORTING)
- tsleep(&exfer->ehci_xfer_flags, PZERO, "ehciaw", 0);
- return;
- }
-
- /*
- * Step 1: Make interrupt routine and timeouts ignore xfer.
- */
- s = splusb();
- exfer->ehci_xfer_flags |= EHCI_XFER_ABORTING;
- xfer->status = status; /* make software ignore it */
- callout_stop(&xfer->timeout_handle);
- usb_rem_task(epipe->pipe.device, &exfer->abort_task);
- splx(s);
-
- /*
- * Step 2: Wait until we know hardware has finished any possible
- * use of the xfer. We do this by removing the entire
- * queue from the async schedule and waiting for the doorbell.
- * Nothing else should be touching the queue now.
- */
- psqh = sqh->prev;
- ehci_rem_qh(sc, sqh, psqh);
-
- /*
- * Step 3: make sure the soft interrupt routine
- * has run. This should remove any completed items off the queue.
- * The hardware has no reference to completed items (TDs).
- * It's safe to remove them at any time.
- */
- s = splusb();
-#ifdef USB_USE_SOFTINTR
- sc->sc_softwake = 1;
-#endif /* USB_USE_SOFTINTR */
- usb_schedsoftintr(&sc->sc_bus);
-#ifdef USB_USE_SOFTINTR
- tsleep(&sc->sc_softwake, PZERO, "ehciab", 0);
-#endif /* USB_USE_SOFTINTR */
-
- /*
- * Step 4: Remove any vestiges of the xfer from the hardware.
- * The complication here is that the hardware may have executed
- * into or even beyond the xfer we're trying to abort.
- * So as we're scanning the TDs of this xfer we check if
- * the hardware points to any of them.
- *
- * first we need to see if there are any transfers
- * on this queue before the xfer we are aborting.. we need
- * to update any pointers that point to us to point past
- * the aborting xfer. (If there is something past us).
- * Hardware and software.
- */
- cur = EHCI_LINK_ADDR(hc32toh(sc, sqh->qh.qh_curqtd));
- hit = 0;
-
- /* If they initially point here. */
- us = exfer->sqtdstart->physaddr;
-
- /* We will change them to point here */
- snext = exfer->sqtdend->nextqtd;
- next = (snext != NULL) ? htohc32(sc, snext->physaddr) : EHCI_NULL(sc);
-
- /*
- * Now loop through any qTDs before us and keep track of the pointer
- * that points to us for the end.
- */
- sqtd = sqh->sqtd;
- while (sqtd && sqtd != exfer->sqtdstart) {
- hit |= (cur == sqtd->physaddr);
- if (EHCI_LINK_ADDR(hc32toh(sc, sqtd->qtd.qtd_next)) == us)
- sqtd->qtd.qtd_next = next;
- if (EHCI_LINK_ADDR(hc32toh(sc, sqtd->qtd.qtd_altnext)) == us)
- sqtd->qtd.qtd_altnext = next;
- sqtd = sqtd->nextqtd;
- }
-
- /*
- * If we already saw the active one then we are pretty much done.
- * We've done all the relinking we need to do.
- */
- if (!hit) {
-
- /*
- * Now reinitialise the QH to point to the next qTD
- * (if there is one). We only need to do this if
- * it was previously pointing to us.
- */
- for (sqtd = exfer->sqtdstart; ; sqtd = sqtd->nextqtd) {
- if (cur == sqtd->physaddr) {
- hit++;
- }
- if (sqtd == exfer->sqtdend)
- break;
- }
- sqtd = sqtd->nextqtd;
- /*
- * Only need to alter the QH if it was pointing at a qTD
- * that we are removing.
- */
- if (hit) {
- sqh->qh.qh_qtd.qtd_next = htohc32(sc, snext->physaddr);
- sqh->qh.qh_qtd.qtd_altnext = EHCI_NULL(sc);
- sqh->qh.qh_qtd.qtd_status &=
- htohc32(sc, EHCI_QTD_TOGGLE_MASK);
- for (i = 0; i < EHCI_QTD_NBUFFERS; i++) {
- sqh->qh.qh_qtd.qtd_buffer[i] = 0;
- sqh->qh.qh_qtd.qtd_buffer_hi[i] = 0;
- }
- }
- }
- ehci_add_qh(sc, sqh, psqh);
- /*
- * Step 5: Execute callback.
- */
-#ifdef DIAGNOSTIC
- exfer->isdone = 1;
-#endif
- /* Do the wakeup first to avoid touching the xfer after the callback. */
- exfer->ehci_xfer_flags &= ~EHCI_XFER_ABORTING;
- if (exfer->ehci_xfer_flags & EHCI_XFER_ABORTWAIT) {
- exfer->ehci_xfer_flags &= ~EHCI_XFER_ABORTWAIT;
- wakeup(&exfer->ehci_xfer_flags);
- }
- usb_transfer_complete(xfer);
-
- /* printf("%s: %d TDs aborted\n", __func__, count); */
- splx(s);
-#undef exfer
-}
-
-void
-ehci_timeout(void *addr)
-{
- struct ehci_xfer *exfer = addr;
- struct ehci_pipe *epipe = (struct ehci_pipe *)exfer->xfer.pipe;
- ehci_softc_t *sc = (ehci_softc_t *)epipe->pipe.device->bus;
-
- DPRINTF(("ehci_timeout: exfer=%p\n", exfer));
-#ifdef USB_DEBUG
- if (ehcidebug > 1)
- usbd_dump_pipe(exfer->xfer.pipe);
-#endif
-
- if (sc->sc_dying) {
- ehci_abort_xfer(&exfer->xfer, USBD_TIMEOUT);
- return;
- }
-
- /* Execute the abort in a process context. */
- usb_add_task(exfer->xfer.pipe->device, &exfer->abort_task,
- USB_TASKQ_HC);
-}
-
-void
-ehci_abort_isoc_xfer(usbd_xfer_handle xfer, usbd_status status)
-{
- ehci_isoc_trans_t trans_status;
- struct ehci_pipe *epipe;
- struct ehci_xfer *exfer;
- ehci_softc_t *sc;
- struct ehci_soft_itd *itd;
- int s, i;
-
- epipe = (struct ehci_pipe *) xfer->pipe;
- exfer = EXFER(xfer);
- sc = (ehci_softc_t *)epipe->pipe.device->bus;
-
- DPRINTF(("ehci_abort_isoc_xfer: xfer %p pipe %p\n", xfer, epipe));
-
- if (sc->sc_dying) {
- s = splusb();
- xfer->status = status;
- callout_stop(&xfer->timeout_handle);
- usb_rem_task(epipe->pipe.device, &exfer->abort_task);
- usb_transfer_complete(xfer);
- splx(s);
- return;
- }
-
- if (exfer->ehci_xfer_flags & EHCI_XFER_ABORTING) {
- DPRINTFN(2, ("ehci_abort_isoc_xfer: already aborting\n"));
-
-#ifdef DIAGNOSTIC
- if (status == USBD_TIMEOUT)
- printf("ehci_abort_xfer: TIMEOUT while aborting\n");
-#endif
-
- xfer->status = status;
- DPRINTFN(2, ("ehci_abort_xfer: waiting for abort to finish\n"));
- exfer->ehci_xfer_flags |= EHCI_XFER_ABORTWAIT;
- while (exfer->ehci_xfer_flags & EHCI_XFER_ABORTING)
- tsleep(&exfer->ehci_xfer_flags, PZERO, "ehciaw", 0);
- return;
- }
- exfer->ehci_xfer_flags |= EHCI_XFER_ABORTING;
-
- xfer->status = status;
- callout_stop(&xfer->timeout_handle);
- usb_rem_task(epipe->pipe.device, &exfer->abort_task);
-
- s = splusb();
- for (itd = exfer->itdstart; itd != NULL; itd = itd->xfer_next) {
-
- for (i = 0; i < 8; i++) {
- trans_status = hc32toh(sc, itd->itd.itd_ctl[i]);
- trans_status &= ~EHCI_ITD_ACTIVE;
- itd->itd.itd_ctl[i] = htohc32(sc, trans_status);
- }
-
- }
- splx(s);
-
- s = splusb();
-#ifdef USB_USE_SOFTINTR
- sc->sc_softwake = 1;
-#endif /* USB_USE_SOFTINTR */
- usb_schedsoftintr(&sc->sc_bus);
-#ifdef USB_USE_SOFTINTR
- tsleep(&sc->sc_softwake, PZERO, "ehciab", 0);
-#endif /* USB_USE_SOFTINTR */
- splx(s);
-
-#ifdef DIAGNOSTIC
- exfer->isdone = 1;
-#endif
- exfer->ehci_xfer_flags &= ~EHCI_XFER_ABORTING;
- if (exfer->ehci_xfer_flags & EHCI_XFER_ABORTWAIT) {
- exfer->ehci_xfer_flags &= ~EHCI_XFER_ABORTWAIT;
- wakeup(&exfer->ehci_xfer_flags);
- }
- usb_transfer_complete(xfer);
-}
-
-void
-ehci_timeout_task(void *addr)
-{
- usbd_xfer_handle xfer = addr;
- int s;
-
- DPRINTF(("ehci_timeout_task: xfer=%p\n", xfer));
-
- s = splusb();
- ehci_abort_xfer(xfer, USBD_TIMEOUT);
- splx(s);
-}
-
-/*
- * Some EHCI chips from VIA / ATI seem to trigger interrupts before writing
- * back the qTD status, or miss signalling occasionally under heavy load.
- * If the host machine is too fast, we can miss transaction completion - when
- * we scan the active list the transaction still seems to be active. This
- * generally exhibits itself as a umass stall that never recovers.
- *
- * We work around this behaviour by setting up this callback after any softintr
- * that completes with transactions still pending, giving us another chance to
- * check for completion after the writeback has taken place.
- */
-void
-ehci_intrlist_timeout(void *arg)
-{
- ehci_softc_t *sc = arg;
- int s = splusb();
-
- DPRINTFN(3, ("ehci_intrlist_timeout\n"));
- usb_schedsoftintr(&sc->sc_bus);
-
- splx(s);
-}
-
-/************************/
-
-static usbd_status
-ehci_device_ctrl_transfer(usbd_xfer_handle xfer)
-{
- usbd_status err;
-
- /* Insert last in queue. */
- err = usb_insert_transfer(xfer);
- if (err)
- return (err);
-
- /* Pipe isn't running, start first */
- return (ehci_device_ctrl_start(STAILQ_FIRST(&xfer->pipe->queue)));
-}
-
-static usbd_status
-ehci_device_ctrl_start(usbd_xfer_handle xfer)
-{
- ehci_softc_t *sc = (ehci_softc_t *)xfer->pipe->device->bus;
- usbd_status err;
-
- if (sc->sc_dying)
- return (USBD_IOERROR);
-
-#ifdef DIAGNOSTIC
- if (!(xfer->rqflags & URQ_REQUEST)) {
- /* XXX panic */
- printf("ehci_device_ctrl_transfer: not a request\n");
- return (USBD_INVAL);
- }
-#endif
-
- err = ehci_device_request(xfer);
- if (err)
- return (err);
-
- if (sc->sc_bus.use_polling)
- ehci_waitintr(sc, xfer);
- return (USBD_IN_PROGRESS);
-}
-
-void
-ehci_device_ctrl_done(usbd_xfer_handle xfer)
-{
- struct ehci_xfer *ex = EXFER(xfer);
- ehci_softc_t *sc = (ehci_softc_t *)xfer->pipe->device->bus;
- struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
-
- DPRINTFN(10,("ehci_ctrl_done: xfer=%p\n", xfer));
-
-#ifdef DIAGNOSTIC
- if (!(xfer->rqflags & URQ_REQUEST)) {
- panic("ehci_ctrl_done: not a request");
- }
-#endif
-
- if (xfer->status != USBD_NOMEM && ehci_active_intr_list(ex)) {
- ehci_del_intr_list(ex); /* remove from active list */
- ehci_free_sqtd_chain(sc, epipe->sqh, ex->sqtdstart,
- ex->sqtdend->nextqtd);
- }
-
- DPRINTFN(5, ("ehci_ctrl_done: length=%d\n", xfer->actlen));
-}
-
-/* Abort a device control request. */
-static void
-ehci_device_ctrl_abort(usbd_xfer_handle xfer)
-{
- DPRINTF(("ehci_device_ctrl_abort: xfer=%p\n", xfer));
- ehci_abort_xfer(xfer, USBD_CANCELLED);
-}
-
-/* Close a device control pipe. */
-static void
-ehci_device_ctrl_close(usbd_pipe_handle pipe)
-{
- ehci_softc_t *sc = (ehci_softc_t *)pipe->device->bus;
- /*struct ehci_pipe *epipe = (struct ehci_pipe *)pipe;*/
-
- DPRINTF(("ehci_device_ctrl_close: pipe=%p\n", pipe));
- ehci_close_pipe(pipe, sc->sc_async_head);
-}
-
-usbd_status
-ehci_device_request(usbd_xfer_handle xfer)
-{
-#define exfer EXFER(xfer)
- struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
- usb_device_request_t *req = &xfer->request;
- usbd_device_handle dev = epipe->pipe.device;
- ehci_softc_t *sc = (ehci_softc_t *)dev->bus;
- ehci_soft_qtd_t *newinactive, *setup, *stat, *next;
- ehci_soft_qh_t *sqh;
- int isread;
- int len;
- usbd_status err;
- int s;
-
- isread = req->bmRequestType & UT_READ;
- len = UGETW(req->wLength);
-
- DPRINTFN(3,("ehci_device_request: type=0x%02x, request=0x%02x, "
- "wValue=0x%04x, wIndex=0x%04x len=%d, addr=%d, endpt=%d\n",
- req->bmRequestType, req->bRequest, UGETW(req->wValue),
- UGETW(req->wIndex), len, dev->address,
- epipe->pipe.endpoint->edesc->bEndpointAddress));
-
- newinactive = ehci_alloc_sqtd(sc);
- if (newinactive == NULL) {
- err = USBD_NOMEM;
- goto bad1;
- }
- newinactive->qtd.qtd_status = htohc32(sc, 0);
- newinactive->qtd.qtd_next = EHCI_NULL(sc);
- newinactive->qtd.qtd_altnext = EHCI_NULL(sc);
-
- stat = ehci_alloc_sqtd(sc);
- if (stat == NULL) {
- err = USBD_NOMEM;
- goto bad2;
- }
-
- sqh = epipe->sqh;
- setup = sqh->inactivesqtd;
- sqh->inactivesqtd = newinactive;
- epipe->u.ctl.length = len;
-
- /* Set up data transaction */
- if (len != 0) {
- ehci_soft_qtd_t *end;
-
- err = ehci_alloc_sqtd_chain(epipe, sc, len, isread, xfer,
- NULL, newinactive, &next, &end);
- if (err)
- goto bad3;
- end->qtd.qtd_status &= htohc32(sc, ~EHCI_QTD_IOC);
- end->nextqtd = stat;
- end->qtd.qtd_next = htohc32(sc, stat->physaddr);
- end->qtd.qtd_altnext = htohc32(sc, newinactive->physaddr);
- } else {
- next = stat;
- }
-
- memcpy(KERNADDR(&epipe->u.ctl.reqdma, 0), req, sizeof *req);
-
- /* Clear toggle, and do not activate until complete */
- setup->qtd.qtd_status = htohc32(sc,
- EHCI_QTD_SET_PID(EHCI_QTD_PID_SETUP) |
- EHCI_QTD_SET_CERR(3) |
- EHCI_QTD_SET_TOGGLE(0) |
- EHCI_QTD_SET_BYTES(sizeof *req)
- );
- setup->qtd.qtd_buffer[0] = htohc32(sc, DMAADDR(&epipe->u.ctl.reqdma, 0));
- setup->qtd.qtd_buffer_hi[0] = 0;
- setup->nextqtd = next;
- setup->qtd.qtd_next = htohc32(sc, next->physaddr);
- setup->qtd.qtd_altnext = htohc32(sc, newinactive->physaddr);
- setup->xfer = xfer;
- setup->len = sizeof *req;
-
- stat->qtd.qtd_status = htohc32(sc,
- EHCI_QTD_ACTIVE |
- EHCI_QTD_SET_PID(isread ? EHCI_QTD_PID_OUT : EHCI_QTD_PID_IN) |
- EHCI_QTD_SET_CERR(3) |
- EHCI_QTD_SET_TOGGLE(1) |
- EHCI_QTD_IOC
- );
- stat->qtd.qtd_buffer[0] = 0; /* XXX not needed? */
- stat->qtd.qtd_buffer_hi[0] = 0; /* XXX not needed? */
- stat->nextqtd = newinactive;
- stat->qtd.qtd_next = htohc32(sc, newinactive->physaddr);
- stat->qtd.qtd_altnext = htohc32(sc, newinactive->physaddr);
- stat->xfer = xfer;
- stat->len = 0;
-
-#ifdef EHCI_DEBUG
- if (ehcidebug > 5) {
- DPRINTF(("ehci_device_request:\n"));
- ehci_dump_sqh(sc, sqh);
- ehci_dump_sqtds(sc, setup);
- }
-#endif
-
- exfer->sqtdstart = setup;
- exfer->sqtdend = stat;
-#ifdef DIAGNOSTIC
- if (!exfer->isdone) {
- printf("ehci_device_request: not done, exfer=%p\n", exfer);
- }
- exfer->isdone = 0;
-#endif
-
- /* Activate the new qTD in the QH list. */
- s = splusb();
- ehci_activate_qh(sc, sqh, setup);
- if (xfer->timeout && !sc->sc_bus.use_polling) {
- callout_reset(&xfer->timeout_handle, MS_TO_TICKS(xfer->timeout),
- ehci_timeout, xfer);
- }
- ehci_add_intr_list(sc, exfer);
- xfer->status = USBD_IN_PROGRESS;
- splx(s);
-
-#ifdef EHCI_DEBUG
- if (ehcidebug > 10) {
- DPRINTF(("ehci_device_request: status=%x\n",
- EOREAD4(sc, EHCI_USBSTS)));
- delay(10000);
- ehci_dump_regs(sc);
- ehci_dump_sqh(sc, sc->sc_async_head);
- ehci_dump_sqh(sc, sqh);
- ehci_dump_sqtds(sc, setup);
- }
-#endif
-
- return (USBD_NORMAL_COMPLETION);
-
- bad3:
- sqh->inactivesqtd = setup;
- ehci_free_sqtd(sc, stat);
- bad2:
- ehci_free_sqtd(sc, newinactive);
- bad1:
- DPRINTFN(-1,("ehci_device_request: no memory\n"));
- xfer->status = err;
- usb_transfer_complete(xfer);
- return (err);
-#undef exfer
-}
-
-/************************/
-
-static usbd_status
-ehci_device_bulk_transfer(usbd_xfer_handle xfer)
-{
- usbd_status err;
-
- /* Insert last in queue. */
- err = usb_insert_transfer(xfer);
- if (err)
- return (err);
-
- /* Pipe isn't running, start first */
- return (ehci_device_bulk_start(STAILQ_FIRST(&xfer->pipe->queue)));
-}
-
-usbd_status
-ehci_device_bulk_start(usbd_xfer_handle xfer)
-{
-#define exfer EXFER(xfer)
- struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
- usbd_device_handle dev = epipe->pipe.device;
- ehci_softc_t *sc = (ehci_softc_t *)dev->bus;
- ehci_soft_qtd_t *data, *dataend, *newinactive;
- ehci_soft_qh_t *sqh;
- usbd_status err;
- int len, isread, endpt;
- int s;
-
- DPRINTFN(2, ("ehci_device_bulk_start: xfer=%p len=%d flags=%d\n",
- xfer, xfer->length, xfer->flags));
-
- if (sc->sc_dying)
- return (USBD_IOERROR);
-
-#ifdef DIAGNOSTIC
- if (xfer->rqflags & URQ_REQUEST)
- panic("ehci_device_bulk_start: a request");
-#endif
-
- len = xfer->length;
- endpt = epipe->pipe.endpoint->edesc->bEndpointAddress;
- isread = UE_GET_DIR(endpt) == UE_DIR_IN;
- sqh = epipe->sqh;
-
- epipe->u.bulk.length = len;
-
- newinactive = ehci_alloc_sqtd(sc);
- if (newinactive == NULL) {
- DPRINTFN(-1,("ehci_device_bulk_start: no sqtd memory\n"));
- err = USBD_NOMEM;
- xfer->status = err;
- usb_transfer_complete(xfer);
- return (err);
- }
- newinactive->qtd.qtd_status = htohc32(sc, 0);
- newinactive->qtd.qtd_next = EHCI_NULL(sc);
- newinactive->qtd.qtd_altnext = EHCI_NULL(sc);
- err = ehci_alloc_sqtd_chain(epipe, sc, len, isread, xfer,
- sqh->inactivesqtd, newinactive, &data, &dataend);
- if (err) {
- DPRINTFN(-1,("ehci_device_bulk_start: no memory\n"));
- ehci_free_sqtd(sc, newinactive);
- xfer->status = err;
- usb_transfer_complete(xfer);
- return (err);
- }
- dataend->nextqtd = newinactive;
- dataend->qtd.qtd_next = htohc32(sc, newinactive->physaddr);
- dataend->qtd.qtd_altnext = htohc32(sc, newinactive->physaddr);
- sqh->inactivesqtd = newinactive;
-
-#ifdef EHCI_DEBUG
- if (ehcidebug > 5) {
- DPRINTF(("ehci_device_bulk_start: data(1)\n"));
- ehci_dump_sqh(sc, sqh);
- ehci_dump_sqtds(sc, data);
- }
-#endif
-
- /* Set up interrupt info. */
- exfer->sqtdstart = data;
- exfer->sqtdend = dataend;
-#ifdef DIAGNOSTIC
- if (!exfer->isdone) {
- printf("ehci_device_bulk_start: not done, ex=%p\n", exfer);
- }
- exfer->isdone = 0;
-#endif
-
- s = splusb();
- ehci_activate_qh(sc, sqh, data);
- if (xfer->timeout && !sc->sc_bus.use_polling) {
- callout_reset(&xfer->timeout_handle, MS_TO_TICKS(xfer->timeout),
- ehci_timeout, xfer);
- }
- ehci_add_intr_list(sc, exfer);
- xfer->status = USBD_IN_PROGRESS;
- splx(s);
-
-#ifdef EHCI_DEBUG
- if (ehcidebug > 10) {
- DPRINTF(("ehci_device_bulk_start: data(2)\n"));
- delay(10000);
- DPRINTF(("ehci_device_bulk_start: data(3)\n"));
- ehci_dump_regs(sc);
-#if 0
- printf("async_head:\n");
- ehci_dump_sqh(sc->sc_async_head);
-#endif
- printf("sqh:\n");
- ehci_dump_sqh(sc, sqh);
- ehci_dump_sqtds(sc, data);
- }
-#endif
-
- if (sc->sc_bus.use_polling)
- ehci_waitintr(sc, xfer);
-
- return (USBD_IN_PROGRESS);
-#undef exfer
-}
-
-static void
-ehci_device_bulk_abort(usbd_xfer_handle xfer)
-{
- DPRINTF(("ehci_device_bulk_abort: xfer=%p\n", xfer));
- ehci_abort_xfer(xfer, USBD_CANCELLED);
-}
-
-/*
- * Close a device bulk pipe.
- */
-static void
-ehci_device_bulk_close(usbd_pipe_handle pipe)
-{
- ehci_softc_t *sc = (ehci_softc_t *)pipe->device->bus;
-
- DPRINTF(("ehci_device_bulk_close: pipe=%p\n", pipe));
- ehci_close_pipe(pipe, sc->sc_async_head);
-}
-
-void
-ehci_device_bulk_done(usbd_xfer_handle xfer)
-{
- struct ehci_xfer *ex = EXFER(xfer);
- ehci_softc_t *sc = (ehci_softc_t *)xfer->pipe->device->bus;
- struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
-
- DPRINTFN(10,("ehci_bulk_done: xfer=%p, actlen=%d\n",
- xfer, xfer->actlen));
-
- if (xfer->status != USBD_NOMEM && ehci_active_intr_list(ex)) {
- ehci_del_intr_list(ex); /* remove from active list */
- ehci_free_sqtd_chain(sc, epipe->sqh, ex->sqtdstart,
- ex->sqtdend->nextqtd);
- }
-
- DPRINTFN(5, ("ehci_bulk_done: length=%d\n", xfer->actlen));
-}
-
-/************************/
-
-static usbd_status
-ehci_device_setintr(ehci_softc_t *sc, ehci_soft_qh_t *sqh, int ival)
-{
- struct ehci_soft_islot *isp;
- int islot, lev;
-
- /* Find a poll rate that is large enough. */
- for (lev = EHCI_IPOLLRATES - 1; lev > 0; lev--)
- if (EHCI_ILEV_IVAL(lev) <= ival)
- break;
-
- /* Pick an interrupt slot at the right level. */
- /* XXX could do better than picking at random. */
- islot = EHCI_IQHIDX(lev, arc4random());
-
- sqh->islot = islot;
- isp = &sc->sc_islots[islot];
- ehci_add_qh(sc, sqh, isp->sqh);
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-static usbd_status
-ehci_device_intr_transfer(usbd_xfer_handle xfer)
-{
- usbd_status err;
-
- /* Insert last in queue. */
- err = usb_insert_transfer(xfer);
- if (err)
- return (err);
-
- /*
- * Pipe isn't running (otherwise err would be USBD_INPROG),
- * so start it first.
- */
- return (ehci_device_intr_start(STAILQ_FIRST(&xfer->pipe->queue)));
-}
-
-static usbd_status
-ehci_device_intr_start(usbd_xfer_handle xfer)
-{
-#define exfer EXFER(xfer)
- struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
- usbd_device_handle dev = xfer->pipe->device;
- ehci_softc_t *sc = (ehci_softc_t *)dev->bus;
- ehci_soft_qtd_t *data, *dataend, *newinactive;
- ehci_soft_qh_t *sqh;
- usbd_status err;
- int len, isread, endpt;
- int s;
-
- DPRINTFN(2, ("ehci_device_intr_start: xfer=%p len=%d flags=%d\n",
- xfer, xfer->length, xfer->flags));
-
- if (sc->sc_dying)
- return (USBD_IOERROR);
-
-#ifdef DIAGNOSTIC
- if (xfer->rqflags & URQ_REQUEST)
- panic("ehci_device_intr_start: a request");
-#endif
-
- len = xfer->length;
- endpt = epipe->pipe.endpoint->edesc->bEndpointAddress;
- isread = UE_GET_DIR(endpt) == UE_DIR_IN;
- sqh = epipe->sqh;
-
- epipe->u.intr.length = len;
-
- newinactive = ehci_alloc_sqtd(sc);
- if (newinactive == NULL) {
- DPRINTFN(-1,("ehci_device_intr_start: no sqtd memory\n"));
- err = USBD_NOMEM;
- xfer->status = err;
- usb_transfer_complete(xfer);
- return (err);
- }
- newinactive->qtd.qtd_status = htohc32(sc, 0);
- newinactive->qtd.qtd_next = EHCI_NULL(sc);
- newinactive->qtd.qtd_altnext = EHCI_NULL(sc);
- err = ehci_alloc_sqtd_chain(epipe, sc, len, isread, xfer,
- sqh->inactivesqtd, newinactive, &data, &dataend);
- if (err) {
- DPRINTFN(-1, ("ehci_device_intr_start: no memory\n"));
- xfer->status = err;
- usb_transfer_complete(xfer);
- return (err);
- }
- dataend->nextqtd = newinactive;
- dataend->qtd.qtd_next = htohc32(sc, newinactive->physaddr);
- dataend->qtd.qtd_altnext = htohc32(sc, newinactive->physaddr);
- sqh->inactivesqtd = newinactive;
-
-#ifdef EHCI_DEBUG
- if (ehcidebug > 5) {
- DPRINTF(("ehci_device_intr_start: data(1)\n"));
- ehci_dump_sqh(sc, sqh);
- ehci_dump_sqtds(sc, data);
- }
-#endif
-
- /* Set up interrupt info. */
- exfer->sqtdstart = data;
- exfer->sqtdend = dataend;
-#ifdef DIAGNOSTIC
- if (!exfer->isdone) {
- printf("ehci_device_intr_start: not done, ex=%p\n", exfer);
- }
- exfer->isdone = 0;
-#endif
-
- s = splusb();
- ehci_activate_qh(sc, sqh, data);
- if (xfer->timeout && !sc->sc_bus.use_polling) {
- callout_reset(&xfer->timeout_handle, MS_TO_TICKS(xfer->timeout),
- ehci_timeout, xfer);
- }
- ehci_add_intr_list(sc, exfer);
- xfer->status = USBD_IN_PROGRESS;
- splx(s);
-
-#ifdef EHCI_DEBUG
- if (ehcidebug > 10) {
- DPRINTF(("ehci_device_intr_start: data(2)\n"));
- delay(10000);
- DPRINTF(("ehci_device_intr_start: data(3)\n"));
- ehci_dump_regs(sc);
- printf("sqh:\n");
- ehci_dump_sqh(sc, sqh);
- ehci_dump_sqtds(sc, data);
- }
-#endif
-
- if (sc->sc_bus.use_polling)
- ehci_waitintr(sc, xfer);
-
- return (USBD_IN_PROGRESS);
-#undef exfer
-}
-
-static void
-ehci_device_intr_abort(usbd_xfer_handle xfer)
-{
- DPRINTFN(1, ("ehci_device_intr_abort: xfer=%p\n", xfer));
- if (xfer->pipe->intrxfer == xfer) {
- DPRINTFN(1, ("ehci_device_intr_abort: remove\n"));
- xfer->pipe->intrxfer = NULL;
- }
- /*
- * XXX - abort_xfer uses ehci_sync_hc, which syncs via the advance
- * async doorbell. That's dependant on the async list, wheras
- * intr xfers are periodic, should not use this?
- */
- ehci_abort_xfer(xfer, USBD_CANCELLED);
-}
-
-static void
-ehci_device_intr_close(usbd_pipe_handle pipe)
-{
- ehci_softc_t *sc = (ehci_softc_t *)pipe->device->bus;
- struct ehci_pipe *epipe = (struct ehci_pipe *)pipe;
- struct ehci_soft_islot *isp;
-
- isp = &sc->sc_islots[epipe->sqh->islot];
- ehci_close_pipe(pipe, isp->sqh);
-}
-
-static void
-ehci_device_intr_done(usbd_xfer_handle xfer)
-{
-#define exfer EXFER(xfer)
- struct ehci_xfer *ex = EXFER(xfer);
- ehci_softc_t *sc = (ehci_softc_t *)xfer->pipe->device->bus;
- struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
- ehci_soft_qtd_t *data, *dataend, *newinactive;
- ehci_soft_qh_t *sqh;
- usbd_status err;
- int len, isread, endpt, s;
-
- DPRINTFN(10, ("ehci_device_intr_done: xfer=%p, actlen=%d\n",
- xfer, xfer->actlen));
-
- sqh = epipe->sqh;
- if (xfer->pipe->repeat) {
- ehci_free_sqtd_chain(sc, sqh, ex->sqtdstart,
- ex->sqtdend->nextqtd);
-
- len = epipe->u.intr.length;
- xfer->length = len;
- endpt = epipe->pipe.endpoint->edesc->bEndpointAddress;
- isread = UE_GET_DIR(endpt) == UE_DIR_IN;
-
- newinactive = ehci_alloc_sqtd(sc);
- if (newinactive == NULL) {
- DPRINTFN(-1,
- ("ehci_device_intr_done: no sqtd memory\n"));
- err = USBD_NOMEM;
- xfer->status = err;
- return;
- }
- newinactive->qtd.qtd_status = htohc32(sc, 0);
- newinactive->qtd.qtd_next = EHCI_NULL(sc);
- newinactive->qtd.qtd_altnext = EHCI_NULL(sc);
- err = ehci_alloc_sqtd_chain(epipe, sc, len, isread, xfer,
- sqh->inactivesqtd, newinactive, &data, &dataend);
- if (err) {
- DPRINTFN(-1, ("ehci_device_intr_done: no memory\n"));
- xfer->status = err;
- return;
- }
- dataend->nextqtd = newinactive;
- dataend->qtd.qtd_next = htohc32(sc, newinactive->physaddr);
- dataend->qtd.qtd_altnext = htohc32(sc, newinactive->physaddr);
- sqh->inactivesqtd = newinactive;
-
- /* Set up interrupt info. */
- exfer->sqtdstart = data;
- exfer->sqtdend = dataend;
-#ifdef DIAGNOSTIC
- if (!exfer->isdone) {
- printf("ehci_device_intr_done: not done, ex=%p\n",
- exfer);
- }
- exfer->isdone = 0;
-#endif
-
- s = splusb();
- ehci_activate_qh(sc, sqh, data);
- if (xfer->timeout && !sc->sc_bus.use_polling) {
- callout_reset(&xfer->timeout_handle,
- MS_TO_TICKS(xfer->timeout), ehci_timeout, xfer);
- }
- splx(s);
-
- xfer->status = USBD_IN_PROGRESS;
- } else if (xfer->status != USBD_NOMEM && ehci_active_intr_list(ex)) {
- ehci_del_intr_list(ex); /* remove from active list */
- ehci_free_sqtd_chain(sc, sqh, ex->sqtdstart,
- ex->sqtdend->nextqtd);
- }
-#undef exfer
-}
-
-/************************/
-
-static usbd_status
-ehci_device_isoc_transfer(usbd_xfer_handle xfer)
-{
- usbd_status err;
-
- err = usb_insert_transfer(xfer);
- if (err && err != USBD_IN_PROGRESS)
- return (err);
-
- return (ehci_device_isoc_start(xfer));
-}
-
-static usbd_status
-ehci_device_isoc_start(usbd_xfer_handle xfer)
-{
- struct ehci_pipe *epipe;
- usbd_device_handle dev;
- ehci_softc_t *sc;
- struct ehci_xfer *exfer;
- ehci_soft_itd_t *itd, *prev, *start, *stop;
- usb_dma_t *dma_buf;
- int i, j, k, frames, uframes, ufrperframe;
- int s, trans_count, offs, total_length;
- int frindex;
-
- start = NULL;
- prev = NULL;
- itd = NULL;
- trans_count = 0;
- total_length = 0;
- exfer = (struct ehci_xfer *) xfer;
- sc = (ehci_softc_t *)xfer->pipe->device->bus;
- dev = xfer->pipe->device;
- epipe = (struct ehci_pipe *)xfer->pipe;
-
- /*
- * To allow continuous transfers, above we start all transfers
- * immediately. However, we're still going to get usbd_start_next call
- * this when another xfer completes. So, check if this is already
- * in progress or not
- */
-
- if (exfer->itdstart != NULL)
- return (USBD_IN_PROGRESS);
-
- DPRINTFN(2, ("ehci_device_isoc_start: xfer %p len %d flags %d\n",
- xfer, xfer->length, xfer->flags));
-
- if (sc->sc_dying)
- return (USBD_IOERROR);
-
- /*
- * To avoid complication, don't allow a request right now that'll span
- * the entire frame table. To within 4 frames, to allow some leeway
- * on either side of where the hc currently is.
- */
- if ((1 << (epipe->pipe.endpoint->edesc->bInterval)) *
- xfer->nframes >= (sc->sc_flsize - 4) * 8) {
- printf("ehci: isoc descriptor requested that spans the entire"
- " frametable, too many frames\n");
- return (USBD_INVAL);
- }
-
-#ifdef DIAGNOSTIC
- if (xfer->rqflags & URQ_REQUEST)
- panic("ehci_device_isoc_start: request\n");
-
- if (!exfer->isdone)
- printf("ehci_device_isoc_start: not done, ex = %p\n", exfer);
- exfer->isdone = 0;
-#endif
-
- /*
- * Step 1: Allocate and initialize itds, how many do we need?
- * One per transfer if interval >= 8 microframes, fewer if we use
- * multiple microframes per frame.
- */
-
- i = epipe->pipe.endpoint->edesc->bInterval;
- if (i > 16 || i == 0) {
- /* Spec page 271 says intervals > 16 are invalid */
- DPRINTF(("ehci_device_isoc_start: bInvertal %d invalid\n", i));
- return (USBD_INVAL);
- }
-
- switch (i) {
- case 1:
- ufrperframe = 8;
- break;
- case 2:
- ufrperframe = 4;
- break;
- case 3:
- ufrperframe = 2;
- break;
- default:
- ufrperframe = 1;
- break;
- }
- frames = (xfer->nframes + (ufrperframe - 1)) / ufrperframe;
- uframes = 8 / ufrperframe;
-
- if (frames == 0) {
- DPRINTF(("ehci_device_isoc_start: frames == 0\n"));
- return (USBD_INVAL);
- }
-
- dma_buf = xfer->buffer;
- offs = 0;
-
- for (i = 0; i < frames; i++) {
- int froffs = offs;
- itd = ehci_alloc_itd(sc);
-
- if (prev != NULL) {
- prev->itd.itd_next =
- htohc32(sc, itd->physaddr | EHCI_LINK_ITD);
- prev->xfer_next = itd;
- } else {
- start = itd;
- }
-
- /*
- * Step 1.5, initialize uframes
- */
- for (j = 0; j < 8; j += uframes) {
- /* Calculate which page in the list this starts in */
- int addr = DMAADDR(dma_buf, froffs);
- addr = EHCI_PAGE_OFFSET(addr);
- addr += (offs - froffs);
- addr = EHCI_PAGE(addr);
- addr /= EHCI_PAGE_SIZE;
-
- /* This gets the initial offset into the first page,
- * looks how far further along the current uframe
- * offset is. Works out how many pages that is.
- */
-
- itd->itd.itd_ctl[j] = htohc32(sc, EHCI_ITD_ACTIVE |
- EHCI_ITD_SET_LEN(xfer->frlengths[trans_count]) |
- EHCI_ITD_SET_PG(addr) |
- EHCI_ITD_SET_OFFS(EHCI_PAGE_OFFSET(DMAADDR(dma_buf,
- offs))));
-
- total_length += xfer->frlengths[trans_count];
- offs += xfer->frlengths[trans_count];
- trans_count++;
-
- if (trans_count >= xfer->nframes) { /*Set IOC*/
- itd->itd.itd_ctl[j] |= htohc32(sc, EHCI_ITD_IOC);
- }
- }
-
- /* Step 1.75, set buffer pointers. To simplify matters, all
- * pointers are filled out for the next 7 hardware pages in
- * the dma block, so no need to worry what pages to cover
- * and what to not.
- */
-
- for (j=0; j < 7; j++) {
- /*
- * Don't try to lookup a page that's past the end
- * of buffer
- */
- int page_offs = EHCI_PAGE(froffs +
- (EHCI_PAGE_SIZE * j));
- if (page_offs >= dma_buf->block->size)
- break;
-
- int page = DMAADDR(dma_buf, page_offs);
- page = EHCI_PAGE(page);
- itd->itd.itd_bufr[j] =
- htohc32(sc, EHCI_ITD_SET_BPTR(page) | EHCI_LINK_ITD);
- }
-
- /*
- * Other special values
- */
-
- k = epipe->pipe.endpoint->edesc->bEndpointAddress;
- itd->itd.itd_bufr[0] |= htohc32(sc,
- EHCI_ITD_SET_EP(UE_GET_ADDR(k)) |
- EHCI_ITD_SET_DADDR(epipe->pipe.device->address));
-
- k = (UE_GET_DIR(epipe->pipe.endpoint->edesc->bEndpointAddress))
- ? 1 : 0;
- j = UE_GET_SIZE(
- UGETW(epipe->pipe.endpoint->edesc->wMaxPacketSize));
- itd->itd.itd_bufr[1] |= htohc32(sc, EHCI_ITD_SET_DIR(k) |
- EHCI_ITD_SET_MAXPKT(UE_GET_SIZE(j)));
-
- /* FIXME: handle invalid trans */
- itd->itd.itd_bufr[2] |=
- htohc32(sc, EHCI_ITD_SET_MULTI(UE_GET_TRANS(j)+1));
- prev = itd;
- } /* End of frame */
-
- stop = itd;
- stop->xfer_next = NULL;
- exfer->isoc_len = total_length;
-
- /*
- * Part 2: Transfer descriptors have now been set up, now they must
- * be scheduled into the period frame list. Erk. Not wanting to
- * complicate matters, transfer is denied if the transfer spans
- * more than the period frame list.
- */
-
- s = splusb();
-
- /* Start inserting frames */
- if (epipe->u.isoc.cur_xfers > 0) {
- frindex = epipe->u.isoc.next_frame;
- } else {
- frindex = EOREAD4(sc, EHCI_FRINDEX);
- frindex = frindex >> 3; /* Erase microframe index */
- frindex += 2;
- }
-
- if (frindex >= sc->sc_flsize)
- frindex &= (sc->sc_flsize - 1);
-
- /* Whats the frame interval? */
- i = (1 << epipe->pipe.endpoint->edesc->bInterval);
- if (i / 8 == 0)
- i = 1;
- else
- i /= 8;
-
- itd = start;
- for (j = 0; j < frames; j++) {
- if (itd == NULL)
- panic("ehci: unexpectedly ran out of isoc itds,"
- "isoc_start\n");
-
- itd->itd.itd_next = sc->sc_flist[frindex];
- if (itd->itd.itd_next == 0)
- /* FIXME: frindex table gets initialized to NULL
- * or EHCI_NULL? */
- itd->itd.itd_next = EHCI_NULL(sc);
-
- sc->sc_flist[frindex] = htohc32(sc, EHCI_LINK_ITD | itd->physaddr);
-
- itd->u.frame_list.next = sc->sc_softitds[frindex];
- sc->sc_softitds[frindex] = itd;
- if (itd->u.frame_list.next != NULL)
- itd->u.frame_list.next->u.frame_list.prev = itd;
- itd->slot = frindex;
- itd->u.frame_list.prev = NULL;
-
- frindex += i;
- if (frindex >= sc->sc_flsize)
- frindex -= sc->sc_flsize;
-
- itd = itd->xfer_next;
- }
-
- epipe->u.isoc.cur_xfers++;
- epipe->u.isoc.next_frame = frindex;
-
- exfer->itdstart = start;
- exfer->itdend = stop;
- exfer->sqtdstart = NULL;
- exfer->sqtdstart = NULL;
-
- ehci_add_intr_list(sc, exfer);
- xfer->status = USBD_IN_PROGRESS;
- xfer->done = 0;
- splx(s);
-
- if (sc->sc_bus.use_polling) {
- printf("Starting ehci isoc xfer with polling. Bad idea?\n");
- ehci_waitintr(sc, xfer);
- }
-
- return (USBD_IN_PROGRESS);
-}
-
-static void
-ehci_device_isoc_abort(usbd_xfer_handle xfer)
-{
- DPRINTFN(1, ("ehci_device_isoc_abort: xfer = %p\n", xfer));
- ehci_abort_isoc_xfer(xfer, USBD_CANCELLED);
-}
-
-static void
-ehci_device_isoc_close(usbd_pipe_handle pipe)
-{
- printf("ehci_device_isoc_close: nothing in the pipe to free?\n");
-}
-
-static void
-ehci_device_isoc_done(usbd_xfer_handle xfer)
-{
- struct ehci_xfer *exfer;
- ehci_softc_t *sc;
- struct ehci_pipe *epipe;
- int s;
-
- exfer = EXFER(xfer);
- sc = (ehci_softc_t *)xfer->pipe->device->bus;
- epipe = (struct ehci_pipe *) xfer->pipe;
-
- s = splusb();
- epipe->u.isoc.cur_xfers--;
- if (xfer->status != USBD_NOMEM && ehci_active_intr_list(exfer)) {
- ehci_del_intr_list(exfer);
- ehci_rem_free_itd_chain(sc, exfer);
- }
- splx(s);
-}
diff --git a/sys/dev/usb/ehci_ddb.c b/sys/dev/usb/ehci_ddb.c
deleted file mode 100644
index 3ebd130..0000000
--- a/sys/dev/usb/ehci_ddb.c
+++ /dev/null
@@ -1,255 +0,0 @@
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include "opt_ddb.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/endian.h>
-#include <sys/bus.h>
-#include <sys/lock.h>
-#include <sys/lockmgr.h>
-
-#include <machine/bus.h>
-#include <machine/endian.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdivar.h>
-
-#include <dev/usb/ehcireg.h>
-#include <dev/usb/ehcivar.h>
-
-#ifdef DDB
-#include <ddb/ddb.h>
-#include <ddb/db_sym.h>
-#else
-#define db_printf printf
-#endif
-
-extern ehci_softc_t *theehci; /* XXX */
-
-void
-ehci_dump_regs(ehci_softc_t *sc)
-{
- int i;
- db_printf("cmd=0x%08x, sts=0x%08x, ien=0x%08x\n",
- EOREAD4(sc, EHCI_USBCMD),
- EOREAD4(sc, EHCI_USBSTS),
- EOREAD4(sc, EHCI_USBINTR));
- db_printf("frindex=0x%08x ctrdsegm=0x%08x periodic=0x%08x async=0x%08x\n",
- EOREAD4(sc, EHCI_FRINDEX),
- EOREAD4(sc, EHCI_CTRLDSSEGMENT),
- EOREAD4(sc, EHCI_PERIODICLISTBASE),
- EOREAD4(sc, EHCI_ASYNCLISTADDR));
- for (i = 1; i <= sc->sc_noport; i++)
- db_printf("port %d status=0x%08x\n", i,
- EOREAD4(sc, EHCI_PORTSC(i)));
-}
-
-static void
-ehci_dump_link(ehci_softc_t *sc, ehci_link_t link, int type)
-{
- link = hc32toh(sc, link);
- db_printf("0x%08x", link);
- if (link & EHCI_LINK_TERMINATE)
- db_printf("<T>");
- else {
- db_printf("<");
- if (type) {
- switch (EHCI_LINK_TYPE(link)) {
- case EHCI_LINK_ITD: db_printf("ITD"); break;
- case EHCI_LINK_QH: db_printf("QH"); break;
- case EHCI_LINK_SITD: db_printf("SITD"); break;
- case EHCI_LINK_FSTN: db_printf("FSTN"); break;
- }
- }
- db_printf(">");
- }
-}
-
-void
-ehci_dump_sqtds(ehci_softc_t *sc, ehci_soft_qtd_t *sqtd)
-{
- int i;
- u_int32_t stop;
-
- stop = 0;
- for (i = 0; sqtd && i < 20 && !stop; sqtd = sqtd->nextqtd, i++) {
- ehci_dump_sqtd(sc, sqtd);
- stop = sqtd->qtd.qtd_next & htohc32(sc, EHCI_LINK_TERMINATE);
- }
- if (sqtd)
- db_printf("dump aborted, too many TDs\n");
-}
-
-void
-ehci_dump_qtd(ehci_softc_t *sc, ehci_qtd_t *qtd)
-{
- u_int32_t s;
-
- db_printf(" next="); ehci_dump_link(sc, qtd->qtd_next, 0);
- db_printf(" altnext="); ehci_dump_link(sc, qtd->qtd_altnext, 0);
- db_printf("\n");
- s = hc32toh(sc, qtd->qtd_status);
- db_printf(" status=0x%08x: toggle=%d bytes=0x%x ioc=%d c_page=0x%x\n",
- s, EHCI_QTD_GET_TOGGLE(s), EHCI_QTD_GET_BYTES(s),
- EHCI_QTD_GET_IOC(s), EHCI_QTD_GET_C_PAGE(s));
- db_printf(" cerr=%d pid=%d stat=%b\n", EHCI_QTD_GET_CERR(s),
- EHCI_QTD_GET_PID(s),
- EHCI_QTD_GET_STATUS(s), EHCI_QTD_STATUS_BITS);
- for (s = 0; s < 5; s++)
- db_printf(" buffer[%d]=0x%08x\n", s, hc32toh(sc, qtd->qtd_buffer[s]));
-}
-
-void
-ehci_dump_sqtd(ehci_softc_t *sc, ehci_soft_qtd_t *sqtd)
-{
- db_printf("QTD(%p) at 0x%08x:\n", sqtd, sqtd->physaddr);
- ehci_dump_qtd(sc, &sqtd->qtd);
-}
-
-void
-ehci_dump_sqh(ehci_softc_t *sc, ehci_soft_qh_t *sqh)
-{
- ehci_qh_t *qh = &sqh->qh;
- u_int32_t endp, endphub;
-
- db_printf("QH(%p) at 0x%08x:\n", sqh, sqh->physaddr);
- db_printf(" sqtd=%p inactivesqtd=%p\n", sqh->sqtd, sqh->inactivesqtd);
- db_printf(" link="); ehci_dump_link(sc, qh->qh_link, 1); db_printf("\n");
- endp = hc32toh(sc, qh->qh_endp);
- db_printf(" endp=0x%08x\n", endp);
- db_printf(" addr=0x%02x inact=%d endpt=%d eps=%d dtc=%d hrecl=%d\n",
- EHCI_QH_GET_ADDR(endp), EHCI_QH_GET_INACT(endp),
- EHCI_QH_GET_ENDPT(endp), EHCI_QH_GET_EPS(endp),
- EHCI_QH_GET_DTC(endp), EHCI_QH_GET_HRECL(endp));
- db_printf(" mpl=0x%x ctl=%d nrl=%d\n",
- EHCI_QH_GET_MPL(endp), EHCI_QH_GET_CTL(endp),
- EHCI_QH_GET_NRL(endp));
- endphub = hc32toh(sc, qh->qh_endphub);
- db_printf(" endphub=0x%08x\n", endphub);
- db_printf(" smask=0x%02x cmask=0x%02x huba=0x%02x port=%d mult=%d\n",
- EHCI_QH_GET_SMASK(endphub), EHCI_QH_GET_CMASK(endphub),
- EHCI_QH_GET_HUBA(endphub), EHCI_QH_GET_PORT(endphub),
- EHCI_QH_GET_MULT(endphub));
- db_printf(" curqtd="); ehci_dump_link(sc, qh->qh_curqtd, 0); db_printf("\n");
- db_printf("Overlay qTD:\n");
- ehci_dump_qtd(sc, &qh->qh_qtd);
-}
-
-void
-ehci_dump_itd(ehci_softc_t *sc, struct ehci_soft_itd *itd)
-{
- ehci_isoc_trans_t t;
- ehci_isoc_bufr_ptr_t b, b2, b3;
- int i;
-
- db_printf("ITD: next phys=%X\n", itd->itd.itd_next);
-
- for (i = 0; i < 8;i++) {
- t = hc32toh(sc, itd->itd.itd_ctl[i]);
- db_printf("ITDctl %d: stat=%X len=%X ioc=%X pg=%X offs=%X\n", i,
- EHCI_ITD_GET_STATUS(t), EHCI_ITD_GET_LEN(t),
- EHCI_ITD_GET_IOC(t), EHCI_ITD_GET_PG(t),
- EHCI_ITD_GET_OFFS(t));
- }
- db_printf("ITDbufr: ");
- for (i = 0; i < 7; i++)
- db_printf("%X,", EHCI_ITD_GET_BPTR(hc32toh(sc, itd->itd.itd_bufr[i])));
-
- b = hc32toh(sc, itd->itd.itd_bufr[0]);
- b2 = hc32toh(sc, itd->itd.itd_bufr[1]);
- b3 = hc32toh(sc, itd->itd.itd_bufr[2]);
- db_printf("\nep=%X daddr=%X dir=%d maxpkt=%X multi=%X\n",
- EHCI_ITD_GET_EP(b), EHCI_ITD_GET_DADDR(b), EHCI_ITD_GET_DIR(b2),
- EHCI_ITD_GET_MAXPKT(b2), EHCI_ITD_GET_MULTI(b3));
-}
-
-void
-ehci_dump_sitd(ehci_softc_t *sc, struct ehci_soft_itd *itd)
-{
- db_printf("SITD %p next=%p prev=%p xfernext=%p physaddr=%X slot=%d\n",
- itd, itd->u.frame_list.next, itd->u.frame_list.prev,
- itd->xfer_next, itd->physaddr, itd->slot);
-}
-
-void
-ehci_dump_exfer(struct ehci_xfer *ex)
-{
-#ifdef DIAGNOSTIC
- db_printf("%p: sqtdstart %p end %p itdstart %p end %p isdone %d\n",
- ex, ex->sqtdstart, ex->sqtdend, ex->itdstart,
- ex->itdend, ex->isdone);
-#else
- db_printf("%p: sqtdstart %p end %p itdstart %p end %p\n",
- ex, ex->sqtdstart, ex->sqtdend, ex->itdstart, ex->itdend);
-#endif
-}
-
-#ifdef DDB
-DB_SHOW_COMMAND(ehci, db_show_ehci)
-{
- if (!have_addr) {
- db_printf("usage: show ehci <addr>\n");
- return;
- }
- ehci_dump_regs((ehci_softc_t *) addr);
-}
-
-DB_SHOW_COMMAND(ehci_sqtds, db_show_ehci_sqtds)
-{
- if (!have_addr) {
- db_printf("usage: show ehci_sqtds <addr>\n");
- return;
- }
- ehci_dump_sqtds(theehci, (ehci_soft_qtd_t *) addr);
-}
-
-DB_SHOW_COMMAND(ehci_qtd, db_show_ehci_qtd)
-{
- if (!have_addr) {
- db_printf("usage: show ehci_qtd <addr>\n");
- return;
- }
- ehci_dump_qtd(theehci, (ehci_qtd_t *) addr);
-}
-
-DB_SHOW_COMMAND(ehci_sqh, db_show_ehci_sqh)
-{
- if (!have_addr) {
- db_printf("usage: show ehci_sqh <addr>\n");
- return;
- }
- ehci_dump_sqh(theehci, (ehci_soft_qh_t *) addr);
-}
-
-DB_SHOW_COMMAND(ehci_itd, db_show_ehci_itd)
-{
- if (!have_addr) {
- db_printf("usage: show ehci_itd <addr>\n");
- return;
- }
- ehci_dump_itd(theehci, (struct ehci_soft_itd *) addr);
-}
-
-DB_SHOW_COMMAND(ehci_sitd, db_show_ehci_sitd)
-{
- if (!have_addr) {
- db_printf("usage: show ehci_sitd <addr>\n");
- return;
- }
- ehci_dump_itd(theehci, (struct ehci_soft_itd *) addr);
-}
-
-DB_SHOW_COMMAND(ehci_xfer, db_show_ehci_xfer)
-{
- if (!have_addr) {
- db_printf("usage: show ehci_xfer <addr>\n");
- return;
- }
- ehci_dump_exfer((struct ehci_xfer *) addr);
-}
-#endif /* DDB */
diff --git a/sys/dev/usb/ehci_ixp4xx.c b/sys/dev/usb/ehci_ixp4xx.c
deleted file mode 100644
index bc800d3..0000000
--- a/sys/dev/usb/ehci_ixp4xx.c
+++ /dev/null
@@ -1,360 +0,0 @@
-/*-
- * Copyright (c) 2008 Sam Leffler. 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
- */
-
-/*
- * IXP435 attachment driver for the USB Enhanced Host Controller.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include "opt_bus.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/bus.h>
-#include <sys/endian.h>
-#include <sys/queue.h>
-#include <sys/lockmgr.h>
-#include <sys/rman.h>
-
-#include <machine/bus.h>
-#include <machine/resource.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdivar.h>
-#include <dev/usb/usb_mem.h>
-
-#include <dev/usb/ehcireg.h>
-#include <dev/usb/ehcivar.h>
-
-#include <arm/xscale/ixp425/ixp425reg.h>
-#include <arm/xscale/ixp425/ixp425var.h>
-
-#define EHCI_VENDORID_IXP4XX 0x42fa05
-#define EHCI_HC_DEVSTR "IXP4XX Integrated USB 2.0 controller"
-
-struct ixp_ehci_softc {
- ehci_softc_t base; /* storage for EHCI code */
- bus_space_tag_t iot;
- bus_space_handle_t ioh;
- struct bus_space tag; /* tag for private bus space ops */
-};
-
-static int ehci_ixp_detach(device_t self);
-
-static uint8_t ehci_bs_r_1(void *, bus_space_handle_t, bus_size_t);
-static void ehci_bs_w_1(void *, bus_space_handle_t, bus_size_t, u_int8_t);
-static uint16_t ehci_bs_r_2(void *, bus_space_handle_t, bus_size_t);
-static void ehci_bs_w_2(void *, bus_space_handle_t, bus_size_t, uint16_t);
-static uint32_t ehci_bs_r_4(void *, bus_space_handle_t, bus_size_t);
-static void ehci_bs_w_4(void *, bus_space_handle_t, bus_size_t, uint32_t);
-
-static int
-ehci_ixp_suspend(device_t self)
-{
- ehci_softc_t *sc;
- int err;
-
- err = bus_generic_suspend(self);
- if (err == 0) {
- sc = device_get_softc(self);
- ehci_power(PWR_SUSPEND, sc);
- }
- return err;
-}
-
-static int
-ehci_ixp_resume(device_t self)
-{
- ehci_softc_t *sc = device_get_softc(self);
-
- ehci_power(PWR_RESUME, sc);
- bus_generic_resume(self);
- return 0;
-}
-
-static int
-ehci_ixp_shutdown(device_t self)
-{
- ehci_softc_t *sc;
- int err;
-
- err = bus_generic_shutdown(self);
- if (err == 0) {
- sc = device_get_softc(self);
- ehci_shutdown(sc);
- }
- return err;
-}
-
-static int
-ehci_ixp_probe(device_t self)
-{
- device_set_desc(self, EHCI_HC_DEVSTR);
- return BUS_PROBE_DEFAULT;
-}
-
-static int
-ehci_ixp_attach(device_t self)
-{
- struct ixp_ehci_softc *isc = device_get_softc(self);
- ehci_softc_t *sc = &isc->base;
- int err, rid;
-
- sc->sc_bus.usbrev = USBREV_2_0;
-
- /* NB: hints fix the memory location and irq */
-
- rid = 0;
- sc->io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY,
- &rid, RF_ACTIVE);
- if (sc->io_res == NULL) {
- device_printf(self, "Could not map memory\n");
- return ENXIO;
- }
-
- /*
- * Craft special resource for bus space ops that handle
- * byte-alignment of non-word addresses. Also, since
- * we're already intercepting bus space ops we handle
- * the register window offset that could otherwise be
- * done with bus_space_subregion.
- */
- isc->iot = rman_get_bustag(sc->io_res);
- isc->tag.bs_cookie = isc->iot;
- /* read single */
- isc->tag.bs_r_1 = ehci_bs_r_1,
- isc->tag.bs_r_2 = ehci_bs_r_2,
- isc->tag.bs_r_4 = ehci_bs_r_4,
- /* write (single) */
- isc->tag.bs_w_1 = ehci_bs_w_1,
- isc->tag.bs_w_2 = ehci_bs_w_2,
- isc->tag.bs_w_4 = ehci_bs_w_4,
-
- sc->iot = &isc->tag;
- sc->ioh = rman_get_bushandle(sc->io_res);
- sc->sc_size = IXP435_USB1_SIZE - 0x100;
-
- rid = 0;
- sc->irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ,
- &rid, RF_ACTIVE);
- if (sc->irq_res == NULL) {
- device_printf(self, "Could not allocate irq\n");
- ehci_ixp_detach(self);
- return ENXIO;
- }
- sc->sc_bus.bdev = device_add_child(self, "usb", -1);
- if (!sc->sc_bus.bdev) {
- device_printf(self, "Could not add USB device\n");
- ehci_ixp_detach(self);
- return ENOMEM;
- }
- device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
-
- sprintf(sc->sc_vendor, "Intel");
- sc->sc_id_vendor = EHCI_VENDORID_IXP4XX;
-
- err = bus_setup_intr(self, sc->irq_res, INTR_TYPE_BIO,
- NULL, (driver_intr_t*)ehci_intr, sc, &sc->ih);
- if (err) {
- device_printf(self, "Could not setup irq, %d\n", err);
- sc->ih = NULL;
- ehci_ixp_detach(self);
- return ENXIO;
- }
-
- /* There are no companion USB controllers */
- sc->sc_ncomp = 0;
-
- /* Allocate a parent dma tag for DMA maps */
- err = bus_dma_tag_create(bus_get_dma_tag(self), 1, 0,
- BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
- BUS_SPACE_MAXSIZE_32BIT, USB_DMA_NSEG, BUS_SPACE_MAXSIZE_32BIT, 0,
- NULL, NULL, &sc->sc_bus.parent_dmatag);
- if (err) {
- device_printf(self, "Could not allocate parent DMA tag (%d)\n",
- err);
- ehci_ixp_detach(self);
- return ENXIO;
- }
-
- /* Allocate a dma tag for transfer buffers */
- err = bus_dma_tag_create(sc->sc_bus.parent_dmatag, 1, 0,
- BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
- BUS_SPACE_MAXSIZE_32BIT, USB_DMA_NSEG, BUS_SPACE_MAXSIZE_32BIT, 0,
- busdma_lock_mutex, &Giant, &sc->sc_bus.buffer_dmatag);
- if (err) {
- device_printf(self, "Could not allocate buffer DMA tag (%d)\n",
- err);
- ehci_ixp_detach(self);
- return ENXIO;
- }
-
- /*
- * Arrange to force Host mode, select big-endian byte alignment,
- * and arrange to not terminate reset operations (the adapter
- * will ignore it if we do but might as well save a reg write).
- * Also, the controller has an embedded Transaction Translator
- * which means port speed must be read from the Port Status
- * register following a port enable.
- */
- sc->sc_flags |= EHCI_SCFLG_TT
- | EHCI_SCFLG_SETMODE
- | EHCI_SCFLG_BIGEDESC
- | EHCI_SCFLG_BIGEMMIO
- | EHCI_SCFLG_NORESTERM
- ;
- (void) ehci_reset(sc);
-
- err = ehci_init(sc);
- if (!err) {
- sc->sc_flags |= EHCI_SCFLG_DONEINIT;
- err = device_probe_and_attach(sc->sc_bus.bdev);
- }
-
- if (err) {
- device_printf(self, "USB init failed err=%d\n", err);
- ehci_ixp_detach(self);
- return EIO;
- }
- return 0;
-}
-
-static int
-ehci_ixp_detach(device_t self)
-{
- struct ixp_ehci_softc *isc = device_get_softc(self);
- ehci_softc_t *sc = &isc->base;
- int err;
-
- if (sc->sc_flags & EHCI_SCFLG_DONEINIT) {
- ehci_detach(sc, 0);
- sc->sc_flags &= ~EHCI_SCFLG_DONEINIT;
- }
-
- /*
- * Disable interrupts that might have been switched on in ehci_init()
- */
- if (sc->iot && sc->ioh)
- bus_space_write_4(sc->iot, sc->ioh, EHCI_USBINTR, 0);
- if (sc->sc_bus.parent_dmatag != NULL)
- bus_dma_tag_destroy(sc->sc_bus.parent_dmatag);
- if (sc->sc_bus.buffer_dmatag != NULL)
- bus_dma_tag_destroy(sc->sc_bus.buffer_dmatag);
-
- if (sc->irq_res && sc->ih) {
- err = bus_teardown_intr(self, sc->irq_res, sc->ih);
-
- if (err)
- device_printf(self, "Could not tear down irq, %d\n",
- err);
- sc->ih = NULL;
- }
- if (sc->sc_bus.bdev != NULL) {
- device_delete_child(self, sc->sc_bus.bdev);
- sc->sc_bus.bdev = NULL;
- }
- if (sc->irq_res != NULL) {
- bus_release_resource(self, SYS_RES_IRQ, 0, sc->irq_res);
- sc->irq_res = NULL;
- }
- if (sc->io_res != NULL) {
- bus_release_resource(self, SYS_RES_MEMORY, 0, sc->io_res);
- sc->io_res = NULL;
- }
- sc->iot = 0;
- sc->ioh = 0;
- return 0;
-}
-
-/*
- * Bus space accessors for PIO operations.
- */
-
-static uint8_t
-ehci_bs_r_1(void *t, bus_space_handle_t h, bus_size_t o)
-{
- return bus_space_read_1((bus_space_tag_t) t, h,
- 0x100 + (o &~ 3) + (3 - (o & 3)));
-}
-
-static void
-ehci_bs_w_1(void *t, bus_space_handle_t h, bus_size_t o, u_int8_t v)
-{
- panic("%s", __func__);
-}
-
-static uint16_t
-ehci_bs_r_2(void *t, bus_space_handle_t h, bus_size_t o)
-{
- return bus_space_read_2((bus_space_tag_t) t, h,
- 0x100 + (o &~ 3) + (2 - (o & 3)));
-}
-
-static void
-ehci_bs_w_2(void *t, bus_space_handle_t h, bus_size_t o, uint16_t v)
-{
- panic("%s", __func__);
-}
-
-static uint32_t
-ehci_bs_r_4(void *t, bus_space_handle_t h, bus_size_t o)
-{
- return bus_space_read_4((bus_space_tag_t) t, h, 0x100 + o);
-}
-
-static void
-ehci_bs_w_4(void *t, bus_space_handle_t h, bus_size_t o, uint32_t v)
-{
- bus_space_write_4((bus_space_tag_t) t, h, 0x100 + o, v);
-}
-
-static device_method_t ehci_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, ehci_ixp_probe),
- DEVMETHOD(device_attach, ehci_ixp_attach),
- DEVMETHOD(device_detach, ehci_ixp_detach),
- DEVMETHOD(device_suspend, ehci_ixp_suspend),
- DEVMETHOD(device_resume, ehci_ixp_resume),
- DEVMETHOD(device_shutdown, ehci_ixp_shutdown),
-
- /* Bus interface */
- DEVMETHOD(bus_print_child, bus_generic_print_child),
-
- {0, 0}
-};
-
-static driver_t ehci_driver = {
- "ehci",
- ehci_methods,
- sizeof(struct ixp_ehci_softc),
-};
-static devclass_t ehci_devclass;
-DRIVER_MODULE(ehci, ixp, ehci_driver, ehci_devclass, 0, 0);
diff --git a/sys/dev/usb/ehci_mbus.c b/sys/dev/usb/ehci_mbus.c
deleted file mode 100644
index 792c89d..0000000
--- a/sys/dev/usb/ehci_mbus.c
+++ /dev/null
@@ -1,396 +0,0 @@
-/*-
- * Copyright (C) 2008 MARVELL INTERNATIONAL LTD.
- * All rights reserved.
- *
- * Developed by Semihalf.
- *
- * 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. Neither the name of MARVELL nor the names of contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY AUTHOR 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 AUTHOR 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.
- */
-
-/*
- * MBus attachment driver for the USB Enhanced Host Controller.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include "opt_bus.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/bus.h>
-#include <sys/queue.h>
-#include <sys/lockmgr.h>
-#include <sys/rman.h>
-#include <sys/endian.h>
-
-#include <machine/bus.h>
-#include <machine/resource.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdivar.h>
-#include <dev/usb/usb_mem.h>
-
-#include <dev/usb/ehcireg.h>
-#include <dev/usb/ehcivar.h>
-
-#include <arm/mv/mvreg.h>
-#include <arm/mv/mvvar.h>
-
-#define EHCI_VENDORID_MRVL 0x1286
-#define EHCI_HC_DEVSTR "Marvell Integrated USB 2.0 controller"
-
-static device_attach_t ehci_mbus_attach;
-static device_detach_t ehci_mbus_detach;
-static device_shutdown_t ehci_mbus_shutdown;
-static device_suspend_t ehci_mbus_suspend;
-static device_resume_t ehci_mbus_resume;
-
-static int err_intr(void *arg);
-
-struct resource *irq_err;
-void *ih_err;
-
-#define USB_BRIDGE_INTR_CAUSE 0x210
-#define USB_BRIDGE_INTR_MASK 0x214
-
-#define MV_USB_ADDR_DECODE_ERR (1 << 0)
-#define MV_USB_HOST_UNDERFLOW (1 << 1)
-#define MV_USB_HOST_OVERFLOW (1 << 2)
-#define MV_USB_DEVICE_UNDERFLOW (1 << 3)
-
-static int
-ehci_mbus_suspend(device_t self)
-{
- ehci_softc_t *sc;
- int err;
-
- err = bus_generic_suspend(self);
- if (err)
- return (err);
-
- sc = device_get_softc(self);
- ehci_power(PWR_SUSPEND, sc);
-
- return (0);
-}
-
-static int
-ehci_mbus_resume(device_t self)
-{
- ehci_softc_t *sc;
-
- sc = device_get_softc(self);
-
- ehci_power(PWR_RESUME, sc);
- bus_generic_resume(self);
-
- return (0);
-}
-
-static int
-ehci_mbus_shutdown(device_t self)
-{
- ehci_softc_t *sc;
- int err;
-
- err = bus_generic_shutdown(self);
- if (err)
- return (err);
-
- sc = device_get_softc(self);
- ehci_shutdown(sc);
-
- return (0);
-}
-
-static int
-ehci_mbus_probe(device_t self)
-{
-
- device_set_desc(self, EHCI_HC_DEVSTR);
-
- return (BUS_PROBE_DEFAULT);
-}
-
-static int
-ehci_mbus_attach(device_t self)
-{
- ehci_softc_t *sc;
- bus_space_handle_t bsh;
- int err, rid;
-
- sc = device_get_softc(self);
- sc->sc_bus.usbrev = USBREV_2_0;
-
- rid = 0;
- sc->io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid, RF_ACTIVE);
- if (!sc->io_res) {
- device_printf(self, "Could not map memory\n");
- return (ENXIO);
- }
- sc->iot = rman_get_bustag(sc->io_res);
- bsh = rman_get_bushandle(sc->io_res);
-
- /*
- * Marvell EHCI host controller registers start at certain offset within
- * the whole USB registers range, so create a subregion for the host
- * mode configuration purposes.
- */
- if (bus_space_subregion(sc->iot, bsh, MV_USB_HOST_OFST,
- MV_USB_SIZE - MV_USB_HOST_OFST, &sc->ioh) != 0)
- panic("%s: unable to subregion USB host registers",
- device_get_name(self));
- sc->sc_size = MV_USB_SIZE - MV_USB_HOST_OFST;
-
- rid = 0;
- irq_err = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid,
- RF_SHAREABLE | RF_ACTIVE);
- if (irq_err == NULL) {
- device_printf(self, "Could not allocate error irq\n");
- ehci_mbus_detach(self);
- return (ENXIO);
- }
-
- /*
- * Notice: Marvell EHCI controller has TWO interrupt lines, so make sure to
- * use the correct rid for the main one (controller interrupt) --
- * refer to obio_devices[] for the right resource number to use here.
- */
- rid = 1;
- sc->irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid,
- RF_SHAREABLE | RF_ACTIVE);
- if (sc->irq_res == NULL) {
- device_printf(self, "Could not allocate irq\n");
- ehci_mbus_detach(self);
- return (ENXIO);
- }
- sc->sc_bus.bdev = device_add_child(self, "usb", -1);
- if (!sc->sc_bus.bdev) {
- device_printf(self, "Could not add USB device\n");
- ehci_mbus_detach(self);
- return (ENOMEM);
- }
- device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
-
- sprintf(sc->sc_vendor, "Marvell");
- sc->sc_id_vendor = EHCI_VENDORID_MRVL;
-
- err = bus_setup_intr(self, irq_err, INTR_FAST | INTR_TYPE_BIO,
- err_intr, NULL, sc, &ih_err);
- if (err) {
- device_printf(self, "Could not setup error irq, %d\n", err);
- ih_err = NULL;
- ehci_mbus_detach(self);
- return (ENXIO);
- }
-
- EWRITE4(sc, USB_BRIDGE_INTR_MASK, MV_USB_ADDR_DECODE_ERR |
- MV_USB_HOST_UNDERFLOW | MV_USB_HOST_OVERFLOW |
- MV_USB_DEVICE_UNDERFLOW);
-
- err = bus_setup_intr(self, sc->irq_res, INTR_TYPE_BIO,
- NULL, (driver_intr_t*)ehci_intr, sc, &sc->ih);
- if (err) {
- device_printf(self, "Could not setup irq, %d\n", err);
- sc->ih = NULL;
- ehci_mbus_detach(self);
- return (ENXIO);
- }
-
- /* There are no companion USB controllers */
- sc->sc_ncomp = 0;
-
- /* Allocate a parent dma tag for DMA maps */
- err = bus_dma_tag_create(bus_get_dma_tag(self), 1, 0,
- BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
- BUS_SPACE_MAXSIZE_32BIT, USB_DMA_NSEG, BUS_SPACE_MAXSIZE_32BIT, 0,
- NULL, NULL, &sc->sc_bus.parent_dmatag);
- if (err) {
- device_printf(self, "Could not allocate parent DMA tag (%d)\n",
- err);
- ehci_mbus_detach(self);
- return (ENXIO);
- }
-
- /* Allocate a dma tag for transfer buffers */
- err = bus_dma_tag_create(sc->sc_bus.parent_dmatag, 1, 0,
- BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
- BUS_SPACE_MAXSIZE_32BIT, USB_DMA_NSEG, BUS_SPACE_MAXSIZE_32BIT, 0,
- busdma_lock_mutex, &Giant, &sc->sc_bus.buffer_dmatag);
- if (err) {
- device_printf(self, "Could not allocate buffer DMA tag (%d)\n",
- err);
- ehci_mbus_detach(self);
- return (ENXIO);
- }
-
- /*
- * Workaround for Marvell integrated EHCI controller: reset of
- * the EHCI core clears the USBMODE register, which sets the core in
- * an undefined state (neither host nor agent), so it needs to be set
- * again for proper operation.
- *
- * Refer to errata document MV-S500832-00D.pdf (p. 5.24 GL USB-2) for
- * details.
- */
- sc->sc_flags |= EHCI_SCFLG_SETMODE;
- if (bootverbose)
- device_printf(self, "5.24 GL USB-2 workaround enabled\n");
-
- /* XXX all MV chips need it? */
- sc->sc_flags |= EHCI_SCFLG_FORCESPEED | EHCI_SCFLG_NORESTERM;
-
- err = ehci_init(sc);
- if (!err) {
- sc->sc_flags |= EHCI_SCFLG_DONEINIT;
- err = device_probe_and_attach(sc->sc_bus.bdev);
- }
-
- if (err) {
- device_printf(self, "USB init failed err=%d\n", err);
- ehci_mbus_detach(self);
- return (EIO);
- }
- return (0);
-}
-
-static int
-ehci_mbus_detach(device_t self)
-{
- ehci_softc_t *sc;
- int err;
-
- sc = device_get_softc(self);
- if (sc->sc_flags & EHCI_SCFLG_DONEINIT) {
- ehci_detach(sc, 0);
- sc->sc_flags &= ~EHCI_SCFLG_DONEINIT;
- }
-
- /*
- * Disable interrupts that might have been switched on in ehci_init()
- */
- if (sc->iot && sc->ioh)
- bus_space_write_4(sc->iot, sc->ioh, EHCI_USBINTR, 0);
- if (sc->sc_bus.parent_dmatag != NULL)
- bus_dma_tag_destroy(sc->sc_bus.parent_dmatag);
- if (sc->sc_bus.buffer_dmatag != NULL)
- bus_dma_tag_destroy(sc->sc_bus.buffer_dmatag);
-
- if (sc->irq_res && sc->ih) {
- err = bus_teardown_intr(self, sc->irq_res, sc->ih);
-
- if (err)
- device_printf(self, "Could not tear down irq, %d\n",
- err);
- sc->ih = NULL;
- }
- EWRITE4(sc, USB_BRIDGE_INTR_MASK, 0);
-
- if (irq_err && ih_err) {
- err = bus_teardown_intr(self, irq_err, ih_err);
-
- if (err)
- device_printf(self, "Could not tear down irq, %d\n",
- err);
- ih_err = NULL;
- }
-
- if (sc->sc_bus.bdev) {
- device_delete_child(self, sc->sc_bus.bdev);
- sc->sc_bus.bdev = NULL;
- }
- if (sc->irq_res) {
- bus_release_resource(self, SYS_RES_IRQ, 0, sc->irq_res);
- sc->irq_res = NULL;
- }
- if (irq_err) {
- bus_release_resource(self, SYS_RES_IRQ, 1, irq_err);
- irq_err = NULL;
- }
- if (sc->io_res) {
- bus_release_resource(self, SYS_RES_MEMORY, 0, sc->io_res);
- sc->io_res = NULL;
- sc->iot = 0;
- sc->ioh = 0;
- }
- return (0);
-}
-
-static int
-err_intr(void *arg)
-{
- ehci_softc_t *sc = arg;
- unsigned int cause;
-
- cause = EREAD4(sc, USB_BRIDGE_INTR_CAUSE);
- if (cause) {
- printf("IRQ ERR: cause: 0x%08x\n", cause);
- if (cause & MV_USB_ADDR_DECODE_ERR)
- printf("IRQ ERR: Address decoding error\n");
- if (cause & MV_USB_HOST_UNDERFLOW)
- printf("IRQ ERR: USB Host Underflow\n");
- if (cause & MV_USB_HOST_OVERFLOW)
- printf("IRQ ERR: USB Host Overflow\n");
- if (cause & MV_USB_DEVICE_UNDERFLOW)
- printf("IRQ ERR: USB Device Underflow\n");
- if (cause & ~(MV_USB_ADDR_DECODE_ERR | MV_USB_HOST_UNDERFLOW |
- MV_USB_HOST_OVERFLOW | MV_USB_DEVICE_UNDERFLOW))
- printf("IRQ ERR: Unknown error\n");
-
- EWRITE4(sc, USB_BRIDGE_INTR_CAUSE, 0);
- }
- return (FILTER_HANDLED);
-}
-
-static device_method_t ehci_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, ehci_mbus_probe),
- DEVMETHOD(device_attach, ehci_mbus_attach),
- DEVMETHOD(device_detach, ehci_mbus_detach),
- DEVMETHOD(device_suspend, ehci_mbus_suspend),
- DEVMETHOD(device_resume, ehci_mbus_resume),
- DEVMETHOD(device_shutdown, ehci_mbus_shutdown),
-
- /* Bus interface */
- DEVMETHOD(bus_print_child, bus_generic_print_child),
-
- {0, 0}
-};
-
-static driver_t ehci_driver = {
- "ehci",
- ehci_methods,
- sizeof(ehci_softc_t),
-};
-
-static devclass_t ehci_devclass;
-
-DRIVER_MODULE(ehci, mbus, ehci_driver, ehci_devclass, 0, 0);
diff --git a/sys/dev/usb/ehci_pci.c b/sys/dev/usb/ehci_pci.c
deleted file mode 100644
index 819bc25..0000000
--- a/sys/dev/usb/ehci_pci.c
+++ /dev/null
@@ -1,636 +0,0 @@
-/*-
- * 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * USB Enhanced Host Controller Driver, a.k.a. USB 2.0 controller.
- *
- * The EHCI 1.0 spec can be found at
- * http://developer.intel.com/technology/usb/download/ehci-r10.pdf
- * and the USB 2.0 spec at
- * http://www.usb.org/developers/docs/usb_20.zip
- */
-
-/* The low level controller code for EHCI has been split into
- * PCI probes and EHCI specific code. This was done to facilitate the
- * sharing of code between *BSD's
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/bus.h>
-#include <sys/queue.h>
-#include <sys/lockmgr.h>
-#include <sys/rman.h>
-#include <sys/endian.h>
-
-#include <machine/bus.h>
-#include <machine/resource.h>
-
-#include <dev/pci/pcivar.h>
-#include <dev/pci/pcireg.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdivar.h>
-#include <dev/usb/usb_mem.h>
-
-#include <dev/usb/ehcireg.h>
-#include <dev/usb/ehcivar.h>
-
-#define PCI_EHCI_VENDORID_ACERLABS 0x10b9
-#define PCI_EHCI_VENDORID_AMD 0x1022
-#define PCI_EHCI_VENDORID_APPLE 0x106b
-#define PCI_EHCI_VENDORID_ATI 0x1002
-#define PCI_EHCI_VENDORID_CMDTECH 0x1095
-#define PCI_EHCI_VENDORID_INTEL 0x8086
-#define PCI_EHCI_VENDORID_NEC 0x1033
-#define PCI_EHCI_VENDORID_OPTI 0x1045
-#define PCI_EHCI_VENDORID_PHILIPS 0x1131
-#define PCI_EHCI_VENDORID_SIS 0x1039
-#define PCI_EHCI_VENDORID_NVIDIA 0x12D2
-#define PCI_EHCI_VENDORID_NVIDIA2 0x10DE
-#define PCI_EHCI_VENDORID_VIA 0x1106
-
-/* AcerLabs/ALi */
-#define PCI_EHCI_DEVICEID_M5239 0x523910b9
-static const char *ehci_device_m5239 = "ALi M5239 USB 2.0 controller";
-
-/* AMD */
-#define PCI_EHCI_DEVICEID_8111 0x10227463
-static const char *ehci_device_8111 = "AMD 8111 USB 2.0 controller";
-#define PCI_EHCI_DEVICEID_CS5536 0x20951022
-static const char *ehci_device_cs5536 = "AMD CS5536 (Geode) USB 2.0 controller";
-
-/* ATI */
-#define PCI_EHCI_DEVICEID_SB200 0x43451002
-static const char *ehci_device_sb200 = "ATI SB200 USB 2.0 controller";
-#define PCI_EHCI_DEVICEID_SB400 0x43731002
-static const char *ehci_device_sb400 = "ATI SB400 USB 2.0 controller";
-
-/* Intel */
-#define PCI_EHCI_DEVICEID_6300 0x25ad8086
-static const char *ehci_device_6300 = "Intel 6300ESB USB 2.0 controller";
-#define PCI_EHCI_DEVICEID_ICH4 0x24cd8086
-static const char *ehci_device_ich4 = "Intel 82801DB/L/M (ICH4) USB 2.0 controller";
-#define PCI_EHCI_DEVICEID_ICH5 0x24dd8086
-static const char *ehci_device_ich5 = "Intel 82801EB/R (ICH5) USB 2.0 controller";
-#define PCI_EHCI_DEVICEID_ICH6 0x265c8086
-static const char *ehci_device_ich6 = "Intel 82801FB (ICH6) USB 2.0 controller";
-#define PCI_EHCI_DEVICEID_ICH7 0x27cc8086
-static const char *ehci_device_ich7 = "Intel 82801GB/R (ICH7) USB 2.0 controller";
-#define PCI_EHCI_DEVICEID_ICH8_A 0x28368086
-static const char *ehci_device_ich8_a = "Intel 82801H (ICH8) USB 2.0 controller USB2-A";
-#define PCI_EHCI_DEVICEID_ICH8_B 0x283a8086
-static const char *ehci_device_ich8_b = "Intel 82801H (ICH8) USB 2.0 controller USB2-B";
-#define PCI_EHCI_DEVICEID_ICH9_A 0x293a8086
-#define PCI_EHCI_DEVICEID_ICH9_B 0x293c8086
-static const char *ehci_device_ich9 = "Intel 82801I (ICH9) USB 2.0 controller";
-#define PCI_EHCI_DEVICEID_63XX 0x268c8086
-static const char *ehci_device_63XX = "Intel 63XXESB USB 2.0 controller";
-
-/* NEC */
-#define PCI_EHCI_DEVICEID_NEC 0x00e01033
-static const char *ehci_device_nec = "NEC uPD 720100 USB 2.0 controller";
-
-/* NVIDIA */
-#define PCI_EHCI_DEVICEID_NF2 0x006810de
-static const char *ehci_device_nf2 = "NVIDIA nForce2 USB 2.0 controller";
-#define PCI_EHCI_DEVICEID_NF2_400 0x008810de
-static const char *ehci_device_nf2_400 = "NVIDIA nForce2 Ultra 400 USB 2.0 controller";
-#define PCI_EHCI_DEVICEID_NF3 0x00d810de
-static const char *ehci_device_nf3 = "NVIDIA nForce3 USB 2.0 controller";
-#define PCI_EHCI_DEVICEID_NF3_250 0x00e810de
-static const char *ehci_device_nf3_250 = "NVIDIA nForce3 250 USB 2.0 controller";
-#define PCI_EHCI_DEVICEID_NF4 0x005b10de
-static const char *ehci_device_nf4 = "NVIDIA nForce4 USB 2.0 controller";
-
-/* Philips */
-#define PCI_EHCI_DEVICEID_ISP156X 0x15621131
-static const char *ehci_device_isp156x = "Philips ISP156x USB 2.0 controller";
-
-#define PCI_EHCI_DEVICEID_VIA 0x31041106
-static const char *ehci_device_via = "VIA VT6202 USB 2.0 controller";
-
-static const char *ehci_device_generic = "EHCI (generic) USB 2.0 controller";
-
-#define PCI_EHCI_BASE_REG 0x10
-
-#ifdef USB_DEBUG
-#define EHCI_DEBUG USB_DEBUG
-#define DPRINTF(x) do { if (ehcidebug) printf x; } while (0)
-extern int ehcidebug;
-#else
-#define DPRINTF(x)
-#endif
-
-static device_attach_t ehci_pci_attach;
-static device_detach_t ehci_pci_detach;
-static device_shutdown_t ehci_pci_shutdown;
-static device_suspend_t ehci_pci_suspend;
-static device_resume_t ehci_pci_resume;
-static void ehci_pci_givecontroller(device_t self);
-static void ehci_pci_takecontroller(device_t self);
-
-static int
-ehci_pci_suspend(device_t self)
-{
- ehci_softc_t *sc = device_get_softc(self);
- int err;
-
- err = bus_generic_suspend(self);
- if (err)
- return (err);
- ehci_power(PWR_SUSPEND, sc);
-
- return 0;
-}
-
-static int
-ehci_pci_resume(device_t self)
-{
- ehci_softc_t *sc = device_get_softc(self);
-
- ehci_pci_takecontroller(self);
- ehci_power(PWR_RESUME, sc);
- bus_generic_resume(self);
-
- return 0;
-}
-
-static int
-ehci_pci_shutdown(device_t self)
-{
- ehci_softc_t *sc = device_get_softc(self);
- int err;
-
- err = bus_generic_shutdown(self);
- if (err)
- return (err);
- ehci_shutdown(sc);
- ehci_pci_givecontroller(self);
-
- return 0;
-}
-
-static const char *
-ehci_pci_match(device_t self)
-{
- u_int32_t device_id = pci_get_devid(self);
-
- switch (device_id) {
- case PCI_EHCI_DEVICEID_M5239:
- return (ehci_device_m5239);
- case PCI_EHCI_DEVICEID_8111:
- return (ehci_device_8111);
- case PCI_EHCI_DEVICEID_CS5536:
- return (ehci_device_cs5536);
- case PCI_EHCI_DEVICEID_SB200:
- return (ehci_device_sb200);
- case PCI_EHCI_DEVICEID_SB400:
- return (ehci_device_sb400);
- case PCI_EHCI_DEVICEID_6300:
- return (ehci_device_6300);
- case PCI_EHCI_DEVICEID_63XX:
- return (ehci_device_63XX);
- case PCI_EHCI_DEVICEID_ICH4:
- return (ehci_device_ich4);
- case PCI_EHCI_DEVICEID_ICH5:
- return (ehci_device_ich5);
- case PCI_EHCI_DEVICEID_ICH6:
- return (ehci_device_ich6);
- case PCI_EHCI_DEVICEID_ICH7:
- return (ehci_device_ich7);
- case PCI_EHCI_DEVICEID_ICH8_A:
- return (ehci_device_ich8_a);
- case PCI_EHCI_DEVICEID_ICH8_B:
- return (ehci_device_ich8_b);
- case PCI_EHCI_DEVICEID_ICH9_A:
- case PCI_EHCI_DEVICEID_ICH9_B:
- return (ehci_device_ich9);
- case PCI_EHCI_DEVICEID_NEC:
- return (ehci_device_nec);
- case PCI_EHCI_DEVICEID_NF2:
- return (ehci_device_nf2);
- case PCI_EHCI_DEVICEID_NF2_400:
- return (ehci_device_nf2_400);
- case PCI_EHCI_DEVICEID_NF3:
- return (ehci_device_nf3);
- case PCI_EHCI_DEVICEID_NF3_250:
- return (ehci_device_nf3_250);
- case PCI_EHCI_DEVICEID_NF4:
- return (ehci_device_nf4);
- case PCI_EHCI_DEVICEID_ISP156X:
- return (ehci_device_isp156x);
- case PCI_EHCI_DEVICEID_VIA:
- return (ehci_device_via);
- default:
- if (pci_get_class(self) == PCIC_SERIALBUS
- && pci_get_subclass(self) == PCIS_SERIALBUS_USB
- && pci_get_progif(self) == PCI_INTERFACE_EHCI) {
- return (ehci_device_generic);
- }
- }
-
- return NULL; /* dunno */
-}
-
-static int
-ehci_pci_probe(device_t self)
-{
- const char *desc = ehci_pci_match(self);
-
- if (desc) {
- device_set_desc(self, desc);
- return BUS_PROBE_DEFAULT;
- } else {
- return ENXIO;
- }
-}
-
-static int
-ehci_pci_attach(device_t self)
-{
- ehci_softc_t *sc = device_get_softc(self);
- devclass_t dc;
- device_t parent;
- device_t *neighbors;
- device_t *nbus;
- struct usbd_bus *bsc;
- int err;
- int rid;
- int ncomp;
- int count, buscount;
- int slot, function;
- int res;
- int i;
-
- switch(pci_read_config(self, PCI_USBREV, 1) & PCI_USBREV_MASK) {
- case PCI_USBREV_PRE_1_0:
- case PCI_USBREV_1_0:
- case PCI_USBREV_1_1:
- device_printf(self, "pre-2.0 USB rev\n");
- if (pci_get_devid(self) == PCI_EHCI_DEVICEID_CS5536) {
- sc->sc_bus.usbrev = USBREV_2_0;
- device_printf(self, "Quirk for CS5536 USB 2.0 enabled\n");
- break;
- }
-
- /*
- * Quirk for Parallels Desktop 4.0.
- */
- if (pci_get_devid(self) == PCI_EHCI_DEVICEID_ICH6) {
- sc->sc_bus.usbrev = USBREV_2_0;
- break;
- }
- sc->sc_bus.usbrev = USBREV_UNKNOWN;
- return ENXIO;
- case PCI_USBREV_2_0:
- sc->sc_bus.usbrev = USBREV_2_0;
- break;
- default:
- sc->sc_bus.usbrev = USBREV_UNKNOWN;
- break;
- }
-
- pci_enable_busmaster(self);
-
- rid = PCI_CBMEM;
- sc->io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid,
- RF_ACTIVE);
- if (!sc->io_res) {
- device_printf(self, "Could not map memory\n");
- return ENXIO;
- }
- sc->iot = rman_get_bustag(sc->io_res);
- sc->ioh = rman_get_bushandle(sc->io_res);
-
- rid = 0;
- sc->irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid,
- RF_SHAREABLE | RF_ACTIVE);
- if (sc->irq_res == NULL) {
- device_printf(self, "Could not allocate irq\n");
- ehci_pci_detach(self);
- return ENXIO;
- }
- sc->sc_bus.bdev = device_add_child(self, "usb", -1);
- if (!sc->sc_bus.bdev) {
- device_printf(self, "Could not add USB device\n");
- ehci_pci_detach(self);
- return ENOMEM;
- }
- device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
-
- /* ehci_pci_match will never return NULL if ehci_pci_probe succeeded */
- device_set_desc(sc->sc_bus.bdev, ehci_pci_match(self));
- switch (pci_get_vendor(self)) {
- case PCI_EHCI_VENDORID_ACERLABS:
- sprintf(sc->sc_vendor, "AcerLabs");
- break;
- case PCI_EHCI_VENDORID_AMD:
- sprintf(sc->sc_vendor, "AMD");
- break;
- case PCI_EHCI_VENDORID_APPLE:
- sprintf(sc->sc_vendor, "Apple");
- break;
- case PCI_EHCI_VENDORID_ATI:
- sprintf(sc->sc_vendor, "ATI");
- break;
- case PCI_EHCI_VENDORID_CMDTECH:
- sprintf(sc->sc_vendor, "CMDTECH");
- break;
- case PCI_EHCI_VENDORID_INTEL:
- sprintf(sc->sc_vendor, "Intel");
- break;
- case PCI_EHCI_VENDORID_NEC:
- sprintf(sc->sc_vendor, "NEC");
- break;
- case PCI_EHCI_VENDORID_OPTI:
- sprintf(sc->sc_vendor, "OPTi");
- break;
- case PCI_EHCI_VENDORID_SIS:
- sprintf(sc->sc_vendor, "SiS");
- break;
- case PCI_EHCI_VENDORID_NVIDIA:
- case PCI_EHCI_VENDORID_NVIDIA2:
- sprintf(sc->sc_vendor, "nVidia");
- break;
- case PCI_EHCI_VENDORID_VIA:
- sprintf(sc->sc_vendor, "VIA");
- break;
- default:
- if (bootverbose)
- device_printf(self, "(New EHCI DeviceId=0x%08x)\n",
- pci_get_devid(self));
- sprintf(sc->sc_vendor, "(0x%04x)", pci_get_vendor(self));
- }
-
- err = bus_setup_intr(self, sc->irq_res, INTR_TYPE_BIO,
- NULL, (driver_intr_t *)ehci_intr, sc, &sc->ih);
- if (err) {
- device_printf(self, "Could not setup irq, %d\n", err);
- sc->ih = NULL;
- ehci_pci_detach(self);
- return ENXIO;
- }
-
- /* Enable workaround for dropped interrupts as required */
- switch (pci_get_vendor(self)) {
- case PCI_EHCI_VENDORID_ATI:
- case PCI_EHCI_VENDORID_VIA:
- sc->sc_flags |= EHCI_SCFLG_LOSTINTRBUG;
- if (bootverbose)
- device_printf(self,
- "Dropped interrupts workaround enabled\n");
- break;
- default:
- break;
- }
-
- /*
- * Find companion controllers. According to the spec they always
- * have lower function numbers so they should be enumerated already.
- */
- parent = device_get_parent(self);
- res = device_get_children(parent, &neighbors, &count);
- if (res != 0) {
- device_printf(self, "Error finding companion busses\n");
- ehci_pci_detach(self);
- return ENXIO;
- }
- ncomp = 0;
- dc = devclass_find("usb");
- slot = pci_get_slot(self);
- function = pci_get_function(self);
- for (i = 0; i < count; i++) {
- if (pci_get_slot(neighbors[i]) == slot && \
- pci_get_function(neighbors[i]) < function) {
- res = device_get_children(neighbors[i],
- &nbus, &buscount);
- if (res != 0)
- continue;
- if (buscount != 1) {
- free(nbus, M_TEMP);
- continue;
- }
- if (device_get_devclass(nbus[0]) != dc) {
- free(nbus, M_TEMP);
- continue;
- }
- bsc = device_get_softc(nbus[0]);
- free(nbus, M_TEMP);
- DPRINTF(("ehci_pci_attach: companion %s\n",
- device_get_nameunit(bsc->bdev)));
- sc->sc_comps[ncomp++] = bsc;
- if (ncomp >= EHCI_COMPANION_MAX)
- break;
- }
- }
- sc->sc_ncomp = ncomp;
-
- /* Allocate a parent dma tag for DMA maps */
- err = bus_dma_tag_create(bus_get_dma_tag(self), 1, 0,
- BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
- BUS_SPACE_MAXSIZE_32BIT, USB_DMA_NSEG, BUS_SPACE_MAXSIZE_32BIT, 0,
- NULL, NULL, &sc->sc_bus.parent_dmatag);
- if (err) {
- device_printf(self, "Could not allocate parent DMA tag (%d)\n",
- err);
- ehci_pci_detach(self);
- return ENXIO;
- }
-
- /* Allocate a dma tag for transfer buffers */
- err = bus_dma_tag_create(sc->sc_bus.parent_dmatag, 1, 0,
- BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
- BUS_SPACE_MAXSIZE_32BIT, USB_DMA_NSEG, BUS_SPACE_MAXSIZE_32BIT, 0,
- busdma_lock_mutex, &Giant, &sc->sc_bus.buffer_dmatag);
- if (err) {
- device_printf(self, "Could not allocate buffer DMA tag (%d)\n",
- err);
- ehci_pci_detach(self);
- return ENXIO;
- }
-
- ehci_pci_takecontroller(self);
- err = ehci_init(sc);
- if (!err) {
- sc->sc_flags |= EHCI_SCFLG_DONEINIT;
- err = device_probe_and_attach(sc->sc_bus.bdev);
- }
-
- if (err) {
- device_printf(self, "USB init failed err=%d\n", err);
- ehci_pci_detach(self);
- return EIO;
- }
- return 0;
-}
-
-static int
-ehci_pci_detach(device_t self)
-{
- ehci_softc_t *sc = device_get_softc(self);
-
- if (sc->sc_flags & EHCI_SCFLG_DONEINIT) {
- ehci_detach(sc, 0);
- sc->sc_flags &= ~EHCI_SCFLG_DONEINIT;
- }
-
- /*
- * disable interrupts that might have been switched on in ehci_init
- */
- if (sc->iot && sc->ioh)
- bus_space_write_4(sc->iot, sc->ioh, EHCI_USBINTR, 0);
- if (sc->sc_bus.parent_dmatag != NULL)
- bus_dma_tag_destroy(sc->sc_bus.parent_dmatag);
- if (sc->sc_bus.buffer_dmatag != NULL)
- bus_dma_tag_destroy(sc->sc_bus.buffer_dmatag);
-
- if (sc->irq_res && sc->ih) {
- int err = bus_teardown_intr(self, sc->irq_res, sc->ih);
-
- if (err)
- /* XXX or should we panic? */
- device_printf(self, "Could not tear down irq, %d\n",
- err);
- sc->ih = NULL;
- }
- if (sc->sc_bus.bdev) {
- device_delete_child(self, sc->sc_bus.bdev);
- sc->sc_bus.bdev = NULL;
- }
- if (sc->irq_res) {
- bus_release_resource(self, SYS_RES_IRQ, 0, sc->irq_res);
- sc->irq_res = NULL;
- }
- if (sc->io_res) {
- bus_release_resource(self, SYS_RES_MEMORY, PCI_CBMEM, sc->io_res);
- sc->io_res = NULL;
- sc->iot = 0;
- sc->ioh = 0;
- }
- return 0;
-}
-
-static void
-ehci_pci_takecontroller(device_t self)
-{
- ehci_softc_t *sc = device_get_softc(self);
- u_int32_t cparams, eec;
- uint8_t bios_sem;
- int eecp, i;
-
- cparams = EREAD4(sc, EHCI_HCCPARAMS);
-
- /* Synchronise with the BIOS if it owns the controller. */
- for (eecp = EHCI_HCC_EECP(cparams); eecp != 0;
- eecp = EHCI_EECP_NEXT(eec)) {
- eec = pci_read_config(self, eecp, 4);
- if (EHCI_EECP_ID(eec) != EHCI_EC_LEGSUP)
- continue;
- bios_sem = pci_read_config(self, eecp + EHCI_LEGSUP_BIOS_SEM,
- 1);
- if (bios_sem) {
- pci_write_config(self, eecp + EHCI_LEGSUP_OS_SEM, 1, 1);
- printf("%s: waiting for BIOS to give up control\n",
- device_get_nameunit(sc->sc_bus.bdev));
- for (i = 0; i < 5000; i++) {
- bios_sem = pci_read_config(self, eecp +
- EHCI_LEGSUP_BIOS_SEM, 1);
- if (bios_sem == 0)
- break;
- DELAY(1000);
- }
- if (bios_sem)
- printf("%s: timed out waiting for BIOS\n",
- device_get_nameunit(sc->sc_bus.bdev));
- }
- }
-}
-
-static void
-ehci_pci_givecontroller(device_t self)
-{
-#if 0
- ehci_softc_t *sc = device_get_softc(self);
- u_int32_t cparams, eec;
- int eecp;
-
- cparams = EREAD4(sc, EHCI_HCCPARAMS);
- for (eecp = EHCI_HCC_EECP(cparams); eecp != 0;
- eecp = EHCI_EECP_NEXT(eec)) {
- eec = pci_read_config(self, eecp, 4);
- if (EHCI_EECP_ID(eec) != EHCI_EC_LEGSUP)
- continue;
- pci_write_config(self, eecp + EHCI_LEGSUP_OS_SEM, 0, 1);
- }
-#endif
-}
-
-static device_method_t ehci_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, ehci_pci_probe),
- DEVMETHOD(device_attach, ehci_pci_attach),
- DEVMETHOD(device_detach, ehci_pci_detach),
- DEVMETHOD(device_suspend, ehci_pci_suspend),
- DEVMETHOD(device_resume, ehci_pci_resume),
- DEVMETHOD(device_shutdown, ehci_pci_shutdown),
-
- /* Bus interface */
- DEVMETHOD(bus_print_child, bus_generic_print_child),
-
- {0, 0}
-};
-
-static driver_t ehci_driver = {
- "ehci",
- ehci_methods,
- sizeof(ehci_softc_t),
-};
-
-static devclass_t ehci_devclass;
-
-DRIVER_MODULE(ehci, pci, ehci_driver, ehci_devclass, 0, 0);
-DRIVER_MODULE(ehci, cardbus, ehci_driver, ehci_devclass, 0, 0);
-MODULE_DEPEND(ehci, usb, 1, 1, 1);
diff --git a/sys/dev/usb/ehcireg.h b/sys/dev/usb/ehcireg.h
deleted file mode 100644
index 3c0f5e7..0000000
--- a/sys/dev/usb/ehcireg.h
+++ /dev/null
@@ -1,344 +0,0 @@
-/* $NetBSD: ehcireg.h,v 1.18 2004/10/22 10:38:17 augustss Exp $ */
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 2001 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net).
- *
- * 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.
- */
-
-/*
- * The EHCI 0.96 spec can be found at
- * http://developer.intel.com/technology/usb/download/ehci-r096.pdf
- * and the USB 2.0 spec at
- * http://www.usb.org/developers/data/usb_20.zip
- */
-
-#ifndef _DEV_PCI_EHCIREG_H_
-#define _DEV_PCI_EHCIREG_H_
-
-/*** PCI config registers ***/
-
-#define PCI_CBMEM 0x10 /* configuration base MEM */
-
-#define PCI_INTERFACE_EHCI 0x20
-
-#define PCI_USBREV 0x60 /* RO USB protocol revision */
-#define PCI_USBREV_MASK 0xff
-#define PCI_USBREV_PRE_1_0 0x00
-#define PCI_USBREV_1_0 0x10
-#define PCI_USBREV_1_1 0x11
-#define PCI_USBREV_2_0 0x20
-
-#define PCI_EHCI_FLADJ 0x61 /*RW Frame len adj, SOF=59488+6*fladj */
-
-#define PCI_EHCI_PORTWAKECAP 0x62 /* RW Port wake caps (opt) */
-
-/* EHCI Extended Capabilities */
-#define EHCI_EC_LEGSUP 0x01
-
-#define EHCI_EECP_NEXT(x) (((x) >> 8) & 0xff)
-#define EHCI_EECP_ID(x) ((x) & 0xff)
-
-/* Legacy support extended capability */
-#define EHCI_LEGSUP_OS_SEM 0x03 /* OS owned semaphore */
-#define EHCI_LEGSUP_BIOS_SEM 0x02 /* BIOS owned semaphore */
-#define EHCI_LEGSUP_USBLEGCTLSTS 0x04
-
-/*** EHCI capability registers ***/
-
-#define EHCI_CAPLENGTH 0x00 /*RO Capability register length field */
-/* reserved 0x01 */
-#define EHCI_HCIVERSION 0x02 /* RO Interface version number */
-
-#define EHCI_HCSPARAMS 0x04 /* RO Structural parameters */
-#define EHCI_HCS_DEBUGPORT(x) (((x) >> 20) & 0xf)
-#define EHCI_HCS_P_INDICATOR(x) ((x) & 0x10000)
-#define EHCI_HCS_N_CC(x) (((x) >> 12) & 0xf) /* # of companion ctlrs */
-#define EHCI_HCS_N_PCC(x) (((x) >> 8) & 0xf) /* # of ports per comp. */
-#define EHCI_HCS_PPC(x) ((x) & 0x10) /* port power control */
-#define EHCI_HCS_N_PORTS(x) ((x) & 0xf) /* # of ports */
-
-#define EHCI_HCCPARAMS 0x08 /* RO Capability parameters */
-#define EHCI_HCC_EECP(x) (((x) >> 8) & 0xff) /* extended ports caps */
-#define EHCI_HCC_IST(x) (((x) >> 4) & 0xf) /* isoc sched threshold */
-#define EHCI_HCC_ASPC(x) ((x) & 0x4) /* async sched park cap */
-#define EHCI_HCC_PFLF(x) ((x) & 0x2) /* prog frame list flag */
-#define EHCI_HCC_64BIT(x) ((x) & 0x1) /* 64 bit address cap */
-
-#define EHCI_HCSP_PORTROUTE 0x0c /*RO Companion port route description */
-
-/* EHCI operational registers. Offset given by EHCI_CAPLENGTH register */
-#define EHCI_USBCMD 0x00 /* RO, RW, WO Command register */
-#define EHCI_CMD_ITC_M 0x00ff0000 /* RW interrupt threshold ctrl */
-#define EHCI_CMD_ITC_1 0x00010000
-#define EHCI_CMD_ITC_2 0x00020000
-#define EHCI_CMD_ITC_4 0x00040000
-#define EHCI_CMD_ITC_8 0x00080000
-#define EHCI_CMD_ITC_16 0x00100000
-#define EHCI_CMD_ITC_32 0x00200000
-#define EHCI_CMD_ITC_64 0x00400000
-#define EHCI_CMD_ASPME 0x00000800 /* RW/RO async park enable */
-#define EHCI_CMD_ASPMC 0x00000300 /* RW/RO async park count */
-#define EHCI_CMD_LHCR 0x00000080 /* RW light host ctrl reset */
-#define EHCI_CMD_IAAD 0x00000040 /* RW intr on async adv door bell */
-#define EHCI_CMD_ASE 0x00000020 /* RW async sched enable */
-#define EHCI_CMD_PSE 0x00000010 /* RW periodic sched enable */
-#define EHCI_CMD_FLS_M 0x0000000c /* RW/RO frame list size */
-#define EHCI_CMD_FLS(x) (((x) >> 2) & 3) /* RW/RO frame list size */
-#define EHCI_CMD_HCRESET 0x00000002 /* RW reset */
-#define EHCI_CMD_RS 0x00000001 /* RW run/stop */
-
-#define EHCI_USBSTS 0x04 /* RO, RW, RWC Status register */
-#define EHCI_STS_ASS 0x00008000 /* RO async sched status */
-#define EHCI_STS_PSS 0x00004000 /* RO periodic sched status */
-#define EHCI_STS_REC 0x00002000 /* RO reclamation */
-#define EHCI_STS_HCH 0x00001000 /* RO host controller halted */
-#define EHCI_STS_IAA 0x00000020 /* RWC interrupt on async adv */
-#define EHCI_STS_HSE 0x00000010 /* RWC host system error */
-#define EHCI_STS_FLR 0x00000008 /* RWC frame list rollover */
-#define EHCI_STS_PCD 0x00000004 /* RWC port change detect */
-#define EHCI_STS_ERRINT 0x00000002 /* RWC error interrupt */
-#define EHCI_STS_INT 0x00000001 /* RWC interrupt */
-#define EHCI_STS_INTRS(x) ((x) & 0x3f)
-
-#define EHCI_NORMAL_INTRS (EHCI_STS_IAA | EHCI_STS_HSE | EHCI_STS_PCD | EHCI_STS_ERRINT | EHCI_STS_INT)
-
-#define EHCI_USBINTR 0x08 /* RW Interrupt register */
-#define EHCI_INTR_IAAE 0x00000020 /* interrupt on async advance ena */
-#define EHCI_INTR_HSEE 0x00000010 /* host system error ena */
-#define EHCI_INTR_FLRE 0x00000008 /* frame list rollover ena */
-#define EHCI_INTR_PCIE 0x00000004 /* port change ena */
-#define EHCI_INTR_UEIE 0x00000002 /* USB error intr ena */
-#define EHCI_INTR_UIE 0x00000001 /* USB intr ena */
-
-#define EHCI_FRINDEX 0x0c /* RW Frame Index register */
-
-#define EHCI_CTRLDSSEGMENT 0x10 /* RW Control Data Structure Segment */
-
-#define EHCI_PERIODICLISTBASE 0x14 /* RW Periodic List Base */
-#define EHCI_ASYNCLISTADDR 0x18 /* RW Async List Base */
-
-#define EHCI_CONFIGFLAG 0x40 /* RW Configure Flag register */
-#define EHCI_CONF_CF 0x00000001 /* RW configure flag */
-
-#define EHCI_PORTSC(n) (0x40+4*(n)) /* RO, RW, RWC Port Status reg */
-#define EHCI_PS_WKOC_E 0x00400000 /* RW wake on over current ena */
-#define EHCI_PS_WKDSCNNT_E 0x00200000 /* RW wake on disconnect ena */
-#define EHCI_PS_WKCNNT_E 0x00100000 /* RW wake on connect ena */
-#define EHCI_PS_PTC 0x000f0000 /* RW port test control */
-#define EHCI_PS_PIC 0x0000c000 /* RW port indicator control */
-#define EHCI_PS_PO 0x00002000 /* RW port owner */
-#define EHCI_PS_PP 0x00001000 /* RW,RO port power */
-#define EHCI_PS_LS 0x00000c00 /* RO line status */
-#define EHCI_PS_IS_LOWSPEED(x) (((x) & EHCI_PS_LS) == 0x00000400)
-#define EHCI_PS_PR 0x00000100 /* RW port reset */
-#define EHCI_PS_SUSP 0x00000080 /* RW suspend */
-#define EHCI_PS_FPR 0x00000040 /* RW force port resume */
-#define EHCI_PS_OCC 0x00000020 /* RWC over current change */
-#define EHCI_PS_OCA 0x00000010 /* RO over current active */
-#define EHCI_PS_PEC 0x00000008 /* RWC port enable change */
-#define EHCI_PS_PE 0x00000004 /* RW port enable */
-#define EHCI_PS_CSC 0x00000002 /* RWC connect status change */
-#define EHCI_PS_CS 0x00000001 /* RO connect status */
-#define EHCI_PS_CLEAR (EHCI_PS_OCC|EHCI_PS_PEC|EHCI_PS_CSC)
-
-#define EHCI_USBMODE 0x68 /* RW USB Device mode register */
-#define EHCI_UM_CM 0x00000003 /* R/WO Controller Mode */
-#define EHCI_UM_CM_IDLE 0x0 /* Idle */
-#define EHCI_UM_CM_HOST 0x3 /* Host Controller */
-#define EHCI_UM_ES 0x00000004 /* R/WO Endian Select */
-#define EHCI_UM_ES_LE 0x0 /* Little-endian byte alignment */
-#define EHCI_UM_ES_BE 0x4 /* Big-endian byte alignment */
-#define EHCI_UM_SDIS 0x00000010 /* R/WO Stream Disable Mode */
-
-#define EHCI_PORT_RESET_COMPLETE 2 /* ms */
-
-#define EHCI_FLALIGN_ALIGN 0x1000
-
-/* No data structure may cross a page boundary. */
-#define EHCI_PAGE_SIZE 0x1000
-#define EHCI_PAGE(x) ((x) &~ 0xfff)
-#define EHCI_PAGE_OFFSET(x) ((x) & 0xfff)
-#if defined(__FreeBSD__)
-#define EHCI_PAGE_MASK(x) ((x) & 0xfff)
-#endif
-
-typedef u_int32_t ehci_link_t;
-#define EHCI_LINK_TERMINATE 0x00000001
-#define EHCI_LINK_TYPE(x) ((x) & 0x00000006)
-#define EHCI_LINK_ITD 0x0
-#define EHCI_LINK_QH 0x2
-#define EHCI_LINK_SITD 0x4
-#define EHCI_LINK_FSTN 0x6
-#define EHCI_LINK_ADDR(x) ((x) &~ 0x1f)
-
-typedef u_int32_t ehci_physaddr_t;
-
-typedef u_int32_t ehci_isoc_trans_t;
-typedef u_int32_t ehci_isoc_bufr_ptr_t;
-
-/* Isochronous Transfer Descriptor */
-typedef struct {
- ehci_link_t itd_next;
- ehci_isoc_trans_t itd_ctl[8];
-#define EHCI_ITD_GET_STATUS(x) (((x) >> 28) & 0xf)
-#define EHCI_ITD_SET_STATUS(x) (((x) & 0xf) << 28)
-#define EHCI_ITD_ACTIVE 0x80000000
-#define EHCI_ITD_BUF_ERR 0x40000000
-#define EHCI_ITD_BABBLE 0x20000000
-#define EHCI_ITD_ERROR 0x10000000
-#define EHCI_ITD_GET_LEN(x) (((x) >> 16) & 0xfff)
-#define EHCI_ITD_SET_LEN(x) (((x) & 0xfff) << 16)
-#define EHCI_ITD_IOC 0x8000
-#define EHCI_ITD_GET_IOC(x) (((x) >> 15) & 1)
-#define EHCI_ITD_SET_IOC(x) (((x) << 15) & EHCI_ITD_IOC)
-#define EHCI_ITD_GET_PG(x) (((x) >> 12) & 0xf)
-#define EHCI_ITD_SET_PG(x) (((x) & 0xf) << 12)
-#define EHCI_ITD_GET_OFFS(x) (((x) >> 0) & 0xfff)
-#define EHCI_ITD_SET_OFFS(x) (((x) & 0xfff) << 0)
- ehci_isoc_bufr_ptr_t itd_bufr[7];
-#define EHCI_ITD_GET_BPTR(x) ((x) & 0xfffff000)
-#define EHCI_ITD_SET_BPTR(x) ((x) & 0xfffff000)
-#define EHCI_ITD_GET_EP(x) (((x) >> 8) & 0xf)
-#define EHCI_ITD_SET_EP(x) (((x) & 0xf) << 8)
-#define EHCI_ITD_GET_DADDR(x) ((x) & 0x7f)
-#define EHCI_ITD_SET_DADDR(x) ((x) & 0x7f)
-#define EHCI_ITD_GET_DIR(x) (((x) >> 11) & 1)
-#define EHCI_ITD_SET_DIR(x) (((x) & 1) << 11)
-#define EHCI_ITD_GET_MAXPKT(x) ((x) & 0x7ff)
-#define EHCI_ITD_SET_MAXPKT(x) ((x) & 0x7ff)
-#define EHCI_ITD_GET_MULTI(x) ((x) & 0x3)
-#define EHCI_ITD_SET_MULTI(x) ((x) & 0x3)
-} ehci_itd_t;
-#define EHCI_ITD_ALIGN 32
-
-/* Split Transaction Isochronous Transfer Descriptor */
-typedef struct {
- ehci_link_t sitd_next;
- /* XXX many more */
-} ehci_sitd_t;
-#define EHCI_SITD_ALIGN 32
-
-/* Queue Element Transfer Descriptor */
-#define EHCI_QTD_NBUFFERS 5
-typedef struct {
- ehci_link_t qtd_next;
- ehci_link_t qtd_altnext;
- u_int32_t qtd_status;
-#define EHCI_QTD_GET_STATUS(x) (((x) >> 0) & 0xff)
-#define EHCI_QTD_SET_STATUS(x) ((x) << 0)
-#define EHCI_QTD_ACTIVE 0x80
-#define EHCI_QTD_HALTED 0x40
-#define EHCI_QTD_BUFERR 0x20
-#define EHCI_QTD_BABBLE 0x10
-#define EHCI_QTD_XACTERR 0x08
-#define EHCI_QTD_MISSEDMICRO 0x04
-#define EHCI_QTD_SPLITXSTATE 0x02
-#define EHCI_QTD_PINGSTATE 0x01
-#define EHCI_QTD_STATERRS 0x7c
-#define EHCI_QTD_GET_PID(x) (((x) >> 8) & 0x3)
-#define EHCI_QTD_SET_PID(x) ((x) << 8)
-#define EHCI_QTD_PID_OUT 0x0
-#define EHCI_QTD_PID_IN 0x1
-#define EHCI_QTD_PID_SETUP 0x2
-#define EHCI_QTD_GET_CERR(x) (((x) >> 10) & 0x3)
-#define EHCI_QTD_SET_CERR(x) ((x) << 10)
-#define EHCI_QTD_GET_C_PAGE(x) (((x) >> 12) & 0x7)
-#define EHCI_QTD_SET_C_PAGE(x) ((x) << 12)
-#define EHCI_QTD_GET_IOC(x) (((x) >> 15) & 0x1)
-#define EHCI_QTD_IOC 0x00008000
-#define EHCI_QTD_GET_BYTES(x) (((x) >> 16) & 0x7fff)
-#define EHCI_QTD_SET_BYTES(x) ((x) << 16)
-#define EHCI_QTD_GET_TOGGLE(x) (((x) >> 31) & 0x1)
-#define EHCI_QTD_SET_TOGGLE(x) ((x) << 31)
-#define EHCI_QTD_TOGGLE_MASK 0x80000000
- ehci_physaddr_t qtd_buffer[EHCI_QTD_NBUFFERS];
- ehci_physaddr_t qtd_buffer_hi[EHCI_QTD_NBUFFERS];
-} ehci_qtd_t;
-#define EHCI_QTD_ALIGN 32
-
-#define EHCI_QTD_STATUS_BITS \
- "\20\10ACTIVE\7HALTED\6BUFERR\5BABBLE\4XACTERR\3MISSED\2SPLIT\1PING"
-
-/* Queue Head */
-typedef struct {
- ehci_link_t qh_link;
- u_int32_t qh_endp;
-#define EHCI_QH_GET_ADDR(x) (((x) >> 0) & 0x7f) /* endpoint addr */
-#define EHCI_QH_SET_ADDR(x) (x)
-#define EHCI_QH_ADDRMASK 0x0000007f
-#define EHCI_QH_GET_INACT(x) (((x) >> 7) & 0x01) /* inactivate on next */
-#define EHCI_QH_INACT 0x00000080
-#define EHCI_QH_GET_ENDPT(x) (((x) >> 8) & 0x0f) /* endpoint no */
-#define EHCI_QH_SET_ENDPT(x) ((x) << 8)
-#define EHCI_QH_GET_EPS(x) (((x) >> 12) & 0x03) /* endpoint speed */
-#define EHCI_QH_SET_EPS(x) ((x) << 12)
-#define EHCI_QH_SPEED_FULL 0x0
-#define EHCI_QH_SPEED_LOW 0x1
-#define EHCI_QH_SPEED_HIGH 0x2
-#define EHCI_QH_GET_DTC(x) (((x) >> 14) & 0x01) /* data toggle control */
-#define EHCI_QH_DTC 0x00004000
-#define EHCI_QH_GET_HRECL(x) (((x) >> 15) & 0x01) /* head of reclamation */
-#define EHCI_QH_HRECL 0x00008000
-#define EHCI_QH_GET_MPL(x) (((x) >> 16) & 0x7ff) /* max packet len */
-#define EHCI_QH_SET_MPL(x) ((x) << 16)
-#define EHCI_QH_MPLMASK 0x07ff0000
-#define EHCI_QH_GET_CTL(x) (((x) >> 27) & 0x01) /* control endpoint */
-#define EHCI_QH_CTL 0x08000000
-#define EHCI_QH_GET_NRL(x) (((x) >> 28) & 0x0f) /* NAK reload */
-#define EHCI_QH_SET_NRL(x) ((x) << 28)
- u_int32_t qh_endphub;
-#define EHCI_QH_GET_SMASK(x) (((x) >> 0) & 0xff) /* intr sched mask */
-#define EHCI_QH_SET_SMASK(x) ((x) << 0)
-#define EHCI_QH_GET_CMASK(x) (((x) >> 8) & 0xff) /* split completion mask */
-#define EHCI_QH_SET_CMASK(x) ((x) << 8)
-#define EHCI_QH_GET_HUBA(x) (((x) >> 16) & 0x7f) /* hub address */
-#define EHCI_QH_SET_HUBA(x) ((x) << 16)
-#define EHCI_QH_GET_PORT(x) (((x) >> 23) & 0x7f) /* hub port */
-#define EHCI_QH_SET_PORT(x) ((x) << 23)
-#define EHCI_QH_GET_MULT(x) (((x) >> 30) & 0x03) /* pipe multiplier */
-#define EHCI_QH_SET_MULT(x) ((x) << 30)
- ehci_link_t qh_curqtd;
- ehci_qtd_t qh_qtd;
-} ehci_qh_t;
-#define EHCI_QH_ALIGN 32
-
-/* Periodic Frame Span Traversal Node */
-typedef struct {
- ehci_link_t fstn_link;
- ehci_link_t fstn_back;
-} ehci_fstn_t;
-#define EHCI_FSTN_ALIGN 32
-
-#endif /* _DEV_PCI_EHCIREG_H_ */
diff --git a/sys/dev/usb/ehcivar.h b/sys/dev/usb/ehcivar.h
deleted file mode 100644
index fdd19ba..0000000
--- a/sys/dev/usb/ehcivar.h
+++ /dev/null
@@ -1,278 +0,0 @@
-/* $NetBSD: ehcivar.h,v 1.19 2005/04/29 15:04:29 augustss Exp $ */
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 2001 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net).
- *
- * 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.
- */
-
-typedef struct ehci_soft_qtd {
- ehci_qtd_t qtd;
- struct ehci_soft_qtd *nextqtd; /* mirrors nextqtd in TD */
- ehci_physaddr_t physaddr;
- usbd_xfer_handle xfer;
- LIST_ENTRY(ehci_soft_qtd) hnext;
- u_int16_t len;
-} ehci_soft_qtd_t;
-#define EHCI_SQTD_SIZE ((sizeof (struct ehci_soft_qtd) + EHCI_QTD_ALIGN - 1) / EHCI_QTD_ALIGN * EHCI_QTD_ALIGN)
-#define EHCI_SQTD_CHUNK (EHCI_PAGE_SIZE / EHCI_SQTD_SIZE)
-
-typedef struct ehci_soft_qh {
- ehci_qh_t qh;
- struct ehci_soft_qh *next;
- struct ehci_soft_qh *prev;
- struct ehci_soft_qtd *sqtd;
- struct ehci_soft_qtd *inactivesqtd;
- ehci_physaddr_t physaddr;
- int islot; /* Interrupt list slot. */
-} ehci_soft_qh_t;
-#define EHCI_SQH_SIZE ((sizeof (struct ehci_soft_qh) + EHCI_QH_ALIGN - 1) / EHCI_QH_ALIGN * EHCI_QH_ALIGN)
-#define EHCI_SQH_CHUNK (EHCI_PAGE_SIZE / EHCI_SQH_SIZE)
-
-typedef struct ehci_soft_itd {
- ehci_itd_t itd;
- union {
- struct {
- /* soft_itds links in a periodic frame*/
- struct ehci_soft_itd *next;
- struct ehci_soft_itd *prev;
- } frame_list;
- /* circular list of free itds */
- LIST_ENTRY(ehci_soft_itd) free_list;
- } u;
- struct ehci_soft_itd *xfer_next; /* Next soft_itd in xfer */
- ehci_physaddr_t physaddr;
- usb_dma_t dma;
- int offs;
- int slot;
- struct timeval t; /* store free time */
-} ehci_soft_itd_t;
-#define EHCI_ITD_SIZE ((sizeof(struct ehci_soft_itd) + EHCI_QH_ALIGN - 1) / EHCI_ITD_ALIGN * EHCI_ITD_ALIGN)
-#define EHCI_ITD_CHUNK (EHCI_PAGE_SIZE / EHCI_ITD_SIZE)
-
-struct ehci_xfer {
- struct usbd_xfer xfer;
- struct usb_task abort_task;
- LIST_ENTRY(ehci_xfer) inext; /* list of active xfers */
- ehci_soft_qtd_t *sqtdstart;
- ehci_soft_qtd_t *sqtdend;
- ehci_soft_itd_t *itdstart;
- ehci_soft_itd_t *itdend;
- u_int isoc_len;
- u_int32_t ehci_xfer_flags;
-#ifdef DIAGNOSTIC
- int isdone;
-#endif
-};
-#define EHCI_XFER_ABORTING 0x0001 /* xfer is aborting. */
-#define EHCI_XFER_ABORTWAIT 0x0002 /* abort completion is being awaited. */
-
-#define EXFER(xfer) ((struct ehci_xfer *)(xfer))
-
-/*
- * Information about an entry in the interrupt list.
- */
-struct ehci_soft_islot {
- ehci_soft_qh_t *sqh; /* Queue Head. */
-};
-
-#define EHCI_FRAMELIST_MAXCOUNT 1024
-#define EHCI_IPOLLRATES 8 /* Poll rates (1ms, 2, 4, 8 ... 128) */
-#define EHCI_INTRQHS ((1 << EHCI_IPOLLRATES) - 1)
-#define EHCI_MAX_POLLRATE (1 << (EHCI_IPOLLRATES - 1))
-#define EHCI_IQHIDX(lev, pos) \
- ((((pos) & ((1 << (lev)) - 1)) | (1 << (lev))) - 1)
-#define EHCI_ILEV_IVAL(lev) (1 << (lev))
-
-#define EHCI_HASH_SIZE 128
-#define EHCI_COMPANION_MAX 8
-
-#define EHCI_FREE_LIST_INTERVAL 100
-
-#define EHCI_SCFLG_DONEINIT 0x0001 /* ehci_init() has been called. */
-#define EHCI_SCFLG_LOSTINTRBUG 0x0002 /* workaround for VIA / ATI chipsets */
-#define EHCI_SCFLG_SETMODE 0x0004 /* set bridge mode again after init (Marvell) */
-#define EHCI_SCFLG_FORCESPEED 0x0008 /* force speed (Marvell) */
-#define EHCI_SCFLG_NORESTERM 0x0010 /* don't terminate reset sequence (Marvell) */
-#define EHCI_SCFLG_BIGEDESC 0x0020 /* big-endian byte order descriptors */
-#define EHCI_SCFLG_BIGEMMIO 0x0040 /* big-endian byte order MMIO */
-#define EHCI_SCFLG_TT 0x0080 /* transaction translator present */
-
-typedef struct ehci_softc {
- struct usbd_bus sc_bus; /* base device */
- int sc_flags;
- bus_space_tag_t iot;
- bus_space_handle_t ioh;
- bus_size_t sc_size;
- void *ih;
-
- struct resource *io_res;
- struct resource *irq_res;
- u_int sc_offs; /* offset to operational regs */
-
- char sc_vendor[32]; /* vendor string for root hub */
- int sc_id_vendor; /* vendor ID for root hub */
-
- u_int32_t sc_cmd; /* shadow of cmd reg during suspend */
-
- u_int sc_ncomp;
- u_int sc_npcomp;
- struct usbd_bus *sc_comps[EHCI_COMPANION_MAX];
-
- usb_dma_t sc_fldma;
- ehci_link_t *sc_flist;
- u_int sc_flsize;
-
- struct ehci_soft_islot sc_islots[EHCI_INTRQHS];
-
- /* jcmm - an array matching sc_flist, but with software pointers,
- * not hardware address pointers
- */
- struct ehci_soft_itd **sc_softitds;
-
- LIST_HEAD(, ehci_xfer) sc_intrhead;
-
- ehci_soft_qh_t *sc_freeqhs;
- ehci_soft_qtd_t *sc_freeqtds;
- LIST_HEAD(sc_freeitds, ehci_soft_itd) sc_freeitds;
-
- int sc_noport;
- u_int8_t sc_addr; /* device address */
- u_int8_t sc_conf; /* device configuration */
- usbd_xfer_handle sc_intrxfer;
- char sc_isreset;
-#ifdef USB_USE_SOFTINTR
- char sc_softwake;
-#endif /* USB_USE_SOFTINTR */
-
- u_int32_t sc_eintrs;
- ehci_soft_qh_t *sc_async_head;
-
- STAILQ_HEAD(, usbd_xfer) sc_free_xfers; /* free xfers */
-
- struct lock sc_doorbell_lock;
-
- struct callout sc_tmo_intrlist;
-
- char sc_dying;
-} ehci_softc_t;
-
-#define EREAD1(sc, a) bus_space_read_1((sc)->iot, (sc)->ioh, (a))
-#define EREAD2(sc, a) bus_space_read_2((sc)->iot, (sc)->ioh, (a))
-#define EREAD4(sc, a) bus_space_read_4((sc)->iot, (sc)->ioh, (a))
-#define EWRITE1(sc, a, x) bus_space_write_1((sc)->iot, (sc)->ioh, (a), (x))
-#define EWRITE2(sc, a, x) bus_space_write_2((sc)->iot, (sc)->ioh, (a), (x))
-#define EWRITE4(sc, a, x) bus_space_write_4((sc)->iot, (sc)->ioh, (a), (x))
-#define EOREAD1(sc, a) bus_space_read_1((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a))
-#define EOREAD2(sc, a) bus_space_read_2((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a))
-#define EOREAD4(sc, a) bus_space_read_4((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a))
-#define EOWRITE1(sc, a, x) bus_space_write_1((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a), (x))
-#define EOWRITE2(sc, a, x) bus_space_write_2((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a), (x))
-#define EOWRITE4(sc, a, x) bus_space_write_4((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a), (x))
-
-#ifdef USB_EHCI_BIG_ENDIAN_DESC
-/*
- * Handle byte order conversion between host and ``host controller''.
- * Typically the latter is little-endian but some controllers require
- * big-endian in which case we may need to manually swap.
- */
-static __inline uint32_t
-htohc32(const struct ehci_softc *sc, const uint32_t v)
-{
- return sc->sc_flags & EHCI_SCFLG_BIGEDESC ? htobe32(v) : htole32(v);
-}
-
-static __inline uint16_t
-htohc16(const struct ehci_softc *sc, const uint16_t v)
-{
- return sc->sc_flags & EHCI_SCFLG_BIGEDESC ? htobe16(v) : htole16(v);
-}
-
-static __inline uint32_t
-hc32toh(const struct ehci_softc *sc, const uint32_t v)
-{
- return sc->sc_flags & EHCI_SCFLG_BIGEDESC ? be32toh(v) : le32toh(v);
-}
-
-static __inline uint16_t
-hc16toh(const struct ehci_softc *sc, const uint16_t v)
-{
- return sc->sc_flags & EHCI_SCFLG_BIGEDESC ? be16toh(v) : le16toh(v);
-}
-#else
-/*
- * Normal little-endian only conversion routines.
- */
-static __inline uint32_t
-htohc32(const struct ehci_softc *sc, const uint32_t v)
-{
- return htole32(v);
-}
-
-static __inline uint16_t
-htohc16(const struct ehci_softc *sc, const uint16_t v)
-{
- return htole16(v);
-}
-
-static __inline uint32_t
-hc32toh(const struct ehci_softc *sc, const uint32_t v)
-{
- return le32toh(v);
-}
-
-static __inline uint16_t
-hc16toh(const struct ehci_softc *sc, const uint16_t v)
-{
- return le16toh(v);
-}
-#endif
-
-usbd_status ehci_reset(ehci_softc_t *);
-usbd_status ehci_init(ehci_softc_t *);
-int ehci_intr(void *);
-int ehci_detach(ehci_softc_t *, int);
-void ehci_power(int state, void *priv);
-void ehci_shutdown(void *v);
-
-#define MS_TO_TICKS(ms) ((ms) * hz / 1000)
-
-void ehci_dump_regs(ehci_softc_t *);
-void ehci_dump_sqtds(ehci_softc_t *, ehci_soft_qtd_t *);
-void ehci_dump_qtd(ehci_softc_t *, ehci_qtd_t *);
-void ehci_dump_sqtd(ehci_softc_t *, ehci_soft_qtd_t *);
-void ehci_dump_sqh(ehci_softc_t *, ehci_soft_qh_t *);
-void ehci_dump_itd(ehci_softc_t *, struct ehci_soft_itd *);
-void ehci_dump_sitd(ehci_softc_t *, struct ehci_soft_itd *);
-void ehci_dump_exfer(struct ehci_xfer *);
diff --git a/sys/dev/usb/hid.c b/sys/dev/usb/hid.c
deleted file mode 100644
index 70facb6..0000000
--- a/sys/dev/usb/hid.c
+++ /dev/null
@@ -1,469 +0,0 @@
-/* $NetBSD: hid.c,v 1.17 2001/11/13 06:24:53 lukem Exp $ */
-
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) 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.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/malloc.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbhid.h>
-
-#include <dev/usb/hid.h>
-
-#ifdef USB_DEBUG
-#define DPRINTF(x) if (usbdebug) printf x
-#define DPRINTFN(n,x) if (usbdebug>(n)) printf x
-extern int usbdebug;
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-static void hid_clear_local(struct hid_item *);
-
-#define MAXUSAGE 100
-struct hid_data {
- u_char *start;
- u_char *end;
- u_char *p;
- struct hid_item cur;
- int32_t usages[MAXUSAGE];
- int nu;
- int minset;
- int multi;
- int multimax;
- int kindset;
-};
-
-static void
-hid_clear_local(struct hid_item *c)
-{
-
- c->usage = 0;
- c->usage_minimum = 0;
- c->usage_maximum = 0;
- c->designator_index = 0;
- c->designator_minimum = 0;
- c->designator_maximum = 0;
- c->string_index = 0;
- c->string_minimum = 0;
- c->string_maximum = 0;
- c->set_delimiter = 0;
-}
-
-struct hid_data *
-hid_start_parse(void *d, int len, int kindset)
-{
- struct hid_data *s;
-
- s = malloc(sizeof *s, M_TEMP, M_WAITOK|M_ZERO);
- s->start = s->p = d;
- s->end = (char *)d + len;
- s->kindset = kindset;
- return (s);
-}
-
-void
-hid_end_parse(struct hid_data *s)
-{
-
- while (s->cur.next != NULL) {
- struct hid_item *hi = s->cur.next->next;
- free(s->cur.next, M_TEMP);
- s->cur.next = hi;
- }
- free(s, M_TEMP);
-}
-
-int
-hid_get_item(struct hid_data *s, struct hid_item *h)
-{
- struct hid_item *c = &s->cur;
- unsigned int bTag, bType, bSize;
- u_int32_t oldpos;
- u_char *data;
- int32_t dval;
- u_char *p;
- struct hid_item *hi;
- int i;
-
- top:
- if (s->multimax != 0) {
- if (s->multi < s->multimax) {
- c->usage = s->usages[min(s->multi, s->nu-1)];
- s->multi++;
- *h = *c;
- c->loc.pos += c->loc.size;
- h->next = 0;
- return (1);
- } else {
- c->loc.count = s->multimax;
- s->multimax = 0;
- s->nu = 0;
- hid_clear_local(c);
- }
- }
- for (;;) {
- p = s->p;
- if (p >= s->end)
- return (0);
-
- bSize = *p++;
- if (bSize == 0xfe) {
- /* long item */
- bSize = *p++;
- bSize |= *p++ << 8;
- bTag = *p++;
- data = p;
- p += bSize;
- bType = 0xff; /* XXX what should it be */
- } else {
- /* short item */
- bTag = bSize >> 4;
- bType = (bSize >> 2) & 3;
- bSize &= 3;
- if (bSize == 3) bSize = 4;
- data = p;
- p += bSize;
- }
- s->p = p;
- switch(bSize) {
- case 0:
- dval = 0;
- break;
- case 1:
- dval = (int8_t)*data++;
- break;
- case 2:
- dval = *data++;
- dval |= *data++ << 8;
- dval = (int16_t)dval;
- break;
- case 4:
- dval = *data++;
- dval |= *data++ << 8;
- dval |= *data++ << 16;
- dval |= *data++ << 24;
- break;
- default:
- printf("BAD LENGTH %d\n", bSize);
- continue;
- }
-
- switch (bType) {
- case 0: /* Main */
- switch (bTag) {
- case 8: /* Input */
- if (!(s->kindset & (1 << hid_input))) {
- if (s->nu > 0)
- s->nu--;
- continue;
- }
- c->kind = hid_input;
- c->flags = dval;
- ret:
- if (c->flags & HIO_VARIABLE) {
- s->multimax = c->loc.count;
- s->multi = 0;
- c->loc.count = 1;
- if (s->minset) {
- for (i = c->usage_minimum;
- i <= c->usage_maximum;
- i++) {
- s->usages[s->nu] = i;
- if (s->nu < MAXUSAGE-1)
- s->nu++;
- }
- s->minset = 0;
- }
- goto top;
- } else {
- *h = *c;
- h->next = 0;
- c->loc.pos +=
- c->loc.size * c->loc.count;
- hid_clear_local(c);
- s->minset = 0;
- return (1);
- }
- case 9: /* Output */
- if (!(s->kindset & (1 << hid_output))) {
- if (s->nu > 0)
- s->nu--;
- continue;
- }
- c->kind = hid_output;
- c->flags = dval;
- goto ret;
- case 10: /* Collection */
- c->kind = hid_collection;
- c->collection = dval;
- c->collevel++;
- *h = *c;
- hid_clear_local(c);
- s->nu = 0;
- return (1);
- case 11: /* Feature */
- if (!(s->kindset & (1 << hid_feature))) {
- if (s->nu > 0)
- s->nu--;
- continue;
- }
- c->kind = hid_feature;
- c->flags = dval;
- goto ret;
- case 12: /* End collection */
- c->kind = hid_endcollection;
- c->collevel--;
- *h = *c;
- hid_clear_local(c);
- s->nu = 0;
- return (1);
- default:
- printf("Main bTag=%d\n", bTag);
- break;
- }
- break;
- case 1: /* Global */
- switch (bTag) {
- case 0:
- c->_usage_page = dval << 16;
- break;
- case 1:
- c->logical_minimum = dval;
- break;
- case 2:
- c->logical_maximum = dval;
- break;
- case 3:
- c->physical_minimum = dval;
- break;
- case 4:
- c->physical_maximum = dval;
- break;
- case 5:
- c->unit_exponent = dval;
- break;
- case 6:
- c->unit = dval;
- break;
- case 7:
- c->loc.size = dval;
- break;
- case 8:
- c->report_ID = dval;
- break;
- case 9:
- c->loc.count = dval;
- break;
- case 10: /* Push */
- hi = malloc(sizeof *hi, M_TEMP, M_WAITOK);
- *hi = s->cur;
- c->next = hi;
- break;
- case 11: /* Pop */
- hi = c->next;
- oldpos = c->loc.pos;
- s->cur = *hi;
- c->loc.pos = oldpos;
- free(hi, M_TEMP);
- break;
- default:
- printf("Global bTag=%d\n", bTag);
- break;
- }
- break;
- case 2: /* Local */
- switch (bTag) {
- case 0:
- if (bSize == 1)
- dval = c->_usage_page | (dval&0xff);
- else if (bSize == 2)
- dval = c->_usage_page | (dval&0xffff);
- c->usage = dval;
- if (s->nu < MAXUSAGE)
- s->usages[s->nu++] = dval;
- /* else XXX */
- break;
- case 1:
- s->minset = 1;
- if (bSize == 1)
- dval = c->_usage_page | (dval&0xff);
- else if (bSize == 2)
- dval = c->_usage_page | (dval&0xffff);
- c->usage_minimum = dval;
- break;
- case 2:
- if (bSize == 1)
- dval = c->_usage_page | (dval&0xff);
- else if (bSize == 2)
- dval = c->_usage_page | (dval&0xffff);
- c->usage_maximum = dval;
- break;
- case 3:
- c->designator_index = dval;
- break;
- case 4:
- c->designator_minimum = dval;
- break;
- case 5:
- c->designator_maximum = dval;
- break;
- case 7:
- c->string_index = dval;
- break;
- case 8:
- c->string_minimum = dval;
- break;
- case 9:
- c->string_maximum = dval;
- break;
- case 10:
- c->set_delimiter = dval;
- break;
- default:
- printf("Local bTag=%d\n", bTag);
- break;
- }
- break;
- default:
- printf("default bType=%d\n", bType);
- break;
- }
- }
-}
-
-int
-hid_report_size(void *buf, int len, enum hid_kind k, u_int8_t *idp)
-{
- struct hid_data *d;
- struct hid_item h;
- int hi, lo, size, id;
-
- id = 0;
- hi = lo = -1;
- for (d = hid_start_parse(buf, len, 1<<k); hid_get_item(d, &h); )
- if (h.kind == k) {
- if (h.report_ID != 0 && !id)
- id = h.report_ID;
- if (h.report_ID == id) {
- if (lo < 0)
- lo = h.loc.pos;
- hi = h.loc.pos + h.loc.size * h.loc.count;
- }
- }
- hid_end_parse(d);
- size = hi - lo;
- if (id != 0) {
- size += 8;
- *idp = id; /* XXX wrong */
- } else
- *idp = 0;
- return ((size + 7) / 8);
-}
-
-int
-hid_locate(void *desc, int size, u_int32_t u, enum hid_kind k,
- struct hid_location *loc, u_int32_t *flags)
-{
- struct hid_data *d;
- struct hid_item h;
-
- for (d = hid_start_parse(desc, size, 1<<k); hid_get_item(d, &h); ) {
- if (h.kind == k && !(h.flags & HIO_CONST) && h.usage == u) {
- if (loc != NULL)
- *loc = h.loc;
- if (flags != NULL)
- *flags = h.flags;
- hid_end_parse(d);
- return (1);
- }
- }
- hid_end_parse(d);
- loc->size = 0;
- return (0);
-}
-
-u_long
-hid_get_data(u_char *buf, struct hid_location *loc)
-{
- u_int hpos = loc->pos;
- u_int hsize = loc->size;
- u_int32_t data;
- int i, s;
-
- DPRINTFN(10, ("hid_get_data: loc %d/%d\n", hpos, hsize));
-
- if (hsize == 0)
- return (0);
-
- data = 0;
- s = hpos / 8;
- for (i = hpos; i < hpos+hsize; i += 8)
- data |= buf[i / 8] << ((i / 8 - s) * 8);
- data >>= hpos % 8;
- data &= (1 << hsize) - 1;
- hsize = 32 - hsize;
- /* Sign extend */
- data = ((int32_t)data << hsize) >> hsize;
- DPRINTFN(10,("hid_get_data: loc %d/%d = %lu\n",
- loc->pos, loc->size, (long)data));
- return (data);
-}
-
-int
-hid_is_collection(void *desc, int size, u_int32_t usage)
-{
- struct hid_data *hd;
- struct hid_item hi;
- int err;
-
- hd = hid_start_parse(desc, size, hid_input);
- if (hd == NULL)
- return (0);
-
- err = hid_get_item(hd, &hi) &&
- hi.kind == hid_collection &&
- hi.usage == usage;
- hid_end_parse(hd);
- return (err);
-}
diff --git a/sys/dev/usb/hid.h b/sys/dev/usb/hid.h
deleted file mode 100644
index a4ab7d2..0000000
--- a/sys/dev/usb/hid.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/* $NetBSD: hid.h,v 1.6 2000/06/01 14:28:57 augustss Exp $ */
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) 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.
- */
-
-enum hid_kind {
- hid_input, hid_output, hid_feature, hid_collection, hid_endcollection
-};
-
-struct hid_location {
- u_int32_t size;
- u_int32_t count;
- u_int32_t pos;
-};
-
-struct hid_item {
- /* Global */
- int32_t _usage_page;
- int32_t logical_minimum;
- int32_t logical_maximum;
- int32_t physical_minimum;
- int32_t physical_maximum;
- int32_t unit_exponent;
- int32_t unit;
- int32_t report_ID;
- /* Local */
- int32_t usage;
- int32_t usage_minimum;
- int32_t usage_maximum;
- int32_t designator_index;
- int32_t designator_minimum;
- int32_t designator_maximum;
- int32_t string_index;
- int32_t string_minimum;
- int32_t string_maximum;
- int32_t set_delimiter;
- /* Misc */
- int32_t collection;
- int collevel;
- enum hid_kind kind;
- u_int32_t flags;
- /* Location */
- struct hid_location loc;
- /* */
- struct hid_item *next;
-};
-
-struct hid_data *hid_start_parse(void *d, int len, int kindset);
-void hid_end_parse(struct hid_data *s);
-int hid_get_item(struct hid_data *s, struct hid_item *h);
-int hid_report_size(void *buf, int len, enum hid_kind k, u_int8_t *id);
-int hid_locate(void *desc, int size, u_int32_t usage,
- enum hid_kind kind, struct hid_location *loc,
- u_int32_t *flags);
-u_long hid_get_data(u_char *buf, struct hid_location *loc);
-int hid_is_collection(void *desc, int size, u_int32_t usage);
diff --git a/sys/dev/usb/if_aue.c b/sys/dev/usb/if_aue.c
deleted file mode 100644
index 1c6d8a3..0000000
--- a/sys/dev/usb/if_aue.c
+++ /dev/null
@@ -1,1498 +0,0 @@
-/*-
- * Copyright (c) 1997, 1998, 1999, 2000
- * Bill Paul <wpaul@ee.columbia.edu>. All rights reserved.
- *
- * Copyright (c) 2006
- * Alfred Perlstein <alfred@freebsd.org>. 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * ADMtek AN986 Pegasus and AN8511 Pegasus II USB to ethernet driver.
- * Datasheet is available from http://www.admtek.com.tw.
- *
- * Written by Bill Paul <wpaul@ee.columbia.edu>
- * Electrical Engineering Department
- * Columbia University, New York City
- *
- * SMP locking by Alfred Perlstein <alfred@freebsd.org>.
- * RED Inc.
- */
-
-/*
- * 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.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/sockio.h>
-#include <sys/mbuf.h>
-#include <sys/malloc.h>
-#include <sys/kernel.h>
-#include <sys/kdb.h>
-#include <sys/lock.h>
-#include <sys/module.h>
-#include <sys/socket.h>
-#include <sys/sx.h>
-#include <sys/taskqueue.h>
-
-#include <net/if.h>
-#include <net/if_arp.h>
-#include <net/ethernet.h>
-#include <net/if_dl.h>
-#include <net/if_media.h>
-#include <net/if_types.h>
-
-#include <net/bpf.h>
-
-#include <sys/bus.h>
-#include <machine/bus.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include <dev/usb/usbdivar.h>
-#include "usbdevs.h"
-#include <dev/usb/usb_ethersubr.h>
-
-#include <dev/mii/mii.h>
-#include <dev/mii/miivar.h>
-
-#include <dev/usb/if_auereg.h>
-
-MODULE_DEPEND(aue, usb, 1, 1, 1);
-MODULE_DEPEND(aue, ether, 1, 1, 1);
-MODULE_DEPEND(aue, miibus, 1, 1, 1);
-
-/* "device miibus" required. See GENERIC if you get errors here. */
-#include "miibus_if.h"
-
-/*
- * Various supported device vendors/products.
- */
-struct aue_type {
- struct usb_devno aue_dev;
- u_int16_t aue_flags;
-#define LSYS 0x0001 /* use Linksys reset */
-#define PNA 0x0002 /* has Home PNA */
-#define PII 0x0004 /* Pegasus II chip */
-};
-
-static const struct aue_type aue_devs[] = {
- {{ USB_VENDOR_3COM, USB_PRODUCT_3COM_3C460B}, PII },
- {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX1}, PNA|PII },
- {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX2}, PII },
- {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_UFE1000}, LSYS },
- {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX4}, PNA },
- {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX5}, PNA },
- {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX6}, PII },
- {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX7}, PII },
- {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX8}, PII },
- {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX9}, PNA },
- {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_XX10}, 0 },
- {{ USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_DSB650TX_PNA}, 0 },
- {{ USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_USB320_EC}, 0 },
- {{ USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_SS1001}, PII },
- {{ USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUS}, PNA },
- {{ USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUSII}, PII },
- {{ USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUSII_2}, PII },
- {{ USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUSII_3}, PII },
- {{ USB_VENDOR_ADMTEK, USB_PRODUCT_ADMTEK_PEGASUSII_4}, PII },
- {{ USB_VENDOR_AEI, USB_PRODUCT_AEI_FASTETHERNET}, PII },
- {{ USB_VENDOR_ALLIEDTELESYN, USB_PRODUCT_ALLIEDTELESYN_ATUSB100}, PII },
- {{ USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC110T}, PII },
- {{ USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_USB2LAN}, PII },
- {{ USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USB100}, 0 },
- {{ USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USBLP100}, PNA },
- {{ USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USBEL100}, 0 },
- {{ USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USBE100}, PII },
- {{ USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB_TX}, 0 },
- {{ USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB_TXS},PII },
- {{ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX4}, LSYS|PII },
- {{ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX1}, LSYS },
- {{ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX}, LSYS },
- {{ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX_PNA}, PNA },
- {{ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX3}, LSYS|PII },
- {{ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650TX2}, LSYS|PII },
- {{ USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650}, LSYS },
- {{ USB_VENDOR_ELCON, USB_PRODUCT_ELCON_PLAN}, PNA|PII },
- {{ USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSB20}, PII },
- {{ USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBTX0}, 0 },
- {{ USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBTX1}, LSYS },
- {{ USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBTX2}, 0 },
- {{ USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBTX3}, LSYS },
- {{ USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_LDUSBLTX}, PII },
- {{ USB_VENDOR_ELSA, USB_PRODUCT_ELSA_USB2ETHERNET}, 0 },
- {{ USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNBR402W}, 0 },
- {{ USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_UF100}, PII },
- {{ USB_VENDOR_HP, USB_PRODUCT_HP_HN210E}, PII },
- {{ USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBETTX}, 0 },
- {{ USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBETTXS}, PII },
- {{ USB_VENDOR_KINGSTON, USB_PRODUCT_KINGSTON_KNU101TX}, 0 },
- {{ USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10TX1}, LSYS|PII },
- {{ USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10T}, LSYS },
- {{ USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB100TX}, LSYS },
- {{ USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB100H1}, LSYS|PNA },
- {{ USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10TA}, LSYS },
- {{ USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10TX2}, LSYS|PII },
- {{ USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUATX1}, 0 },
- {{ USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUATX5}, 0 },
- {{ USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUA2TX5}, PII },
- {{ USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_MN110}, PII },
- {{ USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_FA101}, PII },
- {{ USB_VENDOR_SIEMENS, USB_PRODUCT_SIEMENS_SPEEDSTREAM}, PII },
- {{ USB_VENDOR_SIIG2, USB_PRODUCT_SIIG2_USBTOETHER}, PII },
- {{ USB_VENDOR_SMARTBRIDGES, USB_PRODUCT_SMARTBRIDGES_SMARTNIC},PII },
- {{ USB_VENDOR_SMC, USB_PRODUCT_SMC_2202USB}, 0 },
- {{ USB_VENDOR_SMC, USB_PRODUCT_SMC_2206USB}, PII },
- {{ USB_VENDOR_SOHOWARE, USB_PRODUCT_SOHOWARE_NUB100}, 0 },
- {{ USB_VENDOR_SOHOWARE, USB_PRODUCT_SOHOWARE_NUB110}, PII },
-};
-#define aue_lookup(v, p) ((const struct aue_type *)usb_lookup(aue_devs, v, p))
-
-static device_probe_t aue_match;
-static device_attach_t aue_attach;
-static device_detach_t aue_detach;
-static device_shutdown_t aue_shutdown;
-static miibus_readreg_t aue_miibus_readreg;
-static miibus_writereg_t aue_miibus_writereg;
-static miibus_statchg_t aue_miibus_statchg;
-
-static void aue_reset_pegasus_II(struct aue_softc *sc);
-static int aue_encap(struct aue_softc *, struct mbuf *, int);
-#ifdef AUE_INTR_PIPE
-static void aue_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
-#endif
-static void aue_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
-static void aue_rxeof_thread(struct aue_softc *sc);
-static void aue_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
-static void aue_txeof_thread(struct aue_softc *);
-static void aue_task_sched(struct aue_softc *, int);
-static void aue_task(void *xsc, int pending);
-static void aue_tick(void *);
-static void aue_rxstart(struct ifnet *);
-static void aue_rxstart_thread(struct aue_softc *);
-static void aue_start(struct ifnet *);
-static void aue_start_thread(struct aue_softc *);
-static int aue_ioctl(struct ifnet *, u_long, caddr_t);
-static void aue_init(void *);
-static void aue_init_body(struct aue_softc *);
-static void aue_stop(struct aue_softc *);
-static void aue_watchdog(struct aue_softc *);
-static int aue_ifmedia_upd(struct ifnet *);
-static void aue_ifmedia_sts(struct ifnet *, struct ifmediareq *);
-
-static void aue_eeprom_getword(struct aue_softc *, int, u_int16_t *);
-static void aue_read_eeprom(struct aue_softc *, caddr_t, int, int, int);
-
-static void aue_setmulti(struct aue_softc *);
-static void aue_reset(struct aue_softc *);
-
-static int aue_csr_read_1(struct aue_softc *, int);
-static int aue_csr_write_1(struct aue_softc *, int, int);
-static int aue_csr_read_2(struct aue_softc *, int);
-static int aue_csr_write_2(struct aue_softc *, int, int);
-
-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(aue, uhub, aue_driver, aue_devclass, usbd_driver_load, 0);
-DRIVER_MODULE(miibus, aue, miibus_driver, miibus_devclass, 0, 0);
-
-#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(struct aue_softc *sc, int reg)
-{
- usb_device_request_t req;
- usbd_status err;
- u_int8_t val = 0;
-
- AUE_SXASSERTLOCKED(sc);
-
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = AUE_UR_READREG;
- USETW(req.wValue, 0);
- USETW(req.wIndex, reg);
- USETW(req.wLength, 1);
-
- err = usbd_do_request(sc->aue_udev, &req, &val);
-
- if (err) {
- return (0);
- }
-
- return (val);
-}
-
-static int
-aue_csr_read_2(struct aue_softc *sc, int reg)
-{
- usb_device_request_t req;
- usbd_status err;
- u_int16_t val = 0;
-
- AUE_SXASSERTLOCKED(sc);
-
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = AUE_UR_READREG;
- USETW(req.wValue, 0);
- USETW(req.wIndex, reg);
- USETW(req.wLength, 2);
-
- err = usbd_do_request(sc->aue_udev, &req, &val);
-
- if (err) {
- return (0);
- }
-
- return (val);
-}
-
-static int
-aue_csr_write_1(struct aue_softc *sc, int reg, int val)
-{
- usb_device_request_t req;
- usbd_status err;
-
- AUE_SXASSERTLOCKED(sc);
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = AUE_UR_WRITEREG;
- USETW(req.wValue, val);
- USETW(req.wIndex, reg);
- USETW(req.wLength, 1);
-
- err = usbd_do_request(sc->aue_udev, &req, &val);
-
- if (err) {
- return (-1);
- }
-
- return (0);
-}
-
-static int
-aue_csr_write_2(struct aue_softc *sc, int reg, int val)
-{
- usb_device_request_t req;
- usbd_status err;
-
- AUE_SXASSERTLOCKED(sc);
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = AUE_UR_WRITEREG;
- USETW(req.wValue, val);
- USETW(req.wIndex, reg);
- USETW(req.wLength, 2);
-
- err = usbd_do_request(sc->aue_udev, &req, &val);
-
- if (err) {
- return (-1);
- }
-
- return (0);
-}
-
-/*
- * Read a word of data stored in the EEPROM at address 'addr.'
- */
-static void
-aue_eeprom_getword(struct aue_softc *sc, int addr, u_int16_t *dest)
-{
- int i;
- u_int16_t word = 0;
-
- 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("aue%d: EEPROM read timed out\n",
- sc->aue_unit);
- }
-
- word = aue_csr_read_2(sc, AUE_EE_DATA);
- *dest = word;
-
- return;
-}
-
-/*
- * Read a sequence of words from the EEPROM.
- */
-static void
-aue_read_eeprom(struct aue_softc *sc, caddr_t dest, int off, int cnt, int swap)
-{
- int i;
- u_int16_t word = 0, *ptr;
-
- for (i = 0; i < cnt; i++) {
- aue_eeprom_getword(sc, off + i, &word);
- ptr = (u_int16_t *)(dest + (i * 2));
- if (swap)
- *ptr = ntohs(word);
- else
- *ptr = word;
- }
-
- return;
-}
-
-static int
-aue_miibus_readreg(device_t dev, int phy, int reg)
-{
- struct aue_softc *sc = device_get_softc(dev);
- int i;
- u_int16_t val = 0;
-
- /*
- * 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 == 3)
- return (0);
-#ifdef notdef
- if (phy != 1)
- return (0);
-#endif
- }
-
- 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("aue%d: MII read timed out\n", sc->aue_unit);
- }
-
- val = aue_csr_read_2(sc, AUE_PHY_DATA);
-
- return (val);
-}
-
-static int
-aue_miibus_writereg(device_t dev, int phy, int reg, int data)
-{
- struct aue_softc *sc = device_get_softc(dev);
- int i;
-
- if (phy == 3)
- return (0);
-
- 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("aue%d: MII read timed out\n",
- sc->aue_unit);
- }
-
- return(0);
-}
-
-static void
-aue_miibus_statchg(device_t dev)
-{
- struct aue_softc *sc = device_get_softc(dev);
- struct mii_data *mii = GET_MII(sc);
-
- AUE_CLRBIT(sc, AUE_CTL0, AUE_CTL0_RX_ENB | AUE_CTL0_TX_ENB);
- if (IFM_SUBTYPE(mii->mii_media_active) == IFM_100_TX) {
- 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_flags & LSYS) {
- u_int16_t auxmode;
- auxmode = aue_miibus_readreg(dev, 0, 0x1b);
- aue_miibus_writereg(dev, 0, 0x1b, auxmode | 0x04);
- }
-
- return;
-}
-
-#define AUE_BITS 6
-
-static void
-aue_setmulti(struct aue_softc *sc)
-{
- struct ifnet *ifp;
- struct ifmultiaddr *ifma;
- u_int32_t h = 0, i;
- u_int8_t hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
-
- AUE_SXASSERTLOCKED(sc);
- ifp = sc->aue_ifp;
-
- 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);
-
- /* now program new ones */
- IF_ADDR_LOCK(ifp);
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
- {
- if (ifma->ifma_addr->sa_family != AF_LINK)
- continue;
- h = ether_crc32_le(LLADDR((struct sockaddr_dl *)
- ifma->ifma_addr), ETHER_ADDR_LEN) & ((1 << AUE_BITS) - 1);
- hashtbl[(h >> 3)] |= 1 << (h & 0x7);
- }
- IF_ADDR_UNLOCK(ifp);
-
- /* write the hashtable */
- for (i = 0; i < 8; i++)
- aue_csr_write_1(sc, AUE_MAR0 + i, hashtbl[i]);
-
- return;
-}
-
-static void
-aue_reset_pegasus_II(struct aue_softc *sc)
-{
- /* Magic constants taken from Linux driver. */
- aue_csr_write_1(sc, AUE_REG_1D, 0);
- aue_csr_write_1(sc, AUE_REG_7B, 2);
-#if 0
- if ((sc->aue_flags & HAS_HOME_PNA) && mii_mode)
- aue_csr_write_1(sc, AUE_REG_81, 6);
- else
-#endif
- aue_csr_write_1(sc, AUE_REG_81, 2);
-}
-
-static void
-aue_reset(struct aue_softc *sc)
-{
- int i;
-
- AUE_SXASSERTLOCKED(sc);
- 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("aue%d: reset failed\n", sc->aue_unit);
-
- /*
- * 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);
-
- if (sc->aue_flags & LSYS) {
- /* Grrr. LinkSys has to be different from everyone else. */
- 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);
- }
-
- if (sc->aue_flags & PII)
- aue_reset_pegasus_II(sc);
-
- /* Wait a little while for the chip to get its brains in order. */
- DELAY(10000);
-
- return;
-}
-
-/*
- * Probe for a Pegasus chip.
- */
-static int
-aue_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
-
- if (uaa->iface != NULL)
- return (UMATCH_NONE);
-
- /*
- * Belkin USB Bluetooth dongles of the F8T012xx1 model series conflict
- * with older Belkin USB2LAN adapters. Skip if_aue if we detect one of
- * the devices that look like Bluetooth adapters.
- */
- if (uaa->vendor == USB_VENDOR_BELKIN &&
- uaa->product == USB_PRODUCT_BELKIN_F8T012 && uaa->release == 0x0413)
- return (UMATCH_NONE);
-
- return (aue_lookup(uaa->vendor, uaa->product) != NULL ?
- UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
-}
-
-/*
- * Attach the interface. Allocate softc structures, do ifmedia
- * setup and ethernet/BPF attach.
- */
-static int
-aue_attach(device_t self)
-{
- struct aue_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- u_char eaddr[ETHER_ADDR_LEN];
- struct ifnet *ifp;
- usbd_interface_handle iface;
- usbd_status err;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
- int i;
-
- sc->aue_dev = self;
- sc->aue_udev = uaa->device;
- sc->aue_unit = device_get_unit(self);
-
- if (usbd_set_config_no(sc->aue_udev, AUE_CONFIG_NO, 0)) {
- device_printf(self, "getting interface handle failed\n");
- return ENXIO;
- }
-
- err = usbd_device2interface_handle(uaa->device, AUE_IFACE_IDX, &iface);
- if (err) {
- device_printf(self, "getting interface handle failed\n");
- return ENXIO;
- }
-
- sc->aue_iface = iface;
- sc->aue_flags = aue_lookup(uaa->vendor, uaa->product)->aue_flags;
-
- sc->aue_product = uaa->product;
- sc->aue_vendor = uaa->vendor;
-
- id = usbd_get_interface_descriptor(sc->aue_iface);
-
- /* Find endpoints. */
- for (i = 0; i < id->bNumEndpoints; i++) {
- ed = usbd_interface2endpoint_descriptor(iface, i);
- if (ed == NULL) {
- device_printf(self, "couldn't get ep %d\n", i);
- return ENXIO;
- }
- 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;
- }
- }
-
- mtx_init(&sc->aue_mtx, device_get_nameunit(self), MTX_NETWORK_LOCK,
- MTX_DEF | MTX_RECURSE);
- sx_init(&sc->aue_sx, device_get_nameunit(self));
- TASK_INIT(&sc->aue_task, 0, aue_task, sc);
- usb_ether_task_init(self, 0, &sc->aue_taskqueue);
- AUE_SXLOCK(sc);
-
- /* Reset the adapter. */
- aue_reset(sc);
-
- /*
- * Get station address from the EEPROM.
- */
- aue_read_eeprom(sc, (caddr_t)&eaddr, 0, 3, 0);
-
- ifp = sc->aue_ifp = if_alloc(IFT_ETHER);
- if (ifp == NULL) {
- device_printf(self, "can not if_alloc()\n");
- AUE_SXUNLOCK(sc);
- mtx_destroy(&sc->aue_mtx);
- sx_destroy(&sc->aue_sx);
- usb_ether_task_destroy(&sc->aue_taskqueue);
- return ENXIO;
- }
- ifp->if_softc = sc;
- if_initname(ifp, "aue", sc->aue_unit);
- 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_init = aue_init;
- IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
- ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
- IFQ_SET_READY(&ifp->if_snd);
-
- /*
- * 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 children 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)) {
- device_printf(self, "MII without any PHY!\n");
- if_free(ifp);
- AUE_SXUNLOCK(sc);
- mtx_destroy(&sc->aue_mtx);
- sx_destroy(&sc->aue_sx);
- usb_ether_task_destroy(&sc->aue_taskqueue);
- return ENXIO;
- }
-
- sc->aue_qdat.ifp = ifp;
- sc->aue_qdat.if_rxstart = aue_rxstart;
-
- /*
- * Call MI attach routine.
- */
- ether_ifattach(ifp, eaddr);
- usb_register_netisr();
- sc->aue_dying = 0;
- sc->aue_link = 1;
-
- AUE_SXUNLOCK(sc);
- return 0;
-}
-
-static int
-aue_detach(device_t dev)
-{
- struct aue_softc *sc;
- struct ifnet *ifp;
-
- sc = device_get_softc(dev);
- AUE_SXLOCK(sc);
- ifp = sc->aue_ifp;
- ether_ifdetach(ifp);
- sc->aue_dying = 1;
- AUE_SXUNLOCK(sc);
- callout_drain(&sc->aue_tick_callout);
- usb_ether_task_drain(&sc->aue_taskqueue, &sc->aue_task);
- usb_ether_task_destroy(&sc->aue_taskqueue);
- if_free(ifp);
-
- if (sc->aue_ep[AUE_ENDPT_TX] != NULL)
- usbd_abort_pipe(sc->aue_ep[AUE_ENDPT_TX]);
- if (sc->aue_ep[AUE_ENDPT_RX] != NULL)
- usbd_abort_pipe(sc->aue_ep[AUE_ENDPT_RX]);
-#ifdef AUE_INTR_PIPE
- if (sc->aue_ep[AUE_ENDPT_INTR] != NULL)
- usbd_abort_pipe(sc->aue_ep[AUE_ENDPT_INTR]);
-#endif
-
- mtx_destroy(&sc->aue_mtx);
- sx_destroy(&sc->aue_sx);
-
- return (0);
-}
-
-static void
-aue_rxstart(struct ifnet *ifp)
-{
- struct aue_softc *sc = ifp->if_softc;
- aue_task_sched(sc, AUE_TASK_RXSTART);
-}
-
-static void
-aue_rxstart_thread(struct aue_softc *sc)
-{
- struct ue_chain *c;
- struct ifnet *ifp;
-
- ifp = sc->aue_ifp;
-
- sc = ifp->if_softc;
- AUE_SXASSERTLOCKED(sc);
- c = &sc->aue_cdata.ue_rx_chain[sc->aue_cdata.ue_rx_prod];
-
- c->ue_mbuf = usb_ether_newbuf();
- if (c->ue_mbuf == NULL) {
- device_printf(sc->aue_dev, "no memory for rx list -- packet "
- "dropped!\n");
- ifp->if_ierrors++;
- AUE_UNLOCK(sc);
- return;
- }
-
- /* Setup new transfer. */
- usbd_setup_xfer(c->ue_xfer, sc->aue_ep[AUE_ENDPT_RX],
- c, mtod(c->ue_mbuf, char *), UE_BUFSZ, USBD_SHORT_XFER_OK,
- USBD_NO_TIMEOUT, aue_rxeof);
- usbd_transfer(c->ue_xfer);
-
- return;
-}
-
-/*
- * A frame has been uploaded: pass the resulting mbuf chain up to
- * the higher level protocols.
- */
-static void
-aue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- struct ue_chain *c = priv;
- c->ue_status = status;
- aue_task_sched(c->ue_sc, AUE_TASK_RXEOF);
-}
-
-static void
-aue_rxeof_thread(struct aue_softc *sc)
-{
- struct ue_chain *c = &(sc->aue_cdata.ue_rx_chain[0]);
- struct mbuf *m;
- struct ifnet *ifp;
- int total_len = 0;
- struct aue_rxpkt r;
- usbd_status status = c->ue_status;
-
-
- AUE_SXASSERTLOCKED(sc);
- ifp = sc->aue_ifp;
-
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
- return;
- }
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
- return;
- }
- if (usbd_ratecheck(&sc->aue_rx_notice))
- device_printf(sc->aue_dev, "usb error on rx: %s\n",
- usbd_errstr(status));
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall(sc->aue_ep[AUE_ENDPT_RX]);
- goto done;
- }
-
- usbd_get_xfer_status(c->ue_xfer, NULL, NULL, &total_len, NULL);
-
- if (total_len <= 4 + ETHER_CRC_LEN) {
- ifp->if_ierrors++;
- goto done;
- }
-
- m = c->ue_mbuf;
- bcopy(mtod(m, char *) + total_len - 4, (char *)&r, 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. */
- total_len -= (4 + ETHER_CRC_LEN);
-
- ifp->if_ipackets++;
- m->m_pkthdr.rcvif = (void *)&sc->aue_qdat;
- m->m_pkthdr.len = m->m_len = total_len;
-
- /* Put the packet on the special USB input queue. */
- usb_ether_input(m);
- return;
-done:
-
- /* Setup new transfer. */
- usbd_setup_xfer(c->ue_xfer, sc->aue_ep[AUE_ENDPT_RX],
- c, mtod(c->ue_mbuf, char *), UE_BUFSZ, USBD_SHORT_XFER_OK,
- USBD_NO_TIMEOUT, aue_rxeof);
- usbd_transfer(c->ue_xfer);
-
- return;
-}
-
-/*
- * A frame was downloaded to the chip. It's safe for us to clean up
- * the list buffers.
- */
-
-static void
-aue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- struct ue_chain *c = priv;
- c->ue_status = status;
- aue_task_sched(c->ue_sc, AUE_TASK_TXEOF);
-}
-
-static void
-aue_txeof_thread(struct aue_softc *sc)
-{
- struct ue_chain *c = &(sc->aue_cdata.ue_tx_chain[0]);
- struct ifnet *ifp;
- usbd_status err, status;
-
- AUE_SXASSERTLOCKED(sc);
- status = c->ue_status;
- ifp = sc->aue_ifp;
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
- return;
- }
- device_printf(sc->aue_dev, "usb error on tx: %s\n",
- usbd_errstr(status));
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall(sc->aue_ep[AUE_ENDPT_TX]);
- return;
- }
-
- sc->aue_timer = 0;
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &err);
-
- if (c->ue_mbuf != NULL) {
- c->ue_mbuf->m_pkthdr.rcvif = ifp;
- usb_tx_done(c->ue_mbuf);
- c->ue_mbuf = NULL;
- }
-
- if (err)
- ifp->if_oerrors++;
- else
- ifp->if_opackets++;
-
- return;
-}
-
-static void
-aue_tick(void *xsc)
-{
- struct aue_softc *sc = xsc;
-
- aue_task_sched(sc, AUE_TASK_TICK);
-}
-
-static void
-aue_tick_thread(struct aue_softc *sc)
-{
- struct ifnet *ifp;
- struct mii_data *mii;
-
- AUE_SXASSERTLOCKED(sc);
- ifp = sc->aue_ifp;
- /*
- * If a timer is set (non-zero) then decrement it
- * and if it hits zero, then call the watchdog routine.
- */
- if (sc->aue_timer != 0 && --sc->aue_timer == 0) {
- aue_watchdog(sc);
- }
- if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
- return;
- }
-
- mii = GET_MII(sc);
- if (mii == NULL) {
- goto resched;
- }
-
- mii_tick(mii);
- if (!sc->aue_link && mii->mii_media_status & IFM_ACTIVE &&
- IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
- sc->aue_link++;
- if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
- aue_start_thread(sc);
- }
-resched:
- (void) callout_reset(&sc->aue_tick_callout, hz, aue_tick, sc);
- return;
-}
-
-static int
-aue_encap(struct aue_softc *sc, struct mbuf *m, int idx)
-{
- int total_len;
- struct ue_chain *c;
- usbd_status err;
-
- AUE_SXASSERTLOCKED(sc);
-
- c = &sc->aue_cdata.ue_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->ue_buf + 2);
- c->ue_mbuf = m;
-
- total_len = m->m_pkthdr.len + 2;
-
- /*
- * 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->ue_buf[0] = (u_int8_t)m->m_pkthdr.len;
- c->ue_buf[1] = (u_int8_t)(m->m_pkthdr.len >> 8);
-
- usbd_setup_xfer(c->ue_xfer, sc->aue_ep[AUE_ENDPT_TX],
- c, c->ue_buf, total_len, USBD_FORCE_SHORT_XFER,
- 10000, aue_txeof);
-
- /* Transmit */
- err = usbd_transfer(c->ue_xfer);
- if (err != USBD_IN_PROGRESS) {
- aue_stop(sc);
- return (EIO);
- }
-
- sc->aue_cdata.ue_tx_cnt++;
-
- return (0);
-}
-
-
-static void
-aue_start(struct ifnet *ifp)
-{
- struct aue_softc *sc = ifp->if_softc;
- aue_task_sched(sc, AUE_TASK_START);
-}
-
-static void
-aue_start_thread(struct aue_softc *sc)
-{
- struct ifnet *ifp = sc->aue_ifp;
- struct mbuf *m_head = NULL;
-
- AUE_SXASSERTLOCKED(sc);
-
- if (!sc->aue_link) {
- return;
- }
-
- if (ifp->if_drv_flags & IFF_DRV_OACTIVE) {
- return;
- }
-
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
- if (m_head == NULL) {
- return;
- }
-
- if (aue_encap(sc, m_head, 0)) {
- IFQ_DRV_PREPEND(&ifp->if_snd, m_head);
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- return;
- }
-
- /*
- * If there's a BPF listener, bounce a copy of this frame
- * to him.
- */
- BPF_MTAP(ifp, m_head);
-
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
-
- /*
- * Set a timeout in case the chip goes out to lunch.
- */
- sc->aue_timer = 5;
-
- return;
-}
-
-static void
-aue_init(void *xsc)
-{
- struct aue_softc *sc = xsc;
-
- AUE_SXLOCK(sc);
- aue_init_body(sc);
- AUE_SXUNLOCK(sc);
-}
-
-static void
-aue_init_body(struct aue_softc *sc)
-{
- struct ifnet *ifp = sc->aue_ifp;
- struct mii_data *mii = GET_MII(sc);
- struct ue_chain *c;
- usbd_status err;
- int i;
-
- AUE_SXASSERTLOCKED(sc);
-
- if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
- return;
- }
-
- /*
- * Cancel pending I/O and free all RX/TX buffers.
- */
- aue_reset(sc);
-
- /* Set MAC address */
- for (i = 0; i < ETHER_ADDR_LEN; i++)
- aue_csr_write_1(sc, AUE_PAR0 + i, IF_LLADDR(sc->aue_ifp)[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 (usb_ether_tx_list_init(sc, &sc->aue_cdata,
- sc->aue_udev) == ENOBUFS) {
- device_printf(sc->aue_dev, "tx list init failed\n");
- return;
- }
-
- /* Init RX ring. */
- if (usb_ether_rx_list_init(sc, &sc->aue_cdata,
- sc->aue_udev) == ENOBUFS) {
- device_printf(sc->aue_dev, "rx list init failed\n");
- 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);
-
- /* 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) {
- device_printf(sc->aue_dev, "open rx pipe failed: %s\n",
- usbd_errstr(err));
- return;
- }
- err = usbd_open_pipe(sc->aue_iface, sc->aue_ed[AUE_ENDPT_TX],
- USBD_EXCLUSIVE_USE, &sc->aue_ep[AUE_ENDPT_TX]);
- if (err) {
- device_printf(sc->aue_dev, "open tx pipe failed: %s\n",
- usbd_errstr(err));
- return;
- }
-
-
- /* Start up the receive pipe. */
- for (i = 0; i < UE_RX_LIST_CNT; i++) {
- c = &sc->aue_cdata.ue_rx_chain[i];
- usbd_setup_xfer(c->ue_xfer, sc->aue_ep[AUE_ENDPT_RX],
- c, mtod(c->ue_mbuf, char *), UE_BUFSZ,
- USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, aue_rxeof);
- usbd_transfer(c->ue_xfer);
- }
-
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
-
- callout_init(&sc->aue_tick_callout, CALLOUT_MPSAFE);
- (void) callout_reset(&sc->aue_tick_callout, hz, aue_tick, sc);
- return;
-}
-
-/*
- * Set media options.
- */
-static int
-aue_ifmedia_upd(struct ifnet *ifp)
-{
- struct aue_softc *sc = ifp->if_softc;
- struct mii_data *mii = GET_MII(sc);
-
- sc->aue_link = 0;
- if (mii->mii_instance) {
- struct mii_softc *miisc;
- LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
- mii_phy_reset(miisc);
- }
- mii_mediachg(mii);
- sc->aue_link = 1;
-
- return (0);
-}
-
-/*
- * Report current media status.
- */
-static void
-aue_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
-{
- struct aue_softc *sc = ifp->if_softc;
- struct mii_data *mii = GET_MII(sc);
-
- mii_pollstat(mii);
- ifmr->ifm_active = mii->mii_media_active;
- ifmr->ifm_status = mii->mii_media_status;
-
- return;
-}
-
-static int
-aue_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
-{
- struct aue_softc *sc = ifp->if_softc;
- struct ifreq *ifr = (struct ifreq *)data;
- struct mii_data *mii;
- int error = 0;
-
- /*
- * This prevents recursion in the interface while it's
- * being torn down.
- */
- if (sc->aue_dying)
- return(0);
-
- AUE_GIANTLOCK();
-
- switch(command) {
- case SIOCSIFFLAGS:
- AUE_SXLOCK(sc);
- if (ifp->if_flags & IFF_UP) {
- if (ifp->if_drv_flags & IFF_DRV_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_drv_flags & IFF_DRV_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_drv_flags & IFF_DRV_RUNNING)) {
- aue_init_body(sc);
- }
- sc->aue_dying = 0;
- } else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- aue_stop(sc);
- }
- sc->aue_if_flags = ifp->if_flags;
- AUE_SXUNLOCK(sc);
- break;
- case SIOCADDMULTI:
- case SIOCDELMULTI:
- AUE_SXLOCK(sc);
- aue_setmulti(sc);
- AUE_SXUNLOCK(sc);
- break;
- case SIOCGIFMEDIA:
- case SIOCSIFMEDIA:
- AUE_SXLOCK(sc);
- mii = GET_MII(sc);
- error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
- AUE_SXUNLOCK(sc);
- break;
- default:
- error = ether_ioctl(ifp, command, data);
- break;
- }
-
- AUE_GIANTUNLOCK();
-
- return (error);
-}
-
-static void
-aue_watchdog(struct aue_softc *sc)
-{
- struct ifnet *ifp = sc->aue_ifp;
- struct ue_chain *c;
- usbd_status stat;
-
- AUE_SXASSERTLOCKED(sc);
- ifp->if_oerrors++;
- device_printf(sc->aue_dev, "watchdog timeout\n");
-
- c = &sc->aue_cdata.ue_tx_chain[0];
- usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &stat);
- c->ue_status = stat;
- aue_txeof_thread(sc);
-
- if (!IFQ_IS_EMPTY(&ifp->if_snd))
- aue_start_thread(sc);
- return;
-}
-
-/*
- * Stop the adapter and free any mbufs allocated to the
- * RX and TX lists.
- */
-static void
-aue_stop(struct aue_softc *sc)
-{
- usbd_status err;
- struct ifnet *ifp;
-
- AUE_SXASSERTLOCKED(sc);
- ifp = sc->aue_ifp;
- sc->aue_timer = 0;
-
- aue_csr_write_1(sc, AUE_CTL0, 0);
- aue_csr_write_1(sc, AUE_CTL1, 0);
- aue_reset(sc);
- sc->aue_dying = 1;
-
- /* Stop transfers. */
- if (sc->aue_ep[AUE_ENDPT_RX] != NULL) {
- err = usbd_abort_pipe(sc->aue_ep[AUE_ENDPT_RX]);
- if (err) {
- device_printf(sc->aue_dev,
- "abort rx pipe failed: %s\n", usbd_errstr(err));
- }
- err = usbd_close_pipe(sc->aue_ep[AUE_ENDPT_RX]);
- if (err) {
- device_printf(sc->aue_dev,
- "close rx pipe failed: %s\n", 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) {
- device_printf(sc->aue_dev,
- "abort tx pipe failed: %s\n", usbd_errstr(err));
- }
- err = usbd_close_pipe(sc->aue_ep[AUE_ENDPT_TX]);
- if (err) {
- device_printf(sc->aue_dev,
- "close tx pipe failed: %s\n", usbd_errstr(err));
- }
- sc->aue_ep[AUE_ENDPT_TX] = NULL;
- }
-
-#ifdef AUE_INTR_PIPE
- if (sc->aue_ep[AUE_ENDPT_INTR] != NULL) {
- err = usbd_abort_pipe(sc->aue_ep[AUE_ENDPT_INTR]);
- if (err) {
- device_printf(sc->aue_dev,
- "abort intr pipe failed: %s\n", usbd_errstr(err));
- }
- err = usbd_close_pipe(sc->aue_ep[AUE_ENDPT_INTR]);
- if (err) {
- device_printf(sc->aue_dev,
- "close intr pipe failed: %s\n", usbd_errstr(err));
- }
- sc->aue_ep[AUE_ENDPT_INTR] = NULL;
- }
-#endif
-
- /* Free RX resources. */
- usb_ether_rx_list_free(&sc->aue_cdata);
- /* Free TX resources. */
- usb_ether_tx_list_free(&sc->aue_cdata);
-
-#ifdef AUE_INTR_PIPE
- free(sc->aue_cdata.ue_ibuf, M_USBDEV);
- sc->aue_cdata.ue_ibuf = NULL;
-#endif
-
- sc->aue_link = 0;
-
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
-
- return;
-}
-
-/*
- * Stop all chip I/O so that the kernel's probe routines don't
- * get confused by errant DMAs when rebooting.
- */
-static int
-aue_shutdown(device_t dev)
-{
- struct aue_softc *sc;
-
- sc = device_get_softc(dev);
- AUE_SXLOCK(sc);
- sc->aue_dying++;
- aue_reset(sc);
- aue_stop(sc);
- AUE_SXUNLOCK(sc);
-
- return (0);
-}
-
-static void
-aue_task_sched(struct aue_softc *sc, int task)
-{
-
- AUE_LOCK(sc);
- sc->aue_deferedtasks |= task;
- usb_ether_task_enqueue(&sc->aue_taskqueue, &sc->aue_task);
- AUE_UNLOCK(sc);
-}
-
-/*
- * We defer all interrupt operations to this function.
- *
- * This allows us to do more complex operations, such as synchronous
- * usb io that normally would not be allowed from interrupt context.
- */
-static void
-aue_task(void *arg, int pending)
-{
- struct aue_softc *sc = arg;
- int tasks;
-
- for ( ;; ) {
- AUE_LOCK(sc);
- tasks = sc->aue_deferedtasks;
- sc->aue_deferedtasks = 0;
- AUE_UNLOCK(sc);
-
- if (tasks == 0)
- break;
-
- AUE_GIANTLOCK(); // XXX: usb not giant safe
- AUE_SXLOCK(sc);
- if (sc->aue_dying) {
- AUE_SXUNLOCK(sc);
- break;
- }
- if ((tasks & AUE_TASK_TICK) != 0) {
- aue_tick_thread(sc);
- }
- if ((tasks & AUE_TASK_START) != 0) {
- aue_start_thread(sc);
- }
- if ((tasks & AUE_TASK_RXSTART) != 0) {
- aue_rxstart_thread(sc);
- }
- if ((tasks & AUE_TASK_RXEOF) != 0) {
- aue_rxeof_thread(sc);
- }
- if ((tasks & AUE_TASK_TXEOF) != 0) {
- aue_txeof_thread(sc);
- }
- AUE_SXUNLOCK(sc);
- AUE_GIANTUNLOCK(); // XXX: usb not giant safe
- }
-}
-
diff --git a/sys/dev/usb/if_auereg.h b/sys/dev/usb/if_auereg.h
deleted file mode 100644
index 18cc0f4..0000000
--- a/sys/dev/usb/if_auereg.h
+++ /dev/null
@@ -1,294 +0,0 @@
-/*-
- * Copyright (c) 1997, 1998, 1999
- * Bill Paul <wpaul@ee.columbia.edu>. All rights reserved.
- *
- * Copyright (c) 2006
- * Alfred Perlstein <alfred@freebsd.org>. 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$
- */
-
-/*
- * 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.
- */
-
-#ifndef AUEREG_H
-#define AUEREG_H
-
-#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_INTR_PKTLEN 0x8
-
-#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_REG_1D 0x1D
-#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_REG_7B 0x7B
-#define AUE_GPIO0 0x7E
-#define AUE_GPIO1 0x7F
-#define AUE_REG_81 0x81
-
-#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;
-};
-
-struct aue_rxpkt {
- u_int16_t aue_pktlen;
- u_int8_t 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
-
-#define AUE_INC(x, y) (x) = (x + 1) % y
-
-struct aue_softc {
-#if defined(__FreeBSD__)
-#define GET_MII(sc) (device_get_softc((sc)->aue_miibus))
-#elif defined(__NetBSD__)
-#define GET_MII(sc) (&(sc)->aue_mii)
-#elif defined(__OpenBSD__)
-#define GET_MII(sc) (&(sc)->aue_mii)
-#endif
- struct ifnet *aue_ifp;
- device_t aue_dev;
- device_t aue_miibus;
- 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];
- int aue_unit;
- u_int8_t aue_link;
- int aue_timer;
- int aue_if_flags;
- struct ue_cdata aue_cdata;
- struct callout aue_tick_callout;
- struct usb_taskqueue aue_taskqueue;
- struct task aue_task;
- struct mtx aue_mtx;
- struct sx aue_sx;
- u_int16_t aue_flags;
- char aue_dying;
- struct timeval aue_rx_notice;
- struct usb_qdat aue_qdat;
- int aue_deferedtasks;
-};
-
-#if 0
-/*
- * Some debug code to make sure we don't take a blocking lock in
- * interrupt context.
- */
-#include <sys/types.h>
-#include <sys/proc.h>
-#include <sys/kdb.h>
-
-#define AUE_DUMPSTATE(tag) aue_dumpstate(__func__, tag)
-
-static inline void
-aue_dumpstate(const char *func, const char *tag)
-{
- if ((curthread->td_pflags & TDP_NOSLEEPING) ||
- (curthread->td_pflags & TDP_ITHREAD)) {
- kdb_backtrace();
- printf("%s: %s sleep: %sok ithread: %s\n", func, tag,
- curthread->td_pflags & TDP_NOSLEEPING ? "not" : "",
- curthread->td_pflags & TDP_ITHREAD ? "yes" : "no");
- }
-}
-#else
-#define AUE_DUMPSTATE(tag)
-#endif
-
-#define AUE_LOCK(_sc) mtx_lock(&(_sc)->aue_mtx)
-#define AUE_UNLOCK(_sc) mtx_unlock(&(_sc)->aue_mtx)
-#define AUE_SXLOCK(_sc) \
- do { AUE_DUMPSTATE("sxlock"); sx_xlock(&(_sc)->aue_sx); } while(0)
-#define AUE_SXUNLOCK(_sc) sx_xunlock(&(_sc)->aue_sx)
-#define AUE_SXASSERTLOCKED(_sc) sx_assert(&(_sc)->aue_sx, SX_XLOCKED)
-#define AUE_SXASSERTUNLOCKED(_sc) sx_assert(&(_sc)->aue_sx, SX_UNLOCKED)
-
-#define AUE_TIMEOUT 1000
-#define AUE_MIN_FRAMELEN 60
-#define AUE_INTR_INTERVAL 100 /* ms */
-
-/*
- * These bits are used to notify the task about pending events.
- * The names correspond to the interrupt context routines that would
- * be normally called. (example: AUE_TASK_WATCHDOG -> aue_watchdog())
- */
-#define AUE_TASK_WATCHDOG 0x0001
-#define AUE_TASK_TICK 0x0002
-#define AUE_TASK_START 0x0004
-#define AUE_TASK_RXSTART 0x0008
-#define AUE_TASK_RXEOF 0x0010
-#define AUE_TASK_TXEOF 0x0020
-
-#define AUE_GIANTLOCK() mtx_lock(&Giant);
-#define AUE_GIANTUNLOCK() mtx_unlock(&Giant);
-
-#endif /* !AUEREG_H */
diff --git a/sys/dev/usb/if_axe.c b/sys/dev/usb/if_axe.c
deleted file mode 100644
index 65da32b..0000000
--- a/sys/dev/usb/if_axe.c
+++ /dev/null
@@ -1,1428 +0,0 @@
-/*-
- * Copyright (c) 1997, 1998, 1999, 2000-2003
- * Bill Paul <wpaul@windriver.com>. 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * ASIX Electronics AX88172/AX88178/AX88778 USB 2.0 ethernet driver.
- * Used in the LinkSys USB200M and various other adapters.
- *
- * Manuals available from:
- * http://www.asix.com.tw/datasheet/mac/Ax88172.PDF
- * Note: you need the manual for the AX88170 chip (USB 1.x ethernet
- * controller) to find the definitions for the RX control register.
- * http://www.asix.com.tw/datasheet/mac/Ax88170.PDF
- *
- * Written by Bill Paul <wpaul@windriver.com>
- * Senior Engineer
- * Wind River Systems
- */
-
-/*
- * The AX88172 provides USB ethernet supports at 10 and 100Mbps.
- * It uses an external PHY (reference designs use a RealTek chip),
- * and has a 64-bit multicast hash filter. There is some information
- * missing from the manual which one needs to know in order to make
- * the chip function:
- *
- * - You must set bit 7 in the RX control register, otherwise the
- * chip won't receive any packets.
- * - You must initialize all 3 IPG registers, or you won't be able
- * to send any packets.
- *
- * Note that this device appears to only support loading the station
- * address via autload from the EEPROM (i.e. there's no way to manaully
- * set it).
- *
- * (Adam Weinberger wanted me to name this driver if_gir.c.)
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/endian.h>
-#include <sys/sockio.h>
-#include <sys/mbuf.h>
-#include <sys/malloc.h>
-#include <sys/lock.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/socket.h>
-#include <sys/sx.h>
-
-#include <net/if.h>
-#include <net/if_arp.h>
-#include <net/ethernet.h>
-#include <net/if_dl.h>
-#include <net/if_media.h>
-#include <net/if_types.h>
-
-#include <net/bpf.h>
-
-#include <sys/bus.h>
-#include <machine/bus.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include <dev/usb/usbdivar.h>
-#include "usbdevs.h"
-#include <dev/usb/usb_ethersubr.h>
-
-#include <dev/mii/mii.h>
-#include <dev/mii/miivar.h>
-
-/* "device miibus" required. See GENERIC if you get errors here. */
-#include "miibus_if.h"
-
-/*
- * AXE_178_MAX_FRAME_BURST
- * max frame burst size for Ax88178 and Ax88772
- * 0 2048 bytes
- * 1 4096 bytes
- * 2 8192 bytes
- * 3 16384 bytes
- * use the largest your system can handle without usb stalling.
- *
- * NB: 88772 parts appear to generate lots of input errors with
- * a 2K rx buffer and 8K is only slightly faster than 4K on an
- * EHCI port on a T42 so change at your own risk.
- */
-#define AXE_178_MAX_FRAME_BURST 1
-
-#include <dev/usb/if_axereg.h>
-
-/*
- * Various supported device vendors/products.
- */
-const struct axe_type axe_devs[] = {
- { { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_UF200}, 0 },
- { { USB_VENDOR_ACERCM, USB_PRODUCT_ACERCM_EP1427X2}, 0 },
- { { USB_VENDOR_APPLE, USB_PRODUCT_APPLE_ETHERNET}, AX772 },
- { { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88172}, 0 },
- { { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88772}, AX772 },
- { { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88178}, AX178 },
- { { USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC210T}, 0 },
- { { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D5055 }, AX178 },
- { { USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USB2AR}, 0},
- { { USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_USB200MV2}, AX772 },
- { { USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB2_TX }, 0},
- { { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUBE100}, 0 },
- { { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUBE100B1 }, AX772 },
- { { USB_VENDOR_GOODWAY, USB_PRODUCT_GOODWAY_GWUSB2E}, 0 },
- { { USB_VENDOR_IODATA, USB_PRODUCT_IODATA_ETGUS2 }, AX178 },
- { { USB_VENDOR_JVC, USB_PRODUCT_JVC_MP_PRX1}, 0 },
- { { USB_VENDOR_LINKSYS2, USB_PRODUCT_LINKSYS2_USB200M}, 0 },
- { { USB_VENDOR_LINKSYS4, USB_PRODUCT_LINKSYS4_USB1000 }, AX178 },
- { { USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUAU2KTX}, 0 },
- { { USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_FA120}, 0 },
- { { USB_VENDOR_OQO, USB_PRODUCT_OQO_ETHER01PLUS }, AX772 },
- { { USB_VENDOR_PLANEX3, USB_PRODUCT_PLANEX3_GU1000T }, AX178 },
- { { USB_VENDOR_SYSTEMTALKS, USB_PRODUCT_SYSTEMTALKS_SGCX2UL}, 0 },
- { { USB_VENDOR_SITECOM, USB_PRODUCT_SITECOM_LN029}, 0 },
- { { USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_LN028 }, AX178 }
-};
-
-#define axe_lookup(v, p) ((const struct axe_type *)usb_lookup(axe_devs, v, p))
-
-static device_probe_t axe_match;
-static device_attach_t axe_attach;
-static device_detach_t axe_detach;
-static device_shutdown_t axe_shutdown;
-static miibus_readreg_t axe_miibus_readreg;
-static miibus_writereg_t axe_miibus_writereg;
-static miibus_statchg_t axe_miibus_statchg;
-
-static int axe_encap(struct axe_softc *, struct mbuf *, int);
-static void axe_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
-static void axe_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
-static void axe_tick(void *);
-static void axe_tick_task(void *);
-static void axe_start(struct ifnet *);
-static int axe_ioctl(struct ifnet *, u_long, caddr_t);
-static void axe_init(void *);
-static void axe_stop(struct axe_softc *);
-static void axe_watchdog(struct ifnet *);
-static int axe_cmd(struct axe_softc *, int, int, int, void *);
-static int axe_ifmedia_upd(struct ifnet *);
-static void axe_ifmedia_sts(struct ifnet *, struct ifmediareq *);
-
-static void axe_setmulti(struct axe_softc *);
-
-static device_method_t axe_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, axe_match),
- DEVMETHOD(device_attach, axe_attach),
- DEVMETHOD(device_detach, axe_detach),
- DEVMETHOD(device_shutdown, axe_shutdown),
-
- /* bus interface */
- DEVMETHOD(bus_print_child, bus_generic_print_child),
- DEVMETHOD(bus_driver_added, bus_generic_driver_added),
-
- /* MII interface */
- DEVMETHOD(miibus_readreg, axe_miibus_readreg),
- DEVMETHOD(miibus_writereg, axe_miibus_writereg),
- DEVMETHOD(miibus_statchg, axe_miibus_statchg),
-
- { 0, 0 }
-};
-
-static driver_t axe_driver = {
- "axe",
- axe_methods,
- sizeof(struct axe_softc)
-};
-
-static devclass_t axe_devclass;
-
-DRIVER_MODULE(axe, uhub, axe_driver, axe_devclass, usbd_driver_load, 0);
-DRIVER_MODULE(miibus, axe, miibus_driver, miibus_devclass, 0, 0);
-MODULE_DEPEND(axe, usb, 1, 1, 1);
-MODULE_DEPEND(axe, miibus, 1, 1, 1);
-
-static int
-axe_cmd(struct axe_softc *sc, int cmd, int index, int val, void *buf)
-{
- usb_device_request_t req;
- usbd_status err;
-
- AXE_SLEEPLOCKASSERT(sc);
- if (sc->axe_dying)
- return(0);
-
- if (AXE_CMD_DIR(cmd))
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- else
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = AXE_CMD_CMD(cmd);
- USETW(req.wValue, val);
- USETW(req.wIndex, index);
- USETW(req.wLength, AXE_CMD_LEN(cmd));
-
- err = usbd_do_request(sc->axe_udev, &req, buf);
-
- if (err)
- return(-1);
-
- return(0);
-}
-
-static int
-axe_miibus_readreg(device_t dev, int phy, int reg)
-{
- struct axe_softc *sc = device_get_softc(dev);
- usbd_status err;
- u_int16_t val;
-
- if (sc->axe_dying)
- return(0);
-
- AXE_SLEEPLOCKASSERT(sc);
-#ifdef notdef
- /*
- * The chip tells us the MII address of any supported
- * PHYs attached to the chip, so only read from those.
- */
-
- if (sc->axe_phyaddrs[0] != AXE_NOPHY && phy != sc->axe_phyaddrs[0])
- return (0);
-
- if (sc->axe_phyaddrs[1] != AXE_NOPHY && phy != sc->axe_phyaddrs[1])
- return (0);
-#endif
- if (sc->axe_phyaddrs[0] != 0xFF && sc->axe_phyaddrs[0] != phy)
- return (0);
-
- AXE_LOCK(sc);
- axe_cmd(sc, AXE_CMD_MII_OPMODE_SW, 0, 0, NULL);
- err = axe_cmd(sc, AXE_CMD_MII_READ_REG, reg, phy, (void *)&val);
- axe_cmd(sc, AXE_CMD_MII_OPMODE_HW, 0, 0, NULL);
- AXE_UNLOCK(sc);
-
- if (err) {
- device_printf(sc->axe_dev, "read PHY failed\n");
- return(-1);
- }
-
- if (val && val != 0xffff)
- sc->axe_phyaddrs[0] = phy;
-
- return (le16toh(val));
-}
-
-static int
-axe_miibus_writereg(device_t dev, int phy, int reg, int val)
-{
- struct axe_softc *sc = device_get_softc(dev);
- usbd_status err;
-
- if (sc->axe_dying)
- return(0);
-
- AXE_SLEEPLOCKASSERT(sc);
- AXE_LOCK(sc);
- axe_cmd(sc, AXE_CMD_MII_OPMODE_SW, 0, 0, NULL);
- val = htole32(val);
- err = axe_cmd(sc, AXE_CMD_MII_WRITE_REG, reg, phy, (void *)&val);
- axe_cmd(sc, AXE_CMD_MII_OPMODE_HW, 0, 0, NULL);
- AXE_UNLOCK(sc);
-
- if (err) {
- device_printf(sc->axe_dev, "write PHY failed\n");
- return(-1);
- }
-
- return (0);
-}
-
-static void
-axe_miibus_statchg(device_t dev)
-{
- struct axe_softc *sc = device_get_softc(dev);
- struct mii_data *mii = GET_MII(sc);
- int val, err;
-
- val = (mii->mii_media_active & IFM_GMASK) == IFM_FDX ?
- AXE_MEDIA_FULL_DUPLEX : 0;
- if (sc->axe_flags & (AX178|AX772)) {
- val |= AXE_178_MEDIA_RX_EN | AXE_178_MEDIA_MAGIC;
-
- switch (IFM_SUBTYPE(mii->mii_media_active)) {
- case IFM_1000_T:
- val |= AXE_178_MEDIA_GMII | AXE_178_MEDIA_ENCK;
- break;
- case IFM_100_TX:
- val |= AXE_178_MEDIA_100TX;
- break;
- case IFM_10_T:
- /* doesn't need to be handled */
- break;
- }
- }
- err = axe_cmd(sc, AXE_CMD_WRITE_MEDIA, 0, val, NULL);
- if (err)
- device_printf(dev, "media change failed, error %d\n", err);
-}
-
-/*
- * Set media options.
- */
-static int
-axe_ifmedia_upd(struct ifnet *ifp)
-{
- struct axe_softc *sc = ifp->if_softc;
- struct mii_data *mii = GET_MII(sc);
-
- sc->axe_link = 0;
- if (mii->mii_instance) {
- struct mii_softc *miisc;
- LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
- mii_phy_reset(miisc);
- }
- mii_mediachg(mii);
-
- return (0);
-}
-
-/*
- * Report current media status.
- */
-static void
-axe_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
-{
- struct axe_softc *sc = ifp->if_softc;
- struct mii_data *mii = GET_MII(sc);
-
- mii_pollstat(mii);
- ifmr->ifm_active = mii->mii_media_active;
- ifmr->ifm_status = mii->mii_media_status;
-
- return;
-}
-
-static void
-axe_setmulti(struct axe_softc *sc)
-{
- struct ifnet *ifp;
- struct ifmultiaddr *ifma;
- u_int32_t h = 0;
- u_int16_t rxmode;
- u_int8_t hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
-
- ifp = sc->axe_ifp;
-
- AXE_LOCK(sc);
- axe_cmd(sc, AXE_CMD_RXCTL_READ, 0, 0, (void *)&rxmode);
- rxmode = le16toh(rxmode);
-
- if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
- rxmode |= AXE_RXCMD_ALLMULTI;
- axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL);
- AXE_UNLOCK(sc);
- return;
- } else
- rxmode &= ~AXE_RXCMD_ALLMULTI;
-
- IF_ADDR_LOCK(ifp);
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
- {
- if (ifma->ifma_addr->sa_family != AF_LINK)
- continue;
- h = ether_crc32_be(LLADDR((struct sockaddr_dl *)
- ifma->ifma_addr), ETHER_ADDR_LEN) >> 26;
- hashtbl[h / 8] |= 1 << (h % 8);
- }
- IF_ADDR_UNLOCK(ifp);
-
- axe_cmd(sc, AXE_CMD_WRITE_MCAST, 0, 0, (void *)&hashtbl);
- axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL);
- AXE_UNLOCK(sc);
-
- return;
-}
-
-static void
-axe_ax88178_init(struct axe_softc *sc)
-{
- int gpio0 = 0, phymode = 0;
- u_int16_t eeprom;
-
- axe_cmd(sc, AXE_CMD_SROM_WR_ENABLE, 0, 0, NULL);
- /* XXX magic */
- axe_cmd(sc, AXE_CMD_SROM_READ, 0, 0x0017, &eeprom);
- eeprom = le16toh(eeprom);
- axe_cmd(sc, AXE_CMD_SROM_WR_DISABLE, 0, 0, NULL);
-
- /* if EEPROM is invalid we have to use to GPIO0 */
- if (eeprom == 0xffff) {
- phymode = 0;
- gpio0 = 1;
- } else {
- phymode = eeprom & 7;
- gpio0 = (eeprom & 0x80) ? 0 : 1;
- }
-
- axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x008c, NULL);
- usbd_delay_ms(sc->axe_udev, 40);
- if ((eeprom >> 8) != 1) {
- axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x003c, NULL);
- usbd_delay_ms(sc->axe_udev, 30);
-
- axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x001c, NULL);
- usbd_delay_ms(sc->axe_udev, 300);
-
- axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x003c, NULL);
- usbd_delay_ms(sc->axe_udev, 30);
- } else {
- axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x0004, NULL);
- usbd_delay_ms(sc->axe_udev, 30);
- axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x000c, NULL);
- usbd_delay_ms(sc->axe_udev, 30);
- }
-
- /* soft reset */
- axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, 0, NULL);
- usbd_delay_ms(sc->axe_udev, 150);
- axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0,
- AXE_SW_RESET_PRL | AXE_178_RESET_MAGIC, NULL);
- usbd_delay_ms(sc->axe_udev, 150);
- axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL);
-}
-
-static void
-axe_ax88772_init(struct axe_softc *sc)
-{
- axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x00b0, NULL);
- usbd_delay_ms(sc->axe_udev, 40);
-
- if (sc->axe_phyaddrs[1] == AXE_INTPHY) {
- /* ask for embedded PHY */
- axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, 0x01, NULL);
- usbd_delay_ms(sc->axe_udev, 10);
-
- /* power down and reset state, pin reset state */
- axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_CLEAR, NULL);
- usbd_delay_ms(sc->axe_udev, 60);
-
- /* power down/reset state, pin operating state */
- axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0,
- AXE_SW_RESET_IPPD | AXE_SW_RESET_PRL, NULL);
- usbd_delay_ms(sc->axe_udev, 150);
-
- /* power up, reset */
- axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_PRL, NULL);
-
- /* power up, operating */
- axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0,
- AXE_SW_RESET_IPRL | AXE_SW_RESET_PRL, NULL);
- } else {
- /* ask for external PHY */
- axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, 0x00, NULL);
- usbd_delay_ms(sc->axe_udev, 10);
-
- /* power down/reset state, pin operating state */
- axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0,
- AXE_SW_RESET_IPPD | AXE_SW_RESET_PRL, NULL);
- }
-
- usbd_delay_ms(sc->axe_udev, 150);
- axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL);
-}
-
-static void
-axe_reset(struct axe_softc *sc)
-{
- if (sc->axe_dying)
- return;
-
- if (usbd_set_config_no(sc->axe_udev, AXE_CONFIG_NO, 1) ||
- usbd_device2interface_handle(sc->axe_udev, AXE_IFACE_IDX,
- &sc->axe_iface)) {
- device_printf(sc->axe_dev, "getting interface handle failed\n");
- }
-
- /* Wait a little while for the chip to get its brains in order. */
- DELAY(1000);
- return;
-}
-
-/*
- * Probe for a AX88172 chip.
- */
-static int
-axe_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
-
- if (!uaa->iface)
- return(UMATCH_NONE);
- return (axe_lookup(uaa->vendor, uaa->product) != NULL ?
- UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
-}
-
-/*
- * Attach the interface. Allocate softc structures, do ifmedia
- * setup and ethernet/BPF attach.
- */
-static int
-axe_attach(device_t self)
-{
- struct axe_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- const struct axe_type *type;
- u_char eaddr[ETHER_ADDR_LEN];
- struct ifnet *ifp;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
- int i;
-
- sc->axe_udev = uaa->device;
- sc->axe_dev = self;
- type = axe_lookup(uaa->vendor, uaa->product);
- if (type != NULL)
- sc->axe_flags = type->axe_flags;
-
- if (usbd_set_config_no(sc->axe_udev, AXE_CONFIG_NO, 1)) {
- device_printf(sc->axe_dev, "getting interface handle failed\n");
- return ENXIO;
- }
-
- usb_init_task(&sc->axe_tick_task, axe_tick_task, sc);
-
- if (usbd_device2interface_handle(uaa->device,
- AXE_IFACE_IDX, &sc->axe_iface)) {
- device_printf(sc->axe_dev, "getting interface handle failed\n");
- return ENXIO;
- }
-
- sc->axe_boundary = 64;
- if (sc->axe_flags & (AX178|AX772)) {
- if (sc->axe_udev->speed == USB_SPEED_HIGH) {
- sc->axe_bufsz = AXE_178_MAX_BUFSZ;
- sc->axe_boundary = 512;
- } else
- sc->axe_bufsz = AXE_178_MIN_BUFSZ;
- } else
- sc->axe_bufsz = AXE_172_BUFSZ;
-{ /* XXX debug */
-device_printf(sc->axe_dev, "%s, bufsz %d, boundary %d\n",
- sc->axe_flags & AX178 ? "AX88178" :
- sc->axe_flags & AX772 ? "AX88772" : "AX88172",
- sc->axe_bufsz, sc->axe_boundary);
-}
-
- id = usbd_get_interface_descriptor(sc->axe_iface);
-
- /* Find endpoints. */
- for (i = 0; i < id->bNumEndpoints; i++) {
- ed = usbd_interface2endpoint_descriptor(sc->axe_iface, i);
- if (!ed) {
- device_printf(sc->axe_dev, "couldn't get ep %d\n", i);
- return ENXIO;
- }
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
- sc->axe_ed[AXE_ENDPT_RX] = ed->bEndpointAddress;
- } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
- sc->axe_ed[AXE_ENDPT_TX] = ed->bEndpointAddress;
- } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
- sc->axe_ed[AXE_ENDPT_INTR] = ed->bEndpointAddress;
- }
- }
-
- mtx_init(&sc->axe_mtx, device_get_nameunit(self), MTX_NETWORK_LOCK,
- MTX_DEF | MTX_RECURSE);
- sx_init(&sc->axe_sleeplock, device_get_nameunit(self));
- AXE_SLEEPLOCK(sc);
- AXE_LOCK(sc);
-
- /* We need the PHYID for the init dance in some cases */
- axe_cmd(sc, AXE_CMD_READ_PHYID, 0, 0, (void *)&sc->axe_phyaddrs);
-
- if (sc->axe_flags & AX178)
- axe_ax88178_init(sc);
- else if (sc->axe_flags & AX772)
- axe_ax88772_init(sc);
-
- /*
- * Get station address.
- */
- if (sc->axe_flags & (AX178|AX772))
- axe_cmd(sc, AXE_178_CMD_READ_NODEID, 0, 0, &eaddr);
- else
- axe_cmd(sc, AXE_172_CMD_READ_NODEID, 0, 0, &eaddr);
-
- /*
- * Fetch IPG values.
- */
- axe_cmd(sc, AXE_CMD_READ_IPG012, 0, 0, (void *)&sc->axe_ipgs);
-
- /*
- * Work around broken adapters that appear to lie about
- * their PHY addresses.
- */
- sc->axe_phyaddrs[0] = sc->axe_phyaddrs[1] = 0xFF;
-
- ifp = sc->axe_ifp = if_alloc(IFT_ETHER);
- if (ifp == NULL) {
- device_printf(sc->axe_dev, "can not if_alloc()\n");
- AXE_UNLOCK(sc);
- AXE_SLEEPUNLOCK(sc);
- sx_destroy(&sc->axe_sleeplock);
- mtx_destroy(&sc->axe_mtx);
- return ENXIO;
- }
- ifp->if_softc = sc;
- if_initname(ifp, "axe", device_get_unit(sc->axe_dev));
- ifp->if_mtu = ETHERMTU;
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
- IFF_NEEDSGIANT;
- ifp->if_ioctl = axe_ioctl;
- ifp->if_start = axe_start;
- ifp->if_watchdog = axe_watchdog;
- ifp->if_init = axe_init;
- IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
- ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
- IFQ_SET_READY(&ifp->if_snd);
-
- if (mii_phy_probe(self, &sc->axe_miibus,
- axe_ifmedia_upd, axe_ifmedia_sts)) {
- device_printf(sc->axe_dev, "MII without any PHY!\n");
- if_free(ifp);
- AXE_UNLOCK(sc);
- AXE_SLEEPUNLOCK(sc);
- sx_destroy(&sc->axe_sleeplock);
- mtx_destroy(&sc->axe_mtx);
- return ENXIO;
- }
-
- /*
- * Call MI attach routine.
- */
-
- ether_ifattach(ifp, eaddr);
- callout_handle_init(&sc->axe_stat_ch);
- usb_register_netisr();
-
- sc->axe_dying = 0;
-
- AXE_UNLOCK(sc);
- AXE_SLEEPUNLOCK(sc);
-
- return 0;
-}
-
-static int
-axe_detach(device_t dev)
-{
- struct axe_softc *sc;
- struct ifnet *ifp;
-
- sc = device_get_softc(dev);
- AXE_LOCK(sc);
- ifp = sc->axe_ifp;
-
- sc->axe_dying = 1;
- untimeout(axe_tick, sc, sc->axe_stat_ch);
- usb_rem_task(sc->axe_udev, &sc->axe_tick_task);
-
- ether_ifdetach(ifp);
- if_free(ifp);
-
- if (sc->axe_ep[AXE_ENDPT_TX] != NULL)
- usbd_abort_pipe(sc->axe_ep[AXE_ENDPT_TX]);
- if (sc->axe_ep[AXE_ENDPT_RX] != NULL)
- usbd_abort_pipe(sc->axe_ep[AXE_ENDPT_RX]);
- if (sc->axe_ep[AXE_ENDPT_INTR] != NULL)
- usbd_abort_pipe(sc->axe_ep[AXE_ENDPT_INTR]);
-
- AXE_UNLOCK(sc);
- sx_destroy(&sc->axe_sleeplock);
- mtx_destroy(&sc->axe_mtx);
-
- return(0);
-}
-
-static int
-axe_rx_list_init(struct axe_softc *sc)
-{
- struct axe_cdata *cd;
- struct axe_chain *c;
- int i;
-
- cd = &sc->axe_cdata;
- for (i = 0; i < AXE_RX_LIST_CNT; i++) {
- c = &cd->axe_rx_chain[i];
- c->axe_sc = sc;
- c->axe_idx = i;
- c->axe_mbuf = NULL;
- if (c->axe_xfer == NULL) {
- c->axe_xfer = usbd_alloc_xfer(sc->axe_udev);
- if (c->axe_xfer == NULL)
- return (ENOBUFS);
- c->axe_buf = usbd_alloc_buffer(c->axe_xfer,
- sc->axe_bufsz);
- if (c->axe_buf == NULL) {
- usbd_free_xfer(c->axe_xfer);
- return (ENOBUFS);
- }
- }
- }
-
- return (0);
-}
-
-static void
-axe_rx_list_free(struct axe_softc *sc)
-{
- int i;
-
- for (i = 0; i < AXE_RX_LIST_CNT; i++) {
- if (sc->axe_cdata.axe_rx_chain[i].axe_mbuf != NULL) {
- m_freem(sc->axe_cdata.axe_rx_chain[i].axe_mbuf);
- sc->axe_cdata.axe_rx_chain[i].axe_mbuf = NULL;
- }
- if (sc->axe_cdata.axe_rx_chain[i].axe_xfer != NULL) {
- usbd_free_xfer(sc->axe_cdata.axe_rx_chain[i].axe_xfer);
- sc->axe_cdata.axe_rx_chain[i].axe_xfer = NULL;
- }
- }
-}
-
-static int
-axe_tx_list_init(struct axe_softc *sc)
-{
- struct axe_cdata *cd;
- struct axe_chain *c;
- int i;
-
- cd = &sc->axe_cdata;
- for (i = 0; i < AXE_TX_LIST_CNT; i++) {
- c = &cd->axe_tx_chain[i];
- c->axe_sc = sc;
- c->axe_idx = i;
- c->axe_mbuf = NULL;
- if (c->axe_xfer == NULL) {
- c->axe_xfer = usbd_alloc_xfer(sc->axe_udev);
- if (c->axe_xfer == NULL)
- return (ENOBUFS);
- c->axe_buf = usbd_alloc_buffer(c->axe_xfer,
- sc->axe_bufsz);
- if (c->axe_buf == NULL) {
- usbd_free_xfer(c->axe_xfer);
- return (ENOBUFS);
- }
- }
- }
-
- return (0);
-}
-
-static void
-axe_tx_list_free(struct axe_softc *sc)
-{
- int i;
-
- /* Free TX resources. */
- for (i = 0; i < AXE_TX_LIST_CNT; i++) {
- if (sc->axe_cdata.axe_tx_chain[i].axe_mbuf != NULL) {
- m_freem(sc->axe_cdata.axe_tx_chain[i].axe_mbuf);
- sc->axe_cdata.axe_tx_chain[i].axe_mbuf = NULL;
- }
- if (sc->axe_cdata.axe_tx_chain[i].axe_xfer != NULL) {
- usbd_free_xfer(sc->axe_cdata.axe_tx_chain[i].axe_xfer);
- sc->axe_cdata.axe_tx_chain[i].axe_xfer = NULL;
- }
- }
-}
-
-/*
- * A frame has been uploaded: pass the resulting mbuf chain up to
- * the higher level protocols.
- */
-static void
-axe_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- struct axe_softc *sc;
- struct axe_chain *c = (struct axe_chain *) priv;
- struct mbuf *m;
- u_char *buf;
- struct ifnet *ifp;
- struct axe_sframe_hdr *hdr;
- int total_len = 0;
- int pktlen = 0;
-
- sc = c->axe_sc;
- AXE_LOCK(sc);
- ifp = sc->axe_ifp;
-
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
- AXE_UNLOCK(sc);
- return;
- }
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
- AXE_UNLOCK(sc);
- return;
- }
- if (usbd_ratecheck(&sc->axe_rx_notice))
- device_printf(sc->axe_dev, "usb error on rx: %s\n",
- usbd_errstr(status));
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall(sc->axe_ep[AXE_ENDPT_RX]);
- goto done;
- }
-
- usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
-
- buf = c->axe_buf;
-
- do {
- if (sc->axe_flags & (AX178|AX772)) {
- if (total_len < sizeof(struct axe_sframe_hdr)) {
- ifp->if_ierrors++;
- goto done;
- }
- if ((pktlen % 2) != 0)
- pktlen++;
- buf += pktlen;
-
- hdr = (struct axe_sframe_hdr *) buf;
- total_len -= sizeof(struct axe_sframe_hdr);
- if ((hdr->len ^ hdr->ilen) != 0xffff) {
- ifp->if_ierrors++;
- goto done;
- }
- pktlen = le16toh(hdr->len);
- if (pktlen > total_len) {
- ifp->if_ierrors++;
- goto done;
- }
-
- buf += sizeof(struct axe_sframe_hdr);
- total_len -= pktlen + (pktlen % 2);
- } else {
- pktlen = total_len;
- total_len = 0;
- }
-
- if (pktlen < sizeof(struct ether_header)) {
- ifp->if_ierrors++;
- goto done;
- }
- m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
- if (m == NULL) {
- ifp->if_ierrors++;
- goto done;
- }
- m->m_data += ETHER_ALIGN;
- memcpy(mtod(m, void *), buf, pktlen);
- m->m_pkthdr.len = m->m_len = pktlen;
- m->m_pkthdr.rcvif = ifp;
-
- ifp->if_input(ifp, m);
- ifp->if_ipackets++;
- } while (total_len > 0);
- /* fall thru... */
-done:
- /* Setup new transfer. */
- usbd_setup_xfer(xfer, sc->axe_ep[AXE_ENDPT_RX],
- c, c->axe_buf, sc->axe_bufsz, USBD_SHORT_XFER_OK | USBD_NO_COPY,
- USBD_NO_TIMEOUT, axe_rxeof);
- usbd_transfer(xfer);
- AXE_UNLOCK(sc);
-
- return;
-}
-
-/*
- * A frame was downloaded to the chip. It's safe for us to clean up
- * the list buffers.
- */
-
-static void
-axe_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- struct axe_softc *sc;
- struct axe_chain *c;
- struct ifnet *ifp;
- usbd_status err;
-
- c = priv;
- sc = c->axe_sc;
- AXE_LOCK(sc);
- ifp = sc->axe_ifp;
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
- AXE_UNLOCK(sc);
- return;
- }
- device_printf(sc->axe_dev, "usb error on tx: %s\n",
- usbd_errstr(status));
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall(sc->axe_ep[AXE_ENDPT_TX]);
- AXE_UNLOCK(sc);
- return;
- }
-
- ifp->if_timer = 0;
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- usbd_get_xfer_status(c->axe_xfer, NULL, NULL, NULL, &err);
-
- if (c->axe_mbuf != NULL) {
- m_freem(c->axe_mbuf);
- c->axe_mbuf = NULL;
- }
-
- if (err)
- ifp->if_oerrors++;
- else
- ifp->if_opackets++;
-
- AXE_UNLOCK(sc);
-
- if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
- axe_start(ifp);
-
- return;
-}
-
-static void
-axe_tick(void *xsc)
-{
- struct axe_softc *sc = xsc;
-
- if (sc == NULL)
- return;
- if (sc->axe_dying)
- return;
-
- /* Perform periodic stuff in process context */
- usb_add_task(sc->axe_udev, &sc->axe_tick_task, USB_TASKQ_DRIVER);
-}
-
-static void
-axe_tick_task(void *xsc)
-{
- struct axe_softc *sc;
- struct ifnet *ifp;
- struct mii_data *mii;
-
- sc = xsc;
-
- if (sc == NULL)
- return;
-
- AXE_SLEEPLOCK(sc);
- AXE_LOCK(sc);
-
- ifp = sc->axe_ifp;
- mii = GET_MII(sc);
- if (mii == NULL) {
- AXE_UNLOCK(sc);
- AXE_SLEEPUNLOCK(sc);
- return;
- }
-
- mii_tick(mii);
- if (!sc->axe_link && mii->mii_media_status & IFM_ACTIVE &&
- IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
- sc->axe_link++;
- if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
- axe_start(ifp);
- }
-
- sc->axe_stat_ch = timeout(axe_tick, sc, hz);
-
- AXE_UNLOCK(sc);
- AXE_SLEEPUNLOCK(sc);
-
- return;
-}
-
-static int
-axe_encap(struct axe_softc *sc, struct mbuf *m, int idx)
-{
- struct axe_chain *c;
- usbd_status err;
- struct axe_sframe_hdr hdr;
- int length;
-
- c = &sc->axe_cdata.axe_tx_chain[idx];
-
- /*
- * Copy the mbuf data into a contiguous buffer, leaving two
- * bytes at the beginning to hold the frame length.
- */
- if (sc->axe_flags & (AX178|AX772)) {
- hdr.len = htole16(m->m_pkthdr.len);
- hdr.ilen = ~hdr.len;
-
- memcpy(c->axe_buf, &hdr, sizeof(hdr));
- length = sizeof(hdr);
-
- m_copydata(m, 0, m->m_pkthdr.len, c->axe_buf + length);
- length += m->m_pkthdr.len;
-
- if ((length % sc->axe_boundary) == 0) {
- hdr.len = 0;
- hdr.ilen = 0xffff;
- memcpy(c->axe_buf + length, &hdr, sizeof(hdr));
- length += sizeof(hdr);
- }
- } else {
- m_copydata(m, 0, m->m_pkthdr.len, c->axe_buf);
- length = m->m_pkthdr.len;
- }
- c->axe_mbuf = m;
-
- usbd_setup_xfer(c->axe_xfer, sc->axe_ep[AXE_ENDPT_TX],
- c, c->axe_buf, length, USBD_FORCE_SHORT_XFER, 10000, axe_txeof);
-
- /* Transmit */
- err = usbd_transfer(c->axe_xfer);
- if (err != USBD_IN_PROGRESS) {
- /* XXX probably don't want to sleep here */
- AXE_SLEEPLOCK(sc);
- axe_stop(sc);
- AXE_SLEEPUNLOCK(sc);
- return(EIO);
- }
-
- sc->axe_cdata.axe_tx_cnt++;
-
- return(0);
-}
-
-static void
-axe_start(struct ifnet *ifp)
-{
- struct axe_softc *sc;
- struct mbuf *m_head = NULL;
-
- sc = ifp->if_softc;
- AXE_LOCK(sc);
-
- if (!sc->axe_link) {
- AXE_UNLOCK(sc);
- return;
- }
-
- if (ifp->if_drv_flags & IFF_DRV_OACTIVE) {
- AXE_UNLOCK(sc);
- return;
- }
-
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
- if (m_head == NULL) {
- AXE_UNLOCK(sc);
- return;
- }
-
- if (axe_encap(sc, m_head, 0)) {
- IFQ_DRV_PREPEND(&ifp->if_snd, m_head);
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- AXE_UNLOCK(sc);
- return;
- }
-
- /*
- * If there's a BPF listener, bounce a copy of this frame
- * to him.
- */
- BPF_MTAP(ifp, m_head);
-
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
-
- /*
- * Set a timeout in case the chip goes out to lunch.
- */
- ifp->if_timer = 5;
- AXE_UNLOCK(sc);
-
- return;
-}
-
-static void
-axe_init(void *xsc)
-{
- struct axe_softc *sc = xsc;
- struct ifnet *ifp = sc->axe_ifp;
- struct axe_chain *c;
- usbd_status err;
- int i;
- int rxmode;
-
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- return;
-
- AXE_SLEEPLOCK(sc);
- AXE_LOCK(sc);
-
- /*
- * Cancel pending I/O and free all RX/TX buffers.
- */
-
- axe_reset(sc);
-
-#ifdef notdef
- /* Set MAC address */
- axe_mac(sc, IF_LLADDR(sc->axe_ifp), 1);
-#endif
-
- /* Enable RX logic. */
-
- /* Init TX ring. */
- if (axe_tx_list_init(sc) == ENOBUFS) {
- device_printf(sc->axe_dev, "tx list init failed\n");
- AXE_UNLOCK(sc);
- AXE_SLEEPUNLOCK(sc);
- return;
- }
-
- /* Init RX ring. */
- if (axe_rx_list_init(sc) == ENOBUFS) {
- device_printf(sc->axe_dev, "rx list init failed\n");
- AXE_UNLOCK(sc);
- AXE_SLEEPUNLOCK(sc);
- return;
- }
-
- /* Set transmitter IPG values */
- if (sc->axe_flags & (AX178|AX772)) {
- axe_cmd(sc, AXE_178_CMD_WRITE_IPG012, sc->axe_ipgs[2],
- (sc->axe_ipgs[1]<<8) | sc->axe_ipgs[0], NULL);
- } else {
- axe_cmd(sc, AXE_172_CMD_WRITE_IPG0, 0, sc->axe_ipgs[0], NULL);
- axe_cmd(sc, AXE_172_CMD_WRITE_IPG1, 0, sc->axe_ipgs[1], NULL);
- axe_cmd(sc, AXE_172_CMD_WRITE_IPG2, 0, sc->axe_ipgs[2], NULL);
- }
-
- /* Enable receiver, set RX mode */
- rxmode = AXE_RXCMD_MULTICAST|AXE_RXCMD_ENABLE;
- if (sc->axe_flags & (AX178|AX772)) {
- if (sc->axe_bufsz == AXE_178_MAX_BUFSZ)
- rxmode |= AXE_178_RXCMD_MFB;
- } else
- rxmode |= AXE_172_RXCMD_UNICAST;
-
- /* If we want promiscuous mode, set the allframes bit. */
- if (ifp->if_flags & IFF_PROMISC)
- rxmode |= AXE_RXCMD_PROMISC;
-
- if (ifp->if_flags & IFF_BROADCAST)
- rxmode |= AXE_RXCMD_BROADCAST;
-
- axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL);
-
- /* Load the multicast filter. */
- axe_setmulti(sc);
-
- /* Open RX and TX pipes. */
- err = usbd_open_pipe(sc->axe_iface, sc->axe_ed[AXE_ENDPT_RX],
- USBD_EXCLUSIVE_USE, &sc->axe_ep[AXE_ENDPT_RX]);
- if (err) {
- device_printf(sc->axe_dev, "open rx pipe failed: %s\n",
- usbd_errstr(err));
- AXE_UNLOCK(sc);
- AXE_SLEEPUNLOCK(sc);
- return;
- }
-
- err = usbd_open_pipe(sc->axe_iface, sc->axe_ed[AXE_ENDPT_TX],
- USBD_EXCLUSIVE_USE, &sc->axe_ep[AXE_ENDPT_TX]);
- if (err) {
- device_printf(sc->axe_dev, "open tx pipe failed: %s\n",
- usbd_errstr(err));
- AXE_UNLOCK(sc);
- AXE_SLEEPUNLOCK(sc);
- return;
- }
-
- /* Start up the receive pipe. */
- for (i = 0; i < AXE_RX_LIST_CNT; i++) {
- c = &sc->axe_cdata.axe_rx_chain[i];
- usbd_setup_xfer(c->axe_xfer, sc->axe_ep[AXE_ENDPT_RX],
- c, c->axe_buf, sc->axe_bufsz,
- USBD_SHORT_XFER_OK | USBD_NO_COPY,
- USBD_NO_TIMEOUT, axe_rxeof);
- usbd_transfer(c->axe_xfer);
- }
-
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
-
- AXE_UNLOCK(sc);
- AXE_SLEEPUNLOCK(sc);
-
- sc->axe_stat_ch = timeout(axe_tick, sc, hz);
-
- return;
-}
-
-static int
-axe_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
-{
- struct axe_softc *sc = ifp->if_softc;
- struct ifreq *ifr = (struct ifreq *)data;
- struct mii_data *mii;
- u_int16_t rxmode;
- int error = 0;
-
- switch(command) {
- case SIOCSIFFLAGS:
- if (ifp->if_flags & IFF_UP) {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
- ifp->if_flags & IFF_PROMISC &&
- !(sc->axe_if_flags & IFF_PROMISC)) {
- AXE_SLEEPLOCK(sc);
- AXE_LOCK(sc);
- axe_cmd(sc, AXE_CMD_RXCTL_READ,
- 0, 0, (void *)&rxmode);
- rxmode = le16toh(rxmode);
- rxmode |= AXE_RXCMD_PROMISC;
- axe_cmd(sc, AXE_CMD_RXCTL_WRITE,
- 0, rxmode, NULL);
- AXE_UNLOCK(sc);
- axe_setmulti(sc);
- AXE_SLEEPUNLOCK(sc);
- } else if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
- !(ifp->if_flags & IFF_PROMISC) &&
- sc->axe_if_flags & IFF_PROMISC) {
- AXE_SLEEPLOCK(sc);
- AXE_LOCK(sc);
- axe_cmd(sc, AXE_CMD_RXCTL_READ,
- 0, 0, (void *)&rxmode);
- rxmode = le16toh(rxmode);
- rxmode &= ~AXE_RXCMD_PROMISC;
- axe_cmd(sc, AXE_CMD_RXCTL_WRITE,
- 0, rxmode, NULL);
- AXE_UNLOCK(sc);
- axe_setmulti(sc);
- AXE_SLEEPUNLOCK(sc);
- } else if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
- axe_init(sc);
- } else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
- AXE_SLEEPLOCK(sc);
- axe_stop(sc);
- AXE_SLEEPUNLOCK(sc);
- }
- }
- sc->axe_if_flags = ifp->if_flags;
- error = 0;
- break;
- case SIOCADDMULTI:
- case SIOCDELMULTI:
- AXE_SLEEPLOCK(sc);
- axe_setmulti(sc);
- AXE_SLEEPUNLOCK(sc);
- error = 0;
- break;
- case SIOCGIFMEDIA:
- case SIOCSIFMEDIA:
- AXE_SLEEPLOCK(sc);
- mii = GET_MII(sc);
- error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
- AXE_SLEEPUNLOCK(sc);
- break;
-
- default:
- error = ether_ioctl(ifp, command, data);
- break;
- }
-
- return(error);
-}
-
-static void
-axe_watchdog(struct ifnet *ifp)
-{
- struct axe_softc *sc;
- struct axe_chain *c;
- usbd_status stat;
-
- sc = ifp->if_softc;
- AXE_LOCK(sc);
-
- ifp->if_oerrors++;
- device_printf(sc->axe_dev, "watchdog timeout\n");
-
- c = &sc->axe_cdata.axe_tx_chain[0];
- usbd_get_xfer_status(c->axe_xfer, NULL, NULL, NULL, &stat);
- axe_txeof(c->axe_xfer, c, stat);
-
- AXE_UNLOCK(sc);
-
- if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
- axe_start(ifp);
-
- return;
-}
-
-/*
- * Stop the adapter and free any mbufs allocated to the
- * RX and TX lists.
- */
-static void
-axe_stop(struct axe_softc *sc)
-{
- usbd_status err;
- struct ifnet *ifp;
-
- AXE_SLEEPLOCKASSERT(sc);
- AXE_LOCK(sc);
-
- ifp = sc->axe_ifp;
- ifp->if_timer = 0;
-
- untimeout(axe_tick, sc, sc->axe_stat_ch);
-
- /* Stop transfers. */
- if (sc->axe_ep[AXE_ENDPT_RX] != NULL) {
- err = usbd_abort_pipe(sc->axe_ep[AXE_ENDPT_RX]);
- if (err) {
- device_printf(sc->axe_dev, "abort rx pipe failed: %s\n",
- usbd_errstr(err));
- }
- err = usbd_close_pipe(sc->axe_ep[AXE_ENDPT_RX]);
- if (err) {
- device_printf(sc->axe_dev, "close rx pipe failed: %s\n",
- usbd_errstr(err));
- }
- sc->axe_ep[AXE_ENDPT_RX] = NULL;
- }
-
- if (sc->axe_ep[AXE_ENDPT_TX] != NULL) {
- err = usbd_abort_pipe(sc->axe_ep[AXE_ENDPT_TX]);
- if (err) {
- device_printf(sc->axe_dev, "abort tx pipe failed: %s\n",
- usbd_errstr(err));
- }
- err = usbd_close_pipe(sc->axe_ep[AXE_ENDPT_TX]);
- if (err) {
- device_printf(sc->axe_dev, "close tx pipe failed: %s\n",
- usbd_errstr(err));
- }
- sc->axe_ep[AXE_ENDPT_TX] = NULL;
- }
-
- if (sc->axe_ep[AXE_ENDPT_INTR] != NULL) {
- err = usbd_abort_pipe(sc->axe_ep[AXE_ENDPT_INTR]);
- if (err) {
- device_printf(sc->axe_dev,
- "abort intr pipe failed: %s\n", usbd_errstr(err));
- }
- err = usbd_close_pipe(sc->axe_ep[AXE_ENDPT_INTR]);
- if (err) {
- device_printf(sc->axe_dev,
- "close intr pipe failed: %s\n", usbd_errstr(err));
- }
- sc->axe_ep[AXE_ENDPT_INTR] = NULL;
- }
-
- axe_reset(sc);
-
- /* Free RX resources. */
- axe_rx_list_free(sc);
- /* Free TX resources. */
- axe_tx_list_free(sc);
-
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
- sc->axe_link = 0;
- AXE_UNLOCK(sc);
-
- return;
-}
-
-/*
- * Stop all chip I/O so that the kernel's probe routines don't
- * get confused by errant DMAs when rebooting.
- */
-static int
-axe_shutdown(device_t dev)
-{
- struct axe_softc *sc;
-
- sc = device_get_softc(dev);
-
- AXE_SLEEPLOCK(sc);
- axe_stop(sc);
- AXE_SLEEPUNLOCK(sc);
-
- return (0);
-}
diff --git a/sys/dev/usb/if_axereg.h b/sys/dev/usb/if_axereg.h
deleted file mode 100644
index 4503b19..0000000
--- a/sys/dev/usb/if_axereg.h
+++ /dev/null
@@ -1,254 +0,0 @@
-/*-
- * Copyright (c) 1997, 1998, 1999, 2000-2003
- * Bill Paul <wpaul@windriver.com>. 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$
- */
-
-/*
- * Definitions for the ASIX Electronics AX88172 to ethernet controller.
- */
-
-
-/*
- * Vendor specific commands
- * ASIX conveniently doesn't document the 'set NODEID' command in their
- * datasheet (thanks a lot guys).
- * To make handling these commands easier, I added some extra data
- * which is decided by the axe_cmd() routine. Commands are encoded
- * in 16 bites, with the format: LDCC. L and D are both nibbles in
- * the high byte. L represents the data length (0 to 15) and D
- * represents the direction (0 for vendor read, 1 for vendor write).
- * CC is the command byte, as specified in the manual.
- */
-
-#define AXE_CMD_DIR(x) (((x) & 0x0F00) >> 8)
-#define AXE_CMD_LEN(x) (((x) & 0xF000) >> 12)
-#define AXE_CMD_CMD(x) ((x) & 0x00FF)
-
-#define AXE_172_CMD_READ_RXTX_SRAM 0x2002
-#define AXE_182_CMD_READ_RXTX_SRAM 0x8002
-#define AXE_172_CMD_WRITE_RX_SRAM 0x0103
-#define AXE_172_CMD_WRITE_TX_SRAM 0x0104
-#define AXE_182_CMD_WRITE_RXTX_SRAM 0x8103
-#define AXE_CMD_MII_OPMODE_SW 0x0106
-#define AXE_CMD_MII_READ_REG 0x2007
-#define AXE_CMD_MII_WRITE_REG 0x2108
-#define AXE_CMD_MII_READ_OPMODE 0x1009
-#define AXE_CMD_MII_OPMODE_HW 0x010A
-#define AXE_CMD_SROM_READ 0x200B
-#define AXE_CMD_SROM_WRITE 0x010C
-#define AXE_CMD_SROM_WR_ENABLE 0x010D
-#define AXE_CMD_SROM_WR_DISABLE 0x010E
-#define AXE_CMD_RXCTL_READ 0x200F
-#define AXE_CMD_RXCTL_WRITE 0x0110
-#define AXE_CMD_READ_IPG012 0x3011
-#define AXE_172_CMD_WRITE_IPG0 0x0112
-#define AXE_172_CMD_WRITE_IPG1 0x0113
-#define AXE_172_CMD_WRITE_IPG2 0x0114
-#define AXE_178_CMD_WRITE_IPG012 0x0112
-#define AXE_CMD_READ_MCAST 0x8015
-#define AXE_CMD_WRITE_MCAST 0x8116
-#define AXE_172_CMD_READ_NODEID 0x6017
-#define AXE_172_CMD_WRITE_NODEID 0x6118
-#define AXE_178_CMD_READ_NODEID 0x6013
-#define AXE_178_CMD_WRITE_NODEID 0x6114
-#define AXE_CMD_READ_PHYID 0x2019
-#define AXE_172_CMD_READ_MEDIA 0x101A
-#define AXE_178_CMD_READ_MEDIA 0x201A
-#define AXE_CMD_WRITE_MEDIA 0x011B
-#define AXE_CMD_READ_MONITOR_MODE 0x101C
-#define AXE_CMD_WRITE_MONITOR_MODE 0x011D
-#define AXE_CMD_READ_GPIO 0x101E
-#define AXE_CMD_WRITE_GPIO 0x011F
-#define AXE_CMD_SW_RESET_REG 0x0120
-#define AXE_CMD_SW_PHY_STATUS 0x0021
-#define AXE_CMD_SW_PHY_SELECT 0x0122
-
-#define AXE_SW_RESET_CLEAR 0x00
-#define AXE_SW_RESET_RR 0x01
-#define AXE_SW_RESET_RT 0x02
-#define AXE_SW_RESET_PRTE 0x04
-#define AXE_SW_RESET_PRL 0x08
-#define AXE_SW_RESET_BZ 0x10
-#define AXE_SW_RESET_IPRL 0x20
-#define AXE_SW_RESET_IPPD 0x40
-
-/* AX88178 documentation says to always write this bit... */
-#define AXE_178_RESET_MAGIC 0x40
-
-#define AXE_178_MEDIA_GMII 0x0001
-#define AXE_MEDIA_FULL_DUPLEX 0x0002
-#define AXE_172_MEDIA_TX_ABORT_ALLOW 0x0004
-/* AX88178/88772 documentation says to always write 1 to bit 2 */
-#define AXE_178_MEDIA_MAGIC 0x0004
-/* AX88772 documentation says to always write 0 to bit 3 */
-#define AXE_178_MEDIA_ENCK 0x0008
-#define AXE_172_MEDIA_FLOW_CONTROL_EN 0x0010
-#define AXE_178_MEDIA_RXFLOW_CONTROL_EN 0x0010
-#define AXE_178_MEDIA_TXFLOW_CONTROL_EN 0x0020
-#define AXE_178_MEDIA_JUMBO_EN 0x0040
-#define AXE_178_MEDIA_LTPF_ONLY 0x0080
-#define AXE_178_MEDIA_RX_EN 0x0100
-#define AXE_178_MEDIA_100TX 0x0200
-#define AXE_178_MEDIA_SBP 0x0800
-#define AXE_178_MEDIA_SUPERMAC 0x1000
-
-#define AXE_RXCMD_PROMISC 0x0001
-#define AXE_RXCMD_ALLMULTI 0x0002
-#define AXE_172_RXCMD_UNICAST 0x0004
-#define AXE_178_RXCMD_KEEP_INVALID_CRC 0x0004
-#define AXE_RXCMD_BROADCAST 0x0008
-#define AXE_RXCMD_MULTICAST 0x0010
-#define AXE_178_RXCMD_AP 0x0020
-#define AXE_RXCMD_ENABLE 0x0080
-#define AXE_178_RXCMD_MFB_2048 0x0000 /* 2K max frame burst */
-#define AXE_178_RXCMD_MFB_4096 0x0100 /* 4K max frame burst */
-#define AXE_178_RXCMD_MFB_8192 0x0200 /* 8K max frame burst */
-#define AXE_178_RXCMD_MFB_16384 0x0300 /* 16K max frame burst*/
-
-#define AXE_NOPHY 0xE0
-#define AXE_INTPHY 0x10
-
-#define AXE_TIMEOUT 1000
-#define AXE_172_BUFSZ 1536
-#define AXE_178_MIN_BUFSZ 2048
-#define AXE_MIN_FRAMELEN 60
-#define AXE_RX_FRAMES 1
-#define AXE_TX_FRAMES 1
-
-#if AXE_178_MAX_FRAME_BURST == 0
-#define AXE_178_RXCMD_MFB AXE_178_RXCMD_MFB_2048
-#define AXE_178_MAX_BUFSZ 2048
-#elif AXE_178_MAX_FRAME_BURST == 1
-#define AXE_178_RXCMD_MFB AXE_178_RXCMD_MFB_4096
-#define AXE_178_MAX_BUFSZ 4096
-#elif AXE_178_MAX_FRAME_BURST == 2
-#define AXE_178_RXCMD_MFB AXE_178_RXCMD_MFB_8192
-#define AXE_178_MAX_BUFSZ 8192
-#else
-#define AXE_178_RXCMD_MFB AXE_178_RXCMD_MFB_16384
-#define AXE_178_MAX_BUFSZ 16384
-#endif
-
-#define AXE_RX_LIST_CNT 1
-#define AXE_TX_LIST_CNT 1
-
-struct axe_chain {
- struct axe_softc *axe_sc;
- usbd_xfer_handle axe_xfer;
- char *axe_buf;
- struct mbuf *axe_mbuf;
- int axe_accum;
- int axe_idx;
-};
-
-struct axe_cdata {
- struct axe_chain axe_tx_chain[AXE_TX_LIST_CNT];
- struct axe_chain axe_rx_chain[AXE_RX_LIST_CNT];
- int axe_tx_prod;
- int axe_tx_cons;
- int axe_tx_cnt;
- int axe_rx_prod;
-};
-
-#define AXE_CTL_READ 0x01
-#define AXE_CTL_WRITE 0x02
-
-#define AXE_CONFIG_NO 1
-#define AXE_IFACE_IDX 0
-
-/*
- * The interrupt endpoint is currently unused
- * by the ASIX part.
- */
-#define AXE_ENDPT_RX 0x0
-#define AXE_ENDPT_TX 0x1
-#define AXE_ENDPT_INTR 0x2
-#define AXE_ENDPT_MAX 0x3
-
-struct axe_sframe_hdr {
- uint16_t len;
- uint16_t ilen;
-} __packed;
-
-struct axe_type {
- struct usb_devno axe_dev;
- uint32_t axe_flags;
-#define AX172 0x0000 /* AX88172 */
-#define AX178 0x0001 /* AX88178 */
-#define AX772 0x0002 /* AX88772 */
-};
-
-#define AXE_INC(x, y) (x) = (x + 1) % y
-
-struct axe_softc {
-#if defined(__FreeBSD__)
-#define GET_MII(sc) (device_get_softc((sc)->axe_miibus))
-#elif defined(__NetBSD__)
-#define GET_MII(sc) (&(sc)->axe_mii)
-#elif defined(__OpenBSD__)
-#define GET_MII(sc) (&(sc)->axe_mii)
-#endif
- struct ifnet *axe_ifp;
- device_t axe_miibus;
- device_t axe_dev;
- usbd_device_handle axe_udev;
- usbd_interface_handle axe_iface;
- u_int16_t axe_vendor;
- u_int16_t axe_product;
- u_int16_t axe_flags;
- int axe_ed[AXE_ENDPT_MAX];
- usbd_pipe_handle axe_ep[AXE_ENDPT_MAX];
- int axe_if_flags;
- struct axe_cdata axe_cdata;
- struct callout_handle axe_stat_ch;
- struct mtx axe_mtx;
- struct sx axe_sleeplock;
- char axe_dying;
- int axe_link;
- unsigned char axe_ipgs[3];
- unsigned char axe_phyaddrs[2];
- struct timeval axe_rx_notice;
- struct usb_task axe_tick_task;
- int axe_bufsz;
- int axe_boundary;
-};
-
-#if 0
-#define AXE_LOCK(_sc) mtx_lock(&(_sc)->axe_mtx)
-#define AXE_UNLOCK(_sc) mtx_unlock(&(_sc)->axe_mtx)
-#else
-#define AXE_LOCK(_sc)
-#define AXE_UNLOCK(_sc)
-#endif
-#define AXE_SLEEPLOCK(_sc) sx_xlock(&(_sc)->axe_sleeplock)
-#define AXE_SLEEPUNLOCK(_sc) sx_xunlock(&(_sc)->axe_sleeplock)
-#define AXE_SLEEPLOCKASSERT(_sc) sx_assert(&(_sc)->axe_sleeplock, SX_XLOCKED)
diff --git a/sys/dev/usb/if_cdce.c b/sys/dev/usb/if_cdce.c
deleted file mode 100644
index d41a54f..0000000
--- a/sys/dev/usb/if_cdce.c
+++ /dev/null
@@ -1,771 +0,0 @@
-/* $NetBSD: if_cdce.c,v 1.4 2004/10/24 12:50:54 augustss Exp $ */
-
-/*
- * Copyright (c) 1997, 1998, 1999, 2000-2003 Bill Paul <wpaul@windriver.com>
- * Copyright (c) 2003-2005 Craig Boston
- * Copyright (c) 2004 Daniel Hartmeier
- * 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, THE VOICES IN HIS HEAD OR
- * THE 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.
- */
-
-/*
- * USB Communication Device Class (Ethernet Networking Control Model)
- * http://www.usb.org/developers/devclass_docs/usbcdc11.pdf
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/sockio.h>
-#include <sys/mbuf.h>
-#include <sys/malloc.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/socket.h>
-#include <sys/endian.h>
-
-#include <net/if.h>
-#include <net/if_arp.h>
-#include <net/ethernet.h>
-#include <net/if_types.h>
-#include <net/if_media.h>
-
-#include <net/bpf.h>
-
-#include <sys/bus.h>
-#include <machine/bus.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include <dev/usb/usbdivar.h>
-#include <dev/usb/usb_ethersubr.h>
-
-#include <dev/usb/usbcdc.h>
-#include "usbdevs.h"
-#include <dev/usb/if_cdcereg.h>
-
-static device_probe_t cdce_match;
-static device_attach_t cdce_attach;
-static device_detach_t cdce_detach;
-static device_shutdown_t cdce_shutdown;
-
-static device_method_t cdce_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, cdce_match),
- DEVMETHOD(device_attach, cdce_attach),
- DEVMETHOD(device_detach, cdce_detach),
- DEVMETHOD(device_shutdown, cdce_shutdown),
-
- { 0, 0 }
-};
-
-static driver_t cdce_driver = {
- "cdce",
- cdce_methods,
- sizeof(struct cdce_softc)
-};
-
-static devclass_t cdce_devclass;
-
-DRIVER_MODULE(cdce, uhub, cdce_driver, cdce_devclass, usbd_driver_load, 0);
-MODULE_VERSION(cdce, 0);
-MODULE_DEPEND(cdce, usb, 1, 1, 1);
-
-static int cdce_encap(struct cdce_softc *, struct mbuf *, int);
-static void cdce_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
-static void cdce_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
-static void cdce_start(struct ifnet *);
-static int cdce_ioctl(struct ifnet *, u_long, caddr_t);
-static void cdce_init(void *);
-static void cdce_reset(struct cdce_softc *);
-static void cdce_stop(struct cdce_softc *);
-static void cdce_rxstart(struct ifnet *);
-static int cdce_ifmedia_upd(struct ifnet *ifp);
-static void cdce_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr);
-
-static const struct cdce_type cdce_devs[] = {
- {{ USB_VENDOR_ACERLABS, USB_PRODUCT_ACERLABS_M5632 }, CDCE_NO_UNION },
- {{ USB_VENDOR_AMBIT, USB_PRODUCT_AMBIT_NTL_250 }, CDCE_NO_UNION },
- {{ USB_VENDOR_COMPAQ, USB_PRODUCT_COMPAQ_IPAQLINUX }, CDCE_NO_UNION },
- {{ USB_VENDOR_GMATE, USB_PRODUCT_GMATE_YP3X00 }, CDCE_NO_UNION },
- {{ USB_VENDOR_MOTOROLA2, USB_PRODUCT_MOTOROLA2_USBLAN }, CDCE_ZAURUS | CDCE_NO_UNION },
- {{ USB_VENDOR_MOTOROLA2, USB_PRODUCT_MOTOROLA2_USBLAN2 }, CDCE_ZAURUS | CDCE_NO_UNION },
- {{ USB_VENDOR_NETCHIP, USB_PRODUCT_NETCHIP_ETHERNETGADGET }, CDCE_NO_UNION },
- {{ USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2501 }, CDCE_NO_UNION },
- {{ USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SL5500 }, CDCE_ZAURUS },
- {{ USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SL5600 }, CDCE_ZAURUS | CDCE_NO_UNION },
- {{ USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SLA300 }, CDCE_ZAURUS | CDCE_NO_UNION },
- {{ USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SLC700 }, CDCE_ZAURUS | CDCE_NO_UNION },
- {{ USB_VENDOR_SHARP, USB_PRODUCT_SHARP_SLC750 }, CDCE_ZAURUS | CDCE_NO_UNION },
-};
-#define cdce_lookup(v, p) ((const struct cdce_type *)usb_lookup(cdce_devs, v, p))
-
-static int
-cdce_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usb_interface_descriptor_t *id;
-
- if (uaa->iface == NULL)
- return (UMATCH_NONE);
-
- id = usbd_get_interface_descriptor(uaa->iface);
- if (id == NULL)
- return (UMATCH_NONE);
-
- if (cdce_lookup(uaa->vendor, uaa->product) != NULL)
- return (UMATCH_VENDOR_PRODUCT);
-
- if (id->bInterfaceClass == UICLASS_CDC && id->bInterfaceSubClass ==
- UISUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL)
- return (UMATCH_IFACECLASS_GENERIC);
-
- return (UMATCH_NONE);
-}
-
-static int
-cdce_attach(device_t self)
-{
- struct cdce_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- struct ifnet *ifp;
- usbd_device_handle dev = uaa->device;
- const struct cdce_type *t;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
- const usb_cdc_union_descriptor_t *ud;
- usb_config_descriptor_t *cd;
- int data_ifcno;
- int i, j, numalts;
- u_char eaddr[ETHER_ADDR_LEN];
- const usb_cdc_ethernet_descriptor_t *ue;
- char eaddr_str[USB_MAX_STRING_LEN];
-
- sc->cdce_dev = self;
- sc->cdce_udev = uaa->device;
-
- t = cdce_lookup(uaa->vendor, uaa->product);
- if (t)
- sc->cdce_flags = t->cdce_flags;
-
- if (sc->cdce_flags & CDCE_NO_UNION)
- sc->cdce_data_iface = uaa->iface;
- else {
- ud = (const usb_cdc_union_descriptor_t *)usb_find_desc(sc->cdce_udev,
- UDESC_CS_INTERFACE, UDESCSUB_CDC_UNION);
- if (ud == NULL) {
- device_printf(sc->cdce_dev, "no union descriptor\n");
- return ENXIO;
- }
- data_ifcno = ud->bSlaveInterface[0];
-
- for (i = 0; i < uaa->nifaces; i++) {
- if (uaa->ifaces[i] != NULL) {
- id = usbd_get_interface_descriptor(
- uaa->ifaces[i]);
- if (id != NULL && id->bInterfaceNumber ==
- data_ifcno) {
- sc->cdce_data_iface = uaa->ifaces[i];
- uaa->ifaces[i] = NULL;
- }
- }
- }
- }
-
- if (sc->cdce_data_iface == NULL) {
- device_printf(sc->cdce_dev, "no data interface\n");
- return ENXIO;
- }
-
- /*
- * <quote>
- * The Data Class interface of a networking device shall have a minimum
- * of two interface settings. The first setting (the default interface
- * setting) includes no endpoints and therefore no networking traffic is
- * exchanged whenever the default interface setting is selected. One or
- * more additional interface settings are used for normal operation, and
- * therefore each includes a pair of endpoints (one IN, and one OUT) to
- * exchange network traffic. Select an alternate interface setting to
- * initialize the network aspects of the device and to enable the
- * exchange of network traffic.
- * </quote>
- *
- * Some devices, most notably cable modems, include interface settings
- * that have no IN or OUT endpoint, therefore loop through the list of all
- * available interface settings looking for one with both IN and OUT
- * endpoints.
- */
- id = usbd_get_interface_descriptor(sc->cdce_data_iface);
- cd = usbd_get_config_descriptor(sc->cdce_udev);
- numalts = usbd_get_no_alts(cd, id->bInterfaceNumber);
-
- for (j = 0; j < numalts; j++) {
- if (usbd_set_interface(sc->cdce_data_iface, j)) {
- device_printf(sc->cdce_dev,
- "setting alternate interface failed\n");
- return ENXIO;
- }
- /* Find endpoints. */
- id = usbd_get_interface_descriptor(sc->cdce_data_iface);
- sc->cdce_bulkin_no = sc->cdce_bulkout_no = -1;
- for (i = 0; i < id->bNumEndpoints; i++) {
- ed = usbd_interface2endpoint_descriptor(sc->cdce_data_iface, i);
- if (!ed) {
- device_printf(sc->cdce_dev,
- "could not read endpoint descriptor\n");
- return ENXIO;
- }
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
- sc->cdce_bulkin_no = ed->bEndpointAddress;
- } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
- sc->cdce_bulkout_no = ed->bEndpointAddress;
- } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
- /* XXX: CDC spec defines an interrupt pipe, but it is not
- * needed for simple host-to-host applications. */
- } else {
- device_printf(sc->cdce_dev,
- "unexpected endpoint\n");
- }
- }
- /* If we found something, try and use it... */
- if ((sc->cdce_bulkin_no != -1) && (sc->cdce_bulkout_no != -1))
- break;
- }
-
- if (sc->cdce_bulkin_no == -1) {
- device_printf(sc->cdce_dev, "could not find data bulk in\n");
- return ENXIO;
- }
- if (sc->cdce_bulkout_no == -1 ) {
- device_printf(sc->cdce_dev, "could not find data bulk out\n");
- return ENXIO;
- }
-
- mtx_init(&sc->cdce_mtx, device_get_nameunit(sc->cdce_dev), MTX_NETWORK_LOCK,
- MTX_DEF | MTX_RECURSE);
- ifmedia_init(&sc->cdce_ifmedia, 0, cdce_ifmedia_upd, cdce_ifmedia_sts);
- CDCE_LOCK(sc);
-
- ue = (const usb_cdc_ethernet_descriptor_t *)usb_find_desc(dev,
- UDESC_INTERFACE, UDESCSUB_CDC_ENF);
- if (!ue || usbd_get_string(dev, ue->iMacAddress, eaddr_str,
- sizeof(eaddr_str))) {
- /* Fake MAC address */
- device_printf(sc->cdce_dev, "faking MAC address\n");
- eaddr[0]= 0x2a;
- memcpy(&eaddr[1], &ticks, sizeof(u_int32_t));
- eaddr[5] = (u_int8_t)device_get_unit(sc->cdce_dev);
- } else {
- int i;
-
- memset(eaddr, 0, ETHER_ADDR_LEN);
- for (i = 0; i < ETHER_ADDR_LEN * 2; i++) {
- int c = eaddr_str[i];
-
- if ('0' <= c && c <= '9')
- c -= '0';
- else
- c -= 'A' - 10;
- c &= 0xf;
- if (c % 2 == 0)
- c <<= 4;
- eaddr[i / 2] |= c;
- }
- }
-
- ifp = GET_IFP(sc) = if_alloc(IFT_ETHER);
- if (ifp == NULL) {
- device_printf(sc->cdce_dev, "can not if_alloc()\n");
- CDCE_UNLOCK(sc);
- mtx_destroy(&sc->cdce_mtx);
- return ENXIO;
- }
- ifp->if_softc = sc;
- if_initname(ifp, "cdce", device_get_unit(sc->cdce_dev));
- ifp->if_mtu = ETHERMTU;
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
- IFF_NEEDSGIANT;
- ifp->if_ioctl = cdce_ioctl;
- ifp->if_output = ether_output;
- ifp->if_start = cdce_start;
- ifp->if_init = cdce_init;
- ifp->if_baudrate = 11000000;
- ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
-
- sc->q.ifp = ifp;
- sc->q.if_rxstart = cdce_rxstart;
-
- /* No IFM type for 11Mbps USB, so go with 10baseT */
- ifmedia_add(&sc->cdce_ifmedia, IFM_ETHER | IFM_10_T, 0, 0);
- ifmedia_set(&sc->cdce_ifmedia, IFM_ETHER | IFM_10_T);
-
- ether_ifattach(ifp, eaddr);
- usb_register_netisr();
-
- CDCE_UNLOCK(sc);
-
- usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->cdce_udev,
- sc->cdce_dev);
-
- return 0;
-}
-
-static int
-cdce_detach(device_t self)
-{
- struct cdce_softc *sc = device_get_softc(self);
- struct ifnet *ifp;
-
- CDCE_LOCK(sc);
- sc->cdce_dying = 1;
- ifp = GET_IFP(sc);
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- cdce_shutdown(sc->cdce_dev);
-
- ether_ifdetach(ifp);
- if_free(ifp);
- ifmedia_removeall(&sc->cdce_ifmedia);
- CDCE_UNLOCK(sc);
- mtx_destroy(&sc->cdce_mtx);
-
- usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->cdce_udev,
- sc->cdce_dev);
-
- return (0);
-}
-
-static void
-cdce_start(struct ifnet *ifp)
-{
- struct cdce_softc *sc;
- struct mbuf *m_head = NULL;
-
- sc = ifp->if_softc;
- CDCE_LOCK(sc);
-
-
- if (sc->cdce_dying ||
- ifp->if_drv_flags & IFF_DRV_OACTIVE ||
- !(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
- CDCE_UNLOCK(sc);
- return;
- }
-
- IF_DEQUEUE(&ifp->if_snd, m_head);
- if (m_head == NULL) {
- CDCE_UNLOCK(sc);
- return;
- }
-
- if (cdce_encap(sc, m_head, 0)) {
- IF_PREPEND(&ifp->if_snd, m_head);
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- CDCE_UNLOCK(sc);
- return;
- }
-
- BPF_MTAP(ifp, m_head);
-
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
-
- CDCE_UNLOCK(sc);
-
- return;
-}
-
-static int
-cdce_encap(struct cdce_softc *sc, struct mbuf *m, int idx)
-{
- struct ue_chain *c;
- usbd_status err;
- int extra = 0;
-
- c = &sc->cdce_cdata.ue_tx_chain[idx];
-
- m_copydata(m, 0, m->m_pkthdr.len, c->ue_buf);
- if (sc->cdce_flags & CDCE_ZAURUS) {
- /* Zaurus wants a 32-bit CRC appended to every frame */
- u_int32_t crc;
-
- crc = htole32(crc32(c->ue_buf, m->m_pkthdr.len));
- bcopy(&crc, c->ue_buf + m->m_pkthdr.len, 4);
- extra = 4;
- }
- c->ue_mbuf = m;
-
- usbd_setup_xfer(c->ue_xfer, sc->cdce_bulkout_pipe, c, c->ue_buf,
- m->m_pkthdr.len + extra, 0, 10000, cdce_txeof);
- err = usbd_transfer(c->ue_xfer);
- if (err != USBD_IN_PROGRESS) {
- cdce_stop(sc);
- return (EIO);
- }
-
- sc->cdce_cdata.ue_tx_cnt++;
-
- return (0);
-}
-
-static void
-cdce_stop(struct cdce_softc *sc)
-{
- usbd_status err;
- struct ifnet *ifp;
-
- CDCE_LOCK(sc);
-
- cdce_reset(sc);
-
- ifp = GET_IFP(sc);
- ifp->if_timer = 0;
-
- if (sc->cdce_bulkin_pipe != NULL) {
- err = usbd_abort_pipe(sc->cdce_bulkin_pipe);
- if (err)
- device_printf(sc->cdce_dev,
- "abort rx pipe failed: %s\n", usbd_errstr(err));
- err = usbd_close_pipe(sc->cdce_bulkin_pipe);
- if (err)
- device_printf(sc->cdce_dev,
- "close rx pipe failed: %s\n", usbd_errstr(err));
- sc->cdce_bulkin_pipe = NULL;
- }
-
- if (sc->cdce_bulkout_pipe != NULL) {
- err = usbd_abort_pipe(sc->cdce_bulkout_pipe);
- if (err)
- device_printf(sc->cdce_dev,
- "abort tx pipe failed: %s\n", usbd_errstr(err));
- err = usbd_close_pipe(sc->cdce_bulkout_pipe);
- if (err)
- device_printf(sc->cdce_dev,
- "close tx pipe failed: %s\n", usbd_errstr(err));
- sc->cdce_bulkout_pipe = NULL;
- }
-
- usb_ether_rx_list_free(&sc->cdce_cdata);
- usb_ether_tx_list_free(&sc->cdce_cdata);
-
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
- CDCE_UNLOCK(sc);
-
- return;
-}
-
-static int
-cdce_shutdown(device_t dev)
-{
- struct cdce_softc *sc;
-
- sc = device_get_softc(dev);
- cdce_stop(sc);
-
- return (0);
-}
-
-static int
-cdce_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
-{
- struct cdce_softc *sc = ifp->if_softc;
- struct ifreq *ifr = (struct ifreq *)data;
- int error = 0;
-
- if (sc->cdce_dying)
- return (ENXIO);
-
- switch(command) {
- case SIOCSIFFLAGS:
- if (ifp->if_flags & IFF_UP) {
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
- cdce_init(sc);
- } else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- cdce_stop(sc);
- }
- error = 0;
- break;
-
- case SIOCSIFMEDIA:
- case SIOCGIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &sc->cdce_ifmedia, command);
- break;
-
- default:
- error = ether_ioctl(ifp, command, data);
- break;
- }
-
- return (error);
-}
-
-static void
-cdce_reset(struct cdce_softc *sc)
-{
- /* XXX Maybe reset the bulk pipes here? */
- return;
-}
-
-static void
-cdce_init(void *xsc)
-{
- struct cdce_softc *sc = xsc;
- struct ifnet *ifp = GET_IFP(sc);
- struct ue_chain *c;
- usbd_status err;
- int i;
-
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- return;
-
- CDCE_LOCK(sc);
- cdce_reset(sc);
-
- if (usb_ether_tx_list_init(sc, &sc->cdce_cdata,
- sc->cdce_udev) == ENOBUFS) {
- device_printf(sc->cdce_dev, "tx list init failed\n");
- CDCE_UNLOCK(sc);
- return;
- }
-
- if (usb_ether_rx_list_init(sc, &sc->cdce_cdata,
- sc->cdce_udev) == ENOBUFS) {
- device_printf(sc->cdce_dev, "rx list init failed\n");
- CDCE_UNLOCK(sc);
- return;
- }
-
- /* Maybe set multicast / broadcast here??? */
-
- err = usbd_open_pipe(sc->cdce_data_iface, sc->cdce_bulkin_no,
- USBD_EXCLUSIVE_USE, &sc->cdce_bulkin_pipe);
- if (err) {
- device_printf(sc->cdce_dev, "open rx pipe failed: %s\n",
- usbd_errstr(err));
- CDCE_UNLOCK(sc);
- return;
- }
-
- err = usbd_open_pipe(sc->cdce_data_iface, sc->cdce_bulkout_no,
- USBD_EXCLUSIVE_USE, &sc->cdce_bulkout_pipe);
- if (err) {
- device_printf(sc->cdce_dev, "open tx pipe failed: %s\n",
- usbd_errstr(err));
- CDCE_UNLOCK(sc);
- return;
- }
-
- for (i = 0; i < UE_RX_LIST_CNT; i++) {
- c = &sc->cdce_cdata.ue_rx_chain[i];
- usbd_setup_xfer(c->ue_xfer, sc->cdce_bulkin_pipe, c,
- mtod(c->ue_mbuf, char *), UE_BUFSZ, USBD_SHORT_XFER_OK,
- USBD_NO_TIMEOUT, cdce_rxeof);
- usbd_transfer(c->ue_xfer);
- }
-
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
-
- CDCE_UNLOCK(sc);
-
- return;
-}
-
-static void
-cdce_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- struct ue_chain *c = priv;
- struct cdce_softc *sc = c->ue_sc;
- struct ifnet *ifp;
- struct mbuf *m;
- int total_len = 0;
-
- CDCE_LOCK(sc);
- ifp = GET_IFP(sc);
-
- if (sc->cdce_dying || !(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
- CDCE_UNLOCK(sc);
- return;
- }
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
- CDCE_UNLOCK(sc);
- return;
- }
- if (sc->cdce_rxeof_errors == 0)
- device_printf(sc->cdce_dev, "usb error on rx: %s\n",
- usbd_errstr(status));
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall_async(sc->cdce_bulkin_pipe);
- DELAY(sc->cdce_rxeof_errors * 10000);
- sc->cdce_rxeof_errors++;
- goto done;
- }
-
- sc->cdce_rxeof_errors = 0;
-
- usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
-
- if (sc->cdce_flags & CDCE_ZAURUS)
- total_len -= 4; /* Strip off CRC added by Zaurus */
-
- m = c->ue_mbuf;
-
- if (total_len < sizeof(struct ether_header)) {
- ifp->if_ierrors++;
- goto done;
- }
-
- ifp->if_ipackets++;
- m->m_pkthdr.rcvif = (struct ifnet *)&sc->q;
- m->m_pkthdr.len = m->m_len = total_len;
-
- /* Put the packet on the special USB input queue. */
- usb_ether_input(m);
- CDCE_UNLOCK(sc);
-
- return;
-
-done:
- /* Setup new transfer. */
- usbd_setup_xfer(c->ue_xfer, sc->cdce_bulkin_pipe, c,
- mtod(c->ue_mbuf, char *),
- UE_BUFSZ, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT,
- cdce_rxeof);
- usbd_transfer(c->ue_xfer);
- CDCE_UNLOCK(sc);
-
- return;
-}
-
-static void
-cdce_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- struct ue_chain *c = priv;
- struct cdce_softc *sc = c->ue_sc;
- struct ifnet *ifp;
- usbd_status err;
-
- CDCE_LOCK(sc);
- ifp = GET_IFP(sc);
-
- if (sc->cdce_dying ||
- !(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
- CDCE_UNLOCK(sc);
- return;
- }
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
- CDCE_UNLOCK(sc);
- return;
- }
- ifp->if_oerrors++;
- device_printf(sc->cdce_dev, "usb error on tx: %s\n",
- usbd_errstr(status));
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall_async(sc->cdce_bulkout_pipe);
- CDCE_UNLOCK(sc);
- return;
- }
-
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &err);
-
- if (c->ue_mbuf != NULL) {
- c->ue_mbuf->m_pkthdr.rcvif = ifp;
- usb_tx_done(c->ue_mbuf);
- c->ue_mbuf = NULL;
- }
-
- if (err)
- ifp->if_oerrors++;
- else
- ifp->if_opackets++;
-
- CDCE_UNLOCK(sc);
-
- return;
-}
-
-static void
-cdce_rxstart(struct ifnet *ifp)
-{
- struct cdce_softc *sc;
- struct ue_chain *c;
-
- sc = ifp->if_softc;
- CDCE_LOCK(sc);
-
- if (sc->cdce_dying || !(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
- CDCE_UNLOCK(sc);
- return;
- }
-
- c = &sc->cdce_cdata.ue_rx_chain[sc->cdce_cdata.ue_rx_prod];
-
- c->ue_mbuf = usb_ether_newbuf();
- if (c->ue_mbuf == NULL) {
- device_printf(sc->cdce_dev, "no memory for rx list "
- "-- packet dropped!\n");
- ifp->if_ierrors++;
- CDCE_UNLOCK(sc);
- return;
- }
-
- usbd_setup_xfer(c->ue_xfer, sc->cdce_bulkin_pipe, c,
- mtod(c->ue_mbuf, char *), UE_BUFSZ, USBD_SHORT_XFER_OK,
- USBD_NO_TIMEOUT, cdce_rxeof);
- usbd_transfer(c->ue_xfer);
-
- CDCE_UNLOCK(sc);
- return;
-}
-
-static int
-cdce_ifmedia_upd(struct ifnet *ifp)
-{
-
- /* no-op, cdce has only 1 possible media type */
- return 0;
-}
-
-static void
-cdce_ifmedia_sts(struct ifnet * const ifp, struct ifmediareq *req)
-{
-
- req->ifm_status = IFM_AVALID | IFM_ACTIVE;
- req->ifm_active = IFM_ETHER | IFM_10_T;
-}
diff --git a/sys/dev/usb/if_cdcereg.h b/sys/dev/usb/if_cdcereg.h
deleted file mode 100644
index e658eab..0000000
--- a/sys/dev/usb/if_cdcereg.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (c) 2003-2005 Craig Boston
- * 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, THE VOICES IN HIS HEAD OR
- * THE 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.
- *
- * $FreeBSD$
- */
-
-#ifndef _USB_IF_CDCEREG_H_
-#define _USB_IF_CDCEREG_H_
-
-struct cdce_type {
- struct usb_devno cdce_dev;
- u_int16_t cdce_flags;
-#define CDCE_ZAURUS 1
-#define CDCE_NO_UNION 2
-};
-
-struct cdce_softc {
- struct ifnet *cdce_ifp;
-#define GET_IFP(sc) ((sc)->cdce_ifp)
- struct ifmedia cdce_ifmedia;
-
- usbd_device_handle cdce_udev;
- usbd_interface_handle cdce_data_iface;
- int cdce_bulkin_no;
- usbd_pipe_handle cdce_bulkin_pipe;
- int cdce_bulkout_no;
- usbd_pipe_handle cdce_bulkout_pipe;
- char cdce_dying;
- device_t cdce_dev;
-
- struct ue_cdata cdce_cdata;
- struct timeval cdce_rx_notice;
- int cdce_rxeof_errors;
-
- u_int16_t cdce_flags;
-
- struct mtx cdce_mtx;
-
- struct usb_qdat q;
-};
-
-/* We are still under Giant */
-#if 0
-#define CDCE_LOCK(_sc) mtx_lock(&(_sc)->cdce_mtx)
-#define CDCE_UNLOCK(_sc) mtx_unlock(&(_sc)->cdce_mtx)
-#else
-#define CDCE_LOCK(_sc)
-#define CDCE_UNLOCK(_sc)
-#endif
-
-#endif /* _USB_IF_CDCEREG_H_ */
diff --git a/sys/dev/usb/if_cue.c b/sys/dev/usb/if_cue.c
deleted file mode 100644
index cd3a543..0000000
--- a/sys/dev/usb/if_cue.c
+++ /dev/null
@@ -1,1074 +0,0 @@
-/*-
- * Copyright (c) 1997, 1998, 1999, 2000
- * Bill Paul <wpaul@ee.columbia.edu>. 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * CATC USB-EL1210A USB to ethernet driver. Used in the CATC Netmate
- * adapters and others.
- *
- * Written by Bill Paul <wpaul@ee.columbia.edu>
- * 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.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/sockio.h>
-#include <sys/mbuf.h>
-#include <sys/malloc.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/socket.h>
-
-#include <net/if.h>
-#include <net/if_arp.h>
-#include <net/ethernet.h>
-#include <net/if_dl.h>
-#include <net/if_types.h>
-
-#include <net/bpf.h>
-
-#include <sys/bus.h>
-#include <machine/bus.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include <dev/usb/usbdivar.h>
-#include "usbdevs.h"
-#include <dev/usb/usb_ethersubr.h>
-
-#include <dev/usb/if_cuereg.h>
-
-/*
- * 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 },
- { USB_VENDOR_SMARTBRIDGES, USB_PRODUCT_SMARTBRIDGES_SMARTLINK },
- /* Belkin F5U111 adapter covered by NETMATE entry */
- { 0, 0 }
-};
-
-static device_probe_t cue_match;
-static device_attach_t cue_attach;
-static device_detach_t cue_detach;
-static device_shutdown_t cue_shutdown;
-
-static int cue_encap(struct cue_softc *, struct mbuf *, int);
-static void cue_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
-static void cue_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
-static void cue_tick(void *);
-static void cue_rxstart(struct ifnet *);
-static void cue_start(struct ifnet *);
-static int cue_ioctl(struct ifnet *, u_long, caddr_t);
-static void cue_init(void *);
-static void cue_stop(struct cue_softc *);
-static void cue_watchdog(struct ifnet *);
-
-static void cue_setmulti(struct cue_softc *);
-static uint32_t cue_mchash(const uint8_t *);
-static void cue_reset(struct cue_softc *);
-
-static int cue_csr_read_1(struct cue_softc *, int);
-static int cue_csr_write_1(struct cue_softc *, int, int);
-static int cue_csr_read_2(struct cue_softc *, int);
-#ifdef notdef
-static int cue_csr_write_2(struct cue_softc *, int, int);
-#endif
-static int cue_mem(struct cue_softc *, int, int, void *, int);
-static int cue_getmac(struct cue_softc *, void *);
-
-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(cue, uhub, cue_driver, cue_devclass, usbd_driver_load, 0);
-MODULE_DEPEND(cue, usb, 1, 1, 1);
-MODULE_DEPEND(cue, ether, 1, 1, 1);
-
-#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(struct cue_softc *sc, int reg)
-{
- usb_device_request_t req;
- usbd_status err;
- u_int8_t val = 0;
-
- if (sc->cue_dying)
- return(0);
-
- CUE_LOCK(sc);
-
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = CUE_CMD_READREG;
- USETW(req.wValue, 0);
- USETW(req.wIndex, reg);
- USETW(req.wLength, 1);
-
- err = usbd_do_request(sc->cue_udev, &req, &val);
-
- CUE_UNLOCK(sc);
-
- if (err)
- return(0);
-
- return(val);
-}
-
-static int
-cue_csr_read_2(struct cue_softc *sc, int reg)
-{
- usb_device_request_t req;
- usbd_status err;
- u_int16_t val = 0;
-
- if (sc->cue_dying)
- return(0);
-
- CUE_LOCK(sc);
-
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = CUE_CMD_READREG;
- USETW(req.wValue, 0);
- USETW(req.wIndex, reg);
- USETW(req.wLength, 2);
-
- err = usbd_do_request(sc->cue_udev, &req, &val);
-
- CUE_UNLOCK(sc);
-
- if (err)
- return(0);
-
- return(val);
-}
-
-static int
-cue_csr_write_1(struct cue_softc *sc, int reg, int val)
-{
- usb_device_request_t req;
- usbd_status err;
-
- if (sc->cue_dying)
- return(0);
-
- CUE_LOCK(sc);
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = CUE_CMD_WRITEREG;
- USETW(req.wValue, val);
- USETW(req.wIndex, reg);
- USETW(req.wLength, 0);
-
- err = usbd_do_request(sc->cue_udev, &req, NULL);
-
- CUE_UNLOCK(sc);
-
- if (err)
- return(-1);
-
- return(0);
-}
-
-#ifdef notdef
-static int
-cue_csr_write_2(struct cue_softc *sc, int reg, int val)
-{
- usb_device_request_t req;
- usbd_status err;
-
- if (sc->cue_dying)
- return(0);
-
- CUE_LOCK(sc);
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = CUE_CMD_WRITEREG;
- USETW(req.wValue, val);
- USETW(req.wIndex, reg);
- USETW(req.wLength, 0);
-
- err = usbd_do_request(sc->cue_udev, &req, NULL);
-
- CUE_UNLOCK(sc);
-
- if (err)
- return(-1);
-
- return(0);
-}
-#endif
-
-static int
-cue_mem(struct cue_softc *sc, int cmd, int addr, void *buf, int len)
-{
- usb_device_request_t req;
- usbd_status err;
-
- if (sc->cue_dying)
- return(0);
-
- CUE_LOCK(sc);
-
- 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);
-
- err = usbd_do_request(sc->cue_udev, &req, buf);
-
- CUE_UNLOCK(sc);
-
- if (err)
- return(-1);
-
- return(0);
-}
-
-static int
-cue_getmac(struct cue_softc *sc, void *buf)
-{
- usb_device_request_t req;
- usbd_status err;
-
- if (sc->cue_dying)
- return(0);
-
- CUE_LOCK(sc);
-
- 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);
-
- err = usbd_do_request(sc->cue_udev, &req, buf);
-
- CUE_UNLOCK(sc);
-
- if (err) {
- device_printf(sc->cue_dev, "read MAC address failed\n");
- return(-1);
- }
-
- return(0);
-}
-
-#define CUE_BITS 9
-
-static uint32_t
-cue_mchash(const uint8_t *addr)
-{
- uint32_t crc;
-
- /* Compute CRC for the address value. */
- crc = ether_crc32_le(addr, ETHER_ADDR_LEN);
-
- return (crc & ((1 << CUE_BITS) - 1));
-}
-
-static void
-cue_setmulti(struct cue_softc *sc)
-{
- struct ifnet *ifp;
- struct ifmultiaddr *ifma;
- u_int32_t h = 0, i;
-
- ifp = sc->cue_ifp;
-
- 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_ADDR_LOCK(ifp);
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
- {
- if (ifma->ifma_addr->sa_family != AF_LINK)
- continue;
- h = cue_mchash(LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
- sc->cue_mctab[h >> 3] |= 1 << (h & 0x7);
- }
- IF_ADDR_UNLOCK(ifp);
-
- /*
- * Also include the broadcast address in the filter
- * so we can receive broadcast frames.
- */
- if (ifp->if_flags & IFF_BROADCAST) {
- h = cue_mchash(ifp->if_broadcastaddr);
- 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);
-
- return;
-}
-
-static void
-cue_reset(struct cue_softc *sc)
-{
- usb_device_request_t req;
- usbd_status err;
-
- 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);
- err = usbd_do_request(sc->cue_udev, &req, NULL);
- if (err)
- device_printf(sc->cue_dev, "reset failed\n");
-
- /* Wait a little while for the chip to get its brains in order. */
- DELAY(1000);
- return;
-}
-
-/*
- * Probe for a Pegasus chip.
- */
-static int
-cue_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
- struct cue_type *t;
-
- if (!uaa->iface)
- return(UMATCH_NONE);
-
- t = cue_devs;
- while(t->cue_vid) {
- if (uaa->vendor == t->cue_vid &&
- uaa->product == t->cue_did) {
- return(UMATCH_VENDOR_PRODUCT);
- }
- t++;
- }
-
- return(UMATCH_NONE);
-}
-
-/*
- * Attach the interface. Allocate softc structures, do ifmedia
- * setup and ethernet/BPF attach.
- */
-static int
-cue_attach(device_t self)
-{
- struct cue_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- u_char eaddr[ETHER_ADDR_LEN];
- struct ifnet *ifp;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
- int i;
-
- sc->cue_dev = self;
- sc->cue_iface = uaa->iface;
- sc->cue_udev = uaa->device;
-
- if (usbd_set_config_no(sc->cue_udev, CUE_CONFIG_NO, 0)) {
- device_printf(sc->cue_dev, "getting interface handle failed\n");
- return ENXIO;
- }
-
- id = usbd_get_interface_descriptor(uaa->iface);
-
- /* Find endpoints. */
- for (i = 0; i < id->bNumEndpoints; i++) {
- ed = usbd_interface2endpoint_descriptor(uaa->iface, i);
- if (!ed) {
- device_printf(sc->cue_dev, "couldn't get ep %d\n", i);
- return ENXIO;
- }
- 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;
- }
- }
-
- mtx_init(&sc->cue_mtx, device_get_nameunit(self), MTX_NETWORK_LOCK,
- MTX_DEF | MTX_RECURSE);
- CUE_LOCK(sc);
-
-#ifdef notdef
- /* Reset the adapter. */
- cue_reset(sc);
-#endif
- /*
- * Get station address.
- */
- cue_getmac(sc, &eaddr);
-
- ifp = sc->cue_ifp = if_alloc(IFT_ETHER);
- if (ifp == NULL) {
- device_printf(sc->cue_dev, "can not if_alloc()\n");
- CUE_UNLOCK(sc);
- mtx_destroy(&sc->cue_mtx);
- return ENXIO;
- }
- ifp->if_softc = sc;
- if_initname(ifp, "cue", device_get_unit(sc->cue_dev));
- ifp->if_mtu = ETHERMTU;
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
- IFF_NEEDSGIANT;
- ifp->if_ioctl = cue_ioctl;
- ifp->if_start = cue_start;
- ifp->if_watchdog = cue_watchdog;
- ifp->if_init = cue_init;
- ifp->if_baudrate = 10000000;
- ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
-
- sc->cue_qdat.ifp = ifp;
- sc->cue_qdat.if_rxstart = cue_rxstart;
-
- /*
- * Call MI attach routine.
- */
- ether_ifattach(ifp, eaddr);
- callout_handle_init(&sc->cue_stat_ch);
- usb_register_netisr();
- sc->cue_dying = 0;
-
- CUE_UNLOCK(sc);
- return 0;
-}
-
-static int
-cue_detach(device_t dev)
-{
- struct cue_softc *sc;
- struct ifnet *ifp;
-
- sc = device_get_softc(dev);
- CUE_LOCK(sc);
- ifp = sc->cue_ifp;
-
- sc->cue_dying = 1;
- untimeout(cue_tick, sc, sc->cue_stat_ch);
- ether_ifdetach(ifp);
- if_free(ifp);
-
- if (sc->cue_ep[CUE_ENDPT_TX] != NULL)
- usbd_abort_pipe(sc->cue_ep[CUE_ENDPT_TX]);
- if (sc->cue_ep[CUE_ENDPT_RX] != NULL)
- usbd_abort_pipe(sc->cue_ep[CUE_ENDPT_RX]);
- if (sc->cue_ep[CUE_ENDPT_INTR] != NULL)
- usbd_abort_pipe(sc->cue_ep[CUE_ENDPT_INTR]);
-
- CUE_UNLOCK(sc);
- mtx_destroy(&sc->cue_mtx);
-
- return(0);
-}
-
-static void
-cue_rxstart(struct ifnet *ifp)
-{
- struct cue_softc *sc;
- struct ue_chain *c;
-
- sc = ifp->if_softc;
- CUE_LOCK(sc);
- c = &sc->cue_cdata.ue_rx_chain[sc->cue_cdata.ue_rx_prod];
-
- c->ue_mbuf = usb_ether_newbuf();
- if (c->ue_mbuf == NULL) {
- device_printf(sc->cue_dev, "no memory for rx list "
- "-- packet dropped!\n");
- ifp->if_ierrors++;
- CUE_UNLOCK(sc);
- return;
- }
-
- /* Setup new transfer. */
- usbd_setup_xfer(c->ue_xfer, sc->cue_ep[CUE_ENDPT_RX],
- c, mtod(c->ue_mbuf, char *), UE_BUFSZ, USBD_SHORT_XFER_OK,
- USBD_NO_TIMEOUT, cue_rxeof);
- usbd_transfer(c->ue_xfer);
- CUE_UNLOCK(sc);
-
- return;
-}
-
-/*
- * A frame has been uploaded: pass the resulting mbuf chain up to
- * the higher level protocols.
- */
-static void
-cue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- struct cue_softc *sc;
- struct ue_chain *c;
- struct mbuf *m;
- struct ifnet *ifp;
- int total_len = 0;
- u_int16_t len;
-
- c = priv;
- sc = c->ue_sc;
- CUE_LOCK(sc);
- ifp = sc->cue_ifp;
-
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
- CUE_UNLOCK(sc);
- return;
- }
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
- CUE_UNLOCK(sc);
- return;
- }
- if (usbd_ratecheck(&sc->cue_rx_notice))
- device_printf(sc->cue_dev, "usb error on rx: %s\n",
- usbd_errstr(status));
- 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);
-
- m = c->ue_mbuf;
- len = *mtod(m, u_int16_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.rcvif = (void *)&sc->cue_qdat;
- m->m_pkthdr.len = m->m_len = total_len;
-
- /* Put the packet on the special USB input queue. */
- usb_ether_input(m);
- CUE_UNLOCK(sc);
-
- return;
-done:
- /* Setup new transfer. */
- usbd_setup_xfer(c->ue_xfer, sc->cue_ep[CUE_ENDPT_RX],
- c, mtod(c->ue_mbuf, char *), UE_BUFSZ, USBD_SHORT_XFER_OK,
- USBD_NO_TIMEOUT, cue_rxeof);
- usbd_transfer(c->ue_xfer);
- CUE_UNLOCK(sc);
-
- return;
-}
-
-/*
- * A frame was downloaded to the chip. It's safe for us to clean up
- * the list buffers.
- */
-
-static void
-cue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- struct cue_softc *sc;
- struct ue_chain *c;
- struct ifnet *ifp;
- usbd_status err;
-
- c = priv;
- sc = c->ue_sc;
- CUE_LOCK(sc);
- ifp = sc->cue_ifp;
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
- CUE_UNLOCK(sc);
- return;
- }
- device_printf(sc->cue_dev, "usb error on tx: %s\n",
- usbd_errstr(status));
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall(sc->cue_ep[CUE_ENDPT_TX]);
- CUE_UNLOCK(sc);
- return;
- }
-
- ifp->if_timer = 0;
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &err);
-
- if (c->ue_mbuf != NULL) {
- c->ue_mbuf->m_pkthdr.rcvif = ifp;
- usb_tx_done(c->ue_mbuf);
- c->ue_mbuf = NULL;
- }
-
- if (err)
- ifp->if_oerrors++;
- else
- ifp->if_opackets++;
-
- CUE_UNLOCK(sc);
-
- return;
-}
-
-static void
-cue_tick(void *xsc)
-{
- struct cue_softc *sc;
- struct ifnet *ifp;
-
- sc = xsc;
-
- if (sc == NULL)
- return;
-
- CUE_LOCK(sc);
-
- ifp = sc->cue_ifp;
-
- 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++;
-
- sc->cue_stat_ch = timeout(cue_tick, sc, hz);
-
- CUE_UNLOCK(sc);
-
- return;
-}
-
-static int
-cue_encap(struct cue_softc *sc, struct mbuf *m, int idx)
-{
- int total_len;
- struct ue_chain *c;
- usbd_status err;
-
- c = &sc->cue_cdata.ue_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->ue_buf + 2);
- c->ue_mbuf = m;
-
- total_len = m->m_pkthdr.len + 2;
-
- /* The first two bytes are the frame length */
- c->ue_buf[0] = (u_int8_t)m->m_pkthdr.len;
- c->ue_buf[1] = (u_int8_t)(m->m_pkthdr.len >> 8);
-
- usbd_setup_xfer(c->ue_xfer, sc->cue_ep[CUE_ENDPT_TX],
- c, c->ue_buf, total_len, 0, 10000, cue_txeof);
-
- /* Transmit */
- err = usbd_transfer(c->ue_xfer);
- if (err != USBD_IN_PROGRESS) {
- cue_stop(sc);
- return(EIO);
- }
-
- sc->cue_cdata.ue_tx_cnt++;
-
- return(0);
-}
-
-static void
-cue_start(struct ifnet *ifp)
-{
- struct cue_softc *sc;
- struct mbuf *m_head = NULL;
-
- sc = ifp->if_softc;
- CUE_LOCK(sc);
-
- if (ifp->if_drv_flags & IFF_DRV_OACTIVE) {
- CUE_UNLOCK(sc);
- return;
- }
-
- IF_DEQUEUE(&ifp->if_snd, m_head);
- if (m_head == NULL) {
- CUE_UNLOCK(sc);
- return;
- }
-
- if (cue_encap(sc, m_head, 0)) {
- IF_PREPEND(&ifp->if_snd, m_head);
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- CUE_UNLOCK(sc);
- return;
- }
-
- /*
- * If there's a BPF listener, bounce a copy of this frame
- * to him.
- */
- BPF_MTAP(ifp, m_head);
-
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
-
- /*
- * Set a timeout in case the chip goes out to lunch.
- */
- ifp->if_timer = 5;
- CUE_UNLOCK(sc);
-
- return;
-}
-
-static void
-cue_init(void *xsc)
-{
- struct cue_softc *sc = xsc;
- struct ifnet *ifp = sc->cue_ifp;
- struct ue_chain *c;
- usbd_status err;
- int i;
-
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- return;
-
- CUE_LOCK(sc);
-
- /*
- * Cancel pending I/O and free all RX/TX buffers.
- */
-#ifdef foo
- cue_reset(sc);
-#endif
-
- /* Set MAC address */
- for (i = 0; i < ETHER_ADDR_LEN; i++)
- cue_csr_write_1(sc, CUE_PAR0 - i, IF_LLADDR(sc->cue_ifp)[i]);
-
- /* Enable RX logic. */
- cue_csr_write_1(sc, CUE_ETHCTL, CUE_ETHCTL_RX_ON|CUE_ETHCTL_MCAST_ON);
-
- /* If we want promiscuous mode, set the allframes bit. */
- if (ifp->if_flags & IFF_PROMISC) {
- CUE_SETBIT(sc, CUE_ETHCTL, CUE_ETHCTL_PROMISC);
- } else {
- CUE_CLRBIT(sc, CUE_ETHCTL, CUE_ETHCTL_PROMISC);
- }
-
- /* Init TX ring. */
- if (usb_ether_tx_list_init(sc, &sc->cue_cdata,
- sc->cue_udev) == ENOBUFS) {
- device_printf(sc->cue_dev, "tx list init failed\n");
- CUE_UNLOCK(sc);
- return;
- }
-
- /* Init RX ring. */
- if (usb_ether_rx_list_init(sc, &sc->cue_cdata,
- sc->cue_udev) == ENOBUFS) {
- device_printf(sc->cue_dev, "rx list init failed\n");
- CUE_UNLOCK(sc);
- 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);
-
- /* 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) {
- device_printf(sc->cue_dev, "open rx pipe failed: %s\n",
- usbd_errstr(err));
- CUE_UNLOCK(sc);
- return;
- }
- err = usbd_open_pipe(sc->cue_iface, sc->cue_ed[CUE_ENDPT_TX],
- USBD_EXCLUSIVE_USE, &sc->cue_ep[CUE_ENDPT_TX]);
- if (err) {
- device_printf(sc->cue_dev, "open tx pipe failed: %s\n",
- usbd_errstr(err));
- CUE_UNLOCK(sc);
- return;
- }
-
- /* Start up the receive pipe. */
- for (i = 0; i < UE_RX_LIST_CNT; i++) {
- c = &sc->cue_cdata.ue_rx_chain[i];
- usbd_setup_xfer(c->ue_xfer, sc->cue_ep[CUE_ENDPT_RX],
- c, mtod(c->ue_mbuf, char *), UE_BUFSZ,
- USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, cue_rxeof);
- usbd_transfer(c->ue_xfer);
- }
-
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
-
- CUE_UNLOCK(sc);
-
- sc->cue_stat_ch = timeout(cue_tick, sc, hz);
-
- return;
-}
-
-static int
-cue_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
-{
- struct cue_softc *sc = ifp->if_softc;
- int error = 0;
-
- CUE_LOCK(sc);
-
- switch(command) {
- case SIOCSIFFLAGS:
- if (ifp->if_flags & IFF_UP) {
- if (ifp->if_drv_flags & IFF_DRV_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_drv_flags & IFF_DRV_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_drv_flags & IFF_DRV_RUNNING))
- cue_init(sc);
- } else {
- if (ifp->if_drv_flags & IFF_DRV_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 = ether_ioctl(ifp, command, data);
- break;
- }
-
- CUE_UNLOCK(sc);
-
- return(error);
-}
-
-static void
-cue_watchdog(struct ifnet *ifp)
-{
- struct cue_softc *sc;
- struct ue_chain *c;
- usbd_status stat;
-
- sc = ifp->if_softc;
- CUE_LOCK(sc);
-
- ifp->if_oerrors++;
- device_printf(sc->cue_dev, "watchdog timeout\n");
-
- c = &sc->cue_cdata.ue_tx_chain[0];
- usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &stat);
- cue_txeof(c->ue_xfer, c, stat);
-
- if (ifp->if_snd.ifq_head != NULL)
- cue_start(ifp);
- CUE_UNLOCK(sc);
-
- return;
-}
-
-/*
- * Stop the adapter and free any mbufs allocated to the
- * RX and TX lists.
- */
-static void
-cue_stop(struct cue_softc *sc)
-{
- usbd_status err;
- struct ifnet *ifp;
-
- CUE_LOCK(sc);
-
- ifp = sc->cue_ifp;
- ifp->if_timer = 0;
-
- cue_csr_write_1(sc, CUE_ETHCTL, 0);
- cue_reset(sc);
- untimeout(cue_tick, sc, sc->cue_stat_ch);
-
- /* Stop transfers. */
- if (sc->cue_ep[CUE_ENDPT_RX] != NULL) {
- err = usbd_abort_pipe(sc->cue_ep[CUE_ENDPT_RX]);
- if (err) {
- device_printf(sc->cue_dev, "abort rx pipe failed: %s\n",
- usbd_errstr(err));
- }
- err = usbd_close_pipe(sc->cue_ep[CUE_ENDPT_RX]);
- if (err) {
- device_printf(sc->cue_dev, "close rx pipe failed: %s\n",
- 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) {
- device_printf(sc->cue_dev, "abort tx pipe failed: %s\n",
- usbd_errstr(err));
- }
- err = usbd_close_pipe(sc->cue_ep[CUE_ENDPT_TX]);
- if (err) {
- device_printf(sc->cue_dev, "close tx pipe failed: %s\n",
- 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) {
- device_printf(sc->cue_dev, "abort intr pipe failed: %s\n",
- usbd_errstr(err));
- }
- err = usbd_close_pipe(sc->cue_ep[CUE_ENDPT_INTR]);
- if (err) {
- device_printf(sc->cue_dev, "close intr pipe failed: %s\n",
- usbd_errstr(err));
- }
- sc->cue_ep[CUE_ENDPT_INTR] = NULL;
- }
-
- /* Free RX resources. */
- usb_ether_rx_list_free(&sc->cue_cdata);
- /* Free TX resources. */
- usb_ether_tx_list_free(&sc->cue_cdata);
-
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
- CUE_UNLOCK(sc);
-
- return;
-}
-
-/*
- * Stop all chip I/O so that the kernel's probe routines don't
- * get confused by errant DMAs when rebooting.
- */
-static int
-cue_shutdown(device_t dev)
-{
- struct cue_softc *sc;
-
- sc = device_get_softc(dev);
-
- CUE_LOCK(sc);
- cue_reset(sc);
- cue_stop(sc);
- CUE_UNLOCK(sc);
-
- return (0);
-}
diff --git a/sys/dev/usb/if_cuereg.h b/sys/dev/usb/if_cuereg.h
deleted file mode 100644
index 4c81653..0000000
--- a/sys/dev/usb/if_cuereg.h
+++ /dev/null
@@ -1,168 +0,0 @@
-/*-
- * Copyright (c) 1997, 1998, 1999, 2000
- * Bill Paul <wpaul@ee.columbia.edu>. 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$
- */
-
-/*
- * 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 CUE_MIN_FRAMELEN 60
-#define CUE_RX_FRAMES 1
-#define CUE_TX_FRAMES 1
-
-#define CUE_CTL_READ 0x01
-#define CUE_CTL_WRITE 0x02
-
-#define CUE_CONFIG_NO 1
-
-/*
- * The interrupt endpoint is currently unused
- * by the KLSI 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;
-};
-
-#define CUE_INC(x, y) (x) = (x + 1) % y
-
-struct cue_softc {
- struct ifnet *cue_ifp;
- device_t cue_dev;
- usbd_device_handle cue_udev;
- usbd_interface_handle cue_iface;
- int cue_ed[CUE_ENDPT_MAX];
- usbd_pipe_handle cue_ep[CUE_ENDPT_MAX];
- u_int8_t cue_mctab[CUE_MCAST_TABLE_LEN];
- int cue_if_flags;
- u_int16_t cue_rxfilt;
- struct ue_cdata cue_cdata;
- struct callout_handle cue_stat_ch;
- struct mtx cue_mtx;
- char cue_dying;
- struct timeval cue_rx_notice;
- struct usb_qdat cue_qdat;
-};
-
-#if 0
-#define CUE_LOCK(_sc) mtx_lock(&(_sc)->cue_mtx)
-#define CUE_UNLOCK(_sc) mtx_unlock(&(_sc)->cue_mtx)
-#else
-#define CUE_LOCK(_sc)
-#define CUE_UNLOCK(_sc)
-#endif
diff --git a/sys/dev/usb/if_kue.c b/sys/dev/usb/if_kue.c
deleted file mode 100644
index f68eaa8..0000000
--- a/sys/dev/usb/if_kue.c
+++ /dev/null
@@ -1,1024 +0,0 @@
-/*-
- * Copyright (c) 1997, 1998, 1999, 2000
- * Bill Paul <wpaul@ee.columbia.edu>. 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * Kawasaki LSI KL5KUSB101B USB to ethernet adapter driver.
- *
- * Written by Bill Paul <wpaul@ee.columbia.edu>
- * Electrical Engineering Department
- * Columbia University, New York City
- */
-
-/*
- * The KLSI USB to ethernet adapter chip contains an USB serial interface,
- * ethernet MAC and embedded microcontroller (called the QT Engine).
- * The chip must have firmware loaded into it before it will operate.
- * Packets are passed between the chip and host via bulk transfers.
- * There is an interrupt endpoint mentioned in the software spec, however
- * it's currently unused. This device is 10Mbps half-duplex only, hence
- * there is no media selection logic. The MAC supports a 128 entry
- * multicast filter, though the exact size of the filter can depend
- * on the firmware. Curiously, while the software spec describes various
- * ethernet statistics counters, my sample adapter and firmware combination
- * claims not to support any statistics counters at all.
- *
- * Note that once we load the firmware in the device, we have to be
- * careful not to load it again: if you restart your computer but
- * leave the adapter attached to the USB controller, it may remain
- * powered on and retain its firmware. In this case, we don't need
- * to load the firmware a second time.
- *
- * Special thanks to Rob Furr for providing an ADS Technologies
- * adapter for development and testing. No monkeys were harmed during
- * the development of this driver.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/sockio.h>
-#include <sys/mbuf.h>
-#include <sys/malloc.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/socket.h>
-
-#include <net/if.h>
-#include <net/if_arp.h>
-#include <net/ethernet.h>
-#include <net/if_dl.h>
-#include <net/if_media.h>
-#include <net/if_types.h>
-
-#include <net/bpf.h>
-
-#include <sys/bus.h>
-#include <machine/bus.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include <dev/usb/usbdivar.h>
-#include "usbdevs.h"
-#include <dev/usb/usb_ethersubr.h>
-
-#include <dev/usb/if_kuereg.h>
-#include <dev/usb/kue_fw.h>
-
-MODULE_DEPEND(kue, usb, 1, 1, 1);
-MODULE_DEPEND(kue, ether, 1, 1, 1);
-
-/*
- * Various supported device vendors/products.
- */
-static struct kue_type kue_devs[] = {
- { USB_VENDOR_3COM, USB_PRODUCT_3COM_3C19250 },
- { USB_VENDOR_3COM, USB_PRODUCT_3COM_3C460 },
- { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_URE450 },
- { USB_VENDOR_ADS, USB_PRODUCT_ADS_UBS10BT },
- { USB_VENDOR_ADS, USB_PRODUCT_ADS_UBS10BTX },
- { USB_VENDOR_AOX, USB_PRODUCT_AOX_USB101 },
- { USB_VENDOR_ASANTE, USB_PRODUCT_ASANTE_EA },
- { USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC10T },
- { USB_VENDOR_ATEN, USB_PRODUCT_ATEN_DSB650C },
- { USB_VENDOR_COREGA, USB_PRODUCT_COREGA_ETHER_USB_T },
- { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650C },
- { USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_E45 },
- { USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_XX1 },
- { USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_XX2 },
- { USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBETT },
- { USB_VENDOR_JATON, USB_PRODUCT_JATON_EDA },
- { USB_VENDOR_KINGSTON, USB_PRODUCT_KINGSTON_XX1 },
- { USB_VENDOR_KLSI, USB_PRODUCT_AOX_USB101 },
- { USB_VENDOR_KLSI, USB_PRODUCT_KLSI_DUH3E10BT },
- { USB_VENDOR_KLSI, USB_PRODUCT_KLSI_DUH3E10BTN },
- { USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10T },
- { USB_VENDOR_MOBILITY, USB_PRODUCT_MOBILITY_EA },
- { USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_EA101 },
- { USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_EA101X },
- { USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_ENET },
- { USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_ENET2 },
- { USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_ENET3 },
- { USB_VENDOR_PORTGEAR, USB_PRODUCT_PORTGEAR_EA8 },
- { USB_VENDOR_PORTGEAR, USB_PRODUCT_PORTGEAR_EA9 },
- { USB_VENDOR_PORTSMITH, USB_PRODUCT_PORTSMITH_EEA },
- { USB_VENDOR_SHARK, USB_PRODUCT_SHARK_PA },
- { USB_VENDOR_SILICOM, USB_PRODUCT_SILICOM_U2E },
- { USB_VENDOR_SILICOM, USB_PRODUCT_SILICOM_GPE },
- { USB_VENDOR_SMC, USB_PRODUCT_SMC_2102USB },
- { 0, 0 }
-};
-
-static device_probe_t kue_match;
-static device_attach_t kue_attach;
-static device_detach_t kue_detach;
-static device_shutdown_t kue_shutdown;
-static int kue_encap(struct kue_softc *, struct mbuf *, int);
-static void kue_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
-static void kue_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
-static void kue_start(struct ifnet *);
-static void kue_rxstart(struct ifnet *);
-static int kue_ioctl(struct ifnet *, u_long, caddr_t);
-static void kue_init(void *);
-static void kue_stop(struct kue_softc *);
-static void kue_watchdog(struct ifnet *);
-
-static void kue_setmulti(struct kue_softc *);
-static void kue_reset(struct kue_softc *);
-
-static usbd_status kue_do_request(usbd_device_handle,
- usb_device_request_t *, void *);
-static usbd_status kue_ctl(struct kue_softc *, int, u_int8_t,
- u_int16_t, char *, int);
-static usbd_status kue_setword(struct kue_softc *, u_int8_t, u_int16_t);
-static int kue_load_fw(struct kue_softc *);
-
-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(kue, uhub, kue_driver, kue_devclass, usbd_driver_load, 0);
-
-/*
- * We have a custom do_request function which is almost like the
- * regular do_request function, except it has a much longer timeout.
- * Why? Because we need to make requests over the control endpoint
- * to download the firmware to the device, which can take longer
- * than the default timeout.
- */
-static usbd_status
-kue_do_request(usbd_device_handle dev, usb_device_request_t *req, void *data)
-{
- usbd_xfer_handle xfer;
- usbd_status err;
-
- xfer = usbd_alloc_xfer(dev);
- usbd_setup_default_xfer(xfer, dev, 0, 500000, req,
- data, UGETW(req->wLength), USBD_SHORT_XFER_OK, 0);
- err = usbd_sync_transfer(xfer);
- usbd_free_xfer(xfer);
- return(err);
-}
-
-static usbd_status
-kue_setword(struct kue_softc *sc, u_int8_t breq, u_int16_t word)
-{
- usbd_device_handle dev;
- usb_device_request_t req;
- usbd_status err;
-
- if (sc->kue_dying)
- return(USBD_NORMAL_COMPLETION);
-
- dev = sc->kue_udev;
-
- KUE_LOCK(sc);
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
-
- req.bRequest = breq;
- USETW(req.wValue, word);
- USETW(req.wIndex, 0);
- USETW(req.wLength, 0);
-
- err = kue_do_request(dev, &req, NULL);
-
- KUE_UNLOCK(sc);
-
- return(err);
-}
-
-static usbd_status
-kue_ctl(struct kue_softc *sc, int rw, u_int8_t breq, u_int16_t val,
- char *data, int len)
-{
- usbd_device_handle dev;
- usb_device_request_t req;
- usbd_status err;
-
- dev = sc->kue_udev;
-
- if (sc->kue_dying)
- return(USBD_NORMAL_COMPLETION);
-
- KUE_LOCK(sc);
-
- if (rw == KUE_CTL_WRITE)
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- else
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
-
- req.bRequest = breq;
- USETW(req.wValue, val);
- USETW(req.wIndex, 0);
- USETW(req.wLength, len);
-
- err = kue_do_request(dev, &req, data);
-
- KUE_UNLOCK(sc);
-
- return(err);
-}
-
-static int
-kue_load_fw(struct kue_softc *sc)
-{
- usbd_status err;
- usb_device_descriptor_t *dd;
- int hwrev;
-
- dd = &sc->kue_udev->ddesc;
- hwrev = UGETW(dd->bcdDevice);
-
- /*
- * First, check if we even need to load the firmware.
- * If the device was still attached when the system was
- * rebooted, it may already have firmware loaded in it.
- * If this is the case, we don't need to do it again.
- * And in fact, if we try to load it again, we'll hang,
- * so we have to avoid this condition if we don't want
- * to look stupid.
- *
- * We can test this quickly by checking the bcdRevision
- * code. The NIC will return a different revision code if
- * it's probed while the firmware is still loaded and
- * running.
- */
- if (hwrev == 0x0202)
- return(0);
-
- /* Load code segment */
- err = kue_ctl(sc, KUE_CTL_WRITE, KUE_CMD_SEND_SCAN,
- 0, kue_code_seg, sizeof(kue_code_seg));
- if (err) {
- device_printf(sc->kue_dev, "failed to load code segment: %s\n",
- usbd_errstr(err));
- return(ENXIO);
- }
-
- /* Load fixup segment */
- err = kue_ctl(sc, KUE_CTL_WRITE, KUE_CMD_SEND_SCAN,
- 0, kue_fix_seg, sizeof(kue_fix_seg));
- if (err) {
- device_printf(sc->kue_dev, "failed to load fixup segment: %s\n",
- usbd_errstr(err));
- return(ENXIO);
- }
-
- /* Send trigger command. */
- err = kue_ctl(sc, KUE_CTL_WRITE, KUE_CMD_SEND_SCAN,
- 0, kue_trig_seg, sizeof(kue_trig_seg));
- if (err) {
- device_printf(sc->kue_dev, "failed to load trigger segment: %s\n",
- usbd_errstr(err));
- return(ENXIO);
- }
-
- return(0);
-}
-
-static void
-kue_setmulti(struct kue_softc *sc)
-{
- struct ifnet *ifp;
- struct ifmultiaddr *ifma;
- int i = 0;
-
- ifp = sc->kue_ifp;
-
- if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
- sc->kue_rxfilt |= KUE_RXFILT_ALLMULTI;
- sc->kue_rxfilt &= ~KUE_RXFILT_MULTICAST;
- kue_setword(sc, KUE_CMD_SET_PKT_FILTER, sc->kue_rxfilt);
- return;
- }
-
- sc->kue_rxfilt &= ~KUE_RXFILT_ALLMULTI;
-
- IF_ADDR_LOCK(ifp);
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
- {
- 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++;
- }
- IF_ADDR_UNLOCK(ifp);
-
- if (i == KUE_MCFILTCNT(sc))
- sc->kue_rxfilt |= KUE_RXFILT_ALLMULTI;
- else {
- sc->kue_rxfilt |= KUE_RXFILT_MULTICAST;
- kue_ctl(sc, KUE_CTL_WRITE, KUE_CMD_SET_MCAST_FILTERS,
- i, sc->kue_mcfilters, i * ETHER_ADDR_LEN);
- }
-
- kue_setword(sc, KUE_CMD_SET_PKT_FILTER, sc->kue_rxfilt);
-
- return;
-}
-
-/*
- * Issue a SET_CONFIGURATION command to reset the MAC. This should be
- * done after the firmware is loaded into the adapter in order to
- * bring it into proper operation.
- */
-static void
-kue_reset(struct kue_softc *sc)
-{
- if (usbd_set_config_no(sc->kue_udev, KUE_CONFIG_NO, 0) ||
- usbd_device2interface_handle(sc->kue_udev, KUE_IFACE_IDX,
- &sc->kue_iface)) {
- device_printf(sc->kue_dev, "getting interface handle failed\n");
- }
-
- /* Wait a little while for the chip to get its brains in order. */
- DELAY(1000);
- return;
-}
-
-/*
- * Probe for a KLSI chip.
- */
-static int
-kue_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
- struct kue_type *t;
-
- if (!uaa->iface)
- return(UMATCH_NONE);
-
- t = kue_devs;
- while (t->kue_vid) {
- if (uaa->vendor == t->kue_vid && uaa->product == t->kue_did)
- return (UMATCH_VENDOR_PRODUCT);
- t++;
- }
- return (UMATCH_NONE);
-}
-
-/*
- * Attach the interface. Allocate softc structures, do
- * setup and ethernet/BPF attach.
- */
-static int
-kue_attach(device_t self)
-{
- struct kue_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- struct ifnet *ifp;
- usbd_status err;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
- int i;
-
- sc->kue_dev = self;
- sc->kue_iface = uaa->iface;
- sc->kue_udev = uaa->device;
-
- id = usbd_get_interface_descriptor(uaa->iface);
-
- /* Find endpoints. */
- for (i = 0; i < id->bNumEndpoints; i++) {
- ed = usbd_interface2endpoint_descriptor(uaa->iface, i);
- if (!ed) {
- device_printf(sc->kue_dev, "couldn't get ep %d\n", i);
- return ENXIO;
- }
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
- sc->kue_ed[KUE_ENDPT_RX] = ed->bEndpointAddress;
- } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
- sc->kue_ed[KUE_ENDPT_TX] = ed->bEndpointAddress;
- } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
- sc->kue_ed[KUE_ENDPT_INTR] = ed->bEndpointAddress;
- }
- }
-
- mtx_init(&sc->kue_mtx, device_get_nameunit(self), MTX_NETWORK_LOCK,
- MTX_DEF | MTX_RECURSE);
- KUE_LOCK(sc);
-
- /* Load the firmware into the NIC. */
- if (kue_load_fw(sc)) {
- KUE_UNLOCK(sc);
- mtx_destroy(&sc->kue_mtx);
- return ENXIO;
- }
-
- /* Reset the adapter. */
- kue_reset(sc);
-
- /* Read ethernet descriptor */
- err = kue_ctl(sc, KUE_CTL_READ, KUE_CMD_GET_ETHER_DESCRIPTOR,
- 0, (char *)&sc->kue_desc, sizeof(sc->kue_desc));
-
- sc->kue_mcfilters = malloc(KUE_MCFILTCNT(sc) * ETHER_ADDR_LEN,
- M_USBDEV, M_NOWAIT);
-
- ifp = sc->kue_ifp = if_alloc(IFT_ETHER);
- if (ifp == NULL) {
- device_printf(sc->kue_dev, "can not if_alloc()\n");
- KUE_UNLOCK(sc);
- mtx_destroy(&sc->kue_mtx);
- return ENXIO;
- }
- ifp->if_softc = sc;
- if_initname(ifp, "kue", device_get_unit(sc->kue_dev));
- ifp->if_mtu = ETHERMTU;
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
- IFF_NEEDSGIANT;
- ifp->if_ioctl = kue_ioctl;
- ifp->if_start = kue_start;
- ifp->if_watchdog = kue_watchdog;
- ifp->if_init = kue_init;
- ifp->if_baudrate = 10000000;
- ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
-
- sc->kue_qdat.ifp = ifp;
- sc->kue_qdat.if_rxstart = kue_rxstart;
-
- /*
- * Call MI attach routine.
- */
- ether_ifattach(ifp, sc->kue_desc.kue_macaddr);
- usb_register_netisr();
- sc->kue_dying = 0;
-
- KUE_UNLOCK(sc);
-
- return 0;
-}
-
-static int
-kue_detach(device_t dev)
-{
- struct kue_softc *sc;
- struct ifnet *ifp;
-
- sc = device_get_softc(dev);
- KUE_LOCK(sc);
- ifp = sc->kue_ifp;
-
- sc->kue_dying = 1;
-
- if (ifp != NULL) {
- ether_ifdetach(ifp);
- if_free(ifp);
- }
-
- if (sc->kue_ep[KUE_ENDPT_TX] != NULL)
- usbd_abort_pipe(sc->kue_ep[KUE_ENDPT_TX]);
- if (sc->kue_ep[KUE_ENDPT_RX] != NULL)
- usbd_abort_pipe(sc->kue_ep[KUE_ENDPT_RX]);
- if (sc->kue_ep[KUE_ENDPT_INTR] != NULL)
- usbd_abort_pipe(sc->kue_ep[KUE_ENDPT_INTR]);
-
- if (sc->kue_mcfilters != NULL)
- free(sc->kue_mcfilters, M_USBDEV);
-
- KUE_UNLOCK(sc);
- mtx_destroy(&sc->kue_mtx);
-
- return(0);
-}
-
-static void
-kue_rxstart(struct ifnet *ifp)
-{
- struct kue_softc *sc;
- struct ue_chain *c;
-
- sc = ifp->if_softc;
- KUE_LOCK(sc);
- c = &sc->kue_cdata.ue_rx_chain[sc->kue_cdata.ue_rx_prod];
-
- c->ue_mbuf = usb_ether_newbuf();
- if (c->ue_mbuf == NULL) {
- device_printf(sc->kue_dev, "no memory for rx list "
- "-- packet dropped!\n");
- ifp->if_ierrors++;
- KUE_UNLOCK(sc);
- return;
- }
-
- /* Setup new transfer. */
- usbd_setup_xfer(c->ue_xfer, sc->kue_ep[KUE_ENDPT_RX],
- c, mtod(c->ue_mbuf, char *), UE_BUFSZ, USBD_SHORT_XFER_OK,
- USBD_NO_TIMEOUT, kue_rxeof);
- usbd_transfer(c->ue_xfer);
-
- KUE_UNLOCK(sc);
-
- return;
-}
-
-/*
- * A frame has been uploaded: pass the resulting mbuf chain up to
- * the higher level protocols.
- */
-static void kue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv,
- usbd_status status)
-{
- struct kue_softc *sc;
- struct ue_chain *c;
- struct mbuf *m;
- struct ifnet *ifp;
- int total_len = 0;
- u_int16_t len;
-
- c = priv;
- sc = c->ue_sc;
- KUE_LOCK(sc);
- ifp = sc->kue_ifp;
-
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
- KUE_UNLOCK(sc);
- return;
- }
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
- KUE_UNLOCK(sc);
- return;
- }
- if (usbd_ratecheck(&sc->kue_rx_notice))
- device_printf(sc->kue_dev, "usb error on rx: %s\n",
- usbd_errstr(status));
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall(sc->kue_ep[KUE_ENDPT_RX]);
- goto done;
- }
-
- usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
- m = c->ue_mbuf;
- if (total_len <= 1)
- goto done;
-
- len = *mtod(m, u_int16_t *);
- m_adj(m, sizeof(u_int16_t));
-
- /* No errors; receive the packet. */
- total_len = len;
-
- if (len < sizeof(struct ether_header)) {
- ifp->if_ierrors++;
- goto done;
- }
-
- ifp->if_ipackets++;
- m->m_pkthdr.rcvif = (void *)&sc->kue_qdat;
- m->m_pkthdr.len = m->m_len = total_len;
-
- /* Put the packet on the special USB input queue. */
- usb_ether_input(m);
- KUE_UNLOCK(sc);
-
- return;
-done:
-
- /* Setup new transfer. */
- usbd_setup_xfer(c->ue_xfer, sc->kue_ep[KUE_ENDPT_RX],
- c, mtod(c->ue_mbuf, char *), UE_BUFSZ, USBD_SHORT_XFER_OK,
- USBD_NO_TIMEOUT, kue_rxeof);
- usbd_transfer(c->ue_xfer);
- KUE_UNLOCK(sc);
-
- return;
-}
-
-/*
- * A frame was downloaded to the chip. It's safe for us to clean up
- * the list buffers.
- */
-
-static void
-kue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- struct kue_softc *sc;
- struct ue_chain *c;
- struct ifnet *ifp;
- usbd_status err;
-
- c = priv;
- sc = c->ue_sc;
- KUE_LOCK(sc);
-
- ifp = sc->kue_ifp;
- ifp->if_timer = 0;
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
- KUE_UNLOCK(sc);
- return;
- }
- device_printf(sc->kue_dev, "usb error on tx: %s\n",
- usbd_errstr(status));
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall(sc->kue_ep[KUE_ENDPT_TX]);
- KUE_UNLOCK(sc);
- return;
- }
-
- usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &err);
-
- if (c->ue_mbuf != NULL) {
- c->ue_mbuf->m_pkthdr.rcvif = ifp;
- usb_tx_done(c->ue_mbuf);
- c->ue_mbuf = NULL;
- }
-
- if (err)
- ifp->if_oerrors++;
- else
- ifp->if_opackets++;
-
- KUE_UNLOCK(sc);
-
- return;
-}
-
-static int
-kue_encap(struct kue_softc *sc, struct mbuf *m, int idx)
-{
- int total_len;
- struct ue_chain *c;
- usbd_status err;
-
- c = &sc->kue_cdata.ue_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->ue_buf + 2);
- c->ue_mbuf = m;
-
- total_len = m->m_pkthdr.len + 2;
- total_len += 64 - (total_len % 64);
-
- /* Frame length is specified in the first 2 bytes of the buffer. */
- c->ue_buf[0] = (u_int8_t)m->m_pkthdr.len;
- c->ue_buf[1] = (u_int8_t)(m->m_pkthdr.len >> 8);
-
- usbd_setup_xfer(c->ue_xfer, sc->kue_ep[KUE_ENDPT_TX],
- c, c->ue_buf, total_len, 0, 10000, kue_txeof);
-
- /* Transmit */
- err = usbd_transfer(c->ue_xfer);
- if (err != USBD_IN_PROGRESS) {
- kue_stop(sc);
- return(EIO);
- }
-
- sc->kue_cdata.ue_tx_cnt++;
-
- return(0);
-}
-
-static void
-kue_start(struct ifnet *ifp)
-{
- struct kue_softc *sc;
- struct mbuf *m_head = NULL;
-
- sc = ifp->if_softc;
- KUE_LOCK(sc);
-
- if (ifp->if_drv_flags & IFF_DRV_OACTIVE) {
- KUE_UNLOCK(sc);
- return;
- }
-
- IF_DEQUEUE(&ifp->if_snd, m_head);
- if (m_head == NULL) {
- KUE_UNLOCK(sc);
- return;
- }
-
- if (kue_encap(sc, m_head, 0)) {
- IF_PREPEND(&ifp->if_snd, m_head);
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- KUE_UNLOCK(sc);
- return;
- }
-
- /*
- * If there's a BPF listener, bounce a copy of this frame
- * to him.
- */
- BPF_MTAP(ifp, m_head);
-
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
-
- /*
- * Set a timeout in case the chip goes out to lunch.
- */
- ifp->if_timer = 5;
- KUE_UNLOCK(sc);
-
- return;
-}
-
-static void
-kue_init(void *xsc)
-{
- struct kue_softc *sc = xsc;
- struct ifnet *ifp = sc->kue_ifp;
- struct ue_chain *c;
- usbd_status err;
- int i;
-
- KUE_LOCK(sc);
-
- if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
- KUE_UNLOCK(sc);
- return;
- }
-
- /* Set MAC address */
- kue_ctl(sc, KUE_CTL_WRITE, KUE_CMD_SET_MAC,
- 0, IF_LLADDR(sc->kue_ifp), ETHER_ADDR_LEN);
-
- sc->kue_rxfilt = KUE_RXFILT_UNICAST|KUE_RXFILT_BROADCAST;
-
- /* If we want promiscuous mode, set the allframes bit. */
- if (ifp->if_flags & IFF_PROMISC)
- sc->kue_rxfilt |= KUE_RXFILT_PROMISC;
-
- kue_setword(sc, KUE_CMD_SET_PKT_FILTER, sc->kue_rxfilt);
-
- /* I'm not sure how to tune these. */
-#ifdef notdef
- /*
- * Leave this one alone for now; setting it
- * wrong causes lockups on some machines/controllers.
- */
- kue_setword(sc, KUE_CMD_SET_SOFS, 1);
-#endif
- kue_setword(sc, KUE_CMD_SET_URB_SIZE, 64);
-
- /* Init TX ring. */
- if (usb_ether_tx_list_init(sc, &sc->kue_cdata,
- sc->kue_udev) == ENOBUFS) {
- device_printf(sc->kue_dev, "tx list init failed\n");
- KUE_UNLOCK(sc);
- return;
- }
-
- /* Init RX ring. */
- if (usb_ether_rx_list_init(sc, &sc->kue_cdata,
- sc->kue_udev) == ENOBUFS) {
- device_printf(sc->kue_dev, "rx list init failed\n");
- KUE_UNLOCK(sc);
- return;
- }
-
- /* Load the multicast filter. */
- kue_setmulti(sc);
-
- /* Open RX and TX pipes. */
- err = usbd_open_pipe(sc->kue_iface, sc->kue_ed[KUE_ENDPT_RX],
- USBD_EXCLUSIVE_USE, &sc->kue_ep[KUE_ENDPT_RX]);
- if (err) {
- device_printf(sc->kue_dev, "open rx pipe failed: %s\n",
- usbd_errstr(err));
- KUE_UNLOCK(sc);
- return;
- }
-
- err = usbd_open_pipe(sc->kue_iface, sc->kue_ed[KUE_ENDPT_TX],
- USBD_EXCLUSIVE_USE, &sc->kue_ep[KUE_ENDPT_TX]);
- if (err) {
- device_printf(sc->kue_dev, "open tx pipe failed: %s\n",
- usbd_errstr(err));
- KUE_UNLOCK(sc);
- return;
- }
-
- /* Start up the receive pipe. */
- for (i = 0; i < UE_RX_LIST_CNT; i++) {
- c = &sc->kue_cdata.ue_rx_chain[i];
- usbd_setup_xfer(c->ue_xfer, sc->kue_ep[KUE_ENDPT_RX],
- c, mtod(c->ue_mbuf, char *), UE_BUFSZ,
- USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, kue_rxeof);
- usbd_transfer(c->ue_xfer);
- }
-
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
-
- KUE_UNLOCK(sc);
-
- return;
-}
-
-static int
-kue_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
-{
- struct kue_softc *sc = ifp->if_softc;
- int error = 0;
-
- KUE_LOCK(sc);
-
- switch(command) {
- case SIOCSIFFLAGS:
- if (ifp->if_flags & IFF_UP) {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
- ifp->if_flags & IFF_PROMISC &&
- !(sc->kue_if_flags & IFF_PROMISC)) {
- sc->kue_rxfilt |= KUE_RXFILT_PROMISC;
- kue_setword(sc, KUE_CMD_SET_PKT_FILTER,
- sc->kue_rxfilt);
- } else if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
- !(ifp->if_flags & IFF_PROMISC) &&
- sc->kue_if_flags & IFF_PROMISC) {
- sc->kue_rxfilt &= ~KUE_RXFILT_PROMISC;
- kue_setword(sc, KUE_CMD_SET_PKT_FILTER,
- sc->kue_rxfilt);
- } else if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
- kue_init(sc);
- } else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- kue_stop(sc);
- }
- sc->kue_if_flags = ifp->if_flags;
- error = 0;
- break;
- case SIOCADDMULTI:
- case SIOCDELMULTI:
- kue_setmulti(sc);
- error = 0;
- break;
- default:
- error = ether_ioctl(ifp, command, data);
- break;
- }
-
- KUE_UNLOCK(sc);
-
- return(error);
-}
-
-static void
-kue_watchdog(struct ifnet *ifp)
-{
- struct kue_softc *sc;
- struct ue_chain *c;
- usbd_status stat;
-
- sc = ifp->if_softc;
- KUE_LOCK(sc);
- ifp->if_oerrors++;
- device_printf(sc->kue_dev, "watchdog timeout\n");
-
- c = &sc->kue_cdata.ue_tx_chain[0];
- usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &stat);
- kue_txeof(c->ue_xfer, c, stat);
-
- if (ifp->if_snd.ifq_head != NULL)
- kue_start(ifp);
- KUE_UNLOCK(sc);
-
- return;
-}
-
-/*
- * Stop the adapter and free any mbufs allocated to the
- * RX and TX lists.
- */
-static void
-kue_stop(struct kue_softc *sc)
-{
- usbd_status err;
- struct ifnet *ifp;
-
- KUE_LOCK(sc);
- ifp = sc->kue_ifp;
- ifp->if_timer = 0;
-
- /* Stop transfers. */
- if (sc->kue_ep[KUE_ENDPT_RX] != NULL) {
- err = usbd_abort_pipe(sc->kue_ep[KUE_ENDPT_RX]);
- if (err) {
- device_printf(sc->kue_dev, "abort rx pipe failed: %s\n",
- usbd_errstr(err));
- }
- err = usbd_close_pipe(sc->kue_ep[KUE_ENDPT_RX]);
- if (err) {
- device_printf(sc->kue_dev, "close rx pipe failed: %s\n",
- usbd_errstr(err));
- }
- sc->kue_ep[KUE_ENDPT_RX] = NULL;
- }
-
- if (sc->kue_ep[KUE_ENDPT_TX] != NULL) {
- err = usbd_abort_pipe(sc->kue_ep[KUE_ENDPT_TX]);
- if (err) {
- device_printf(sc->kue_dev, "abort tx pipe failed: %s\n",
- usbd_errstr(err));
- }
- err = usbd_close_pipe(sc->kue_ep[KUE_ENDPT_TX]);
- if (err) {
- device_printf(sc->kue_dev, "close tx pipe failed: %s\n",
- usbd_errstr(err));
- }
- sc->kue_ep[KUE_ENDPT_TX] = NULL;
- }
-
- if (sc->kue_ep[KUE_ENDPT_INTR] != NULL) {
- err = usbd_abort_pipe(sc->kue_ep[KUE_ENDPT_INTR]);
- if (err) {
- device_printf(sc->kue_dev, "abort intr pipe failed: %s\n",
- usbd_errstr(err));
- }
- err = usbd_close_pipe(sc->kue_ep[KUE_ENDPT_INTR]);
- if (err) {
- device_printf(sc->kue_dev, "close intr pipe failed: %s\n",
- usbd_errstr(err));
- }
- sc->kue_ep[KUE_ENDPT_INTR] = NULL;
- }
-
- /* Free RX resources. */
- usb_ether_rx_list_free(&sc->kue_cdata);
- /* Free TX resources. */
- usb_ether_tx_list_free(&sc->kue_cdata);
-
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
- KUE_UNLOCK(sc);
-
- return;
-}
-
-/*
- * Stop all chip I/O so that the kernel's probe routines don't
- * get confused by errant DMAs when rebooting.
- */
-static int
-kue_shutdown(device_t dev)
-{
- struct kue_softc *sc;
-
- sc = device_get_softc(dev);
-
- kue_stop(sc);
-
- return (0);
-}
diff --git a/sys/dev/usb/if_kuereg.h b/sys/dev/usb/if_kuereg.h
deleted file mode 100644
index 595eaa7..0000000
--- a/sys/dev/usb/if_kuereg.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/*-
- * Copyright (c) 1997, 1998, 1999, 2000
- * Bill Paul <wpaul@ee.columbia.edu>. 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$
- */
-
-/*
- * Definitions for the KLSI KL5KUSB101B USB to ethernet controller.
- * The KLSI part is controlled via vendor control requests, the structure
- * of which depend a bit on the firmware running on the internal
- * microcontroller. The one exception is the 'send scan data' command,
- * which is used to load the firmware.
- */
-
-#define KUE_CMD_GET_ETHER_DESCRIPTOR 0x00
-#define KUE_CMD_SET_MCAST_FILTERS 0x01
-#define KUE_CMD_SET_PKT_FILTER 0x02
-#define KUE_CMD_GET_ETHERSTATS 0x03
-#define KUE_CMD_GET_GPIO 0x04
-#define KUE_CMD_SET_GPIO 0x05
-#define KUE_CMD_SET_MAC 0x06
-#define KUE_CMD_GET_MAC 0x07
-#define KUE_CMD_SET_URB_SIZE 0x08
-#define KUE_CMD_SET_SOFS 0x09
-#define KUE_CMD_SET_EVEN_PKTS 0x0A
-#define KUE_CMD_SEND_SCAN 0xFF
-
-struct kue_ether_desc {
- u_int8_t kue_len;
- u_int8_t kue_rsvd0;
- u_int8_t kue_rsvd1;
- u_int8_t kue_macaddr[ETHER_ADDR_LEN];
- u_int8_t kue_etherstats[4];
- u_int8_t kue_maxseg[2];
- u_int8_t kue_mcastfilt[2];
- u_int8_t kue_rsvd2;
-};
-
-#define KUE_ETHERSTATS(x) \
- (*(u_int32_t *)&(x)->kue_desc.kue_etherstats)
-#define KUE_MAXSEG(x) \
- (*(u_int16_t *)&(x)->kue_desc.kue_maxseg)
-#define KUE_MCFILTCNT(x) \
- ((*(u_int16_t *)&(x)->kue_desc.kue_mcastfilt) & 0x7FFF)
-#define KUE_MCFILT(x, y) \
- (char *)&(sc->kue_mcfilters[y * ETHER_ADDR_LEN])
-
-#define KUE_STAT_TX_OK 0x00000001
-#define KUE_STAT_RX_OK 0x00000002
-#define KUE_STAT_TX_ERR 0x00000004
-#define KUE_STAT_RX_ERR 0x00000008
-#define KUE_STAT_RX_NOBUF 0x00000010
-#define KUE_STAT_TX_UCAST_BYTES 0x00000020
-#define KUE_STAT_TX_UCAST_FRAMES 0x00000040
-#define KUE_STAT_TX_MCAST_BYTES 0x00000080
-#define KUE_STAT_TX_MCAST_FRAMES 0x00000100
-#define KUE_STAT_TX_BCAST_BYTES 0x00000200
-#define KUE_STAT_TX_BCAST_FRAMES 0x00000400
-#define KUE_STAT_RX_UCAST_BYTES 0x00000800
-#define KUE_STAT_RX_UCAST_FRAMES 0x00001000
-#define KUE_STAT_RX_MCAST_BYTES 0x00002000
-#define KUE_STAT_RX_MCAST_FRAMES 0x00004000
-#define KUE_STAT_RX_BCAST_BYTES 0x00008000
-#define KUE_STAT_RX_BCAST_FRAMES 0x00010000
-#define KUE_STAT_RX_CRCERR 0x00020000
-#define KUE_STAT_TX_QUEUE_LENGTH 0x00040000
-#define KUE_STAT_RX_ALIGNERR 0x00080000
-#define KUE_STAT_TX_SINGLECOLL 0x00100000
-#define KUE_STAT_TX_MULTICOLL 0x00200000
-#define KUE_STAT_TX_DEFERRED 0x00400000
-#define KUE_STAT_TX_MAXCOLLS 0x00800000
-#define KUE_STAT_RX_OVERRUN 0x01000000
-#define KUE_STAT_TX_UNDERRUN 0x02000000
-#define KUE_STAT_TX_SQE_ERR 0x04000000
-#define KUE_STAT_TX_CARRLOSS 0x08000000
-#define KUE_STAT_RX_LATECOLL 0x10000000
-
-#define KUE_RXFILT_PROMISC 0x0001
-#define KUE_RXFILT_ALLMULTI 0x0002
-#define KUE_RXFILT_UNICAST 0x0004
-#define KUE_RXFILT_BROADCAST 0x0008
-#define KUE_RXFILT_MULTICAST 0x0010
-
-#define KUE_TIMEOUT 1000
-#define KUE_MIN_FRAMELEN 60
-
-#define KUE_CTL_READ 0x01
-#define KUE_CTL_WRITE 0x02
-
-#define KUE_CONFIG_NO 1
-#define KUE_IFACE_IDX 0
-
-/*
- * The interrupt endpoint is currently unused
- * by the KLSI part.
- */
-#define KUE_ENDPT_RX 0x0
-#define KUE_ENDPT_TX 0x1
-#define KUE_ENDPT_INTR 0x2
-#define KUE_ENDPT_MAX 0x3
-
-struct kue_type {
- u_int16_t kue_vid;
- u_int16_t kue_did;
-};
-
-#define KUE_INC(x, y) (x) = (x + 1) % y
-
-struct kue_softc {
- struct ifnet *kue_ifp;
- device_t kue_dev;
- usbd_device_handle kue_udev;
- usbd_interface_handle kue_iface;
- struct kue_ether_desc kue_desc;
- int kue_ed[KUE_ENDPT_MAX];
- usbd_pipe_handle kue_ep[KUE_ENDPT_MAX];
- int kue_if_flags;
- u_int16_t kue_rxfilt;
- u_int8_t *kue_mcfilters;
- struct ue_cdata kue_cdata;
- struct mtx kue_mtx;
- char kue_dying;
- struct timeval kue_rx_notice;
- struct usb_qdat kue_qdat;
-};
-
-#if 0
-#define KUE_LOCK(_sc) mtx_lock(&(_sc)->kue_mtx)
-#define KUE_UNLOCK(_sc) mtx_unlock(&(_sc)->kue_mtx)
-#else
-#define KUE_LOCK(_sc)
-#define KUE_UNLOCK(_sc)
-#endif
diff --git a/sys/dev/usb/if_rue.c b/sys/dev/usb/if_rue.c
deleted file mode 100644
index 4449f7d..0000000
--- a/sys/dev/usb/if_rue.c
+++ /dev/null
@@ -1,1393 +0,0 @@
-/*-
- * Copyright (c) 2001-2003, Shunsuke Akiyama <akiyama@FreeBSD.org>.
- * Copyright (c) 1997, 1998, 1999, 2000 Bill Paul <wpaul@ee.columbia.edu>.
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- */
-/*-
- * Copyright (c) 1997, 1998, 1999, 2000
- * Bill Paul <wpaul@ee.columbia.edu>. 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * RealTek RTL8150 USB to fast ethernet controller driver.
- * Datasheet is available from
- * ftp://ftp.realtek.com.tw/lancard/data_sheet/8150/.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/sockio.h>
-#include <sys/mbuf.h>
-#include <sys/malloc.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/socket.h>
-#include <sys/sysctl.h>
-
-#include <net/if.h>
-#include <net/if_arp.h>
-#include <net/ethernet.h>
-#include <net/if_dl.h>
-#include <net/if_media.h>
-#include <net/if_types.h>
-
-#include <net/bpf.h>
-
-#include <sys/bus.h>
-#include <machine/bus.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include <dev/usb/usbdivar.h>
-#include "usbdevs.h"
-#include <dev/usb/usb_ethersubr.h>
-
-#include <dev/mii/mii.h>
-#include <dev/mii/miivar.h>
-
-#include <dev/usb/if_ruereg.h>
-
-/* "device miibus" required. See GENERIC if you get errors here. */
-#include "miibus_if.h"
-
-#ifdef USB_DEBUG
-static int ruedebug = 0;
-SYSCTL_NODE(_hw_usb, OID_AUTO, rue, CTLFLAG_RW, 0, "USB rue");
-SYSCTL_INT(_hw_usb_rue, OID_AUTO, debug, CTLFLAG_RW,
- &ruedebug, 0, "rue debug level");
-
-#define DPRINTFN(n, x) do { \
- if (ruedebug > (n)) \
- printf x; \
- } while (0);
-#else
-#define DPRINTFN(n, x)
-#endif
-#define DPRINTF(x) DPRINTFN(0, x)
-
-/*
- * Various supported device vendors/products.
- */
-
-static struct rue_type rue_devs[] = {
- { USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUAKTX },
- { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_USBKR100 },
- { 0, 0 }
-};
-
-static device_probe_t rue_match;
-static device_attach_t rue_attach;
-static device_detach_t rue_detach;
-static device_shutdown_t rue_shutdown;
-static miibus_readreg_t rue_miibus_readreg;
-static miibus_writereg_t rue_miibus_writereg;
-static miibus_statchg_t rue_miibus_statchg;
-
-static int rue_encap(struct rue_softc *, struct mbuf *, int);
-#ifdef RUE_INTR_PIPE
-static void rue_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
-#endif
-static void rue_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
-static void rue_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
-static void rue_tick(void *);
-static void rue_tick_task(void *);
-static void rue_rxstart(struct ifnet *);
-static void rue_start(struct ifnet *);
-static int rue_ioctl(struct ifnet *, u_long, caddr_t);
-static void rue_init(void *);
-static void rue_stop(struct rue_softc *);
-static void rue_watchdog(struct ifnet *);
-static int rue_ifmedia_upd(struct ifnet *);
-static void rue_ifmedia_sts(struct ifnet *, struct ifmediareq *);
-
-static void rue_setmulti(struct rue_softc *);
-static void rue_reset(struct rue_softc *);
-
-static int rue_read_mem(struct rue_softc *, u_int16_t, void *, u_int16_t);
-static int rue_write_mem(struct rue_softc *, u_int16_t, void *, u_int16_t);
-static int rue_csr_read_1(struct rue_softc *, int);
-static int rue_csr_write_1(struct rue_softc *, int, u_int8_t);
-static int rue_csr_read_2(struct rue_softc *, int);
-static int rue_csr_write_2(struct rue_softc *, int, u_int16_t);
-static int rue_csr_write_4(struct rue_softc *, int, u_int32_t);
-
-static device_method_t rue_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, rue_match),
- DEVMETHOD(device_attach, rue_attach),
- DEVMETHOD(device_detach, rue_detach),
- DEVMETHOD(device_shutdown, rue_shutdown),
-
- /* Bus interface */
- DEVMETHOD(bus_print_child, bus_generic_print_child),
- DEVMETHOD(bus_driver_added, bus_generic_driver_added),
-
- /* MII interface */
- DEVMETHOD(miibus_readreg, rue_miibus_readreg),
- DEVMETHOD(miibus_writereg, rue_miibus_writereg),
- DEVMETHOD(miibus_statchg, rue_miibus_statchg),
-
- { 0, 0 }
-};
-
-static driver_t rue_driver = {
- "rue",
- rue_methods,
- sizeof(struct rue_softc)
-};
-
-static devclass_t rue_devclass;
-
-DRIVER_MODULE(rue, uhub, rue_driver, rue_devclass, usbd_driver_load, 0);
-DRIVER_MODULE(miibus, rue, miibus_driver, miibus_devclass, 0, 0);
-MODULE_DEPEND(rue, usb, 1, 1, 1);
-MODULE_DEPEND(rue, ether, 1, 1, 1);
-MODULE_DEPEND(rue, miibus, 1, 1, 1);
-
-#define RUE_SETBIT(sc, reg, x) \
- rue_csr_write_1(sc, reg, rue_csr_read_1(sc, reg) | (x))
-
-#define RUE_CLRBIT(sc, reg, x) \
- rue_csr_write_1(sc, reg, rue_csr_read_1(sc, reg) & ~(x))
-
-#define RUE_SETBIT_2(sc, reg, x) \
- rue_csr_write_2(sc, reg, rue_csr_read_2(sc, reg) | (x))
-
-#define RUE_CLRBIT_2(sc, reg, x) \
- rue_csr_write_2(sc, reg, rue_csr_read_2(sc, reg) & ~(x))
-
-static int
-rue_read_mem(struct rue_softc *sc, u_int16_t addr, void *buf, u_int16_t len)
-{
- usb_device_request_t req;
- usbd_status err;
-
- if (sc->rue_dying)
- return (0);
-
- RUE_LOCK(sc);
-
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = UR_SET_ADDRESS;
- USETW(req.wValue, addr);
- USETW(req.wIndex, 0);
- USETW(req.wLength, len);
-
- err = usbd_do_request(sc->rue_udev, &req, buf);
-
- RUE_UNLOCK(sc);
-
- if (err) {
- device_printf(sc->rue_dev, "control pipe read failed: %s\n",
- usbd_errstr(err));
- return (-1);
- }
-
- return (0);
-}
-
-static int
-rue_write_mem(struct rue_softc *sc, u_int16_t addr, void *buf, u_int16_t len)
-{
- usb_device_request_t req;
- usbd_status err;
-
- if (sc->rue_dying)
- return (0);
-
- RUE_LOCK(sc);
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = UR_SET_ADDRESS;
- USETW(req.wValue, addr);
- USETW(req.wIndex, 0);
- USETW(req.wLength, len);
-
- err = usbd_do_request(sc->rue_udev, &req, buf);
-
- RUE_UNLOCK(sc);
-
- if (err) {
- device_printf(sc->rue_dev, "control pipe write failed: %s\n",
- usbd_errstr(err));
- return (-1);
- }
-
- return (0);
-}
-
-static int
-rue_csr_read_1(struct rue_softc *sc, int reg)
-{
- int err;
- u_int8_t val = 0;
-
- err = rue_read_mem(sc, reg, &val, 1);
-
- if (err)
- return (0);
-
- return (val);
-}
-
-static int
-rue_csr_read_2(struct rue_softc *sc, int reg)
-{
- int err;
- u_int16_t val = 0;
- uWord w;
-
- USETW(w, val);
- err = rue_read_mem(sc, reg, &w, 2);
- val = UGETW(w);
-
- if (err)
- return (0);
-
- return (val);
-}
-
-static int
-rue_csr_write_1(struct rue_softc *sc, int reg, u_int8_t val)
-{
- int err;
-
- err = rue_write_mem(sc, reg, &val, 1);
-
- if (err)
- return (-1);
-
- return (0);
-}
-
-static int
-rue_csr_write_2(struct rue_softc *sc, int reg, u_int16_t val)
-{
- int err;
- uWord w;
-
- USETW(w, val);
- err = rue_write_mem(sc, reg, &w, 2);
-
- if (err)
- return (-1);
-
- return (0);
-}
-
-static int
-rue_csr_write_4(struct rue_softc *sc, int reg, u_int32_t val)
-{
- int err;
- uDWord dw;
-
- USETDW(dw, val);
- err = rue_write_mem(sc, reg, &dw, 4);
-
- if (err)
- return (-1);
-
- return (0);
-}
-
-static int
-rue_miibus_readreg(device_t dev, int phy, int reg)
-{
- struct rue_softc *sc = device_get_softc(dev);
- int rval;
- int ruereg;
-
- if (phy != 0) /* RTL8150 supports PHY == 0, only */
- return (0);
-
- switch (reg) {
- case MII_BMCR:
- ruereg = RUE_BMCR;
- break;
- case MII_BMSR:
- ruereg = RUE_BMSR;
- break;
- case MII_ANAR:
- ruereg = RUE_ANAR;
- break;
- case MII_ANER:
- ruereg = RUE_AER;
- break;
- case MII_ANLPAR:
- ruereg = RUE_ANLP;
- break;
- case MII_PHYIDR1:
- case MII_PHYIDR2:
- return (0);
- break;
- default:
- if (RUE_REG_MIN <= reg && reg <= RUE_REG_MAX) {
- rval = rue_csr_read_1(sc, reg);
- return (rval);
- }
- device_printf(sc->rue_dev, "bad phy register\n");
- return (0);
- }
-
- rval = rue_csr_read_2(sc, ruereg);
-
- return (rval);
-}
-
-static int
-rue_miibus_writereg(device_t dev, int phy, int reg, int data)
-{
- struct rue_softc *sc = device_get_softc(dev);
- int ruereg;
-
- if (phy != 0) /* RTL8150 supports PHY == 0, only */
- return (0);
-
- switch (reg) {
- case MII_BMCR:
- ruereg = RUE_BMCR;
- break;
- case MII_BMSR:
- ruereg = RUE_BMSR;
- break;
- case MII_ANAR:
- ruereg = RUE_ANAR;
- break;
- case MII_ANER:
- ruereg = RUE_AER;
- break;
- case MII_ANLPAR:
- ruereg = RUE_ANLP;
- break;
- case MII_PHYIDR1:
- case MII_PHYIDR2:
- return (0);
- break;
- default:
- if (RUE_REG_MIN <= reg && reg <= RUE_REG_MAX) {
- rue_csr_write_1(sc, reg, data);
- return (0);
- }
- device_printf(sc->rue_dev, "bad phy register\n");
- return (0);
- }
- rue_csr_write_2(sc, ruereg, data);
-
- return (0);
-}
-
-static void
-rue_miibus_statchg(device_t dev)
-{
- /*
- * When the code below is enabled the card starts doing weird
- * things after link going from UP to DOWN and back UP.
- *
- * Looks like some of register writes below messes up PHY
- * interface.
- *
- * No visible regressions were found after commenting this code
- * out, so that disable it for good.
- */
-#if 0
- struct rue_softc *sc = device_get_softc(dev);
- struct mii_data *mii = GET_MII(sc);
- int bmcr;
-
- RUE_CLRBIT(sc, RUE_CR, (RUE_CR_RE | RUE_CR_TE));
-
- bmcr = rue_csr_read_2(sc, RUE_BMCR);
-
- if (IFM_SUBTYPE(mii->mii_media_active) == IFM_100_TX)
- bmcr |= RUE_BMCR_SPD_SET;
- else
- bmcr &= ~RUE_BMCR_SPD_SET;
-
- if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX)
- bmcr |= RUE_BMCR_DUPLEX;
- else
- bmcr &= ~RUE_BMCR_DUPLEX;
-
- rue_csr_write_2(sc, RUE_BMCR, bmcr);
-
- RUE_SETBIT(sc, RUE_CR, (RUE_CR_RE | RUE_CR_TE));
-#endif
-}
-
-/*
- * Program the 64-bit multicast hash filter.
- */
-
-static void
-rue_setmulti(struct rue_softc *sc)
-{
- struct ifnet *ifp;
- int h = 0;
- u_int32_t hashes[2] = { 0, 0 };
- struct ifmultiaddr *ifma;
- u_int32_t rxcfg;
- int mcnt = 0;
-
- ifp = sc->rue_ifp;
-
- rxcfg = rue_csr_read_2(sc, RUE_RCR);
-
- if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
- rxcfg |= (RUE_RCR_AAM | RUE_RCR_AAP);
- rxcfg &= ~RUE_RCR_AM;
- rue_csr_write_2(sc, RUE_RCR, rxcfg);
- rue_csr_write_4(sc, RUE_MAR0, 0xFFFFFFFF);
- rue_csr_write_4(sc, RUE_MAR4, 0xFFFFFFFF);
- return;
- }
-
- /* first, zot all the existing hash bits */
- rue_csr_write_4(sc, RUE_MAR0, 0);
- rue_csr_write_4(sc, RUE_MAR4, 0);
-
- /* now program new ones */
- IF_ADDR_LOCK(ifp);
- TAILQ_FOREACH (ifma, &ifp->if_multiaddrs, ifma_link)
- {
- if (ifma->ifma_addr->sa_family != AF_LINK)
- continue;
- h = ether_crc32_be(LLADDR((struct sockaddr_dl *)
- ifma->ifma_addr), ETHER_ADDR_LEN) >> 26;
- if (h < 32)
- hashes[0] |= (1 << h);
- else
- hashes[1] |= (1 << (h - 32));
- mcnt++;
- }
- IF_ADDR_UNLOCK(ifp);
-
- if (mcnt)
- rxcfg |= RUE_RCR_AM;
- else
- rxcfg &= ~RUE_RCR_AM;
-
- rxcfg &= ~(RUE_RCR_AAM | RUE_RCR_AAP);
-
- rue_csr_write_2(sc, RUE_RCR, rxcfg);
- rue_csr_write_4(sc, RUE_MAR0, hashes[0]);
- rue_csr_write_4(sc, RUE_MAR4, hashes[1]);
-}
-
-static void
-rue_reset(struct rue_softc *sc)
-{
- int i;
-
- rue_csr_write_1(sc, RUE_CR, RUE_CR_SOFT_RST);
-
- for (i = 0; i < RUE_TIMEOUT; i++) {
- DELAY(500);
- if (!(rue_csr_read_1(sc, RUE_CR) & RUE_CR_SOFT_RST))
- break;
- }
- if (i == RUE_TIMEOUT)
- device_printf(sc->rue_dev, "reset never completed!\n");
-
- DELAY(10000);
-}
-
-/*
- * Probe for a RTL8150 chip.
- */
-
-static int
-rue_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
- struct rue_type *t;
-
- if (uaa->iface == NULL)
- return (UMATCH_NONE);
-
- t = rue_devs;
- while (t->rue_vid) {
- if (uaa->vendor == t->rue_vid &&
- uaa->product == t->rue_did) {
- return (UMATCH_VENDOR_PRODUCT);
- }
- t++;
- }
-
- return (UMATCH_NONE);
-}
-
-/*
- * Attach the interface. Allocate softc structures, do ifmedia
- * setup and ethernet/BPF attach.
- */
-
-static int
-rue_attach(device_t self)
-{
- struct rue_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- u_char eaddr[ETHER_ADDR_LEN];
- struct ifnet *ifp;
- usbd_interface_handle iface;
- usbd_status err;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
- int i;
- struct rue_type *t;
-
- sc->rue_dev = self;
- sc->rue_udev = uaa->device;
-
- if (usbd_set_config_no(sc->rue_udev, RUE_CONFIG_NO, 0)) {
- device_printf(sc->rue_dev, "getting interface handle failed\n");
- goto error;
- }
-
- usb_init_task(&sc->rue_tick_task, rue_tick_task, sc);
-
- err = usbd_device2interface_handle(uaa->device, RUE_IFACE_IDX, &iface);
- if (err) {
- device_printf(sc->rue_dev, "getting interface handle failed\n");
- goto error;
- }
-
- sc->rue_iface = iface;
-
- t = rue_devs;
- while (t->rue_vid) {
- if (uaa->vendor == t->rue_vid &&
- uaa->product == t->rue_did) {
- sc->rue_info = t;
- break;
- }
- t++;
- }
-
- id = usbd_get_interface_descriptor(sc->rue_iface);
-
- /* Find endpoints */
- for (i = 0; i < id->bNumEndpoints; i++) {
- ed = usbd_interface2endpoint_descriptor(iface, i);
- if (ed == NULL) {
- device_printf(sc->rue_dev, "couldn't get ep %d\n", i);
- goto error;
- }
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
- sc->rue_ed[RUE_ENDPT_RX] = ed->bEndpointAddress;
- } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
- sc->rue_ed[RUE_ENDPT_TX] = ed->bEndpointAddress;
- } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
- sc->rue_ed[RUE_ENDPT_INTR] = ed->bEndpointAddress;
- }
- }
-
- mtx_init(&sc->rue_mtx, device_get_nameunit(self), MTX_NETWORK_LOCK,
- MTX_DEF | MTX_RECURSE);
- RUE_LOCK(sc);
-
- /* Reset the adapter */
- rue_reset(sc);
-
- /* Get station address from the EEPROM */
- err = rue_read_mem(sc, RUE_EEPROM_IDR0,
- (caddr_t)&eaddr, ETHER_ADDR_LEN);
- if (err) {
- device_printf(sc->rue_dev, "couldn't get station address\n");
- goto error1;
- }
-
- ifp = sc->rue_ifp = if_alloc(IFT_ETHER);
- if (ifp == NULL) {
- device_printf(sc->rue_dev, "can not if_alloc()\n");
- goto error1;
- }
- ifp->if_softc = sc;
- if_initname(ifp, "rue", device_get_unit(sc->rue_dev));
- ifp->if_mtu = ETHERMTU;
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
- IFF_NEEDSGIANT;
- ifp->if_ioctl = rue_ioctl;
- ifp->if_start = rue_start;
- ifp->if_watchdog = rue_watchdog;
- ifp->if_init = rue_init;
- ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
-
- /* MII setup */
- if (mii_phy_probe(self, &sc->rue_miibus,
- rue_ifmedia_upd, rue_ifmedia_sts)) {
- device_printf(sc->rue_dev, "MII without any PHY!\n");
- goto error2;
- }
-
- sc->rue_qdat.ifp = ifp;
- sc->rue_qdat.if_rxstart = rue_rxstart;
-
- /* Call MI attach routine */
- ether_ifattach(ifp, eaddr);
- callout_handle_init(&sc->rue_stat_ch);
- usb_register_netisr();
- sc->rue_dying = 0;
-
- RUE_UNLOCK(sc);
- return 0;
-
- error2:
- if_free(ifp);
- error1:
- RUE_UNLOCK(sc);
- mtx_destroy(&sc->rue_mtx);
- error:
- return ENXIO;
-}
-
-static int
-rue_detach(device_t dev)
-{
- struct rue_softc *sc;
- struct ifnet *ifp;
-
- sc = device_get_softc(dev);
- RUE_LOCK(sc);
- ifp = sc->rue_ifp;
-
- sc->rue_dying = 1;
- untimeout(rue_tick, sc, sc->rue_stat_ch);
- usb_rem_task(sc->rue_udev, &sc->rue_tick_task);
- ether_ifdetach(ifp);
- if_free(ifp);
-
- if (sc->rue_ep[RUE_ENDPT_TX] != NULL)
- usbd_abort_pipe(sc->rue_ep[RUE_ENDPT_TX]);
- if (sc->rue_ep[RUE_ENDPT_RX] != NULL)
- usbd_abort_pipe(sc->rue_ep[RUE_ENDPT_RX]);
-#ifdef RUE_INTR_PIPE
- if (sc->rue_ep[RUE_ENDPT_INTR] != NULL)
- usbd_abort_pipe(sc->rue_ep[RUE_ENDPT_INTR]);
-#endif
-
- RUE_UNLOCK(sc);
- mtx_destroy(&sc->rue_mtx);
-
- return (0);
-}
-
-#ifdef RUE_INTR_PIPE
-static void
-rue_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- struct rue_softc *sc = priv;
- struct ifnet *ifp;
- struct rue_intrpkt *p;
-
- RUE_LOCK(sc);
- ifp = sc->rue_ifp;
-
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
- RUE_UNLOCK(sc);
- return;
- }
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
- RUE_UNLOCK(sc);
- return;
- }
- device_printf(sc->rue_dev, "usb error on intr: %s\n",
- usbd_errstr(status));
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall(sc->rue_ep[RUE_ENDPT_INTR]);
- RUE_UNLOCK(sc);
- return;
- }
-
- usbd_get_xfer_status(xfer, NULL, (void **)&p, NULL, NULL);
-
- ifp->if_ierrors += p->rue_rxlost_cnt;
- ifp->if_ierrors += p->rue_crcerr_cnt;
- ifp->if_collisions += p->rue_col_cnt;
-
- RUE_UNLOCK(sc);
-}
-#endif
-
-static void
-rue_rxstart(struct ifnet *ifp)
-{
- struct rue_softc *sc;
- struct ue_chain *c;
-
- sc = ifp->if_softc;
- RUE_LOCK(sc);
- c = &sc->rue_cdata.ue_rx_chain[sc->rue_cdata.ue_rx_prod];
-
- c->ue_mbuf = usb_ether_newbuf();
- if (c->ue_mbuf == NULL) {
- printf("%s: no memory for rx list "
- "-- packet dropped!\n", device_get_nameunit(sc->rue_dev));
- ifp->if_ierrors++;
- RUE_UNLOCK(sc);
- return;
- }
-
- /* Setup new transfer. */
- usbd_setup_xfer(c->ue_xfer, sc->rue_ep[RUE_ENDPT_RX],
- c, mtod(c->ue_mbuf, char *), UE_BUFSZ, USBD_SHORT_XFER_OK,
- USBD_NO_TIMEOUT, rue_rxeof);
- usbd_transfer(c->ue_xfer);
-
- RUE_UNLOCK(sc);
-}
-
-/*
- * A frame has been uploaded: pass the resulting mbuf chain up to
- * the higher level protocols.
- */
-
-static void
-rue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- struct ue_chain *c = priv;
- struct rue_softc *sc = c->ue_sc;
- struct mbuf *m;
- struct ifnet *ifp;
- int total_len = 0;
- struct rue_rxpkt r;
-
- if (sc->rue_dying)
- return;
- RUE_LOCK(sc);
- ifp = sc->rue_ifp;
-
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
- RUE_UNLOCK(sc);
- return;
- }
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
- RUE_UNLOCK(sc);
- return;
- }
- if (usbd_ratecheck(&sc->rue_rx_notice))
- device_printf(sc->rue_dev, "usb error on rx: %s\n",
- usbd_errstr(status));
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall(sc->rue_ep[RUE_ENDPT_RX]);
- goto done;
- }
-
- usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
-
- if (total_len <= ETHER_CRC_LEN) {
- ifp->if_ierrors++;
- goto done;
- }
-
- m = c->ue_mbuf;
- bcopy(mtod(m, char *) + total_len - 4, (char *)&r, sizeof (r));
-
- /* Check recieve packet was valid or not */
- if ((r.rue_rxstat & RUE_RXSTAT_VALID) == 0) {
- ifp->if_ierrors++;
- goto done;
- }
-
- /* No errors; receive the packet. */
- total_len -= ETHER_CRC_LEN;
-
- ifp->if_ipackets++;
- m->m_pkthdr.rcvif = (void *)&sc->rue_qdat;
- m->m_pkthdr.len = m->m_len = total_len;
-
- /* Put the packet on the special USB input queue. */
- usb_ether_input(m);
-
- RUE_UNLOCK(sc);
- return;
-
- done:
- /* Setup new transfer. */
- usbd_setup_xfer(xfer, sc->rue_ep[RUE_ENDPT_RX],
- c, mtod(c->ue_mbuf, char *), UE_BUFSZ,
- USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, rue_rxeof);
- usbd_transfer(xfer);
- RUE_UNLOCK(sc);
-}
-
-/*
- * A frame was downloaded to the chip. It's safe for us to clean up
- * the list buffers.
- */
-
-static void
-rue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- struct ue_chain *c = priv;
- struct rue_softc *sc = c->ue_sc;
- struct ifnet *ifp;
- usbd_status err;
-
- RUE_LOCK(sc);
-
- ifp = sc->rue_ifp;
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
- RUE_UNLOCK(sc);
- return;
- }
- device_printf(sc->rue_dev, "usb error on tx: %s\n",
- usbd_errstr(status));
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall(sc->rue_ep[RUE_ENDPT_TX]);
- RUE_UNLOCK(sc);
- return;
- }
-
- ifp->if_timer = 0;
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &err);
-
- if (c->ue_mbuf != NULL) {
- c->ue_mbuf->m_pkthdr.rcvif = ifp;
- usb_tx_done(c->ue_mbuf);
- c->ue_mbuf = NULL;
- }
-
- if (err)
- ifp->if_oerrors++;
- else
- ifp->if_opackets++;
-
- RUE_UNLOCK(sc);
-}
-
-static void
-rue_tick(void *xsc)
-{
- struct rue_softc *sc = xsc;
-
- if (sc == NULL)
- return;
- if (sc->rue_dying)
- return;
-
- /* Perform periodic stuff in process context */
- usb_add_task(sc->rue_udev, &sc->rue_tick_task, USB_TASKQ_DRIVER);
-}
-
-static void
-rue_tick_task(void *xsc)
-{
- struct rue_softc *sc = xsc;
- struct ifnet *ifp;
- struct mii_data *mii;
-
- if (sc == NULL)
- return;
-
- RUE_LOCK(sc);
-
- ifp = sc->rue_ifp;
- mii = GET_MII(sc);
- if (mii == NULL) {
- RUE_UNLOCK(sc);
- return;
- }
-
- mii_tick(mii);
- if (!sc->rue_link && mii->mii_media_status & IFM_ACTIVE &&
- IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
- sc->rue_link++;
- if (ifp->if_snd.ifq_head != NULL)
- rue_start(ifp);
- }
-
- sc->rue_stat_ch = timeout(rue_tick, sc, hz);
-
- RUE_UNLOCK(sc);
-}
-
-static int
-rue_encap(struct rue_softc *sc, struct mbuf *m, int idx)
-{
- int total_len;
- struct ue_chain *c;
- usbd_status err;
-
- c = &sc->rue_cdata.ue_tx_chain[idx];
-
- /*
- * Copy the mbuf data into a contiguous buffer
- */
- m_copydata(m, 0, m->m_pkthdr.len, c->ue_buf);
- c->ue_mbuf = m;
-
- total_len = m->m_pkthdr.len;
-
- /*
- * This is an undocumented behavior.
- * RTL8150 chip doesn't send frame length smaller than
- * RUE_MIN_FRAMELEN (60) byte packet.
- */
- if (total_len < RUE_MIN_FRAMELEN)
- total_len = RUE_MIN_FRAMELEN;
-
- usbd_setup_xfer(c->ue_xfer, sc->rue_ep[RUE_ENDPT_TX],
- c, c->ue_buf, total_len, USBD_FORCE_SHORT_XFER,
- 10000, rue_txeof);
-
- /* Transmit */
- err = usbd_transfer(c->ue_xfer);
- if (err != USBD_IN_PROGRESS) {
- rue_stop(sc);
- return (EIO);
- }
-
- sc->rue_cdata.ue_tx_cnt++;
-
- return (0);
-}
-
-static void
-rue_start(struct ifnet *ifp)
-{
- struct rue_softc *sc = ifp->if_softc;
- struct mbuf *m_head = NULL;
-
- RUE_LOCK(sc);
-
- if (!sc->rue_link) {
- RUE_UNLOCK(sc);
- return;
- }
-
- if (ifp->if_drv_flags & IFF_DRV_OACTIVE) {
- RUE_UNLOCK(sc);
- return;
- }
-
- IF_DEQUEUE(&ifp->if_snd, m_head);
- if (m_head == NULL) {
- RUE_UNLOCK(sc);
- return;
- }
-
- if (rue_encap(sc, m_head, 0)) {
- IF_PREPEND(&ifp->if_snd, m_head);
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- RUE_UNLOCK(sc);
- return;
- }
-
- /*
- * If there's a BPF listener, bounce a copy of this frame
- * to him.
- */
- BPF_MTAP(ifp, m_head);
-
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
-
- /*
- * Set a timeout in case the chip goes out to lunch.
- */
- ifp->if_timer = 5;
-
- RUE_UNLOCK(sc);
-}
-
-static void
-rue_init(void *xsc)
-{
- struct rue_softc *sc = xsc;
- struct ifnet *ifp = sc->rue_ifp;
- struct mii_data *mii = GET_MII(sc);
- struct ue_chain *c;
- usbd_status err;
- int i;
- int rxcfg;
-
- RUE_LOCK(sc);
-
- if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
- RUE_UNLOCK(sc);
- return;
- }
-
- /*
- * Cancel pending I/O and free all RX/TX buffers.
- */
- rue_reset(sc);
-
- /* Set MAC address */
- rue_write_mem(sc, RUE_IDR0, IF_LLADDR(sc->rue_ifp),
- ETHER_ADDR_LEN);
-
- /* Init TX ring. */
- if (usb_ether_tx_list_init(sc, &sc->rue_cdata,
- sc->rue_udev) == ENOBUFS) {
- device_printf(sc->rue_dev, "tx list init failed\n");
- RUE_UNLOCK(sc);
- return;
- }
-
- /* Init RX ring. */
- if (usb_ether_rx_list_init(sc, &sc->rue_cdata,
- sc->rue_udev) == ENOBUFS) {
- device_printf(sc->rue_dev, "rx list init failed\n");
- RUE_UNLOCK(sc);
- return;
- }
-
-#ifdef RUE_INTR_PIPE
- sc->rue_cdata.ue_ibuf = malloc(RUE_INTR_PKTLEN, M_USBDEV, M_NOWAIT);
-#endif
-
- /*
- * Set the initial TX and RX configuration.
- */
- rue_csr_write_1(sc, RUE_TCR, RUE_TCR_CONFIG);
-
- rxcfg = RUE_RCR_CONFIG;
-
- /* Set capture broadcast bit to capture broadcast frames. */
- if (ifp->if_flags & IFF_BROADCAST)
- rxcfg |= RUE_RCR_AB;
- else
- rxcfg &= ~RUE_RCR_AB;
-
- /* If we want promiscuous mode, set the allframes bit. */
- if (ifp->if_flags & IFF_PROMISC)
- rxcfg |= RUE_RCR_AAP;
- else
- rxcfg &= ~RUE_RCR_AAP;
-
- rue_csr_write_2(sc, RUE_RCR, rxcfg);
-
- /* Load the multicast filter. */
- rue_setmulti(sc);
-
- /* Enable RX and TX */
- rue_csr_write_1(sc, RUE_CR, (RUE_CR_TE | RUE_CR_RE | RUE_CR_EP3CLREN));
-
- mii_mediachg(mii);
-
- /* Open RX and TX pipes. */
- err = usbd_open_pipe(sc->rue_iface, sc->rue_ed[RUE_ENDPT_RX],
- USBD_EXCLUSIVE_USE, &sc->rue_ep[RUE_ENDPT_RX]);
- if (err) {
- device_printf(sc->rue_dev, "open rx pipe failed: %s\n",
- usbd_errstr(err));
- RUE_UNLOCK(sc);
- return;
- }
- err = usbd_open_pipe(sc->rue_iface, sc->rue_ed[RUE_ENDPT_TX],
- USBD_EXCLUSIVE_USE, &sc->rue_ep[RUE_ENDPT_TX]);
- if (err) {
- device_printf(sc->rue_dev, "open tx pipe failed: %s\n",
- usbd_errstr(err));
- RUE_UNLOCK(sc);
- return;
- }
-
-#ifdef RUE_INTR_PIPE
- err = usbd_open_pipe_intr(sc->rue_iface, sc->rue_ed[RUE_ENDPT_INTR],
- USBD_SHORT_XFER_OK,
- &sc->rue_ep[RUE_ENDPT_INTR], sc,
- sc->rue_cdata.ue_ibuf, RUE_INTR_PKTLEN,
- rue_intr, RUE_INTR_INTERVAL);
- if (err) {
- device_printf(sc->rue_dev, "open intr pipe failed: %s\n",
- usbd_errstr(err));
- RUE_UNLOCK(sc);
- return;
- }
-#endif
-
- /* Start up the receive pipe. */
- for (i = 0; i < UE_RX_LIST_CNT; i++) {
- c = &sc->rue_cdata.ue_rx_chain[i];
- usbd_setup_xfer(c->ue_xfer, sc->rue_ep[RUE_ENDPT_RX],
- c, mtod(c->ue_mbuf, char *), UE_BUFSZ,
- USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, rue_rxeof);
- usbd_transfer(c->ue_xfer);
- }
-
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
-
- sc->rue_stat_ch = timeout(rue_tick, sc, hz);
-
- RUE_UNLOCK(sc);
-}
-
-/*
- * Set media options.
- */
-
-static int
-rue_ifmedia_upd(struct ifnet *ifp)
-{
- struct rue_softc *sc = ifp->if_softc;
- struct mii_data *mii = GET_MII(sc);
-
- sc->rue_link = 0;
- if (mii->mii_instance) {
- struct mii_softc *miisc;
- LIST_FOREACH (miisc, &mii->mii_phys, mii_list)
- mii_phy_reset(miisc);
- }
- mii_mediachg(mii);
-
- return (0);
-}
-
-/*
- * Report current media status.
- */
-
-static void
-rue_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
-{
- struct rue_softc *sc = ifp->if_softc;
- struct mii_data *mii = GET_MII(sc);
-
- mii_pollstat(mii);
- ifmr->ifm_active = mii->mii_media_active;
- ifmr->ifm_status = mii->mii_media_status;
-}
-
-static int
-rue_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
-{
- struct rue_softc *sc = ifp->if_softc;
- struct ifreq *ifr = (struct ifreq *)data;
- struct mii_data *mii;
- int error = 0;
-
- RUE_LOCK(sc);
-
- switch (command) {
- case SIOCSIFFLAGS:
- if (ifp->if_flags & IFF_UP) {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
- ifp->if_flags & IFF_PROMISC &&
- !(sc->rue_if_flags & IFF_PROMISC)) {
- RUE_SETBIT_2(sc, RUE_RCR,
- (RUE_RCR_AAM | RUE_RCR_AAP));
- rue_setmulti(sc);
- } else if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
- !(ifp->if_flags & IFF_PROMISC) &&
- sc->rue_if_flags & IFF_PROMISC) {
- RUE_CLRBIT_2(sc, RUE_RCR,
- (RUE_RCR_AAM | RUE_RCR_AAP));
- rue_setmulti(sc);
- } else if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
- rue_init(sc);
- } else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- rue_stop(sc);
- }
- sc->rue_if_flags = ifp->if_flags;
- error = 0;
- break;
- case SIOCADDMULTI:
- case SIOCDELMULTI:
- rue_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 = ether_ioctl(ifp, command, data);
- break;
- }
-
- RUE_UNLOCK(sc);
-
- return (error);
-}
-
-static void
-rue_watchdog(struct ifnet *ifp)
-{
- struct rue_softc *sc = ifp->if_softc;
- struct ue_chain *c;
- usbd_status stat;
-
- RUE_LOCK(sc);
-
- ifp->if_oerrors++;
- device_printf(sc->rue_dev, "watchdog timeout\n");
-
- c = &sc->rue_cdata.ue_tx_chain[0];
- usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &stat);
- rue_txeof(c->ue_xfer, c, stat);
-
- if (ifp->if_snd.ifq_head != NULL)
- rue_start(ifp);
-
- RUE_UNLOCK(sc);
-}
-
-/*
- * Stop the adapter and free any mbufs allocated to the
- * RX and TX lists.
- */
-
-static void
-rue_stop(struct rue_softc *sc)
-{
- usbd_status err;
- struct ifnet *ifp;
-
- RUE_LOCK(sc);
-
- ifp = sc->rue_ifp;
- ifp->if_timer = 0;
-
- rue_csr_write_1(sc, RUE_CR, 0x00);
- rue_reset(sc);
-
- untimeout(rue_tick, sc, sc->rue_stat_ch);
-
- /* Stop transfers. */
- if (sc->rue_ep[RUE_ENDPT_RX] != NULL) {
- err = usbd_abort_pipe(sc->rue_ep[RUE_ENDPT_RX]);
- if (err) {
- device_printf(sc->rue_dev, "abort rx pipe failed: %s\n",
- usbd_errstr(err));
- }
- err = usbd_close_pipe(sc->rue_ep[RUE_ENDPT_RX]);
- if (err) {
- device_printf(sc->rue_dev, "close rx pipe failed: %s\n",
- usbd_errstr(err));
- }
- sc->rue_ep[RUE_ENDPT_RX] = NULL;
- }
-
- if (sc->rue_ep[RUE_ENDPT_TX] != NULL) {
- err = usbd_abort_pipe(sc->rue_ep[RUE_ENDPT_TX]);
- if (err) {
- device_printf(sc->rue_dev, "abort tx pipe failed: %s\n",
- usbd_errstr(err));
- }
- err = usbd_close_pipe(sc->rue_ep[RUE_ENDPT_TX]);
- if (err) {
- device_printf(sc->rue_dev, "close tx pipe failed: %s\n",
- usbd_errstr(err));
- }
- sc->rue_ep[RUE_ENDPT_TX] = NULL;
- }
-
-#ifdef RUE_INTR_PIPE
- if (sc->rue_ep[RUE_ENDPT_INTR] != NULL) {
- err = usbd_abort_pipe(sc->rue_ep[RUE_ENDPT_INTR]);
- if (err) {
- device_printf(sc->rue_dev, "abort intr pipe failed: %s\n",
- usbd_errstr(err));
- }
- err = usbd_close_pipe(sc->rue_ep[RUE_ENDPT_INTR]);
- if (err) {
- device_printf(sc->rue_dev, "close intr pipe failed: %s\n",
- usbd_errstr(err));
- }
- sc->rue_ep[RUE_ENDPT_INTR] = NULL;
- }
-#endif
-
- /* Free RX resources. */
- usb_ether_rx_list_free(&sc->rue_cdata);
- /* Free TX resources. */
- usb_ether_tx_list_free(&sc->rue_cdata);
-
-#ifdef RUE_INTR_PIPE
- free(sc->rue_cdata.ue_ibuf, M_USBDEV);
- sc->rue_cdata.ue_ibuf = NULL;
-#endif
-
- sc->rue_link = 0;
-
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
-
- RUE_UNLOCK(sc);
-}
-
-/*
- * Stop all chip I/O so that the kernel's probe routines don't
- * get confused by errant DMAs when rebooting.
- */
-
-static int
-rue_shutdown(device_t dev)
-{
- struct rue_softc *sc;
-
- sc = device_get_softc(dev);
-
- sc->rue_dying++;
- RUE_LOCK(sc);
- rue_reset(sc);
- rue_stop(sc);
- RUE_UNLOCK(sc);
-
- return (0);
-}
diff --git a/sys/dev/usb/if_ruereg.h b/sys/dev/usb/if_ruereg.h
deleted file mode 100644
index da6470f..0000000
--- a/sys/dev/usb/if_ruereg.h
+++ /dev/null
@@ -1,226 +0,0 @@
-/*-
- * Copyright (c) 2001-2003, Shunsuke Akiyama <akiyama@FreeBSD.org>.
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- * $FreeBSD$
- */
-
-#ifndef _IF_RUEREG_H_
-#define _IF_RUEREG_H_
-
-#define RUE_INTR_PIPE 1 /* Use INTR PIPE */
-
-#define RUE_CONFIG_NO 1
-#define RUE_IFACE_IDX 0
-
-#define RUE_ENDPT_RX 0x0
-#define RUE_ENDPT_TX 0x1
-#define RUE_ENDPT_INTR 0x2
-#define RUE_ENDPT_MAX 0x3
-
-#define RUE_INTR_PKTLEN 0x8
-
-#define RUE_TIMEOUT 1000
-#define ETHER_ALIGN 2
-#define RUE_MIN_FRAMELEN 60
-#define RUE_INTR_INTERVAL 100 /* ms */
-
-/*
- * Registers
- */
-
-#define RUE_IDR0 0x0120
-#define RUE_IDR1 0x0121
-#define RUE_IDR2 0x0122
-#define RUE_IDR3 0x0123
-#define RUE_IDR4 0x0124
-#define RUE_IDR5 0x0125
-
-#define RUE_MAR0 0x0126
-#define RUE_MAR1 0x0127
-#define RUE_MAR2 0x0128
-#define RUE_MAR3 0x0129
-#define RUE_MAR4 0x012A
-#define RUE_MAR5 0x012B
-#define RUE_MAR6 0x012C
-#define RUE_MAR7 0x012D
-
-#define RUE_CR 0x012E /* B, R/W */
-#define RUE_CR_SOFT_RST 0x10
-#define RUE_CR_RE 0x08
-#define RUE_CR_TE 0x04
-#define RUE_CR_EP3CLREN 0x02
-
-#define RUE_TCR 0x012F /* B, R/W */
-#define RUE_TCR_TXRR1 0x80
-#define RUE_TCR_TXRR0 0x40
-#define RUE_TCR_IFG1 0x10
-#define RUE_TCR_IFG0 0x08
-#define RUE_TCR_NOCRC 0x01
-#define RUE_TCR_CONFIG (RUE_TCR_TXRR1|RUE_TCR_TXRR0|RUE_TCR_IFG1|RUE_TCR_IFG0)
-
-#define RUE_RCR 0x0130 /* W, R/W */
-#define RUE_RCR_TAIL 0x80
-#define RUE_RCR_AER 0x40
-#define RUE_RCR_AR 0x20
-#define RUE_RCR_AM 0x10
-#define RUE_RCR_AB 0x08
-#define RUE_RCR_AD 0x04
-#define RUE_RCR_AAM 0x02
-#define RUE_RCR_AAP 0x01
-#define RUE_RCR_CONFIG (RUE_RCR_TAIL|RUE_RCR_AD)
-
-#define RUE_TSR 0x0132
-#define RUE_RSR 0x0133
-#define RUE_CON0 0x0135
-#define RUE_CON1 0x0136
-#define RUE_MSR 0x0137
-#define RUE_PHYADD 0x0138
-#define RUE_PHYDAT 0x0139
-
-#define RUE_PHYCNT 0x013B /* B, R/W */
-#define RUE_PHYCNT_PHYOWN 0x40
-#define RUE_PHYCNT_RWCR 0x20
-
-#define RUE_GPPC 0x013D
-#define RUE_WAKECNT 0x013E
-
-#define RUE_BMCR 0x0140
-#define RUE_BMCR_SPD_SET 0x2000
-#define RUE_BMCR_DUPLEX 0x0100
-
-#define RUE_BMSR 0x0142
-
-#define RUE_ANAR 0x0144 /* W, R/W */
-#define RUE_ANAR_PAUSE 0x0400
-
-#define RUE_ANLP 0x0146 /* W, R/O */
-#define RUE_ANLP_PAUSE 0x0400
-
-#define RUE_AER 0x0148
-
-#define RUE_NWAYT 0x014A
-#define RUE_CSCR 0x014C
-
-#define RUE_CRC0 0x014E
-#define RUE_CRC1 0x0150
-#define RUE_CRC2 0x0152
-#define RUE_CRC3 0x0154
-#define RUE_CRC4 0x0156
-
-#define RUE_BYTEMASK0 0x0158
-#define RUE_BYTEMASK1 0x0160
-#define RUE_BYTEMASK2 0x0168
-#define RUE_BYTEMASK3 0x0170
-#define RUE_BYTEMASK4 0x0178
-
-#define RUE_PHY1 0x0180
-#define RUE_PHY2 0x0184
-
-#define RUE_TW1 0x0186
-
-#define RUE_REG_MIN 0x0120
-#define RUE_REG_MAX 0x0189
-
-/*
- * EEPROM address declarations
- */
-
-#define RUE_EEPROM_BASE 0x1200
-
-#define RUE_EEPROM_IDR0 (RUE_EEPROM_BASE + 0x02)
-#define RUE_EEPROM_IDR1 (RUE_EEPROM_BASE + 0x03)
-#define RUE_EEPROM_IDR2 (RUE_EEPROM_BASE + 0x03)
-#define RUE_EEPROM_IDR3 (RUE_EEPROM_BASE + 0x03)
-#define RUE_EEPROM_IDR4 (RUE_EEPROM_BASE + 0x03)
-#define RUE_EEPROM_IDR5 (RUE_EEPROM_BASE + 0x03)
-
-#define RUE_EEPROM_INTERVAL (RUE_EEPROM_BASE + 0x17)
-
-struct rue_intrpkt {
- u_int8_t rue_tsr;
- u_int8_t rue_rsr;
- u_int8_t rue_gep_msr;
- u_int8_t rue_waksr;
- u_int8_t rue_txok_cnt;
- u_int8_t rue_rxlost_cnt;
- u_int8_t rue_crcerr_cnt;
- u_int8_t rue_col_cnt;
-};
-
-struct rue_rxpkt {
- u_int16_t rue_pktlen : 12;
- u_int16_t rue_rxstat : 4;
-};
-
-#define RUE_RXSTAT_VALID 0x01
-#define RUE_RXSTAT_RUNT 0x02
-#define RUE_RXSTAT_PMATCH 0x04
-#define RUE_RXSTAT_MCAST 0x08
-
-#define RUE_RXSTAT_MASK RUE_RXSTAT_VALID
-
-struct rue_type {
- u_int16_t rue_vid;
- u_int16_t rue_did;
-};
-
-struct rue_softc {
- struct ifnet *rue_ifp;
- device_t rue_dev;
- device_t rue_miibus;
- usbd_device_handle rue_udev;
- usbd_interface_handle rue_iface;
- struct rue_type *rue_info;
- int rue_ed[RUE_ENDPT_MAX];
- usbd_pipe_handle rue_ep[RUE_ENDPT_MAX];
- int rue_unit;
- u_int8_t rue_link;
- int rue_if_flags;
- struct ue_cdata rue_cdata;
- struct callout_handle rue_stat_ch;
- struct mtx rue_mtx;
- char rue_dying;
- struct timeval rue_rx_notice;
- struct usb_qdat rue_qdat;
- struct usb_task rue_tick_task;
-};
-
-#if defined(__FreeBSD__)
-#define GET_MII(sc) (device_get_softc((sc)->rue_miibus))
-#elif defined(__NetBSD__)
-#define GET_MII(sc) (&(sc)->rue_mii)
-#elif defined(__OpenBSD__)
-#define GET_MII(sc) (&(sc)->rue_mii)
-#endif
-
-#if 0
-#define RUE_LOCK(_sc) mtx_lock(&(_sc)->rue_mtx)
-#define RUE_UNLOCK(_sc) mtx_unlock(&(_sc)->rue_mtx)
-#else
-#define RUE_LOCK(_sc)
-#define RUE_UNLOCK(_sc)
-#endif
-
-#endif /* _IF_RUEREG_H_ */
diff --git a/sys/dev/usb/if_rum.c b/sys/dev/usb/if_rum.c
deleted file mode 100644
index c0c7cb6..0000000
--- a/sys/dev/usb/if_rum.c
+++ /dev/null
@@ -1,2560 +0,0 @@
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 2005-2007 Damien Bergamini <damien.bergamini@free.fr>
- * Copyright (c) 2006 Niall O'Higgins <niallo@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*-
- * Ralink Technology RT2501USB/RT2601USB chipset driver
- * http://www.ralinktech.com.tw/
- */
-
-#include <sys/param.h>
-#include <sys/sysctl.h>
-#include <sys/sockio.h>
-#include <sys/mbuf.h>
-#include <sys/kernel.h>
-#include <sys/socket.h>
-#include <sys/systm.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/endian.h>
-
-#include <machine/bus.h>
-#include <machine/resource.h>
-#include <sys/rman.h>
-
-#include <net/bpf.h>
-#include <net/if.h>
-#include <net/if_arp.h>
-#include <net/ethernet.h>
-#include <net/if_dl.h>
-#include <net/if_media.h>
-#include <net/if_types.h>
-
-#include <net80211/ieee80211_var.h>
-#include <net80211/ieee80211_amrr.h>
-#include <net80211/ieee80211_phy.h>
-#include <net80211/ieee80211_radiotap.h>
-#include <net80211/ieee80211_regdomain.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include "usbdevs.h"
-
-#include <dev/usb/if_rumreg.h>
-#include <dev/usb/if_rumvar.h>
-#include <dev/usb/rt2573_ucode.h>
-
-#ifdef USB_DEBUG
-#define DPRINTF(x) do { if (rumdebug > 0) printf x; } while (0)
-#define DPRINTFN(n, x) do { if (rumdebug >= (n)) printf x; } while (0)
-int rumdebug = 0;
-SYSCTL_NODE(_hw_usb, OID_AUTO, rum, CTLFLAG_RW, 0, "USB rum");
-SYSCTL_INT(_hw_usb_rum, OID_AUTO, debug, CTLFLAG_RW, &rumdebug, 0,
- "rum debug level");
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n, x)
-#endif
-
-/* various supported device vendors/products */
-static const struct usb_devno rum_devs[] = {
- { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_HWU54DM },
- { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2573_2 },
- { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2573_3 },
- { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2573_4 },
- { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_WUG2700 },
- { USB_VENDOR_AMIT, USB_PRODUCT_AMIT_CGWLUSB2GO },
- { USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2573_1 },
- { USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2573_2 },
- { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D7050A },
- { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D9050V3 },
- { USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSB54GC },
- { USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSB54GR },
- { USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_C54RU2 },
- { USB_VENDOR_COREGA, USB_PRODUCT_COREGA_CGWLUSB2GL },
- { USB_VENDOR_COREGA, USB_PRODUCT_COREGA_CGWLUSB2GPX },
- { USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_CWD854F },
- { USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_RT2573 },
- { USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWLG122C1 },
- { USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_WUA1340 },
- { USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA111 },
- { USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA110 },
- { USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNWB01GS },
- { USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNWI05GS },
- { USB_VENDOR_GIGASET, USB_PRODUCT_GIGASET_RT2573 },
- { USB_VENDOR_GOODWAY, USB_PRODUCT_GOODWAY_RT2573 },
- { USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWGUSB254LB },
- { USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWGUSB254V2AP },
- { USB_VENDOR_HUAWEI3COM, USB_PRODUCT_HUAWEI3COM_WUB320G },
- { USB_VENDOR_MELCO, USB_PRODUCT_MELCO_G54HP },
- { USB_VENDOR_MELCO, USB_PRODUCT_MELCO_SG54HP },
- { USB_VENDOR_MELCO, USB_PRODUCT_MELCO_SG54HG },
- { USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_1 },
- { USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_2 },
- { USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_3 },
- { USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_4 },
- { USB_VENDOR_NOVATECH, USB_PRODUCT_NOVATECH_RT2573 },
- { USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUS54HP },
- { USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUS54MINI2 },
- { USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUSMM },
- { USB_VENDOR_QCOM, USB_PRODUCT_QCOM_RT2573 },
- { USB_VENDOR_QCOM, USB_PRODUCT_QCOM_RT2573_2 },
- { USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2573 },
- { USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2573_2 },
- { USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2671 },
- { USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL113R2 },
- { USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL172 },
- { USB_VENDOR_SPARKLAN, USB_PRODUCT_SPARKLAN_RT2573 },
- { USB_VENDOR_SURECOM, USB_PRODUCT_SURECOM_RT2573 }
-};
-
-MODULE_DEPEND(rum, wlan, 1, 1, 1);
-MODULE_DEPEND(rum, wlan_amrr, 1, 1, 1);
-MODULE_DEPEND(rum, usb, 1, 1, 1);
-
-static struct ieee80211vap *rum_vap_create(struct ieee80211com *,
- const char name[IFNAMSIZ], int unit, int opmode,
- int flags, const uint8_t bssid[IEEE80211_ADDR_LEN],
- const uint8_t mac[IEEE80211_ADDR_LEN]);
-static void rum_vap_delete(struct ieee80211vap *);
-static int rum_alloc_tx_list(struct rum_softc *);
-static void rum_free_tx_list(struct rum_softc *);
-static int rum_alloc_rx_list(struct rum_softc *);
-static void rum_free_rx_list(struct rum_softc *);
-static void rum_task(void *);
-static void rum_scantask(void *);
-static int rum_newstate(struct ieee80211vap *,
- enum ieee80211_state, int);
-static void rum_txeof(usbd_xfer_handle, usbd_private_handle,
- usbd_status);
-static void rum_rxeof(usbd_xfer_handle, usbd_private_handle,
- usbd_status);
-static void rum_setup_tx_desc(struct rum_softc *,
- struct rum_tx_desc *, uint32_t, uint16_t, int,
- int);
-static int rum_tx_mgt(struct rum_softc *, struct mbuf *,
- struct ieee80211_node *);
-static int rum_tx_raw(struct rum_softc *, struct mbuf *,
- struct ieee80211_node *,
- const struct ieee80211_bpf_params *);
-static int rum_tx_data(struct rum_softc *, struct mbuf *,
- struct ieee80211_node *);
-static void rum_start(struct ifnet *);
-static void rum_watchdog(void *);
-static int rum_ioctl(struct ifnet *, u_long, caddr_t);
-static void rum_eeprom_read(struct rum_softc *, uint16_t, void *,
- int);
-static uint32_t rum_read(struct rum_softc *, uint16_t);
-static void rum_read_multi(struct rum_softc *, uint16_t, void *,
- int);
-static void rum_write(struct rum_softc *, uint16_t, uint32_t);
-static void rum_write_multi(struct rum_softc *, uint16_t, void *,
- size_t);
-static void rum_bbp_write(struct rum_softc *, uint8_t, uint8_t);
-static uint8_t rum_bbp_read(struct rum_softc *, uint8_t);
-static void rum_rf_write(struct rum_softc *, uint8_t, uint32_t);
-static void rum_select_antenna(struct rum_softc *);
-static void rum_enable_mrr(struct rum_softc *);
-static void rum_set_txpreamble(struct rum_softc *);
-static void rum_set_basicrates(struct rum_softc *);
-static void rum_select_band(struct rum_softc *,
- struct ieee80211_channel *);
-static void rum_set_chan(struct rum_softc *,
- struct ieee80211_channel *);
-static void rum_enable_tsf_sync(struct rum_softc *);
-static void rum_update_slot(struct ifnet *);
-static void rum_set_bssid(struct rum_softc *, const uint8_t *);
-static void rum_set_macaddr(struct rum_softc *, const uint8_t *);
-static void rum_update_promisc(struct rum_softc *);
-static const char *rum_get_rf(int);
-static void rum_read_eeprom(struct rum_softc *);
-static int rum_bbp_init(struct rum_softc *);
-static void rum_init_locked(struct rum_softc *);
-static void rum_init(void *);
-static void rum_stop(void *);
-static int rum_load_microcode(struct rum_softc *, const u_char *,
- size_t);
-static int rum_prepare_beacon(struct rum_softc *,
- struct ieee80211vap *);
-static int rum_raw_xmit(struct ieee80211_node *, struct mbuf *,
- const struct ieee80211_bpf_params *);
-static struct ieee80211_node *rum_node_alloc(struct ieee80211vap *,
- const uint8_t mac[IEEE80211_ADDR_LEN]);
-static void rum_newassoc(struct ieee80211_node *, int);
-static void rum_scan_start(struct ieee80211com *);
-static void rum_scan_end(struct ieee80211com *);
-static void rum_set_channel(struct ieee80211com *);
-static int rum_get_rssi(struct rum_softc *, uint8_t);
-static void rum_amrr_start(struct rum_softc *,
- struct ieee80211_node *);
-static void rum_amrr_timeout(void *);
-static void rum_amrr_update(usbd_xfer_handle, usbd_private_handle,
- usbd_status);
-
-static const struct {
- uint32_t reg;
- uint32_t val;
-} rum_def_mac[] = {
- { RT2573_TXRX_CSR0, 0x025fb032 },
- { RT2573_TXRX_CSR1, 0x9eaa9eaf },
- { RT2573_TXRX_CSR2, 0x8a8b8c8d },
- { RT2573_TXRX_CSR3, 0x00858687 },
- { RT2573_TXRX_CSR7, 0x2e31353b },
- { RT2573_TXRX_CSR8, 0x2a2a2a2c },
- { RT2573_TXRX_CSR15, 0x0000000f },
- { RT2573_MAC_CSR6, 0x00000fff },
- { RT2573_MAC_CSR8, 0x016c030a },
- { RT2573_MAC_CSR10, 0x00000718 },
- { RT2573_MAC_CSR12, 0x00000004 },
- { RT2573_MAC_CSR13, 0x00007f00 },
- { RT2573_SEC_CSR0, 0x00000000 },
- { RT2573_SEC_CSR1, 0x00000000 },
- { RT2573_SEC_CSR5, 0x00000000 },
- { RT2573_PHY_CSR1, 0x000023b0 },
- { RT2573_PHY_CSR5, 0x00040a06 },
- { RT2573_PHY_CSR6, 0x00080606 },
- { RT2573_PHY_CSR7, 0x00000408 },
- { RT2573_AIFSN_CSR, 0x00002273 },
- { RT2573_CWMIN_CSR, 0x00002344 },
- { RT2573_CWMAX_CSR, 0x000034aa }
-};
-
-static const struct {
- uint8_t reg;
- uint8_t val;
-} rum_def_bbp[] = {
- { 3, 0x80 },
- { 15, 0x30 },
- { 17, 0x20 },
- { 21, 0xc8 },
- { 22, 0x38 },
- { 23, 0x06 },
- { 24, 0xfe },
- { 25, 0x0a },
- { 26, 0x0d },
- { 32, 0x0b },
- { 34, 0x12 },
- { 37, 0x07 },
- { 39, 0xf8 },
- { 41, 0x60 },
- { 53, 0x10 },
- { 54, 0x18 },
- { 60, 0x10 },
- { 61, 0x04 },
- { 62, 0x04 },
- { 75, 0xfe },
- { 86, 0xfe },
- { 88, 0xfe },
- { 90, 0x0f },
- { 99, 0x00 },
- { 102, 0x16 },
- { 107, 0x04 }
-};
-
-static const struct rfprog {
- uint8_t chan;
- uint32_t r1, r2, r3, r4;
-} rum_rf5226[] = {
- { 1, 0x00b03, 0x001e1, 0x1a014, 0x30282 },
- { 2, 0x00b03, 0x001e1, 0x1a014, 0x30287 },
- { 3, 0x00b03, 0x001e2, 0x1a014, 0x30282 },
- { 4, 0x00b03, 0x001e2, 0x1a014, 0x30287 },
- { 5, 0x00b03, 0x001e3, 0x1a014, 0x30282 },
- { 6, 0x00b03, 0x001e3, 0x1a014, 0x30287 },
- { 7, 0x00b03, 0x001e4, 0x1a014, 0x30282 },
- { 8, 0x00b03, 0x001e4, 0x1a014, 0x30287 },
- { 9, 0x00b03, 0x001e5, 0x1a014, 0x30282 },
- { 10, 0x00b03, 0x001e5, 0x1a014, 0x30287 },
- { 11, 0x00b03, 0x001e6, 0x1a014, 0x30282 },
- { 12, 0x00b03, 0x001e6, 0x1a014, 0x30287 },
- { 13, 0x00b03, 0x001e7, 0x1a014, 0x30282 },
- { 14, 0x00b03, 0x001e8, 0x1a014, 0x30284 },
-
- { 34, 0x00b03, 0x20266, 0x36014, 0x30282 },
- { 38, 0x00b03, 0x20267, 0x36014, 0x30284 },
- { 42, 0x00b03, 0x20268, 0x36014, 0x30286 },
- { 46, 0x00b03, 0x20269, 0x36014, 0x30288 },
-
- { 36, 0x00b03, 0x00266, 0x26014, 0x30288 },
- { 40, 0x00b03, 0x00268, 0x26014, 0x30280 },
- { 44, 0x00b03, 0x00269, 0x26014, 0x30282 },
- { 48, 0x00b03, 0x0026a, 0x26014, 0x30284 },
- { 52, 0x00b03, 0x0026b, 0x26014, 0x30286 },
- { 56, 0x00b03, 0x0026c, 0x26014, 0x30288 },
- { 60, 0x00b03, 0x0026e, 0x26014, 0x30280 },
- { 64, 0x00b03, 0x0026f, 0x26014, 0x30282 },
-
- { 100, 0x00b03, 0x0028a, 0x2e014, 0x30280 },
- { 104, 0x00b03, 0x0028b, 0x2e014, 0x30282 },
- { 108, 0x00b03, 0x0028c, 0x2e014, 0x30284 },
- { 112, 0x00b03, 0x0028d, 0x2e014, 0x30286 },
- { 116, 0x00b03, 0x0028e, 0x2e014, 0x30288 },
- { 120, 0x00b03, 0x002a0, 0x2e014, 0x30280 },
- { 124, 0x00b03, 0x002a1, 0x2e014, 0x30282 },
- { 128, 0x00b03, 0x002a2, 0x2e014, 0x30284 },
- { 132, 0x00b03, 0x002a3, 0x2e014, 0x30286 },
- { 136, 0x00b03, 0x002a4, 0x2e014, 0x30288 },
- { 140, 0x00b03, 0x002a6, 0x2e014, 0x30280 },
-
- { 149, 0x00b03, 0x002a8, 0x2e014, 0x30287 },
- { 153, 0x00b03, 0x002a9, 0x2e014, 0x30289 },
- { 157, 0x00b03, 0x002ab, 0x2e014, 0x30281 },
- { 161, 0x00b03, 0x002ac, 0x2e014, 0x30283 },
- { 165, 0x00b03, 0x002ad, 0x2e014, 0x30285 }
-}, rum_rf5225[] = {
- { 1, 0x00b33, 0x011e1, 0x1a014, 0x30282 },
- { 2, 0x00b33, 0x011e1, 0x1a014, 0x30287 },
- { 3, 0x00b33, 0x011e2, 0x1a014, 0x30282 },
- { 4, 0x00b33, 0x011e2, 0x1a014, 0x30287 },
- { 5, 0x00b33, 0x011e3, 0x1a014, 0x30282 },
- { 6, 0x00b33, 0x011e3, 0x1a014, 0x30287 },
- { 7, 0x00b33, 0x011e4, 0x1a014, 0x30282 },
- { 8, 0x00b33, 0x011e4, 0x1a014, 0x30287 },
- { 9, 0x00b33, 0x011e5, 0x1a014, 0x30282 },
- { 10, 0x00b33, 0x011e5, 0x1a014, 0x30287 },
- { 11, 0x00b33, 0x011e6, 0x1a014, 0x30282 },
- { 12, 0x00b33, 0x011e6, 0x1a014, 0x30287 },
- { 13, 0x00b33, 0x011e7, 0x1a014, 0x30282 },
- { 14, 0x00b33, 0x011e8, 0x1a014, 0x30284 },
-
- { 34, 0x00b33, 0x01266, 0x26014, 0x30282 },
- { 38, 0x00b33, 0x01267, 0x26014, 0x30284 },
- { 42, 0x00b33, 0x01268, 0x26014, 0x30286 },
- { 46, 0x00b33, 0x01269, 0x26014, 0x30288 },
-
- { 36, 0x00b33, 0x01266, 0x26014, 0x30288 },
- { 40, 0x00b33, 0x01268, 0x26014, 0x30280 },
- { 44, 0x00b33, 0x01269, 0x26014, 0x30282 },
- { 48, 0x00b33, 0x0126a, 0x26014, 0x30284 },
- { 52, 0x00b33, 0x0126b, 0x26014, 0x30286 },
- { 56, 0x00b33, 0x0126c, 0x26014, 0x30288 },
- { 60, 0x00b33, 0x0126e, 0x26014, 0x30280 },
- { 64, 0x00b33, 0x0126f, 0x26014, 0x30282 },
-
- { 100, 0x00b33, 0x0128a, 0x2e014, 0x30280 },
- { 104, 0x00b33, 0x0128b, 0x2e014, 0x30282 },
- { 108, 0x00b33, 0x0128c, 0x2e014, 0x30284 },
- { 112, 0x00b33, 0x0128d, 0x2e014, 0x30286 },
- { 116, 0x00b33, 0x0128e, 0x2e014, 0x30288 },
- { 120, 0x00b33, 0x012a0, 0x2e014, 0x30280 },
- { 124, 0x00b33, 0x012a1, 0x2e014, 0x30282 },
- { 128, 0x00b33, 0x012a2, 0x2e014, 0x30284 },
- { 132, 0x00b33, 0x012a3, 0x2e014, 0x30286 },
- { 136, 0x00b33, 0x012a4, 0x2e014, 0x30288 },
- { 140, 0x00b33, 0x012a6, 0x2e014, 0x30280 },
-
- { 149, 0x00b33, 0x012a8, 0x2e014, 0x30287 },
- { 153, 0x00b33, 0x012a9, 0x2e014, 0x30289 },
- { 157, 0x00b33, 0x012ab, 0x2e014, 0x30281 },
- { 161, 0x00b33, 0x012ac, 0x2e014, 0x30283 },
- { 165, 0x00b33, 0x012ad, 0x2e014, 0x30285 }
-};
-
-static int
-rum_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
-
- if (uaa->iface != NULL)
- return UMATCH_NONE;
-
- return (usb_lookup(rum_devs, uaa->vendor, uaa->product) != NULL) ?
- UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
-}
-
-static int
-rum_attach(device_t self)
-{
- struct rum_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- struct ieee80211com *ic;
- struct ifnet *ifp;
- const uint8_t *ucode = NULL;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
- usbd_status error;
- int i, ntries, size;
- uint8_t bands;
- uint32_t tmp;
-
- sc->sc_udev = uaa->device;
- sc->sc_dev = self;
-
- if (usbd_set_config_no(sc->sc_udev, RT2573_CONFIG_NO, 0) != 0) {
- device_printf(self, "could not set configuration no\n");
- return ENXIO;
- }
-
- /* get the first interface handle */
- error = usbd_device2interface_handle(sc->sc_udev, RT2573_IFACE_INDEX,
- &sc->sc_iface);
- if (error != 0) {
- device_printf(self, "could not get interface handle\n");
- return ENXIO;
- }
-
- /*
- * Find endpoints.
- */
- id = usbd_get_interface_descriptor(sc->sc_iface);
-
- sc->sc_rx_no = sc->sc_tx_no = -1;
- for (i = 0; i < id->bNumEndpoints; i++) {
- ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
- if (ed == NULL) {
- device_printf(self,
- "no endpoint descriptor for iface %d\n", i);
- return ENXIO;
- }
-
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
- sc->sc_rx_no = ed->bEndpointAddress;
- else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
- sc->sc_tx_no = ed->bEndpointAddress;
- }
- if (sc->sc_rx_no == -1 || sc->sc_tx_no == -1) {
- device_printf(self, "missing endpoint\n");
- return ENXIO;
- }
-
- ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
- if (ifp == NULL) {
- device_printf(self, "can not if_alloc()\n");
- return ENXIO;
- }
- ic = ifp->if_l2com;
-
- mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev), MTX_NETWORK_LOCK,
- MTX_DEF | MTX_RECURSE);
-
- usb_init_task(&sc->sc_task, rum_task, sc);
- usb_init_task(&sc->sc_scantask, rum_scantask, sc);
- callout_init(&sc->watchdog_ch, 0);
-
- /* retrieve RT2573 rev. no */
- for (ntries = 0; ntries < 1000; ntries++) {
- if ((tmp = rum_read(sc, RT2573_MAC_CSR0)) != 0)
- break;
- DELAY(1000);
- }
- if (ntries == 1000) {
- device_printf(self, "timeout waiting for chip to settle\n");
- goto bad;
- }
-
- /* retrieve MAC address and various other things from EEPROM */
- rum_read_eeprom(sc);
-
- device_printf(self, "MAC/BBP RT2573 (rev 0x%05x), RF %s\n",
- tmp, rum_get_rf(sc->rf_rev));
-
- ucode = rt2573_ucode;
- size = sizeof rt2573_ucode;
- error = rum_load_microcode(sc, ucode, size);
- if (error != 0) {
- device_printf(self, "could not load 8051 microcode\n");
- goto bad;
- }
-
- ifp->if_softc = sc;
- if_initname(ifp, "rum", device_get_unit(sc->sc_dev));
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
- IFF_NEEDSGIANT; /* USB stack is still under Giant lock */
- ifp->if_init = rum_init;
- ifp->if_ioctl = rum_ioctl;
- ifp->if_start = rum_start;
- IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
- ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
- IFQ_SET_READY(&ifp->if_snd);
-
- ic->ic_ifp = ifp;
- ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
-
- /* set device capabilities */
- ic->ic_caps =
- IEEE80211_C_STA /* station mode supported */
- | IEEE80211_C_IBSS /* IBSS mode supported */
- | IEEE80211_C_MONITOR /* monitor mode supported */
- | IEEE80211_C_HOSTAP /* HostAp mode supported */
- | IEEE80211_C_TXPMGT /* tx power management */
- | IEEE80211_C_SHPREAMBLE /* short preamble supported */
- | IEEE80211_C_SHSLOT /* short slot time supported */
- | IEEE80211_C_BGSCAN /* bg scanning supported */
- | IEEE80211_C_WPA /* 802.11i */
- ;
-
- bands = 0;
- setbit(&bands, IEEE80211_MODE_11B);
- setbit(&bands, IEEE80211_MODE_11G);
- if (sc->rf_rev == RT2573_RF_5225 || sc->rf_rev == RT2573_RF_5226)
- setbit(&bands, IEEE80211_MODE_11A);
- ieee80211_init_channels(ic, NULL, &bands);
-
- ieee80211_ifattach(ic);
- ic->ic_newassoc = rum_newassoc;
- ic->ic_raw_xmit = rum_raw_xmit;
- ic->ic_node_alloc = rum_node_alloc;
- ic->ic_scan_start = rum_scan_start;
- ic->ic_scan_end = rum_scan_end;
- ic->ic_set_channel = rum_set_channel;
-
- ic->ic_vap_create = rum_vap_create;
- ic->ic_vap_delete = rum_vap_delete;
-
- sc->sc_rates = ieee80211_get_ratetable(ic->ic_curchan);
-
- bpfattach(ifp, DLT_IEEE802_11_RADIO,
- sizeof (struct ieee80211_frame) + sizeof(sc->sc_txtap));
-
- sc->sc_rxtap_len = sizeof sc->sc_rxtap;
- sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
- sc->sc_rxtap.wr_ihdr.it_present = htole32(RT2573_RX_RADIOTAP_PRESENT);
-
- sc->sc_txtap_len = sizeof sc->sc_txtap;
- sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
- sc->sc_txtap.wt_ihdr.it_present = htole32(RT2573_TX_RADIOTAP_PRESENT);
-
- if (bootverbose)
- ieee80211_announce(ic);
-
- return 0;
-bad:
- mtx_destroy(&sc->sc_mtx);
- if_free(ifp);
- return ENXIO;
-}
-
-static int
-rum_detach(device_t self)
-{
- struct rum_softc *sc = device_get_softc(self);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
-
- rum_stop(sc);
- bpfdetach(ifp);
- ieee80211_ifdetach(ic);
-
- usb_rem_task(sc->sc_udev, &sc->sc_task);
- usb_rem_task(sc->sc_udev, &sc->sc_scantask);
- callout_stop(&sc->watchdog_ch);
-
- if (sc->amrr_xfer != NULL) {
- usbd_free_xfer(sc->amrr_xfer);
- sc->amrr_xfer = NULL;
- }
-
- if (sc->sc_rx_pipeh != NULL) {
- usbd_abort_pipe(sc->sc_rx_pipeh);
- usbd_close_pipe(sc->sc_rx_pipeh);
- }
- if (sc->sc_tx_pipeh != NULL) {
- usbd_abort_pipe(sc->sc_tx_pipeh);
- usbd_close_pipe(sc->sc_tx_pipeh);
- }
-
- rum_free_rx_list(sc);
- rum_free_tx_list(sc);
-
- if_free(ifp);
- mtx_destroy(&sc->sc_mtx);
-
- return 0;
-}
-
-static struct ieee80211vap *
-rum_vap_create(struct ieee80211com *ic,
- const char name[IFNAMSIZ], int unit, int opmode, int flags,
- const uint8_t bssid[IEEE80211_ADDR_LEN],
- const uint8_t mac[IEEE80211_ADDR_LEN])
-{
- struct rum_vap *rvp;
- struct ieee80211vap *vap;
-
- if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */
- return NULL;
- rvp = (struct rum_vap *) malloc(sizeof(struct rum_vap),
- M_80211_VAP, M_NOWAIT | M_ZERO);
- if (rvp == NULL)
- return NULL;
- vap = &rvp->vap;
- /* enable s/w bmiss handling for sta mode */
- ieee80211_vap_setup(ic, vap, name, unit, opmode,
- flags | IEEE80211_CLONE_NOBEACONS, bssid, mac);
-
- /* override state transition machine */
- rvp->newstate = vap->iv_newstate;
- vap->iv_newstate = rum_newstate;
-
- callout_init(&rvp->amrr_ch, 0);
- ieee80211_amrr_init(&rvp->amrr, vap,
- IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
- IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD,
- 1000 /* 1 sec */);
-
- /* complete setup */
- ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status);
- ic->ic_opmode = opmode;
- return vap;
-}
-
-static void
-rum_vap_delete(struct ieee80211vap *vap)
-{
- struct rum_vap *rvp = RUM_VAP(vap);
-
- callout_stop(&rvp->amrr_ch);
- ieee80211_amrr_cleanup(&rvp->amrr);
- ieee80211_vap_detach(vap);
- free(rvp, M_80211_VAP);
-}
-
-static int
-rum_alloc_tx_list(struct rum_softc *sc)
-{
- struct rum_tx_data *data;
- int i, error;
-
- sc->tx_queued = sc->tx_cur = 0;
-
- for (i = 0; i < RUM_TX_LIST_COUNT; i++) {
- data = &sc->tx_data[i];
-
- data->sc = sc;
-
- data->xfer = usbd_alloc_xfer(sc->sc_udev);
- if (data->xfer == NULL) {
- device_printf(sc->sc_dev,
- "could not allocate tx xfer\n");
- error = ENOMEM;
- goto fail;
- }
- data->buf = usbd_alloc_buffer(data->xfer,
- RT2573_TX_DESC_SIZE + MCLBYTES);
- if (data->buf == NULL) {
- device_printf(sc->sc_dev,
- "could not allocate tx buffer\n");
- error = ENOMEM;
- goto fail;
- }
- /* clean Tx descriptor */
- bzero(data->buf, RT2573_TX_DESC_SIZE);
- }
-
- return 0;
-
-fail: rum_free_tx_list(sc);
- return error;
-}
-
-static void
-rum_free_tx_list(struct rum_softc *sc)
-{
- struct rum_tx_data *data;
- int i;
-
- for (i = 0; i < RUM_TX_LIST_COUNT; i++) {
- data = &sc->tx_data[i];
-
- if (data->xfer != NULL) {
- usbd_free_xfer(data->xfer);
- data->xfer = NULL;
- }
-
- if (data->ni != NULL) {
- ieee80211_free_node(data->ni);
- data->ni = NULL;
- }
- }
-}
-
-static int
-rum_alloc_rx_list(struct rum_softc *sc)
-{
- struct rum_rx_data *data;
- int i, error;
-
- for (i = 0; i < RUM_RX_LIST_COUNT; i++) {
- data = &sc->rx_data[i];
-
- data->sc = sc;
-
- data->xfer = usbd_alloc_xfer(sc->sc_udev);
- if (data->xfer == NULL) {
- device_printf(sc->sc_dev,
- "could not allocate rx xfer\n");
- error = ENOMEM;
- goto fail;
- }
- if (usbd_alloc_buffer(data->xfer, MCLBYTES) == NULL) {
- device_printf(sc->sc_dev,
- "could not allocate rx buffer\n");
- error = ENOMEM;
- goto fail;
- }
-
- data->m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
- if (data->m == NULL) {
- device_printf(sc->sc_dev,
- "could not allocate rx mbuf\n");
- error = ENOMEM;
- goto fail;
- }
-
- data->buf = mtod(data->m, uint8_t *);
- }
-
- return 0;
-
-fail: rum_free_rx_list(sc);
- return error;
-}
-
-static void
-rum_free_rx_list(struct rum_softc *sc)
-{
- struct rum_rx_data *data;
- int i;
-
- for (i = 0; i < RUM_RX_LIST_COUNT; i++) {
- data = &sc->rx_data[i];
-
- if (data->xfer != NULL) {
- usbd_free_xfer(data->xfer);
- data->xfer = NULL;
- }
- if (data->m != NULL) {
- m_freem(data->m);
- data->m = NULL;
- }
- }
-}
-
-static void
-rum_task(void *arg)
-{
- struct rum_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
- struct rum_vap *rvp = RUM_VAP(vap);
- const struct ieee80211_txparam *tp;
- enum ieee80211_state ostate;
- struct ieee80211_node *ni;
- uint32_t tmp;
-
- ostate = vap->iv_state;
-
- RUM_LOCK(sc);
-
- switch (sc->sc_state) {
- case IEEE80211_S_INIT:
- if (ostate == IEEE80211_S_RUN) {
- /* abort TSF synchronization */
- tmp = rum_read(sc, RT2573_TXRX_CSR9);
- rum_write(sc, RT2573_TXRX_CSR9, tmp & ~0x00ffffff);
- }
- break;
-
- case IEEE80211_S_RUN:
- ni = vap->iv_bss;
-
- if (vap->iv_opmode != IEEE80211_M_MONITOR) {
- rum_update_slot(ic->ic_ifp);
- rum_enable_mrr(sc);
- rum_set_txpreamble(sc);
- rum_set_basicrates(sc);
- rum_set_bssid(sc, ni->ni_bssid);
- }
-
- if (vap->iv_opmode == IEEE80211_M_HOSTAP ||
- vap->iv_opmode == IEEE80211_M_IBSS)
- rum_prepare_beacon(sc, vap);
-
- if (vap->iv_opmode != IEEE80211_M_MONITOR)
- rum_enable_tsf_sync(sc);
-
- /* enable automatic rate adaptation */
- tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_bsschan)];
- if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE)
- rum_amrr_start(sc, ni);
- break;
- default:
- break;
- }
-
- RUM_UNLOCK(sc);
-
- IEEE80211_LOCK(ic);
- rvp->newstate(vap, sc->sc_state, sc->sc_arg);
- if (vap->iv_newstate_cb != NULL)
- vap->iv_newstate_cb(vap, sc->sc_state, sc->sc_arg);
- IEEE80211_UNLOCK(ic);
-}
-
-static int
-rum_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
-{
- struct rum_vap *rvp = RUM_VAP(vap);
- struct ieee80211com *ic = vap->iv_ic;
- struct rum_softc *sc = ic->ic_ifp->if_softc;
-
- usb_rem_task(sc->sc_udev, &sc->sc_task);
- usb_rem_task(sc->sc_udev, &sc->sc_scantask);
- callout_stop(&rvp->amrr_ch);
-
- /* do it in a process context */
- sc->sc_state = nstate;
- sc->sc_arg = arg;
-
- if (nstate == IEEE80211_S_INIT) {
- rvp->newstate(vap, nstate, arg);
- return 0;
- } else {
- usb_add_task(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER);
- return EINPROGRESS;
- }
-}
-
-static void
-rum_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- struct rum_tx_data *data = priv;
- struct rum_softc *sc = data->sc;
- struct ifnet *ifp = sc->sc_ifp;
-
- if (data->m != NULL && data->m->m_flags & M_TXCB)
- ieee80211_process_callback(data->ni, data->m, 0/*XXX*/);
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
- return;
-
- device_printf(sc->sc_dev, "could not transmit buffer: %s\n",
- usbd_errstr(status));
-
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall_async(sc->sc_tx_pipeh);
-
- ifp->if_oerrors++;
- return;
- }
-
- m_freem(data->m);
- data->m = NULL;
- ieee80211_free_node(data->ni);
- data->ni = NULL;
-
- sc->tx_queued--;
- ifp->if_opackets++;
-
- DPRINTFN(10, ("tx done\n"));
-
- sc->sc_tx_timer = 0;
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- rum_start(ifp);
-}
-
-static void
-rum_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- struct rum_rx_data *data = priv;
- struct rum_softc *sc = data->sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct rum_rx_desc *desc;
- struct ieee80211_node *ni;
- struct mbuf *mnew, *m;
- int len, rssi;
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
- return;
-
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall_async(sc->sc_rx_pipeh);
- goto skip;
- }
-
- usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL);
-
- if (len < RT2573_RX_DESC_SIZE + sizeof (struct ieee80211_frame_min)) {
- DPRINTF(("%s: xfer too short %d\n",
- device_get_nameunit(sc->sc_dev), len));
- ifp->if_ierrors++;
- goto skip;
- }
-
- desc = (struct rum_rx_desc *)data->buf;
-
- if (le32toh(desc->flags) & RT2573_RX_CRC_ERROR) {
- /*
- * This should not happen since we did not request to receive
- * those frames when we filled RT2573_TXRX_CSR0.
- */
- DPRINTFN(5, ("CRC error\n"));
- ifp->if_ierrors++;
- goto skip;
- }
-
- mnew = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
- if (mnew == NULL) {
- ifp->if_ierrors++;
- goto skip;
- }
-
- m = data->m;
- data->m = mnew;
- data->buf = mtod(data->m, uint8_t *);
-
- /* finalize mbuf */
- m->m_pkthdr.rcvif = ifp;
- m->m_data = (caddr_t)(desc + 1);
- m->m_pkthdr.len = m->m_len = (le32toh(desc->flags) >> 16) & 0xfff;
-
- rssi = rum_get_rssi(sc, desc->rssi);
-
- if (bpf_peers_present(ifp->if_bpf)) {
- struct rum_rx_radiotap_header *tap = &sc->sc_rxtap;
-
- tap->wr_flags = IEEE80211_RADIOTAP_F_FCS;
- tap->wr_rate = ieee80211_plcp2rate(desc->rate,
- (desc->flags & htole32(RT2573_RX_OFDM)) ?
- IEEE80211_T_OFDM : IEEE80211_T_CCK);
- tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
- tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
- tap->wr_antenna = sc->rx_ant;
- tap->wr_antsignal = rssi;
-
- bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m);
- }
-
- ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *));
- if (ni != NULL) {
- /* Error happened during RSSI conversion. */
- if (rssi < 0)
- rssi = -30; /* XXX ignored by net80211 */
- (void) ieee80211_input(ni, m, rssi, RT2573_NOISE_FLOOR, 0);
- ieee80211_free_node(ni);
- } else
- (void) ieee80211_input_all(ic, m, rssi, RT2573_NOISE_FLOOR, 0);
-
- DPRINTFN(15, ("rx done\n"));
-
-skip: /* setup a new transfer */
- usbd_setup_xfer(xfer, sc->sc_rx_pipeh, data, data->buf, MCLBYTES,
- USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, rum_rxeof);
- usbd_transfer(xfer);
-}
-
-static uint8_t
-rum_plcp_signal(int rate)
-{
- switch (rate) {
- /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
- case 12: return 0xb;
- case 18: return 0xf;
- case 24: return 0xa;
- case 36: return 0xe;
- case 48: return 0x9;
- case 72: return 0xd;
- case 96: return 0x8;
- case 108: return 0xc;
-
- /* CCK rates (NB: not IEEE std, device-specific) */
- case 2: return 0x0;
- case 4: return 0x1;
- case 11: return 0x2;
- case 22: return 0x3;
- }
- return 0xff; /* XXX unsupported/unknown rate */
-}
-
-static void
-rum_setup_tx_desc(struct rum_softc *sc, struct rum_tx_desc *desc,
- uint32_t flags, uint16_t xflags, int len, int rate)
-{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- uint16_t plcp_length;
- int remainder;
-
- desc->flags = htole32(flags);
- desc->flags |= htole32(RT2573_TX_VALID);
- desc->flags |= htole32(len << 16);
-
- desc->xflags = htole16(xflags);
-
- desc->wme = htole16(RT2573_QID(0) | RT2573_AIFSN(2) |
- RT2573_LOGCWMIN(4) | RT2573_LOGCWMAX(10));
-
- /* setup PLCP fields */
- desc->plcp_signal = rum_plcp_signal(rate);
- desc->plcp_service = 4;
-
- len += IEEE80211_CRC_LEN;
- if (ieee80211_rate2phytype(sc->sc_rates, rate) == IEEE80211_T_OFDM) {
- desc->flags |= htole32(RT2573_TX_OFDM);
-
- plcp_length = len & 0xfff;
- desc->plcp_length_hi = plcp_length >> 6;
- desc->plcp_length_lo = plcp_length & 0x3f;
- } else {
- plcp_length = (16 * len + rate - 1) / rate;
- if (rate == 22) {
- remainder = (16 * len) % 22;
- if (remainder != 0 && remainder < 7)
- desc->plcp_service |= RT2573_PLCP_LENGEXT;
- }
- desc->plcp_length_hi = plcp_length >> 8;
- desc->plcp_length_lo = plcp_length & 0xff;
-
- if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
- desc->plcp_signal |= 0x08;
- }
-}
-
-#define RUM_TX_TIMEOUT 5000
-
-static int
-rum_sendprot(struct rum_softc *sc,
- const struct mbuf *m, struct ieee80211_node *ni, int prot, int rate)
-{
- struct ieee80211com *ic = ni->ni_ic;
- const struct ieee80211_frame *wh;
- struct rum_tx_desc *desc;
- struct rum_tx_data *data;
- struct mbuf *mprot;
- int protrate, ackrate, pktlen, flags, isshort;
- uint16_t dur;
- usbd_status error;
-
- KASSERT(prot == IEEE80211_PROT_RTSCTS || prot == IEEE80211_PROT_CTSONLY,
- ("protection %d", prot));
-
- wh = mtod(m, const struct ieee80211_frame *);
- pktlen = m->m_pkthdr.len + IEEE80211_CRC_LEN;
-
- protrate = ieee80211_ctl_rate(sc->sc_rates, rate);
- ackrate = ieee80211_ack_rate(sc->sc_rates, rate);
-
- isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0;
- dur = ieee80211_compute_duration(sc->sc_rates, pktlen, rate, isshort);
- + ieee80211_ack_duration(sc->sc_rates, rate, isshort);
- flags = RT2573_TX_MORE_FRAG;
- if (prot == IEEE80211_PROT_RTSCTS) {
- /* NB: CTS is the same size as an ACK */
- dur += ieee80211_ack_duration(sc->sc_rates, rate, isshort);
- flags |= RT2573_TX_NEED_ACK;
- mprot = ieee80211_alloc_rts(ic, wh->i_addr1, wh->i_addr2, dur);
- } else {
- mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, dur);
- }
- if (mprot == NULL) {
- /* XXX stat + msg */
- return ENOBUFS;
- }
- data = &sc->tx_data[sc->tx_cur];
- desc = (struct rum_tx_desc *)data->buf;
-
- data->m = mprot;
- data->ni = ieee80211_ref_node(ni);
- m_copydata(mprot, 0, mprot->m_pkthdr.len,
- data->buf + RT2573_TX_DESC_SIZE);
- rum_setup_tx_desc(sc, desc, flags, 0, mprot->m_pkthdr.len, protrate);
-
- usbd_setup_xfer(data->xfer, sc->sc_tx_pipeh, data, data->buf,
- /* NB: no roundup necessary */
- RT2573_TX_DESC_SIZE + mprot->m_pkthdr.len,
- USBD_FORCE_SHORT_XFER | USBD_NO_COPY, RUM_TX_TIMEOUT, rum_txeof);
-
- error = usbd_transfer(data->xfer);
- if (error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS) {
- data->m = NULL;
- data->ni = NULL;
- return error;
- }
-
- sc->tx_queued++;
- sc->tx_cur = (sc->tx_cur + 1) % RUM_TX_LIST_COUNT;
-
- return 0;
-}
-
-static int
-rum_tx_mgt(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
-{
- struct ieee80211vap *vap = ni->ni_vap;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct rum_tx_desc *desc;
- struct rum_tx_data *data;
- struct ieee80211_frame *wh;
- const struct ieee80211_txparam *tp;
- struct ieee80211_key *k;
- uint32_t flags = 0;
- uint16_t dur;
- usbd_status error;
- int xferlen;
-
- data = &sc->tx_data[sc->tx_cur];
- data->m = m0;
- data->ni = ni;
- desc = (struct rum_tx_desc *)data->buf;
-
- wh = mtod(m0, struct ieee80211_frame *);
- if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
- k = ieee80211_crypto_encap(ni, m0);
- if (k == NULL) {
- m_freem(m0);
- return ENOBUFS;
- }
- wh = mtod(m0, struct ieee80211_frame *);
- }
-
- tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
-
- if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
- flags |= RT2573_TX_NEED_ACK;
-
- dur = ieee80211_ack_duration(sc->sc_rates, tp->mgmtrate,
- ic->ic_flags & IEEE80211_F_SHPREAMBLE);
- *(uint16_t *)wh->i_dur = htole16(dur);
-
- /* tell hardware to add timestamp for probe responses */
- if ((wh->i_fc[0] &
- (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
- (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP))
- flags |= RT2573_TX_TIMESTAMP;
- }
-
- if (bpf_peers_present(ifp->if_bpf)) {
- struct rum_tx_radiotap_header *tap = &sc->sc_txtap;
-
- tap->wt_flags = 0;
- tap->wt_rate = tp->mgmtrate;
- tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
- tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
- tap->wt_antenna = sc->tx_ant;
-
- bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0);
- }
-
- m_copydata(m0, 0, m0->m_pkthdr.len, data->buf + RT2573_TX_DESC_SIZE);
- rum_setup_tx_desc(sc, desc, flags, 0, m0->m_pkthdr.len, tp->mgmtrate);
-
- /* align end on a 4-bytes boundary */
- xferlen = (RT2573_TX_DESC_SIZE + m0->m_pkthdr.len + 3) & ~3;
-
- /*
- * No space left in the last URB to store the extra 4 bytes, force
- * sending of another URB.
- */
- if ((xferlen % 64) == 0)
- xferlen += 4;
-
- DPRINTFN(10, ("sending mgt frame len=%d rate=%d xfer len=%d\n",
- m0->m_pkthdr.len + (int)RT2573_TX_DESC_SIZE, tp->mgmtrate, xferlen));
-
- usbd_setup_xfer(data->xfer, sc->sc_tx_pipeh, data, data->buf, xferlen,
- USBD_FORCE_SHORT_XFER | USBD_NO_COPY, RUM_TX_TIMEOUT, rum_txeof);
-
- error = usbd_transfer(data->xfer);
- if (error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS) {
- m_freem(m0);
- data->m = NULL;
- data->ni = NULL;
- return error;
- }
-
- sc->tx_queued++;
- sc->tx_cur = (sc->tx_cur + 1) % RUM_TX_LIST_COUNT;
-
- return 0;
-}
-
-static int
-rum_tx_raw(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
- const struct ieee80211_bpf_params *params)
-{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct rum_tx_desc *desc;
- struct rum_tx_data *data;
- uint32_t flags;
- usbd_status error;
- int xferlen, rate;
-
- KASSERT(params != NULL, ("no raw xmit params"));
-
- data = &sc->tx_data[sc->tx_cur];
- desc = (struct rum_tx_desc *)data->buf;
-
- rate = params->ibp_rate0 & IEEE80211_RATE_VAL;
- /* XXX validate */
- if (rate == 0) {
- m_freem(m0);
- return EINVAL;
- }
- flags = 0;
- if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0)
- flags |= RT2573_TX_NEED_ACK;
- if (params->ibp_flags & (IEEE80211_BPF_RTS|IEEE80211_BPF_CTS)) {
- error = rum_sendprot(sc, m0, ni,
- params->ibp_flags & IEEE80211_BPF_RTS ?
- IEEE80211_PROT_RTSCTS : IEEE80211_PROT_CTSONLY,
- rate);
- if (error) {
- m_freem(m0);
- return error;
- }
- flags |= RT2573_TX_LONG_RETRY | RT2573_TX_IFS_SIFS;
- }
-
- if (bpf_peers_present(ifp->if_bpf)) {
- struct rum_tx_radiotap_header *tap = &sc->sc_txtap;
-
- tap->wt_flags = 0;
- tap->wt_rate = rate;
- tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
- tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
- tap->wt_antenna = sc->tx_ant;
-
- bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0);
- }
-
- data->m = m0;
- data->ni = ni;
-
- m_copydata(m0, 0, m0->m_pkthdr.len, data->buf + RT2573_TX_DESC_SIZE);
- /* XXX need to setup descriptor ourself */
- rum_setup_tx_desc(sc, desc, flags, 0, m0->m_pkthdr.len, rate);
-
- /* align end on a 4-bytes boundary */
- xferlen = (RT2573_TX_DESC_SIZE + m0->m_pkthdr.len + 3) & ~3;
-
- /*
- * No space left in the last URB to store the extra 4 bytes, force
- * sending of another URB.
- */
- if ((xferlen % 64) == 0)
- xferlen += 4;
-
- DPRINTFN(10, ("sending raw frame len=%u rate=%u xfer len=%u\n",
- m0->m_pkthdr.len, rate, xferlen));
-
- usbd_setup_xfer(data->xfer, sc->sc_tx_pipeh, data, data->buf,
- xferlen, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, RUM_TX_TIMEOUT,
- rum_txeof);
-
- error = usbd_transfer(data->xfer);
- if (error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS)
- return error;
-
- sc->tx_queued++;
- sc->tx_cur = (sc->tx_cur + 1) % RUM_TX_LIST_COUNT;
-
- return 0;
-}
-
-static int
-rum_tx_data(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
-{
- struct ieee80211vap *vap = ni->ni_vap;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct rum_tx_desc *desc;
- struct rum_tx_data *data;
- struct ieee80211_frame *wh;
- const struct ieee80211_txparam *tp;
- struct ieee80211_key *k;
- uint32_t flags = 0;
- uint16_t dur;
- usbd_status error;
- int rate, xferlen;
-
- wh = mtod(m0, struct ieee80211_frame *);
-
- tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)];
- if (IEEE80211_IS_MULTICAST(wh->i_addr1))
- rate = tp->mcastrate;
- else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
- rate = tp->ucastrate;
- else {
- (void) ieee80211_amrr_choose(ni, &RUM_NODE(ni)->amn);
- rate = ni->ni_txrate;
- }
-
- if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
- k = ieee80211_crypto_encap(ni, m0);
- if (k == NULL) {
- m_freem(m0);
- return ENOBUFS;
- }
-
- /* packet header may have moved, reset our local pointer */
- wh = mtod(m0, struct ieee80211_frame *);
- }
-
- if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
- int prot = IEEE80211_PROT_NONE;
- if (m0->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold)
- prot = IEEE80211_PROT_RTSCTS;
- else if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
- ieee80211_rate2phytype(sc->sc_rates, rate) == IEEE80211_T_OFDM)
- prot = ic->ic_protmode;
- if (prot != IEEE80211_PROT_NONE) {
- error = rum_sendprot(sc, m0, ni, prot, rate);
- if (error) {
- m_freem(m0);
- return error;
- }
- flags |= RT2573_TX_LONG_RETRY | RT2573_TX_IFS_SIFS;
- }
- }
-
- data = &sc->tx_data[sc->tx_cur];
- desc = (struct rum_tx_desc *)data->buf;
-
- data->m = m0;
- data->ni = ni;
-
- if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
- flags |= RT2573_TX_NEED_ACK;
- flags |= RT2573_TX_MORE_FRAG;
-
- dur = ieee80211_ack_duration(sc->sc_rates, rate,
- ic->ic_flags & IEEE80211_F_SHPREAMBLE);
- *(uint16_t *)wh->i_dur = htole16(dur);
- }
-
- if (bpf_peers_present(ifp->if_bpf)) {
- struct rum_tx_radiotap_header *tap = &sc->sc_txtap;
-
- tap->wt_flags = 0;
- tap->wt_rate = rate;
- tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
- tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
- tap->wt_antenna = sc->tx_ant;
-
- bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0);
- }
-
- m_copydata(m0, 0, m0->m_pkthdr.len, data->buf + RT2573_TX_DESC_SIZE);
- rum_setup_tx_desc(sc, desc, flags, 0, m0->m_pkthdr.len, rate);
-
- /* align end on a 4-bytes boundary */
- xferlen = (RT2573_TX_DESC_SIZE + m0->m_pkthdr.len + 3) & ~3;
-
- /*
- * No space left in the last URB to store the extra 4 bytes, force
- * sending of another URB.
- */
- if ((xferlen % 64) == 0)
- xferlen += 4;
-
- DPRINTFN(10, ("sending frame len=%d rate=%d xfer len=%d\n",
- m0->m_pkthdr.len + (int)RT2573_TX_DESC_SIZE, rate, xferlen));
-
- usbd_setup_xfer(data->xfer, sc->sc_tx_pipeh, data, data->buf, xferlen,
- USBD_FORCE_SHORT_XFER | USBD_NO_COPY, RUM_TX_TIMEOUT, rum_txeof);
-
- error = usbd_transfer(data->xfer);
- if (error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS) {
- m_freem(m0);
- data->m = NULL;
- data->ni = NULL;
- return error;
- }
-
- sc->tx_queued++;
- sc->tx_cur = (sc->tx_cur + 1) % RUM_TX_LIST_COUNT;
-
- return 0;
-}
-
-static void
-rum_start(struct ifnet *ifp)
-{
- struct rum_softc *sc = ifp->if_softc;
- struct ieee80211_node *ni;
- struct mbuf *m;
-
- for (;;) {
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL)
- break;
- if (sc->tx_queued >= RUM_TX_LIST_COUNT-1) {
- IFQ_DRV_PREPEND(&ifp->if_snd, m);
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- break;
- }
- ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
- m = ieee80211_encap(ni, m);
- if (m == NULL) {
- ieee80211_free_node(ni);
- continue;
- }
- if (rum_tx_data(sc, m, ni) != 0) {
- ieee80211_free_node(ni);
- ifp->if_oerrors++;
- break;
- }
- sc->sc_tx_timer = 5;
- callout_reset(&sc->watchdog_ch, hz, rum_watchdog, sc);
- }
-}
-
-static void
-rum_watchdog(void *arg)
-{
- struct rum_softc *sc = arg;
-
- RUM_LOCK(sc);
-
- if (sc->sc_tx_timer > 0) {
- if (--sc->sc_tx_timer == 0) {
- device_printf(sc->sc_dev, "device timeout\n");
- /*rum_init(ifp); XXX needs a process context! */
- sc->sc_ifp->if_oerrors++;
- RUM_UNLOCK(sc);
- return;
- }
- callout_reset(&sc->watchdog_ch, hz, rum_watchdog, sc);
- }
-
- RUM_UNLOCK(sc);
-}
-
-static int
-rum_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
-{
- struct rum_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ifreq *ifr = (struct ifreq *) data;
- int error = 0, startall = 0;
-
- switch (cmd) {
- case SIOCSIFFLAGS:
- RUM_LOCK(sc);
- if (ifp->if_flags & IFF_UP) {
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
- rum_init(sc);
- startall = 1;
- } else
- rum_update_promisc(sc);
- } else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- rum_stop(sc);
- }
- RUM_UNLOCK(sc);
- if (startall)
- ieee80211_start_all(ic);
- break;
- case SIOCGIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
- break;
- case SIOCGIFADDR:
- error = ether_ioctl(ifp, cmd, data);
- break;
- default:
- error = EINVAL;
- break;
- }
- return error;
-}
-
-static void
-rum_eeprom_read(struct rum_softc *sc, uint16_t addr, void *buf, int len)
-{
- usb_device_request_t req;
- usbd_status error;
-
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = RT2573_READ_EEPROM;
- USETW(req.wValue, 0);
- USETW(req.wIndex, addr);
- USETW(req.wLength, len);
-
- error = usbd_do_request(sc->sc_udev, &req, buf);
- if (error != 0) {
- device_printf(sc->sc_dev, "could not read EEPROM: %s\n",
- usbd_errstr(error));
- }
-}
-
-static uint32_t
-rum_read(struct rum_softc *sc, uint16_t reg)
-{
- uint32_t val;
-
- rum_read_multi(sc, reg, &val, sizeof val);
-
- return le32toh(val);
-}
-
-static void
-rum_read_multi(struct rum_softc *sc, uint16_t reg, void *buf, int len)
-{
- usb_device_request_t req;
- usbd_status error;
-
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = RT2573_READ_MULTI_MAC;
- USETW(req.wValue, 0);
- USETW(req.wIndex, reg);
- USETW(req.wLength, len);
-
- error = usbd_do_request(sc->sc_udev, &req, buf);
- if (error != 0) {
- device_printf(sc->sc_dev,
- "could not multi read MAC register: %s\n",
- usbd_errstr(error));
- }
-}
-
-static void
-rum_write(struct rum_softc *sc, uint16_t reg, uint32_t val)
-{
- uint32_t tmp = htole32(val);
-
- rum_write_multi(sc, reg, &tmp, sizeof tmp);
-}
-
-static void
-rum_write_multi(struct rum_softc *sc, uint16_t reg, void *buf, size_t len)
-{
- usb_device_request_t req;
- usbd_status error;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = RT2573_WRITE_MULTI_MAC;
- USETW(req.wValue, 0);
- USETW(req.wIndex, reg);
- USETW(req.wLength, len);
-
- error = usbd_do_request(sc->sc_udev, &req, buf);
- if (error != 0) {
- device_printf(sc->sc_dev,
- "could not multi write MAC register: %s\n",
- usbd_errstr(error));
- }
-}
-
-static void
-rum_bbp_write(struct rum_softc *sc, uint8_t reg, uint8_t val)
-{
- uint32_t tmp;
- int ntries;
-
- for (ntries = 0; ntries < 5; ntries++) {
- if (!(rum_read(sc, RT2573_PHY_CSR3) & RT2573_BBP_BUSY))
- break;
- }
- if (ntries == 5) {
- device_printf(sc->sc_dev, "could not write to BBP\n");
- return;
- }
-
- tmp = RT2573_BBP_BUSY | (reg & 0x7f) << 8 | val;
- rum_write(sc, RT2573_PHY_CSR3, tmp);
-}
-
-static uint8_t
-rum_bbp_read(struct rum_softc *sc, uint8_t reg)
-{
- uint32_t val;
- int ntries;
-
- for (ntries = 0; ntries < 5; ntries++) {
- if (!(rum_read(sc, RT2573_PHY_CSR3) & RT2573_BBP_BUSY))
- break;
- }
- if (ntries == 5) {
- device_printf(sc->sc_dev, "could not read BBP\n");
- return 0;
- }
-
- val = RT2573_BBP_BUSY | RT2573_BBP_READ | reg << 8;
- rum_write(sc, RT2573_PHY_CSR3, val);
-
- for (ntries = 0; ntries < 100; ntries++) {
- val = rum_read(sc, RT2573_PHY_CSR3);
- if (!(val & RT2573_BBP_BUSY))
- return val & 0xff;
- DELAY(1);
- }
-
- device_printf(sc->sc_dev, "could not read BBP\n");
- return 0;
-}
-
-static void
-rum_rf_write(struct rum_softc *sc, uint8_t reg, uint32_t val)
-{
- uint32_t tmp;
- int ntries;
-
- for (ntries = 0; ntries < 5; ntries++) {
- if (!(rum_read(sc, RT2573_PHY_CSR4) & RT2573_RF_BUSY))
- break;
- }
- if (ntries == 5) {
- device_printf(sc->sc_dev, "could not write to RF\n");
- return;
- }
-
- tmp = RT2573_RF_BUSY | RT2573_RF_20BIT | (val & 0xfffff) << 2 |
- (reg & 3);
- rum_write(sc, RT2573_PHY_CSR4, tmp);
-
- /* remember last written value in sc */
- sc->rf_regs[reg] = val;
-
- DPRINTFN(15, ("RF R[%u] <- 0x%05x\n", reg & 3, val & 0xfffff));
-}
-
-static void
-rum_select_antenna(struct rum_softc *sc)
-{
- uint8_t bbp4, bbp77;
- uint32_t tmp;
-
- bbp4 = rum_bbp_read(sc, 4);
- bbp77 = rum_bbp_read(sc, 77);
-
- /* TBD */
-
- /* make sure Rx is disabled before switching antenna */
- tmp = rum_read(sc, RT2573_TXRX_CSR0);
- rum_write(sc, RT2573_TXRX_CSR0, tmp | RT2573_DISABLE_RX);
-
- rum_bbp_write(sc, 4, bbp4);
- rum_bbp_write(sc, 77, bbp77);
-
- rum_write(sc, RT2573_TXRX_CSR0, tmp);
-}
-
-/*
- * Enable multi-rate retries for frames sent at OFDM rates.
- * In 802.11b/g mode, allow fallback to CCK rates.
- */
-static void
-rum_enable_mrr(struct rum_softc *sc)
-{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- uint32_t tmp;
-
- tmp = rum_read(sc, RT2573_TXRX_CSR4);
-
- tmp &= ~RT2573_MRR_CCK_FALLBACK;
- if (!IEEE80211_IS_CHAN_5GHZ(ic->ic_bsschan))
- tmp |= RT2573_MRR_CCK_FALLBACK;
- tmp |= RT2573_MRR_ENABLED;
-
- rum_write(sc, RT2573_TXRX_CSR4, tmp);
-}
-
-static void
-rum_set_txpreamble(struct rum_softc *sc)
-{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- uint32_t tmp;
-
- tmp = rum_read(sc, RT2573_TXRX_CSR4);
-
- tmp &= ~RT2573_SHORT_PREAMBLE;
- if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
- tmp |= RT2573_SHORT_PREAMBLE;
-
- rum_write(sc, RT2573_TXRX_CSR4, tmp);
-}
-
-static void
-rum_set_basicrates(struct rum_softc *sc)
-{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
-
- /* update basic rate set */
- if (ic->ic_curmode == IEEE80211_MODE_11B) {
- /* 11b basic rates: 1, 2Mbps */
- rum_write(sc, RT2573_TXRX_CSR5, 0x3);
- } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_bsschan)) {
- /* 11a basic rates: 6, 12, 24Mbps */
- rum_write(sc, RT2573_TXRX_CSR5, 0x150);
- } else {
- /* 11b/g basic rates: 1, 2, 5.5, 11Mbps */
- rum_write(sc, RT2573_TXRX_CSR5, 0xf);
- }
-}
-
-/*
- * Reprogram MAC/BBP to switch to a new band. Values taken from the reference
- * driver.
- */
-static void
-rum_select_band(struct rum_softc *sc, struct ieee80211_channel *c)
-{
- uint8_t bbp17, bbp35, bbp96, bbp97, bbp98, bbp104;
- uint32_t tmp;
-
- /* update all BBP registers that depend on the band */
- bbp17 = 0x20; bbp96 = 0x48; bbp104 = 0x2c;
- bbp35 = 0x50; bbp97 = 0x48; bbp98 = 0x48;
- if (IEEE80211_IS_CHAN_5GHZ(c)) {
- bbp17 += 0x08; bbp96 += 0x10; bbp104 += 0x0c;
- bbp35 += 0x10; bbp97 += 0x10; bbp98 += 0x10;
- }
- if ((IEEE80211_IS_CHAN_2GHZ(c) && sc->ext_2ghz_lna) ||
- (IEEE80211_IS_CHAN_5GHZ(c) && sc->ext_5ghz_lna)) {
- bbp17 += 0x10; bbp96 += 0x10; bbp104 += 0x10;
- }
-
- sc->bbp17 = bbp17;
- rum_bbp_write(sc, 17, bbp17);
- rum_bbp_write(sc, 96, bbp96);
- rum_bbp_write(sc, 104, bbp104);
-
- if ((IEEE80211_IS_CHAN_2GHZ(c) && sc->ext_2ghz_lna) ||
- (IEEE80211_IS_CHAN_5GHZ(c) && sc->ext_5ghz_lna)) {
- rum_bbp_write(sc, 75, 0x80);
- rum_bbp_write(sc, 86, 0x80);
- rum_bbp_write(sc, 88, 0x80);
- }
-
- rum_bbp_write(sc, 35, bbp35);
- rum_bbp_write(sc, 97, bbp97);
- rum_bbp_write(sc, 98, bbp98);
-
- tmp = rum_read(sc, RT2573_PHY_CSR0);
- tmp &= ~(RT2573_PA_PE_2GHZ | RT2573_PA_PE_5GHZ);
- if (IEEE80211_IS_CHAN_2GHZ(c))
- tmp |= RT2573_PA_PE_2GHZ;
- else
- tmp |= RT2573_PA_PE_5GHZ;
- rum_write(sc, RT2573_PHY_CSR0, tmp);
-}
-
-static void
-rum_set_chan(struct rum_softc *sc, struct ieee80211_channel *c)
-{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- const struct rfprog *rfprog;
- uint8_t bbp3, bbp94 = RT2573_BBPR94_DEFAULT;
- int8_t power;
- u_int i, chan;
-
- chan = ieee80211_chan2ieee(ic, c);
- if (chan == 0 || chan == IEEE80211_CHAN_ANY)
- return;
-
- /* select the appropriate RF settings based on what EEPROM says */
- rfprog = (sc->rf_rev == RT2573_RF_5225 ||
- sc->rf_rev == RT2573_RF_2527) ? rum_rf5225 : rum_rf5226;
-
- /* find the settings for this channel (we know it exists) */
- for (i = 0; rfprog[i].chan != chan; i++);
-
- power = sc->txpow[i];
- if (power < 0) {
- bbp94 += power;
- power = 0;
- } else if (power > 31) {
- bbp94 += power - 31;
- power = 31;
- }
-
- /*
- * If we are switching from the 2GHz band to the 5GHz band or
- * vice-versa, BBP registers need to be reprogrammed.
- */
- if (c->ic_flags != ic->ic_curchan->ic_flags) {
- rum_select_band(sc, c);
- rum_select_antenna(sc);
- }
- ic->ic_curchan = c;
-
- rum_rf_write(sc, RT2573_RF1, rfprog[i].r1);
- rum_rf_write(sc, RT2573_RF2, rfprog[i].r2);
- rum_rf_write(sc, RT2573_RF3, rfprog[i].r3 | power << 7);
- rum_rf_write(sc, RT2573_RF4, rfprog[i].r4 | sc->rffreq << 10);
-
- rum_rf_write(sc, RT2573_RF1, rfprog[i].r1);
- rum_rf_write(sc, RT2573_RF2, rfprog[i].r2);
- rum_rf_write(sc, RT2573_RF3, rfprog[i].r3 | power << 7 | 1);
- rum_rf_write(sc, RT2573_RF4, rfprog[i].r4 | sc->rffreq << 10);
-
- rum_rf_write(sc, RT2573_RF1, rfprog[i].r1);
- rum_rf_write(sc, RT2573_RF2, rfprog[i].r2);
- rum_rf_write(sc, RT2573_RF3, rfprog[i].r3 | power << 7);
- rum_rf_write(sc, RT2573_RF4, rfprog[i].r4 | sc->rffreq << 10);
-
- DELAY(10);
-
- /* enable smart mode for MIMO-capable RFs */
- bbp3 = rum_bbp_read(sc, 3);
-
- bbp3 &= ~RT2573_SMART_MODE;
- if (sc->rf_rev == RT2573_RF_5225 || sc->rf_rev == RT2573_RF_2527)
- bbp3 |= RT2573_SMART_MODE;
-
- rum_bbp_write(sc, 3, bbp3);
-
- if (bbp94 != RT2573_BBPR94_DEFAULT)
- rum_bbp_write(sc, 94, bbp94);
-}
-
-/*
- * Enable TSF synchronization and tell h/w to start sending beacons for IBSS
- * and HostAP operating modes.
- */
-static void
-rum_enable_tsf_sync(struct rum_softc *sc)
-{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
- uint32_t tmp;
-
- if (vap->iv_opmode != IEEE80211_M_STA) {
- /*
- * Change default 16ms TBTT adjustment to 8ms.
- * Must be done before enabling beacon generation.
- */
- rum_write(sc, RT2573_TXRX_CSR10, 1 << 12 | 8);
- }
-
- tmp = rum_read(sc, RT2573_TXRX_CSR9) & 0xff000000;
-
- /* set beacon interval (in 1/16ms unit) */
- tmp |= vap->iv_bss->ni_intval * 16;
-
- tmp |= RT2573_TSF_TICKING | RT2573_ENABLE_TBTT;
- if (vap->iv_opmode == IEEE80211_M_STA)
- tmp |= RT2573_TSF_MODE(1);
- else
- tmp |= RT2573_TSF_MODE(2) | RT2573_GENERATE_BEACON;
-
- rum_write(sc, RT2573_TXRX_CSR9, tmp);
-}
-
-static void
-rum_update_slot(struct ifnet *ifp)
-{
- struct rum_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
- uint8_t slottime;
- uint32_t tmp;
-
- slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20;
-
- tmp = rum_read(sc, RT2573_MAC_CSR9);
- tmp = (tmp & ~0xff) | slottime;
- rum_write(sc, RT2573_MAC_CSR9, tmp);
-
- DPRINTF(("setting slot time to %uus\n", slottime));
-}
-
-static void
-rum_set_bssid(struct rum_softc *sc, const uint8_t *bssid)
-{
- uint32_t tmp;
-
- tmp = bssid[0] | bssid[1] << 8 | bssid[2] << 16 | bssid[3] << 24;
- rum_write(sc, RT2573_MAC_CSR4, tmp);
-
- tmp = bssid[4] | bssid[5] << 8 | RT2573_ONE_BSSID << 16;
- rum_write(sc, RT2573_MAC_CSR5, tmp);
-}
-
-static void
-rum_set_macaddr(struct rum_softc *sc, const uint8_t *addr)
-{
- uint32_t tmp;
-
- tmp = addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24;
- rum_write(sc, RT2573_MAC_CSR2, tmp);
-
- tmp = addr[4] | addr[5] << 8 | 0xff << 16;
- rum_write(sc, RT2573_MAC_CSR3, tmp);
-}
-
-static void
-rum_update_promisc(struct rum_softc *sc)
-{
- struct ifnet *ifp = sc->sc_ifp;
- uint32_t tmp;
-
- tmp = rum_read(sc, RT2573_TXRX_CSR0);
-
- tmp &= ~RT2573_DROP_NOT_TO_ME;
- if (!(ifp->if_flags & IFF_PROMISC))
- tmp |= RT2573_DROP_NOT_TO_ME;
-
- rum_write(sc, RT2573_TXRX_CSR0, tmp);
-
- DPRINTF(("%s promiscuous mode\n", (ifp->if_flags & IFF_PROMISC) ?
- "entering" : "leaving"));
-}
-
-static const char *
-rum_get_rf(int rev)
-{
- switch (rev) {
- case RT2573_RF_2527: return "RT2527 (MIMO XR)";
- case RT2573_RF_2528: return "RT2528";
- case RT2573_RF_5225: return "RT5225 (MIMO XR)";
- case RT2573_RF_5226: return "RT5226";
- default: return "unknown";
- }
-}
-
-static void
-rum_read_eeprom(struct rum_softc *sc)
-{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- uint16_t val;
-#ifdef RUM_DEBUG
- int i;
-#endif
-
- /* read MAC address */
- rum_eeprom_read(sc, RT2573_EEPROM_ADDRESS, ic->ic_myaddr, 6);
-
- rum_eeprom_read(sc, RT2573_EEPROM_ANTENNA, &val, 2);
- val = le16toh(val);
- sc->rf_rev = (val >> 11) & 0x1f;
- sc->hw_radio = (val >> 10) & 0x1;
- sc->rx_ant = (val >> 4) & 0x3;
- sc->tx_ant = (val >> 2) & 0x3;
- sc->nb_ant = val & 0x3;
-
- DPRINTF(("RF revision=%d\n", sc->rf_rev));
-
- rum_eeprom_read(sc, RT2573_EEPROM_CONFIG2, &val, 2);
- val = le16toh(val);
- sc->ext_5ghz_lna = (val >> 6) & 0x1;
- sc->ext_2ghz_lna = (val >> 4) & 0x1;
-
- DPRINTF(("External 2GHz LNA=%d\nExternal 5GHz LNA=%d\n",
- sc->ext_2ghz_lna, sc->ext_5ghz_lna));
-
- rum_eeprom_read(sc, RT2573_EEPROM_RSSI_2GHZ_OFFSET, &val, 2);
- val = le16toh(val);
- if ((val & 0xff) != 0xff)
- sc->rssi_2ghz_corr = (int8_t)(val & 0xff); /* signed */
-
- /* Only [-10, 10] is valid */
- if (sc->rssi_2ghz_corr < -10 || sc->rssi_2ghz_corr > 10)
- sc->rssi_2ghz_corr = 0;
-
- rum_eeprom_read(sc, RT2573_EEPROM_RSSI_5GHZ_OFFSET, &val, 2);
- val = le16toh(val);
- if ((val & 0xff) != 0xff)
- sc->rssi_5ghz_corr = (int8_t)(val & 0xff); /* signed */
-
- /* Only [-10, 10] is valid */
- if (sc->rssi_5ghz_corr < -10 || sc->rssi_5ghz_corr > 10)
- sc->rssi_5ghz_corr = 0;
-
- if (sc->ext_2ghz_lna)
- sc->rssi_2ghz_corr -= 14;
- if (sc->ext_5ghz_lna)
- sc->rssi_5ghz_corr -= 14;
-
- DPRINTF(("RSSI 2GHz corr=%d\nRSSI 5GHz corr=%d\n",
- sc->rssi_2ghz_corr, sc->rssi_5ghz_corr));
-
- rum_eeprom_read(sc, RT2573_EEPROM_FREQ_OFFSET, &val, 2);
- val = le16toh(val);
- if ((val & 0xff) != 0xff)
- sc->rffreq = val & 0xff;
-
- DPRINTF(("RF freq=%d\n", sc->rffreq));
-
- /* read Tx power for all a/b/g channels */
- rum_eeprom_read(sc, RT2573_EEPROM_TXPOWER, sc->txpow, 14);
- /* XXX default Tx power for 802.11a channels */
- memset(sc->txpow + 14, 24, sizeof (sc->txpow) - 14);
-#ifdef RUM_DEBUG
- for (i = 0; i < 14; i++)
- DPRINTF(("Channel=%d Tx power=%d\n", i + 1, sc->txpow[i]));
-#endif
-
- /* read default values for BBP registers */
- rum_eeprom_read(sc, RT2573_EEPROM_BBP_BASE, sc->bbp_prom, 2 * 16);
-#ifdef RUM_DEBUG
- for (i = 0; i < 14; i++) {
- if (sc->bbp_prom[i].reg == 0 || sc->bbp_prom[i].reg == 0xff)
- continue;
- DPRINTF(("BBP R%d=%02x\n", sc->bbp_prom[i].reg,
- sc->bbp_prom[i].val));
- }
-#endif
-}
-
-static int
-rum_bbp_init(struct rum_softc *sc)
-{
-#define N(a) (sizeof (a) / sizeof ((a)[0]))
- int i, ntries;
-
- /* wait for BBP to be ready */
- for (ntries = 0; ntries < 100; ntries++) {
- const uint8_t val = rum_bbp_read(sc, 0);
- if (val != 0 && val != 0xff)
- break;
- DELAY(1000);
- }
- if (ntries == 100) {
- device_printf(sc->sc_dev, "timeout waiting for BBP\n");
- return EIO;
- }
-
- /* initialize BBP registers to default values */
- for (i = 0; i < N(rum_def_bbp); i++)
- rum_bbp_write(sc, rum_def_bbp[i].reg, rum_def_bbp[i].val);
-
- /* write vendor-specific BBP values (from EEPROM) */
- for (i = 0; i < 16; i++) {
- if (sc->bbp_prom[i].reg == 0 || sc->bbp_prom[i].reg == 0xff)
- continue;
- rum_bbp_write(sc, sc->bbp_prom[i].reg, sc->bbp_prom[i].val);
- }
-
- return 0;
-#undef N
-}
-
-static void
-rum_init_locked(struct rum_softc *sc)
-{
-#define N(a) (sizeof (a) / sizeof ((a)[0]))
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct rum_rx_data *data;
- uint32_t tmp;
- usbd_status error;
- int i, ntries;
-
- rum_stop(sc);
-
- /* initialize MAC registers to default values */
- for (i = 0; i < N(rum_def_mac); i++)
- rum_write(sc, rum_def_mac[i].reg, rum_def_mac[i].val);
-
- /* set host ready */
- rum_write(sc, RT2573_MAC_CSR1, 3);
- rum_write(sc, RT2573_MAC_CSR1, 0);
-
- /* wait for BBP/RF to wakeup */
- for (ntries = 0; ntries < 1000; ntries++) {
- if (rum_read(sc, RT2573_MAC_CSR12) & 8)
- break;
- rum_write(sc, RT2573_MAC_CSR12, 4); /* force wakeup */
- DELAY(1000);
- }
- if (ntries == 1000) {
- device_printf(sc->sc_dev,
- "timeout waiting for BBP/RF to wakeup\n");
- goto fail;
- }
-
- if ((error = rum_bbp_init(sc)) != 0)
- goto fail;
-
- /* select default channel */
- rum_select_band(sc, ic->ic_curchan);
- rum_select_antenna(sc);
- rum_set_chan(sc, ic->ic_curchan);
-
- /* clear STA registers */
- rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof sc->sta);
-
- IEEE80211_ADDR_COPY(ic->ic_myaddr, IF_LLADDR(ifp));
- rum_set_macaddr(sc, ic->ic_myaddr);
-
- /* initialize ASIC */
- rum_write(sc, RT2573_MAC_CSR1, 4);
-
- /*
- * Allocate xfer for AMRR statistics requests.
- */
- sc->amrr_xfer = usbd_alloc_xfer(sc->sc_udev);
- if (sc->amrr_xfer == NULL) {
- device_printf(sc->sc_dev, "could not allocate AMRR xfer\n");
- goto fail;
- }
-
- /*
- * Open Tx and Rx USB bulk pipes.
- */
- error = usbd_open_pipe(sc->sc_iface, sc->sc_tx_no, USBD_EXCLUSIVE_USE,
- &sc->sc_tx_pipeh);
- if (error != 0) {
- device_printf(sc->sc_dev, "could not open Tx pipe: %s\n",
- usbd_errstr(error));
- goto fail;
- }
- error = usbd_open_pipe(sc->sc_iface, sc->sc_rx_no, USBD_EXCLUSIVE_USE,
- &sc->sc_rx_pipeh);
- if (error != 0) {
- device_printf(sc->sc_dev, "could not open Rx pipe: %s\n",
- usbd_errstr(error));
- goto fail;
- }
-
- /*
- * Allocate Tx and Rx xfer queues.
- */
- error = rum_alloc_tx_list(sc);
- if (error != 0) {
- device_printf(sc->sc_dev, "could not allocate Tx list\n");
- goto fail;
- }
- error = rum_alloc_rx_list(sc);
- if (error != 0) {
- device_printf(sc->sc_dev, "could not allocate Rx list\n");
- goto fail;
- }
-
- /*
- * Start up the receive pipe.
- */
- for (i = 0; i < RUM_RX_LIST_COUNT; i++) {
- data = &sc->rx_data[i];
-
- usbd_setup_xfer(data->xfer, sc->sc_rx_pipeh, data, data->buf,
- MCLBYTES, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, rum_rxeof);
- usbd_transfer(data->xfer);
- }
-
- /* update Rx filter */
- tmp = rum_read(sc, RT2573_TXRX_CSR0) & 0xffff;
-
- tmp |= RT2573_DROP_PHY_ERROR | RT2573_DROP_CRC_ERROR;
- if (ic->ic_opmode != IEEE80211_M_MONITOR) {
- tmp |= RT2573_DROP_CTL | RT2573_DROP_VER_ERROR |
- RT2573_DROP_ACKCTS;
- if (ic->ic_opmode != IEEE80211_M_HOSTAP)
- tmp |= RT2573_DROP_TODS;
- if (!(ifp->if_flags & IFF_PROMISC))
- tmp |= RT2573_DROP_NOT_TO_ME;
- }
- rum_write(sc, RT2573_TXRX_CSR0, tmp);
-
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
- return;
-
-fail: rum_stop(sc);
-#undef N
-}
-
-static void
-rum_init(void *priv)
-{
- struct rum_softc *sc = priv;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
-
- RUM_LOCK(sc);
- rum_init_locked(sc);
- RUM_UNLOCK(sc);
-
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- ieee80211_start_all(ic); /* start all vap's */
-}
-
-static void
-rum_stop(void *priv)
-{
- struct rum_softc *sc = priv;
- struct ifnet *ifp = sc->sc_ifp;
- uint32_t tmp;
-
- sc->sc_tx_timer = 0;
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
-
- /* disable Rx */
- tmp = rum_read(sc, RT2573_TXRX_CSR0);
- rum_write(sc, RT2573_TXRX_CSR0, tmp | RT2573_DISABLE_RX);
-
- /* reset ASIC */
- rum_write(sc, RT2573_MAC_CSR1, 3);
- rum_write(sc, RT2573_MAC_CSR1, 0);
-
- if (sc->amrr_xfer != NULL) {
- usbd_free_xfer(sc->amrr_xfer);
- sc->amrr_xfer = NULL;
- }
-
- if (sc->sc_rx_pipeh != NULL) {
- usbd_abort_pipe(sc->sc_rx_pipeh);
- usbd_close_pipe(sc->sc_rx_pipeh);
- sc->sc_rx_pipeh = NULL;
- }
- if (sc->sc_tx_pipeh != NULL) {
- usbd_abort_pipe(sc->sc_tx_pipeh);
- usbd_close_pipe(sc->sc_tx_pipeh);
- sc->sc_tx_pipeh = NULL;
- }
-
- rum_free_rx_list(sc);
- rum_free_tx_list(sc);
-}
-
-static int
-rum_load_microcode(struct rum_softc *sc, const u_char *ucode, size_t size)
-{
- usb_device_request_t req;
- uint16_t reg = RT2573_MCU_CODE_BASE;
- usbd_status error;
-
- /* copy firmware image into NIC */
- for (; size >= 4; reg += 4, ucode += 4, size -= 4)
- rum_write(sc, reg, UGETDW(ucode));
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = RT2573_MCU_CNTL;
- USETW(req.wValue, RT2573_MCU_RUN);
- USETW(req.wIndex, 0);
- USETW(req.wLength, 0);
-
- error = usbd_do_request(sc->sc_udev, &req, NULL);
- if (error != 0) {
- device_printf(sc->sc_dev, "could not run firmware: %s\n",
- usbd_errstr(error));
- }
- return error;
-}
-
-static int
-rum_prepare_beacon(struct rum_softc *sc, struct ieee80211vap *vap)
-{
- struct ieee80211com *ic = vap->iv_ic;
- const struct ieee80211_txparam *tp;
- struct rum_tx_desc desc;
- struct mbuf *m0;
-
- m0 = ieee80211_beacon_alloc(vap->iv_bss, &RUM_VAP(vap)->bo);
- if (m0 == NULL) {
- return ENOBUFS;
- }
-
- tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_bsschan)];
- rum_setup_tx_desc(sc, &desc, RT2573_TX_TIMESTAMP, RT2573_TX_HWSEQ,
- m0->m_pkthdr.len, tp->mgmtrate);
-
- /* copy the first 24 bytes of Tx descriptor into NIC memory */
- rum_write_multi(sc, RT2573_HW_BEACON_BASE0, (uint8_t *)&desc, 24);
-
- /* copy beacon header and payload into NIC memory */
- rum_write_multi(sc, RT2573_HW_BEACON_BASE0 + 24, mtod(m0, uint8_t *),
- m0->m_pkthdr.len);
-
- m_freem(m0);
-
- return 0;
-}
-
-static int
-rum_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
- const struct ieee80211_bpf_params *params)
-{
- struct ifnet *ifp = ni->ni_ic->ic_ifp;
- struct rum_softc *sc = ifp->if_softc;
-
- /* prevent management frames from being sent if we're not ready */
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
- m_freem(m);
- ieee80211_free_node(ni);
- return ENETDOWN;
- }
- if (sc->tx_queued >= RUM_TX_LIST_COUNT-1) {
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- m_freem(m);
- ieee80211_free_node(ni);
- return EIO;
- }
-
- ifp->if_opackets++;
-
- if (params == NULL) {
- /*
- * Legacy path; interpret frame contents to decide
- * precisely how to send the frame.
- */
- if (rum_tx_mgt(sc, m, ni) != 0)
- goto bad;
- } else {
- /*
- * Caller supplied explicit parameters to use in
- * sending the frame.
- */
- if (rum_tx_raw(sc, m, ni, params) != 0)
- goto bad;
- }
- sc->sc_tx_timer = 5;
- callout_reset(&sc->watchdog_ch, hz, rum_watchdog, sc);
-
- return 0;
-bad:
- ifp->if_oerrors++;
- ieee80211_free_node(ni);
- return EIO;
-}
-
-static void
-rum_amrr_start(struct rum_softc *sc, struct ieee80211_node *ni)
-{
- struct ieee80211vap *vap = ni->ni_vap;
- struct rum_vap *rvp = RUM_VAP(vap);
-
- /* clear statistic registers (STA_CSR0 to STA_CSR5) */
- rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof sc->sta);
-
- ieee80211_amrr_node_init(&rvp->amrr, &RUM_NODE(ni)->amn, ni);
-
- callout_reset(&rvp->amrr_ch, hz, rum_amrr_timeout, vap);
-}
-
-static void
-rum_amrr_timeout(void *arg)
-{
- struct ieee80211vap *vap = arg;
- struct rum_softc *sc = vap->iv_ic->ic_ifp->if_softc;
- usb_device_request_t req;
-
- /*
- * Asynchronously read statistic registers (cleared by read).
- */
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = RT2573_READ_MULTI_MAC;
- USETW(req.wValue, 0);
- USETW(req.wIndex, RT2573_STA_CSR0);
- USETW(req.wLength, sizeof sc->sta);
-
- usbd_setup_default_xfer(sc->amrr_xfer, sc->sc_udev, vap,
- USBD_DEFAULT_TIMEOUT, &req, sc->sta, sizeof sc->sta, 0,
- rum_amrr_update);
- (void)usbd_transfer(sc->amrr_xfer);
-}
-
-static void
-rum_amrr_update(usbd_xfer_handle xfer, usbd_private_handle priv,
- usbd_status status)
-{
- struct ieee80211vap *vap = priv;
- struct rum_vap *rvp = RUM_VAP(vap);
- struct ifnet *ifp = vap->iv_ic->ic_ifp;
- struct rum_softc *sc = ifp->if_softc;
- int ok, fail;
-
- if (status != USBD_NORMAL_COMPLETION) {
- device_printf(sc->sc_dev, "could not retrieve Tx statistics - "
- "cancelling automatic rate control\n");
- return;
- }
-
- ok = (le32toh(sc->sta[4]) >> 16) + /* TX ok w/o retry */
- (le32toh(sc->sta[5]) & 0xffff); /* TX ok w/ retry */
- fail = (le32toh(sc->sta[5]) >> 16); /* TX retry-fail count */
-
- ieee80211_amrr_tx_update(&RUM_NODE(vap->iv_bss)->amn,
- ok+fail, ok, (le32toh(sc->sta[5]) & 0xffff) + fail);
-
- ifp->if_oerrors += fail; /* count TX retry-fail as Tx errors */
-
- callout_reset(&rvp->amrr_ch, hz, rum_amrr_timeout, vap);
-}
-
-/* ARGUSED */
-static struct ieee80211_node *
-rum_node_alloc(struct ieee80211vap *vap __unused,
- const uint8_t mac[IEEE80211_ADDR_LEN] __unused)
-{
- struct rum_node *rn;
-
- rn = malloc(sizeof(struct rum_node), M_80211_NODE, M_NOWAIT | M_ZERO);
- return rn != NULL ? &rn->ni : NULL;
-}
-
-static void
-rum_newassoc(struct ieee80211_node *ni, int isnew)
-{
- struct ieee80211vap *vap = ni->ni_vap;
-
- ieee80211_amrr_node_init(&RUM_VAP(vap)->amrr, &RUM_NODE(ni)->amn, ni);
-}
-
-static void
-rum_scan_start(struct ieee80211com *ic)
-{
- struct rum_softc *sc = ic->ic_ifp->if_softc;
-
- usb_rem_task(sc->sc_udev, &sc->sc_scantask);
-
- /* do it in a process context */
- sc->sc_scan_action = RUM_SCAN_START;
- usb_add_task(sc->sc_udev, &sc->sc_scantask, USB_TASKQ_DRIVER);
-}
-
-static void
-rum_scan_end(struct ieee80211com *ic)
-{
- struct rum_softc *sc = ic->ic_ifp->if_softc;
-
- usb_rem_task(sc->sc_udev, &sc->sc_scantask);
-
- /* do it in a process context */
- sc->sc_scan_action = RUM_SCAN_END;
- usb_add_task(sc->sc_udev, &sc->sc_scantask, USB_TASKQ_DRIVER);
-}
-
-static void
-rum_set_channel(struct ieee80211com *ic)
-{
- struct rum_softc *sc = ic->ic_ifp->if_softc;
-
- usb_rem_task(sc->sc_udev, &sc->sc_scantask);
-
- /* do it in a process context */
- sc->sc_scan_action = RUM_SET_CHANNEL;
- usb_add_task(sc->sc_udev, &sc->sc_scantask, USB_TASKQ_DRIVER);
-
- sc->sc_rates = ieee80211_get_ratetable(ic->ic_curchan);
-}
-
-static void
-rum_scantask(void *arg)
-{
- struct rum_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
- uint32_t tmp;
-
- RUM_LOCK(sc);
-
- switch (sc->sc_scan_action) {
- case RUM_SCAN_START:
- /* abort TSF synchronization */
- tmp = rum_read(sc, RT2573_TXRX_CSR9);
- rum_write(sc, RT2573_TXRX_CSR9, tmp & ~0x00ffffff);
- rum_set_bssid(sc, ifp->if_broadcastaddr);
- break;
-
- case RUM_SCAN_END:
- rum_enable_tsf_sync(sc);
- /* XXX keep local copy */
- rum_set_bssid(sc, vap->iv_bss->ni_bssid);
- break;
-
- case RUM_SET_CHANNEL:
- mtx_lock(&Giant);
- rum_set_chan(sc, ic->ic_curchan);
- mtx_unlock(&Giant);
- break;
-
- default:
- panic("unknown scan action %d\n", sc->sc_scan_action);
- /* NEVER REACHED */
- break;
- }
-
- RUM_UNLOCK(sc);
-}
-
-static int
-rum_get_rssi(struct rum_softc *sc, uint8_t raw)
-{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- int lna, agc, rssi;
-
- lna = (raw >> 5) & 0x3;
- agc = raw & 0x1f;
-
- if (lna == 0) {
- /*
- * No RSSI mapping
- *
- * NB: Since RSSI is relative to noise floor, -1 is
- * adequate for caller to know error happened.
- */
- return -1;
- }
-
- rssi = (2 * agc) - RT2573_NOISE_FLOOR;
-
- if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
- rssi += sc->rssi_2ghz_corr;
-
- if (lna == 1)
- rssi -= 64;
- else if (lna == 2)
- rssi -= 74;
- else if (lna == 3)
- rssi -= 90;
- } else {
- rssi += sc->rssi_5ghz_corr;
-
- if (!sc->ext_5ghz_lna && lna != 1)
- rssi += 4;
-
- if (lna == 1)
- rssi -= 64;
- else if (lna == 2)
- rssi -= 86;
- else if (lna == 3)
- rssi -= 100;
- }
- return rssi;
-}
-
-static device_method_t rum_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, rum_match),
- DEVMETHOD(device_attach, rum_attach),
- DEVMETHOD(device_detach, rum_detach),
-
- { 0, 0 }
-};
-
-static driver_t rum_driver = {
- "rum",
- rum_methods,
- sizeof(struct rum_softc)
-};
-
-static devclass_t rum_devclass;
-
-DRIVER_MODULE(rum, uhub, rum_driver, rum_devclass, usbd_driver_load, 0);
diff --git a/sys/dev/usb/if_rumreg.h b/sys/dev/usb/if_rumreg.h
deleted file mode 100644
index 75a51bc..0000000
--- a/sys/dev/usb/if_rumreg.h
+++ /dev/null
@@ -1,235 +0,0 @@
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 2005, 2006 Damien Bergamini <damien.bergamini@free.fr>
- * Copyright (c) 2006 Niall O'Higgins <niallo@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#define RT2573_NOISE_FLOOR -95
-
-#define RT2573_TX_DESC_SIZE (sizeof (struct rum_tx_desc))
-#define RT2573_RX_DESC_SIZE (sizeof (struct rum_rx_desc))
-
-#define RT2573_CONFIG_NO 1
-#define RT2573_IFACE_INDEX 0
-
-#define RT2573_MCU_CNTL 0x01
-#define RT2573_WRITE_MAC 0x02
-#define RT2573_READ_MAC 0x03
-#define RT2573_WRITE_MULTI_MAC 0x06
-#define RT2573_READ_MULTI_MAC 0x07
-#define RT2573_READ_EEPROM 0x09
-#define RT2573_WRITE_LED 0x0a
-
-/*
- * Control and status registers.
- */
-#define RT2573_AIFSN_CSR 0x0400
-#define RT2573_CWMIN_CSR 0x0404
-#define RT2573_CWMAX_CSR 0x0408
-#define RT2573_MCU_CODE_BASE 0x0800
-#define RT2573_HW_BEACON_BASE0 0x2400
-#define RT2573_MAC_CSR0 0x3000
-#define RT2573_MAC_CSR1 0x3004
-#define RT2573_MAC_CSR2 0x3008
-#define RT2573_MAC_CSR3 0x300c
-#define RT2573_MAC_CSR4 0x3010
-#define RT2573_MAC_CSR5 0x3014
-#define RT2573_MAC_CSR6 0x3018
-#define RT2573_MAC_CSR7 0x301c
-#define RT2573_MAC_CSR8 0x3020
-#define RT2573_MAC_CSR9 0x3024
-#define RT2573_MAC_CSR10 0x3028
-#define RT2573_MAC_CSR11 0x302c
-#define RT2573_MAC_CSR12 0x3030
-#define RT2573_MAC_CSR13 0x3034
-#define RT2573_MAC_CSR14 0x3038
-#define RT2573_MAC_CSR15 0x303c
-#define RT2573_TXRX_CSR0 0x3040
-#define RT2573_TXRX_CSR1 0x3044
-#define RT2573_TXRX_CSR2 0x3048
-#define RT2573_TXRX_CSR3 0x304c
-#define RT2573_TXRX_CSR4 0x3050
-#define RT2573_TXRX_CSR5 0x3054
-#define RT2573_TXRX_CSR6 0x3058
-#define RT2573_TXRX_CSR7 0x305c
-#define RT2573_TXRX_CSR8 0x3060
-#define RT2573_TXRX_CSR9 0x3064
-#define RT2573_TXRX_CSR10 0x3068
-#define RT2573_TXRX_CSR11 0x306c
-#define RT2573_TXRX_CSR12 0x3070
-#define RT2573_TXRX_CSR13 0x3074
-#define RT2573_TXRX_CSR14 0x3078
-#define RT2573_TXRX_CSR15 0x307c
-#define RT2573_PHY_CSR0 0x3080
-#define RT2573_PHY_CSR1 0x3084
-#define RT2573_PHY_CSR2 0x3088
-#define RT2573_PHY_CSR3 0x308c
-#define RT2573_PHY_CSR4 0x3090
-#define RT2573_PHY_CSR5 0x3094
-#define RT2573_PHY_CSR6 0x3098
-#define RT2573_PHY_CSR7 0x309c
-#define RT2573_SEC_CSR0 0x30a0
-#define RT2573_SEC_CSR1 0x30a4
-#define RT2573_SEC_CSR2 0x30a8
-#define RT2573_SEC_CSR3 0x30ac
-#define RT2573_SEC_CSR4 0x30b0
-#define RT2573_SEC_CSR5 0x30b4
-#define RT2573_STA_CSR0 0x30c0
-#define RT2573_STA_CSR1 0x30c4
-#define RT2573_STA_CSR2 0x30c8
-#define RT2573_STA_CSR3 0x30cc
-#define RT2573_STA_CSR4 0x30d0
-#define RT2573_STA_CSR5 0x30d4
-
-
-/* possible flags for register RT2573_MAC_CSR1 */
-#define RT2573_RESET_ASIC (1 << 0)
-#define RT2573_RESET_BBP (1 << 1)
-#define RT2573_HOST_READY (1 << 2)
-
-/* possible flags for register MAC_CSR5 */
-#define RT2573_ONE_BSSID 3
-
-/* possible flags for register TXRX_CSR0 */
-/* Tx filter flags are in the low 16 bits */
-#define RT2573_AUTO_TX_SEQ (1 << 15)
-/* Rx filter flags are in the high 16 bits */
-#define RT2573_DISABLE_RX (1 << 16)
-#define RT2573_DROP_CRC_ERROR (1 << 17)
-#define RT2573_DROP_PHY_ERROR (1 << 18)
-#define RT2573_DROP_CTL (1 << 19)
-#define RT2573_DROP_NOT_TO_ME (1 << 20)
-#define RT2573_DROP_TODS (1 << 21)
-#define RT2573_DROP_VER_ERROR (1 << 22)
-#define RT2573_DROP_MULTICAST (1 << 23)
-#define RT2573_DROP_BROADCAST (1 << 24)
-#define RT2573_DROP_ACKCTS (1 << 25)
-
-/* possible flags for register TXRX_CSR4 */
-#define RT2573_SHORT_PREAMBLE (1 << 18)
-#define RT2573_MRR_ENABLED (1 << 19)
-#define RT2573_MRR_CCK_FALLBACK (1 << 22)
-
-/* possible flags for register TXRX_CSR9 */
-#define RT2573_TSF_TICKING (1 << 16)
-#define RT2573_TSF_MODE(x) (((x) & 0x3) << 17)
-/* TBTT stands for Target Beacon Transmission Time */
-#define RT2573_ENABLE_TBTT (1 << 19)
-#define RT2573_GENERATE_BEACON (1 << 20)
-
-/* possible flags for register PHY_CSR0 */
-#define RT2573_PA_PE_2GHZ (1 << 16)
-#define RT2573_PA_PE_5GHZ (1 << 17)
-
-/* possible flags for register PHY_CSR3 */
-#define RT2573_BBP_READ (1 << 15)
-#define RT2573_BBP_BUSY (1 << 16)
-/* possible flags for register PHY_CSR4 */
-#define RT2573_RF_20BIT (20 << 24)
-#define RT2573_RF_BUSY (1 << 31)
-
-/* LED values */
-#define RT2573_LED_RADIO (1 << 8)
-#define RT2573_LED_G (1 << 9)
-#define RT2573_LED_A (1 << 10)
-#define RT2573_LED_ON 0x1e1e
-#define RT2573_LED_OFF 0x0
-
-#define RT2573_MCU_RUN (1 << 3)
-
-#define RT2573_SMART_MODE (1 << 0)
-
-#define RT2573_BBPR94_DEFAULT 6
-
-#define RT2573_BBP_WRITE (1 << 15)
-
-/* dual-band RF */
-#define RT2573_RF_5226 1
-#define RT2573_RF_5225 3
-/* single-band RF */
-#define RT2573_RF_2528 2
-#define RT2573_RF_2527 4
-
-#define RT2573_BBP_VERSION 0
-
-struct rum_tx_desc {
- uint32_t flags;
-#define RT2573_TX_BURST (1 << 0)
-#define RT2573_TX_VALID (1 << 1)
-#define RT2573_TX_MORE_FRAG (1 << 2)
-#define RT2573_TX_NEED_ACK (1 << 3)
-#define RT2573_TX_TIMESTAMP (1 << 4)
-#define RT2573_TX_OFDM (1 << 5)
-#define RT2573_TX_IFS_SIFS (1 << 6)
-#define RT2573_TX_LONG_RETRY (1 << 7)
-
- uint16_t wme;
-#define RT2573_QID(v) (v)
-#define RT2573_AIFSN(v) ((v) << 4)
-#define RT2573_LOGCWMIN(v) ((v) << 8)
-#define RT2573_LOGCWMAX(v) ((v) << 12)
-
- uint16_t xflags;
-#define RT2573_TX_HWSEQ (1 << 12)
-
- uint8_t plcp_signal;
- uint8_t plcp_service;
-#define RT2573_PLCP_LENGEXT 0x80
-
- uint8_t plcp_length_lo;
- uint8_t plcp_length_hi;
-
- uint32_t iv;
- uint32_t eiv;
-
- uint8_t offset;
- uint8_t qid;
- uint8_t txpower;
-#define RT2573_DEFAULT_TXPOWER 0
-
- uint8_t reserved;
-} __packed;
-
-struct rum_rx_desc {
- uint32_t flags;
-#define RT2573_RX_BUSY (1 << 0)
-#define RT2573_RX_DROP (1 << 1)
-#define RT2573_RX_CRC_ERROR (1 << 6)
-#define RT2573_RX_OFDM (1 << 7)
-
- uint8_t rate;
- uint8_t rssi;
- uint8_t reserved1;
- uint8_t offset;
- uint32_t iv;
- uint32_t eiv;
- uint32_t reserved2[2];
-} __packed;
-
-#define RT2573_RF1 0
-#define RT2573_RF2 2
-#define RT2573_RF3 1
-#define RT2573_RF4 3
-
-#define RT2573_EEPROM_MACBBP 0x0000
-#define RT2573_EEPROM_ADDRESS 0x0004
-#define RT2573_EEPROM_ANTENNA 0x0020
-#define RT2573_EEPROM_CONFIG2 0x0022
-#define RT2573_EEPROM_BBP_BASE 0x0026
-#define RT2573_EEPROM_TXPOWER 0x0046
-#define RT2573_EEPROM_FREQ_OFFSET 0x005e
-#define RT2573_EEPROM_RSSI_2GHZ_OFFSET 0x009a
-#define RT2573_EEPROM_RSSI_5GHZ_OFFSET 0x009c
diff --git a/sys/dev/usb/if_rumvar.h b/sys/dev/usb/if_rumvar.h
deleted file mode 100644
index 59980c0..0000000
--- a/sys/dev/usb/if_rumvar.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 2005, 2006 Damien Bergamini <damien.bergamini@free.fr>
- * Copyright (c) 2006 Niall O'Higgins <niallo@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#define RUM_RX_LIST_COUNT 1
-#define RUM_TX_LIST_COUNT 8
-
-struct rum_rx_radiotap_header {
- struct ieee80211_radiotap_header wr_ihdr;
- uint8_t wr_flags;
- uint8_t wr_rate;
- uint16_t wr_chan_freq;
- uint16_t wr_chan_flags;
- uint8_t wr_antenna;
- uint8_t wr_antsignal;
-};
-
-#define RT2573_RX_RADIOTAP_PRESENT \
- ((1 << IEEE80211_RADIOTAP_FLAGS) | \
- (1 << IEEE80211_RADIOTAP_RATE) | \
- (1 << IEEE80211_RADIOTAP_CHANNEL) | \
- (1 << IEEE80211_RADIOTAP_ANTENNA) | \
- (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL))
-
-struct rum_tx_radiotap_header {
- struct ieee80211_radiotap_header wt_ihdr;
- uint8_t wt_flags;
- uint8_t wt_rate;
- uint16_t wt_chan_freq;
- uint16_t wt_chan_flags;
- uint8_t wt_antenna;
-};
-
-#define RT2573_TX_RADIOTAP_PRESENT \
- ((1 << IEEE80211_RADIOTAP_FLAGS) | \
- (1 << IEEE80211_RADIOTAP_RATE) | \
- (1 << IEEE80211_RADIOTAP_CHANNEL) | \
- (1 << IEEE80211_RADIOTAP_ANTENNA))
-
-struct rum_softc;
-
-struct rum_tx_data {
- struct rum_softc *sc;
- usbd_xfer_handle xfer;
- uint8_t *buf;
- struct mbuf *m;
- struct ieee80211_node *ni;
-};
-
-struct rum_rx_data {
- struct rum_softc *sc;
- usbd_xfer_handle xfer;
- uint8_t *buf;
- struct mbuf *m;
-};
-
-struct rum_node {
- struct ieee80211_node ni;
- struct ieee80211_amrr_node amn;
-};
-#define RUM_NODE(ni) ((struct rum_node *)(ni))
-
-struct rum_vap {
- struct ieee80211vap vap;
- struct ieee80211_beacon_offsets bo;
- struct ieee80211_amrr amrr;
- struct callout amrr_ch;
-
- int (*newstate)(struct ieee80211vap *,
- enum ieee80211_state, int);
-};
-#define RUM_VAP(vap) ((struct rum_vap *)(vap))
-
-struct rum_softc {
- struct ifnet *sc_ifp;
- const struct ieee80211_rate_table *sc_rates;
-
- device_t sc_dev;
- usbd_device_handle sc_udev;
- usbd_interface_handle sc_iface;
-
- int sc_rx_no;
- int sc_tx_no;
-
- uint8_t rf_rev;
- uint8_t rffreq;
-
- usbd_xfer_handle amrr_xfer;
-
- usbd_pipe_handle sc_rx_pipeh;
- usbd_pipe_handle sc_tx_pipeh;
-
- enum ieee80211_state sc_state;
- int sc_arg;
- struct usb_task sc_task;
-
- struct usb_task sc_scantask;
- int sc_scan_action;
-#define RUM_SCAN_START 0
-#define RUM_SCAN_END 1
-#define RUM_SET_CHANNEL 2
-
- struct rum_rx_data rx_data[RUM_RX_LIST_COUNT];
- struct rum_tx_data tx_data[RUM_TX_LIST_COUNT];
- int tx_queued;
- int tx_cur;
-
- struct mtx sc_mtx;
-
- struct callout watchdog_ch;
-
- int sc_tx_timer;
-
- uint32_t sta[6];
- uint32_t rf_regs[4];
- uint8_t txpow[44];
-
- struct {
- uint8_t val;
- uint8_t reg;
- } __packed bbp_prom[16];
-
- int hw_radio;
- int rx_ant;
- int tx_ant;
- int nb_ant;
- int ext_2ghz_lna;
- int ext_5ghz_lna;
- int rssi_2ghz_corr;
- int rssi_5ghz_corr;
- uint8_t bbp17;
-
- struct rum_rx_radiotap_header sc_rxtap;
- int sc_rxtap_len;
-
- struct rum_tx_radiotap_header sc_txtap;
- int sc_txtap_len;
-};
-
-#if 0
-#define RUM_LOCK(sc) mtx_lock(&(sc)->sc_mtx)
-#define RUM_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx)
-#else
-#define RUM_LOCK(sc) do { ((sc) = (sc)); mtx_lock(&Giant); } while (0)
-#define RUM_UNLOCK(sc) mtx_unlock(&Giant)
-#endif
diff --git a/sys/dev/usb/if_udav.c b/sys/dev/usb/if_udav.c
deleted file mode 100644
index e13170e..0000000
--- a/sys/dev/usb/if_udav.c
+++ /dev/null
@@ -1,1962 +0,0 @@
-/* $NetBSD: if_udav.c,v 1.2 2003/09/04 15:17:38 tsutsui Exp $ */
-/* $nabe: if_udav.c,v 1.3 2003/08/21 16:57:19 nabe Exp $ */
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2003
- * Shingo WATANABE <nabe@nabechan.org>. 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. 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 THE AUTHOR 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 AUTHOR 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.
- *
- */
-
-/*
- * DM9601(DAVICOM USB to Ethernet MAC Controller with Integrated 10/100 PHY)
- * The spec can be found at the following url.
- * http://www.davicom.com.tw/big5/download/Data%20Sheet/DM9601-DS-P01-930914.pdf
- */
-
-/*
- * TODO:
- * Interrupt Endpoint support
- * External PHYs
- * powerhook() support?
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include "opt_inet.h"
-#if defined(__NetBSD__)
-#include "opt_ns.h"
-#endif
-#if defined(__NetBSD__)
-#include "bpfilter.h"
-#endif
-#if defined(__FreeBSD__)
-#define NBPFILTER 1
-#endif
-#if defined(__NetBSD__)
-#include "rnd.h"
-#endif
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/lock.h>
-#include <sys/mbuf.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/socket.h>
-#if defined(__FreeBSD__)
-#include <sys/types.h>
-#include <sys/lockmgr.h>
-#include <sys/sockio.h>
-#endif
-
-#if defined(__NetBSD__)
-#include <sys/device.h>
-#endif
-
-#if defined(NRND) && NRND > 0
-#include <sys/rnd.h>
-#endif
-
-#include <net/if.h>
-#include <net/if_arp.h>
-#include <net/if_dl.h>
-#include <net/if_media.h>
-#include <net/ethernet.h>
-#include <net/if_types.h>
-
-#if NBPFILTER > 0
-#include <net/bpf.h>
-#endif
-#if defined(__NetBSD__)
-#ifndef BPF_MTAP
-#define BPF_MTAP(_ifp, _m) do { \
- if ((_ifp)->if_bpf)) { \
- bpf_mtap((_ifp)->if_bpf, (_m)) ; \
- } \
-} while (0)
-#endif
-#endif
-
-#if defined(__NetBSD__)
-#include <net/if_ether.h>
-#ifdef INET
-#include <netinet/in.h>
-#include <netinet/if_inarp.h>
-#endif /* INET */
-#elif defined(__FreeBSD__) /* defined(__NetBSD__) */
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-#endif /* defined(__FreeBSD__) */
-
-#if defined(__NetBSD__)
-#ifdef NS
-#include <netns/ns.h>
-#include <netns/ns_if.h>
-#endif
-#endif /* defined (__NetBSD__) */
-
-#include <sys/bus.h>
-#include <machine/bus.h>
-
-#include <dev/mii/mii.h>
-#include <dev/mii/miivar.h>
-
-#include <dev/usb/usb_port.h>
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include "usbdevs.h"
-#include <dev/usb/usbdivar.h>
-#include <dev/usb/usb_ethersubr.h>
-
-#include <dev/usb/if_udavreg.h>
-
-#if defined(__FreeBSD__)
-MODULE_DEPEND(udav, usb, 1, 1, 1);
-MODULE_DEPEND(udav, ether, 1, 1, 1);
-MODULE_DEPEND(udav, miibus, 1, 1, 1);
-#endif
-
-/* "device miibus" required. See GENERIC if you get errors here. */
-#include "miibus_if.h"
-
-#if !defined(__FreeBSD__)
-/* Function declarations */
-USB_DECLARE_DRIVER(udav);
-#endif
-
-#if defined(__FreeBSD__)
-static device_probe_t udav_match;
-static device_attach_t udav_attach;
-static device_detach_t udav_detach;
-static device_shutdown_t udav_shutdown;
-static miibus_readreg_t udav_miibus_readreg;
-static miibus_writereg_t udav_miibus_writereg;
-static miibus_statchg_t udav_miibus_statchg;
-#endif
-
-static int udav_openpipes(struct udav_softc *);
-static void udav_start(struct ifnet *);
-static int udav_send(struct udav_softc *, struct mbuf *, int);
-static void udav_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
-#if defined(__FreeBSD__)
-static void udav_rxstart(struct ifnet *ifp);
-#endif
-static void udav_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
-static void udav_tick(void *);
-static void udav_tick_task(void *);
-static int udav_ioctl(struct ifnet *, u_long, caddr_t);
-static void udav_stop_task(struct udav_softc *);
-static void udav_stop(struct ifnet *, int);
-static void udav_watchdog(struct ifnet *);
-static int udav_ifmedia_change(struct ifnet *);
-static void udav_ifmedia_status(struct ifnet *, struct ifmediareq *);
-static void udav_lock_mii(struct udav_softc *);
-static void udav_unlock_mii(struct udav_softc *);
-#if defined(__NetBSD__)
-static int udav_miibus_readreg(device_t, int, int);
-static void udav_miibus_writereg(device_t, int, int, int);
-static void udav_miibus_statchg(device_t);
-static int udav_init(struct ifnet *);
-#elif defined(__FreeBSD__)
-static void udav_init(void *);
-#endif
-static void udav_setmulti(struct udav_softc *);
-static void udav_reset(struct udav_softc *);
-
-static int udav_csr_read(struct udav_softc *, int, void *, int);
-static int udav_csr_write(struct udav_softc *, int, void *, int);
-static int udav_csr_read1(struct udav_softc *, int);
-static int udav_csr_write1(struct udav_softc *, int, unsigned char);
-
-#if 0
-static int udav_mem_read(struct udav_softc *, int, void *, int);
-static int udav_mem_write(struct udav_softc *, int, void *, int);
-static int udav_mem_write1(struct udav_softc *, int, unsigned char);
-#endif
-
-#if defined(__FreeBSD__)
-static device_method_t udav_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, udav_match),
- DEVMETHOD(device_attach, udav_attach),
- DEVMETHOD(device_detach, udav_detach),
- DEVMETHOD(device_shutdown, udav_shutdown),
-
- /* bus interface */
- DEVMETHOD(bus_print_child, bus_generic_print_child),
- DEVMETHOD(bus_driver_added, bus_generic_driver_added),
-
- /* MII interface */
- DEVMETHOD(miibus_readreg, udav_miibus_readreg),
- DEVMETHOD(miibus_writereg, udav_miibus_writereg),
- DEVMETHOD(miibus_statchg, udav_miibus_statchg),
-
- { 0, 0 }
-};
-
-static driver_t udav_driver = {
- "udav",
- udav_methods,
- sizeof(struct udav_softc)
-};
-
-static devclass_t udav_devclass;
-
-DRIVER_MODULE(udav, uhub, udav_driver, udav_devclass, usbd_driver_load, 0);
-DRIVER_MODULE(miibus, udav, miibus_driver, miibus_devclass, 0, 0);
-
-#endif /* defined(__FreeBSD__) */
-
-/* Macros */
-#ifdef UDAV_DEBUG
-#define DPRINTF(x) if (udavdebug) printf x
-#define DPRINTFN(n,x) if (udavdebug >= (n)) printf x
-int udavdebug = 0;
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-#define delay(d) DELAY(d)
-
-#define UDAV_SETBIT(sc, reg, x) \
- udav_csr_write1(sc, reg, udav_csr_read1(sc, reg) | (x))
-
-#define UDAV_CLRBIT(sc, reg, x) \
- udav_csr_write1(sc, reg, udav_csr_read1(sc, reg) & ~(x))
-
-static const struct udav_type {
- struct usb_devno udav_dev;
- u_int16_t udav_flags;
-#define UDAV_EXT_PHY 0x0001
-} udav_devs [] = {
- /* Corega USB-TXC */
- {{ USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB_TXC }, 0},
- /* ShanTou ST268 USB NIC */
- {{ USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_ST268 }, 0},
- /* ShanTou DM9601 USB NIC */
- {{ USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_DM9601}, 0},
-};
-#define udav_lookup(v, p) ((const struct udav_type *)usb_lookup(udav_devs, v, p))
-
-
-/* Probe */
-static int
-udav_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
-
- if (uaa->iface != NULL)
- return (UMATCH_NONE);
-
- return (udav_lookup(uaa->vendor, uaa->product) != NULL ?
- UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
-}
-
-/* Attach */
-static int
-udav_attach(device_t self)
-{
- USB_ATTACH_START(udav, sc, uaa);
- usbd_device_handle dev = uaa->device;
- usbd_interface_handle iface;
- usbd_status err;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
- const char *devname ;
- struct ifnet *ifp;
-#if defined(__NetBSD__)
- struct mii_data *mii;
-#endif
- u_char eaddr[ETHER_ADDR_LEN];
- int i;
-#if defined(__NetBSD__)
- int s;
-#endif
-
- sc->sc_dev = self;
- devname = device_get_nameunit(self);
- /* Move the device into the configured state. */
- err = usbd_set_config_no(dev, UDAV_CONFIG_NO, 1);
- if (err) {
- printf("%s: setting config no failed\n", devname);
- goto bad;
- }
-
- usb_init_task(&sc->sc_tick_task, udav_tick_task, sc);
- lockinit(&sc->sc_mii_lock, PZERO, "udavmii", 0, 0);
- usb_init_task(&sc->sc_stop_task, (void (*)(void *)) udav_stop_task, sc);
-
- /* get control interface */
- err = usbd_device2interface_handle(dev, UDAV_IFACE_INDEX, &iface);
- if (err) {
- printf("%s: failed to get interface, err=%s\n", devname,
- usbd_errstr(err));
- goto bad;
- }
-
- sc->sc_udev = dev;
- sc->sc_ctl_iface = iface;
- sc->sc_flags = udav_lookup(uaa->vendor, uaa->product)->udav_flags;
-
- /* get interface descriptor */
- id = usbd_get_interface_descriptor(sc->sc_ctl_iface);
-
- /* find endpoints */
- sc->sc_bulkin_no = sc->sc_bulkout_no = sc->sc_intrin_no = -1;
- for (i = 0; i < id->bNumEndpoints; i++) {
- ed = usbd_interface2endpoint_descriptor(sc->sc_ctl_iface, i);
- if (ed == NULL) {
- printf("%s: couldn't get endpoint %d\n", devname, i);
- goto bad;
- }
- if ((ed->bmAttributes & UE_XFERTYPE) == UE_BULK &&
- UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN)
- sc->sc_bulkin_no = ed->bEndpointAddress; /* RX */
- else if ((ed->bmAttributes & UE_XFERTYPE) == UE_BULK &&
- UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT)
- sc->sc_bulkout_no = ed->bEndpointAddress; /* TX */
- else if ((ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT &&
- UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN)
- sc->sc_intrin_no = ed->bEndpointAddress; /* Status */
- }
-
- if (sc->sc_bulkin_no == -1 || sc->sc_bulkout_no == -1 ||
- sc->sc_intrin_no == -1) {
- printf("%s: missing endpoint\n", devname);
- goto bad;
- }
-
-#if defined(__FreeBSD__)
- mtx_init(&sc->sc_mtx, device_get_nameunit(self), MTX_NETWORK_LOCK,
- MTX_DEF | MTX_RECURSE);
-#endif
-#if defined(__NetBSD__)
- s = splnet();
-#elif defined(__FreeBSD__)
- UDAV_LOCK(sc);
-#endif
-
- /* reset the adapter */
- udav_reset(sc);
-
- /* Get Ethernet Address */
- err = udav_csr_read(sc, UDAV_PAR, (void *)eaddr, ETHER_ADDR_LEN);
- if (err) {
- printf("%s: read MAC address failed\n", devname);
-#if defined(__NetBSD__)
- splx(s);
-#elif defined(__FreeBSD__)
- UDAV_UNLOCK(sc);
- mtx_destroy(&sc->sc_mtx);
-#endif
- goto bad;
- }
-
- /* Print Ethernet Address */
- printf("%s: Ethernet address %s\n", devname, ether_sprintf(eaddr));
-
- /* initialize interface infomation */
-#if defined(__FreeBSD__)
- ifp = GET_IFP(sc) = if_alloc(IFT_ETHER);
- if (ifp == NULL) {
- printf("%s: can not if_alloc\n", devname);
- UDAV_UNLOCK(sc);
- mtx_destroy(&sc->sc_mtx);
- goto bad;
- }
-#else
- ifp = GET_IFP(sc);
-#endif
- ifp->if_softc = sc;
- ifp->if_mtu = ETHERMTU;
-#if defined(__NetBSD__)
- strncpy(ifp->if_xname, devname, IFNAMSIZ);
-#elif defined(__FreeBSD__)
- if_initname(ifp, "udav", device_get_unit(self));
-#endif
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
- IFF_NEEDSGIANT;
- ifp->if_start = udav_start;
- ifp->if_ioctl = udav_ioctl;
- ifp->if_watchdog = udav_watchdog;
- ifp->if_init = udav_init;
-#if defined(__NetBSD__)
- ifp->if_stop = udav_stop;
-#endif
-#if defined(__FreeBSD__)
- ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
-#endif
-#if defined(__NetBSD__)
- IFQ_SET_READY(&ifp->if_snd);
-#endif
-
-
-#if defined(__NetBSD__)
- /*
- * Do ifmedia setup.
- */
- mii = &sc->sc_mii;
- mii->mii_ifp = ifp;
- mii->mii_readreg = udav_miibus_readreg;
- mii->mii_writereg = udav_miibus_writereg;
- mii->mii_statchg = udav_miibus_statchg;
- mii->mii_flags = MIIF_AUTOTSLEEP;
- ifmedia_init(&mii->mii_media, 0,
- udav_ifmedia_change, udav_ifmedia_status);
- mii_attach(self, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0);
- 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);
- Ether_ifattach(ifp, eaddr);
-#elif defined(__FreeBSD__)
- if (mii_phy_probe(self, &sc->sc_miibus,
- udav_ifmedia_change, udav_ifmedia_status)) {
- printf("%s: MII without any PHY!\n", device_get_nameunit(sc->sc_dev));
- if_free(ifp);
- UDAV_UNLOCK(sc);
- mtx_destroy(&sc->sc_mtx);
- return ENXIO;
- }
-
- sc->sc_qdat.ifp = ifp;
- sc->sc_qdat.if_rxstart = udav_rxstart;
-
- /*
- * Call MI attach routine.
- */
-
- ether_ifattach(ifp, eaddr);
-#endif
-
-#if defined(NRND) && NRND > 0
- rnd_attach_source(&sc->rnd_source, devname, RND_TYPE_NET, 0);
-#endif
-
- usb_callout_init(sc->sc_stat_ch);
-#if defined(__FreeBSD__)
- usb_register_netisr();
-#endif
- sc->sc_attached = 1;
-#if defined(__NetBSD__)
- splx(s);
-#elif defined(__FreeBSD__)
- UDAV_UNLOCK(sc);
-#endif
-
- usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, dev, sc->sc_dev);
-
- return 0;
-
- bad:
- sc->sc_dying = 1;
- return ENXIO;
-}
-
-/* detach */
-static int
-udav_detach(device_t self)
-{
- USB_DETACH_START(udav, sc);
- struct ifnet *ifp = GET_IFP(sc);
-#if defined(__NetBSD__)
- int s;
-#endif
-
- DPRINTF(("%s: %s: enter\n", device_get_nameunit(sc->sc_dev), __func__));
-
- /* Detached before attached finished */
- if (!sc->sc_attached)
- return (0);
-
- UDAV_LOCK(sc);
-
- usb_uncallout(sc->sc_stat_ch, udav_tick, sc);
-
- /* Remove any pending tasks */
- usb_rem_task(sc->sc_udev, &sc->sc_tick_task);
- usb_rem_task(sc->sc_udev, &sc->sc_stop_task);
-
-#if defined(__NetBSD__)
- s = splusb();
-#elif defined(__FreeBSD__)
- UDAV_LOCK(sc);
-#endif
-
- if (--sc->sc_refcnt >= 0) {
- /* Wait for processes to go away */
- usb_detach_wait(sc->sc_dev);
- }
-#if defined(__FreeBSD__)
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
-#else
- if (ifp->if_flags & IFF_RUNNING)
-#endif
- udav_stop(GET_IFP(sc), 1);
-
-#if defined(NRND) && NRND > 0
- rnd_detach_source(&sc->rnd_source);
-#endif
-#if defined(__NetBSD__)
- mii_detach(&sc->sc_mii, MII_PHY_ANY, MII_OFFSET_ANY);
- ifmedia_delete_instance(&sc->sc_mii.mii_media, IFM_INST_ANY);
-#endif
- ether_ifdetach(ifp);
-#if defined(__NetBSD__)
- if_detach(ifp);
-#endif
-#if defined(__FreeBSD__)
- if_free(ifp);
-#endif
-
-#ifdef DIAGNOSTIC
- if (sc->sc_pipe_tx != NULL)
- printf("%s: detach has active tx endpoint.\n",
- device_get_nameunit(sc->sc_dev));
- if (sc->sc_pipe_rx != NULL)
- printf("%s: detach has active rx endpoint.\n",
- device_get_nameunit(sc->sc_dev));
- if (sc->sc_pipe_intr != NULL)
- printf("%s: detach has active intr endpoint.\n",
- device_get_nameunit(sc->sc_dev));
-#endif
- sc->sc_attached = 0;
-
-#if defined(__NetBSD__)
- splx(s);
-#elif defined(__FreeBSD__)
- UDAV_UNLOCK(sc);
-#endif
-
-#if defined(__FreeBSD__)
- mtx_destroy(&sc->sc_mtx);
-#endif
-
- usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev);
- return (0);
-}
-
-#if 0
-/* read memory */
-static int
-udav_mem_read(struct udav_softc *sc, int offset, void *buf, int len)
-{
- usb_device_request_t req;
- usbd_status err;
-
- if (sc == NULL)
- return (0);
-
- DPRINTFN(0x200,
- ("%s: %s: enter\n", device_get_nameunit(sc->sc_dev), __func__));
-
- if (sc->sc_dying)
- return (0);
-
- offset &= 0xffff;
- len &= 0xff;
-
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = UDAV_REQ_MEM_READ;
- USETW(req.wValue, 0x0000);
- USETW(req.wIndex, offset);
- USETW(req.wLength, len);
-
- sc->sc_refcnt++;
- err = usbd_do_request(sc->sc_udev, &req, buf);
- if (--sc->sc_refcnt < 0)
- usb_detach_wakeup(sc->sc_dev);
- if (err) {
- DPRINTF(("%s: %s: read failed. off=%04x, err=%d\n",
- device_get_nameunit(sc->sc_dev), __func__, offset, err));
- }
-
- return (err);
-}
-
-/* write memory */
-static int
-udav_mem_write(struct udav_softc *sc, int offset, void *buf, int len)
-{
- usb_device_request_t req;
- usbd_status err;
-
- if (sc == NULL)
- return (0);
-
- DPRINTFN(0x200,
- ("%s: %s: enter\n", device_get_nameunit(sc->sc_dev), __func__));
-
- if (sc->sc_dying)
- return (0);
-
- offset &= 0xffff;
- len &= 0xff;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = UDAV_REQ_MEM_WRITE;
- USETW(req.wValue, 0x0000);
- USETW(req.wIndex, offset);
- USETW(req.wLength, len);
-
- sc->sc_refcnt++;
- err = usbd_do_request(sc->sc_udev, &req, buf);
- if (--sc->sc_refcnt < 0)
- usb_detach_wakeup(sc->sc_dev);
- if (err) {
- DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n",
- device_get_nameunit(sc->sc_dev), __func__, offset, err));
- }
-
- return (err);
-}
-
-/* write memory */
-static int
-udav_mem_write1(struct udav_softc *sc, int offset, unsigned char ch)
-{
- usb_device_request_t req;
- usbd_status err;
-
- if (sc == NULL)
- return (0);
-
- DPRINTFN(0x200,
- ("%s: %s: enter\n", device_get_nameunit(sc->sc_dev), __func__));
-
- if (sc->sc_dying)
- return (0);
-
- offset &= 0xffff;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = UDAV_REQ_MEM_WRITE1;
- USETW(req.wValue, ch);
- USETW(req.wIndex, offset);
- USETW(req.wLength, 0x0000);
-
- sc->sc_refcnt++;
- err = usbd_do_request(sc->sc_udev, &req, NULL);
- if (--sc->sc_refcnt < 0)
- usb_detach_wakeup(sc->sc_dev);
- if (err) {
- DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n",
- device_get_nameunit(sc->sc_dev), __func__, offset, err));
- }
-
- return (err);
-}
-#endif
-
-/* read register(s) */
-static int
-udav_csr_read(struct udav_softc *sc, int offset, void *buf, int len)
-{
- usb_device_request_t req;
- usbd_status err;
-
- if (sc == NULL)
- return (0);
-
- DPRINTFN(0x200,
- ("%s: %s: enter\n", device_get_nameunit(sc->sc_dev), __func__));
-
- if (sc->sc_dying)
- return (0);
-
- offset &= 0xff;
- len &= 0xff;
-
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = UDAV_REQ_REG_READ;
- USETW(req.wValue, 0x0000);
- USETW(req.wIndex, offset);
- USETW(req.wLength, len);
-
- sc->sc_refcnt++;
- err = usbd_do_request(sc->sc_udev, &req, buf);
- if (--sc->sc_refcnt < 0)
- usb_detach_wakeup(sc->sc_dev);
- if (err) {
- DPRINTF(("%s: %s: read failed. off=%04x, err=%d\n",
- device_get_nameunit(sc->sc_dev), __func__, offset, err));
- }
-
- return (err);
-}
-
-/* write register(s) */
-static int
-udav_csr_write(struct udav_softc *sc, int offset, void *buf, int len)
-{
- usb_device_request_t req;
- usbd_status err;
-
- if (sc == NULL)
- return (0);
-
- DPRINTFN(0x200,
- ("%s: %s: enter\n", device_get_nameunit(sc->sc_dev), __func__));
-
- if (sc->sc_dying)
- return (0);
-
- offset &= 0xff;
- len &= 0xff;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = UDAV_REQ_REG_WRITE;
- USETW(req.wValue, 0x0000);
- USETW(req.wIndex, offset);
- USETW(req.wLength, len);
-
- sc->sc_refcnt++;
- err = usbd_do_request(sc->sc_udev, &req, buf);
- if (--sc->sc_refcnt < 0)
- usb_detach_wakeup(sc->sc_dev);
- if (err) {
- DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n",
- device_get_nameunit(sc->sc_dev), __func__, offset, err));
- }
-
- return (err);
-}
-
-static int
-udav_csr_read1(struct udav_softc *sc, int offset)
-{
- u_int8_t val = 0;
-
- if (sc == NULL)
- return (0);
-
- DPRINTFN(0x200,
- ("%s: %s: enter\n", device_get_nameunit(sc->sc_dev), __func__));
-
- if (sc->sc_dying)
- return (0);
-
- return (udav_csr_read(sc, offset, &val, 1) ? 0 : val);
-}
-
-/* write a register */
-static int
-udav_csr_write1(struct udav_softc *sc, int offset, unsigned char ch)
-{
- usb_device_request_t req;
- usbd_status err;
-
- if (sc == NULL)
- return (0);
-
- DPRINTFN(0x200,
- ("%s: %s: enter\n", device_get_nameunit(sc->sc_dev), __func__));
-
- if (sc->sc_dying)
- return (0);
-
- offset &= 0xff;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = UDAV_REQ_REG_WRITE1;
- USETW(req.wValue, ch);
- USETW(req.wIndex, offset);
- USETW(req.wLength, 0x0000);
-
- sc->sc_refcnt++;
- err = usbd_do_request(sc->sc_udev, &req, NULL);
- if (--sc->sc_refcnt < 0)
- usb_detach_wakeup(sc->sc_dev);
- if (err) {
- DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n",
- device_get_nameunit(sc->sc_dev), __func__, offset, err));
- }
-
- return (err);
-}
-
-#if defined(__NetBSD__)
-static int
-udav_init(struct ifnet *ifp)
-#elif defined(__FreeBSD__)
-static void
-udav_init(void *xsc)
-#endif
-{
-#if defined(__NetBSD__)
- struct udav_softc *sc = ifp->if_softc;
-#elif defined(__FreeBSD__)
- struct udav_softc *sc = (struct udav_softc *)xsc;
- struct ifnet *ifp = GET_IFP(sc);
-#endif
- struct mii_data *mii = GET_MII(sc);
- u_char *eaddr;
-#if defined(__NetBSD__)
- int s;
-#endif
-
- DPRINTF(("%s: %s: enter\n", device_get_nameunit(sc->sc_dev), __func__));
-
- if (sc->sc_dying)
-#if defined(__NetBSD__)
- return (EIO);
-#elif defined(__FreeBSD__)
- return ;
-#endif
-
-#if defined(__NetBSD__)
- s = splnet();
-#elif defined(__FreeBSD__)
- UDAV_LOCK(sc);
-#endif
-
- /* Cancel pending I/O and free all TX/RX buffers */
- udav_stop(ifp, 1);
-
-#if defined(__NetBSD__)
- eaddr = LLADDR(ifp->if_sadl);
-#elif defined(__FreeBSD__)
- eaddr = IF_LLADDR(ifp);
-#endif
- udav_csr_write(sc, UDAV_PAR, eaddr, ETHER_ADDR_LEN);
-
- /* Initialize network control register */
- /* Disable loopback */
- UDAV_CLRBIT(sc, UDAV_NCR, UDAV_NCR_LBK0 | UDAV_NCR_LBK1);
-
- /* Initialize RX control register */
- UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_DIS_LONG | UDAV_RCR_DIS_CRC);
-
- /* If we want promiscuous mode, accept all physical frames. */
- if (ifp->if_flags & IFF_PROMISC)
- UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_ALL|UDAV_RCR_PRMSC);
- else
- UDAV_CLRBIT(sc, UDAV_RCR, UDAV_RCR_ALL|UDAV_RCR_PRMSC);
-
- /* Initialize transmit ring */
- if (usb_ether_tx_list_init(sc, &sc->sc_cdata,
- sc->sc_udev) == ENOBUFS) {
- printf("%s: tx list init failed\n", device_get_nameunit(sc->sc_dev));
-#if defined(__NetBSD__)
- splx(s);
- return (EIO);
-#elif defined(__FreeBSD__)
- UDAV_UNLOCK(sc);
- return ;
-#endif
-
- }
-
- /* Initialize receive ring */
- if (usb_ether_rx_list_init(sc, &sc->sc_cdata,
- sc->sc_udev) == ENOBUFS) {
- printf("%s: rx list init failed\n", device_get_nameunit(sc->sc_dev));
-#if defined(__NetBSD__)
- splx(s);
- return (EIO);
-#elif defined(__FreeBSD__)
- UDAV_UNLOCK(sc);
- return ;
-#endif
- }
-
- /* Load the multicast filter */
- udav_setmulti(sc);
-
- /* Enable RX */
- UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_RXEN);
-
- /* clear POWER_DOWN state of internal PHY */
- UDAV_SETBIT(sc, UDAV_GPCR, UDAV_GPCR_GEP_CNTL0);
- UDAV_CLRBIT(sc, UDAV_GPR, UDAV_GPR_GEPIO0);
-
- mii_mediachg(mii);
-
- if (sc->sc_pipe_tx == NULL || sc->sc_pipe_rx == NULL) {
- if (udav_openpipes(sc)) {
-#if defined(__NetBSD__)
- splx(s);
- return (EIO);
-#elif defined(__FreeBSD__)
- UDAV_UNLOCK(sc);
- return ;
-#endif
- }
- }
-
-#if defined(__FreeBSD__)
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
-#else
- ifp->if_flags |= IFF_RUNNING;
- ifp->if_flags &= ~IFF_OACTIVE;
-#endif
-
-#if defined(__NetBSD__)
- splx(s);
-#elif defined(__FreeBSD__)
- UDAV_UNLOCK(sc);
-#endif
-
- usb_callout(sc->sc_stat_ch, hz, udav_tick, sc);
-
-#if defined(__NetBSD__)
- return (0);
-#elif defined(__FreeBSD__)
- return ;
-#endif
-}
-
-static void
-udav_reset(struct udav_softc *sc)
-{
- int i;
-
- DPRINTF(("%s: %s: enter\n", device_get_nameunit(sc->sc_dev), __func__));
-
- if (sc->sc_dying)
- return;
-
- /* Select PHY */
-#if 1
- /*
- * XXX: force select internal phy.
- * external phy routines are not tested.
- */
- UDAV_CLRBIT(sc, UDAV_NCR, UDAV_NCR_EXT_PHY);
-#else
- if (sc->sc_flags & UDAV_EXT_PHY) {
- UDAV_SETBIT(sc, UDAV_NCR, UDAV_NCR_EXT_PHY);
- } else {
- UDAV_CLRBIT(sc, UDAV_NCR, UDAV_NCR_EXT_PHY);
- }
-#endif
-
- UDAV_SETBIT(sc, UDAV_NCR, UDAV_NCR_RST);
-
- for (i = 0; i < UDAV_TX_TIMEOUT; i++) {
- if (!(udav_csr_read1(sc, UDAV_NCR) & UDAV_NCR_RST))
- break;
- delay(10); /* XXX */
- }
- delay(10000); /* XXX */
-}
-
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-int
-udav_activate(device_t self, enum devact act)
-{
- struct udav_softc *sc = (struct udav_softc *)self;
-
- DPRINTF(("%s: %s: enter, act=%d\n", device_get_nameunit(sc->sc_dev),
- __func__, act));
- switch (act) {
- case DVACT_ACTIVATE:
- return (EOPNOTSUPP);
- break;
-
- case DVACT_DEACTIVATE:
- if_deactivate(&sc->sc_ec.ec_if);
- sc->sc_dying = 1;
- break;
- }
- return (0);
-}
-#endif
-
-#define UDAV_BITS 6
-
-#define UDAV_CALCHASH(addr) \
- (ether_crc32_le((addr), ETHER_ADDR_LEN) & ((1 << UDAV_BITS) - 1))
-
-static void
-udav_setmulti(struct udav_softc *sc)
-{
- struct ifnet *ifp;
-#if defined(__NetBSD__)
- struct ether_multi *enm;
- struct ether_multistep step;
-#elif defined(__FreeBSD__)
- struct ifmultiaddr *ifma;
-#endif
- u_int8_t hashes[8];
- int h = 0;
-
- DPRINTF(("%s: %s: enter\n", device_get_nameunit(sc->sc_dev), __func__));
-
- if (sc->sc_dying)
- return;
-
- ifp = GET_IFP(sc);
-
- if (ifp->if_flags & IFF_PROMISC) {
- UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_ALL|UDAV_RCR_PRMSC);
- return;
- } else if (ifp->if_flags & IFF_ALLMULTI) {
-#if defined(__NetBSD__)
- allmulti:
-#endif
- ifp->if_flags |= IFF_ALLMULTI;
- UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_ALL);
- UDAV_CLRBIT(sc, UDAV_RCR, UDAV_RCR_PRMSC);
- return;
- }
-
- /* first, zot all the existing hash bits */
- memset(hashes, 0x00, sizeof(hashes));
- hashes[7] |= 0x80; /* broadcast address */
- udav_csr_write(sc, UDAV_MAR, hashes, sizeof(hashes));
-
- /* now program new ones */
-#if defined(__NetBSD__)
- ETHER_FIRST_MULTI(step, &sc->sc_ec, enm);
- while (enm != NULL) {
- if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
- ETHER_ADDR_LEN) != 0)
- goto allmulti;
-
- h = UDAV_CALCHASH(enm->enm_addrlo);
- hashes[h>>3] |= 1 << (h & 0x7);
- ETHER_NEXT_MULTI(step, enm);
- }
-#elif defined(__FreeBSD__)
- IF_ADDR_LOCK(ifp);
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
- {
- if (ifma->ifma_addr->sa_family != AF_LINK)
- continue;
- h = UDAV_CALCHASH(LLADDR((struct sockaddr_dl *)
- ifma->ifma_addr));
- hashes[h>>3] |= 1 << (h & 0x7);
- }
- IF_ADDR_UNLOCK(ifp);
-#endif
-
- /* disable all multicast */
- ifp->if_flags &= ~IFF_ALLMULTI;
- UDAV_CLRBIT(sc, UDAV_RCR, UDAV_RCR_ALL);
-
- /* write hash value to the register */
- udav_csr_write(sc, UDAV_MAR, hashes, sizeof(hashes));
-}
-
-static int
-udav_openpipes(struct udav_softc *sc)
-{
- struct ue_chain *c;
- usbd_status err;
- int i;
- int error = 0;
-
- if (sc->sc_dying)
- return (EIO);
-
- sc->sc_refcnt++;
-
- /* Open RX pipe */
- err = usbd_open_pipe(sc->sc_ctl_iface, sc->sc_bulkin_no,
- USBD_EXCLUSIVE_USE, &sc->sc_pipe_rx);
- if (err) {
- printf("%s: open rx pipe failed: %s\n",
- device_get_nameunit(sc->sc_dev), usbd_errstr(err));
- error = EIO;
- goto done;
- }
-
- /* Open TX pipe */
- err = usbd_open_pipe(sc->sc_ctl_iface, sc->sc_bulkout_no,
- USBD_EXCLUSIVE_USE, &sc->sc_pipe_tx);
- if (err) {
- printf("%s: open tx pipe failed: %s\n",
- device_get_nameunit(sc->sc_dev), usbd_errstr(err));
- error = EIO;
- goto done;
- }
-
-#if 0
- /* XXX: interrupt endpoint is not yet supported */
- /* Open Interrupt pipe */
- err = usbd_open_pipe_intr(sc->sc_ctl_iface, sc->sc_intrin_no,
- USBD_EXCLUSIVE_USE, &sc->sc_pipe_intr, sc,
- &sc->sc_cdata.ue_ibuf, UDAV_INTR_PKGLEN,
- udav_intr, UDAV_INTR_INTERVAL);
- if (err) {
- printf("%s: open intr pipe failed: %s\n",
- device_get_nameunit(sc->sc_dev), usbd_errstr(err));
- error = EIO;
- goto done;
- }
-#endif
-
-
- /* Start up the receive pipe. */
- for (i = 0; i < UE_RX_LIST_CNT; i++) {
- c = &sc->sc_cdata.ue_rx_chain[i];
- usbd_setup_xfer(c->ue_xfer, sc->sc_pipe_rx,
- c, c->ue_buf, UE_BUFSZ,
- USBD_SHORT_XFER_OK | USBD_NO_COPY,
- USBD_NO_TIMEOUT, udav_rxeof);
- (void)usbd_transfer(c->ue_xfer);
- DPRINTF(("%s: %s: start read\n", device_get_nameunit(sc->sc_dev),
- __func__));
- }
-
- done:
- if (--sc->sc_refcnt < 0)
- usb_detach_wakeup(sc->sc_dev);
-
- return (error);
-}
-
-static void
-udav_start(struct ifnet *ifp)
-{
- struct udav_softc *sc = ifp->if_softc;
- struct mbuf *m_head = NULL;
-
- DPRINTF(("%s: %s: enter, link=%d\n", device_get_nameunit(sc->sc_dev),
- __func__, sc->sc_link));
-
- if (sc->sc_dying)
- return;
-
- if (!sc->sc_link)
- return;
-
-#if defined(__FreeBSD__)
- if (ifp->if_drv_flags & IFF_DRV_OACTIVE)
-#else
- if (ifp->if_flags & IFF_OACTIVE)
-#endif
- return;
-#if defined(__NetBSD__)
- IFQ_POLL(&ifp->if_snd, m_head);
-#elif defined(__FreeBSD__)
- IF_DEQUEUE(&ifp->if_snd, m_head);
-#endif
- if (m_head == NULL)
- return;
-
- if (udav_send(sc, m_head, 0)) {
-#if defined(__FreeBSD__)
- IF_PREPEND(&ifp->if_snd, m_head);
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
-#else
- ifp->if_flags |= IFF_OACTIVE;
-#endif
- return;
- }
-
-#if defined(__NetBSD__)
- IFQ_DEQUEUE(&ifp->if_snd, m_head);
-#endif
-
-#if NBPFILTER > 0
- BPF_MTAP(ifp, m_head);
-#endif
-
-#if defined(__FreeBSD__)
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
-#else
- ifp->if_flags |= IFF_OACTIVE;
-#endif
-
- /* Set a timeout in case the chip goes out to lunch. */
- ifp->if_timer = 5;
-}
-
-static int
-udav_send(struct udav_softc *sc, struct mbuf *m, int idx)
-{
- int total_len;
- struct ue_chain *c;
- usbd_status err;
-
- DPRINTF(("%s: %s: enter\n", device_get_nameunit(sc->sc_dev),__func__));
-
- c = &sc->sc_cdata.ue_tx_chain[idx];
-
- /* Copy the mbuf data into a contiguous buffer */
- /* first 2 bytes are packet length */
- m_copydata(m, 0, m->m_pkthdr.len, c->ue_buf + 2);
- c->ue_mbuf = m;
- total_len = m->m_pkthdr.len;
- if (total_len < UDAV_MIN_FRAME_LEN) {
- memset(c->ue_buf + 2 + total_len, 0,
- UDAV_MIN_FRAME_LEN - total_len);
- total_len = UDAV_MIN_FRAME_LEN;
- }
-
- /* Frame length is specified in the first 2bytes of the buffer */
- c->ue_buf[0] = (u_int8_t)total_len;
- c->ue_buf[1] = (u_int8_t)(total_len >> 8);
- total_len += 2;
-
- usbd_setup_xfer(c->ue_xfer, sc->sc_pipe_tx, c, c->ue_buf, total_len,
- USBD_FORCE_SHORT_XFER | USBD_NO_COPY,
- UDAV_TX_TIMEOUT, udav_txeof);
-
- /* Transmit */
- sc->sc_refcnt++;
- err = usbd_transfer(c->ue_xfer);
- if (--sc->sc_refcnt < 0)
- usb_detach_wakeup(sc->sc_dev);
- if (err != USBD_IN_PROGRESS) {
- printf("%s: udav_send error=%s\n", device_get_nameunit(sc->sc_dev),
- usbd_errstr(err));
- /* Stop the interface */
- usb_add_task(sc->sc_udev, &sc->sc_stop_task, USB_TASKQ_DRIVER);
- return (EIO);
- }
-
- DPRINTF(("%s: %s: send %d bytes\n", device_get_nameunit(sc->sc_dev),
- __func__, total_len));
-
- sc->sc_cdata.ue_tx_cnt++;
-
- return (0);
-}
-
-static void
-udav_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- struct ue_chain *c = priv;
- struct udav_softc *sc = c->ue_sc;
- struct ifnet *ifp = GET_IFP(sc);
-#if defined(__NetBSD__)
- int s;
-#endif
-
- if (sc->sc_dying)
- return;
-
-#if defined(__NetBSD__)
- s = splnet();
-#elif defined(__FreeBSD__)
- UDAV_LOCK(sc);
-#endif
-
- DPRINTF(("%s: %s: enter\n", device_get_nameunit(sc->sc_dev), __func__));
-
- ifp->if_timer = 0;
-#if defined(__FreeBSD__)
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
-#else
- ifp->if_flags &= ~IFF_OACTIVE;
-#endif
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
-#if defined(__NetBSD__)
- splx(s);
-#elif defined(__FreeBSD__)
- UDAV_UNLOCK(sc);
-#endif
- return;
- }
- ifp->if_oerrors++;
- printf("%s: usb error on tx: %s\n", device_get_nameunit(sc->sc_dev),
- usbd_errstr(status));
- if (status == USBD_STALLED) {
- sc->sc_refcnt++;
- usbd_clear_endpoint_stall(sc->sc_pipe_tx);
- if (--sc->sc_refcnt < 0)
- usb_detach_wakeup(sc->sc_dev);
- }
-#if defined(__NetBSD__)
- splx(s);
-#elif defined(__FreeBSD__)
- UDAV_UNLOCK(sc);
-#endif
- return;
- }
-
- ifp->if_opackets++;
-
- m_freem(c->ue_mbuf);
- c->ue_mbuf = NULL;
-
-#if defined(__NetBSD__)
- if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
-#elif defined(__FreeBSD__)
- if ( ifp->if_snd.ifq_head != NULL )
-#endif
- udav_start(ifp);
-
-#if defined(__NetBSD__)
- splx(s);
-#elif defined(__FreeBSD__)
- UDAV_UNLOCK(sc);
-#endif
-}
-
-static void
-udav_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- struct ue_chain *c = priv;
- struct udav_softc *sc = c->ue_sc;
- struct ifnet *ifp = GET_IFP(sc);
- struct mbuf *m;
- u_int32_t total_len;
- u_int8_t *pktstat;
-#if defined(__NetBSD__)
- int s;
-#endif
-
- DPRINTF(("%s: %s: enter\n", device_get_nameunit(sc->sc_dev),__func__));
-
- if (sc->sc_dying)
- return;
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
- return;
- sc->sc_rx_errs++;
- if (usbd_ratecheck(&sc->sc_rx_notice)) {
- printf("%s: %u usb errors on rx: %s\n",
- device_get_nameunit(sc->sc_dev), sc->sc_rx_errs,
- usbd_errstr(status));
- sc->sc_rx_errs = 0;
- }
- if (status == USBD_STALLED) {
- sc->sc_refcnt++;
- usbd_clear_endpoint_stall(sc->sc_pipe_rx);
- if (--sc->sc_refcnt < 0)
- usb_detach_wakeup(sc->sc_dev);
- }
- goto done;
- }
-
- usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
-
- /* copy data to mbuf */
- m = c->ue_mbuf;
- memcpy(mtod(m, char *), c->ue_buf, total_len);
-
- /* first byte in received data */
- pktstat = mtod(m, u_int8_t *);
- m_adj(m, sizeof(u_int8_t));
- DPRINTF(("%s: RX Status: 0x%02x\n", device_get_nameunit(sc->sc_dev), *pktstat));
-
- total_len = UGETW(mtod(m, u_int8_t *));
- m_adj(m, sizeof(u_int16_t));
-
- if (*pktstat & UDAV_RSR_LCS) {
- ifp->if_collisions++;
- goto done;
- }
-
- if (total_len < sizeof(struct ether_header) ||
- *pktstat & UDAV_RSR_ERR) {
- ifp->if_ierrors++;
- goto done;
- }
-
- ifp->if_ipackets++;
- total_len -= ETHER_CRC_LEN;
-
- m->m_pkthdr.len = m->m_len = total_len;
-#if defined(__NetBSD__)
- m->m_pkthdr.rcvif = ifp;
-#elif defined(__FreeBSD__)
- m->m_pkthdr.rcvif = (struct ifnet *)&sc->sc_qdat;
-#endif
-
-#if defined(__NetBSD__)
- s = splnet();
-#elif defined(__FreeBSD__)
- UDAV_LOCK(sc);
-#endif
-
-#if defined(__NetBSD__)
- c->ue_mbuf = usb_ether_newbuf();
- if (c->ue_mbuf == NULL) {
- printf("%s: no memory for rx list "
- "-- packet dropped!\n", device_get_nameunit(sc->sc_dev));
- ifp->if_ierrors++;
- goto done1;
- }
-#endif
-
-#if NBPFILTER > 0
- BPF_MTAP(ifp, m);
-#endif
-
- DPRINTF(("%s: %s: deliver %d\n", device_get_nameunit(sc->sc_dev),
- __func__, m->m_len));
-#if defined(__NetBSD__)
- IF_INPUT(ifp, m);
-#endif
-#if defined(__FreeBSD__)
- usb_ether_input(m);
- UDAV_UNLOCK(sc);
- return ;
-#endif
-
-#if defined(__NetBSD__)
- done1:
- splx(s);
-#elif defined(__FreeBSD__)
- UDAV_UNLOCK(sc);
-#endif
- done:
- /* Setup new transfer */
- usbd_setup_xfer(xfer, sc->sc_pipe_rx, c, c->ue_buf, UE_BUFSZ,
- USBD_SHORT_XFER_OK | USBD_NO_COPY,
- USBD_NO_TIMEOUT, udav_rxeof);
- sc->sc_refcnt++;
- usbd_transfer(xfer);
- if (--sc->sc_refcnt < 0)
- usb_detach_wakeup(sc->sc_dev);
-
- DPRINTF(("%s: %s: start rx\n", device_get_nameunit(sc->sc_dev), __func__));
-}
-
-#if 0
-static void udav_intr()
-{
-}
-#endif
-
-static int
-udav_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
-{
- struct udav_softc *sc = ifp->if_softc;
- struct ifreq *ifr = (struct ifreq *)data;
- struct mii_data *mii;
-#if defined(__NetBSD__)
- int s;
-#endif
- int error = 0;
-
- DPRINTF(("%s: %s: enter\n", device_get_nameunit(sc->sc_dev), __func__));
-
- if (sc->sc_dying)
- return (EIO);
-
-#if defined(__NetBSD__)
- s = splnet();
-#elif defined(__FreeBSD__)
- UDAV_LOCK(sc);
-#endif
-
- switch (cmd) {
-#if defined(__FreeBSD__)
- case SIOCSIFFLAGS:
- if (ifp->if_flags & IFF_UP) {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
- ifp->if_flags & IFF_PROMISC) {
- UDAV_SETBIT(sc, UDAV_RCR,
- UDAV_RCR_ALL|UDAV_RCR_PRMSC);
- } else if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
- !(ifp->if_flags & IFF_PROMISC)) {
- if (ifp->if_flags & IFF_ALLMULTI)
- UDAV_CLRBIT(sc, UDAV_RCR,
- UDAV_RCR_PRMSC);
- else
- UDAV_CLRBIT(sc, UDAV_RCR,
- UDAV_RCR_ALL|UDAV_RCR_PRMSC);
- } else if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
- udav_init(sc);
- } else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- udav_stop(ifp, 1);
- }
- error = 0;
- break;
- case SIOCADDMULTI:
- case SIOCDELMULTI:
- udav_setmulti(sc);
- error = 0;
- break;
-#endif
- case SIOCGIFMEDIA:
- case SIOCSIFMEDIA:
- mii = GET_MII(sc);
- error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, cmd);
- break;
-
- default:
- error = ether_ioctl(ifp, cmd, data);
-#if defined(__NetBSD__)
- if (error == ENETRESET) {
- udav_setmulti(sc);
- error = 0;
- }
-#endif
- break;
- }
-
-#if defined(__NetBSD__)
- splx(s);
-#elif defined(__FreeBSD__)
- UDAV_UNLOCK(sc);
-#endif
-
- return (error);
-}
-
-static void
-udav_watchdog(struct ifnet *ifp)
-{
- struct udav_softc *sc = ifp->if_softc;
- struct ue_chain *c;
- usbd_status stat;
-#if defined(__NetBSD__)
- int s;
-#endif
-
- DPRINTF(("%s: %s: enter\n", device_get_nameunit(sc->sc_dev), __func__));
-
- ifp->if_oerrors++;
- printf("%s: watchdog timeout\n", device_get_nameunit(sc->sc_dev));
-
-#if defined(__NetBSD__)
- s = splusb();
-#elif defined(__FreeBSD__)
- UDAV_LOCK(sc)
-#endif
- c = &sc->sc_cdata.ue_tx_chain[0];
- usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &stat);
- udav_txeof(c->ue_xfer, c, stat);
-
-#if defined(__NetBSD__)
- if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
-#elif defined(__FreeBSD__)
- if ( ifp->if_snd.ifq_head != NULL )
-#endif
- udav_start(ifp);
-#if defined(__NetBSD__)
- splx(s);
-#elif defined(__FreeBSD__)
- UDAV_UNLOCK(sc);
-#endif
-}
-
-static void
-udav_stop_task(struct udav_softc *sc)
-{
- udav_stop(GET_IFP(sc), 1);
-}
-
-/* Stop the adapter and free any mbufs allocated to the RX and TX lists. */
-static void
-udav_stop(struct ifnet *ifp, int disable)
-{
- struct udav_softc *sc = ifp->if_softc;
- usbd_status err;
-
- DPRINTF(("%s: %s: enter\n", device_get_nameunit(sc->sc_dev), __func__));
-
- ifp->if_timer = 0;
-
- udav_reset(sc);
-
- usb_uncallout(sc->sc_stat_ch, udav_tick, sc);
-
- /* Stop transfers */
- /* RX endpoint */
- if (sc->sc_pipe_rx != NULL) {
- err = usbd_abort_pipe(sc->sc_pipe_rx);
- if (err)
- printf("%s: abort rx pipe failed: %s\n",
- device_get_nameunit(sc->sc_dev), usbd_errstr(err));
- err = usbd_close_pipe(sc->sc_pipe_rx);
- if (err)
- printf("%s: close rx pipe failed: %s\n",
- device_get_nameunit(sc->sc_dev), usbd_errstr(err));
- sc->sc_pipe_rx = NULL;
- }
-
- /* TX endpoint */
- if (sc->sc_pipe_tx != NULL) {
- err = usbd_abort_pipe(sc->sc_pipe_tx);
- if (err)
- printf("%s: abort tx pipe failed: %s\n",
- device_get_nameunit(sc->sc_dev), usbd_errstr(err));
- err = usbd_close_pipe(sc->sc_pipe_tx);
- if (err)
- printf("%s: close tx pipe failed: %s\n",
- device_get_nameunit(sc->sc_dev), usbd_errstr(err));
- sc->sc_pipe_tx = NULL;
- }
-
-#if 0
- /* XXX: Interrupt endpoint is not yet supported!! */
- /* Interrupt endpoint */
- if (sc->sc_pipe_intr != NULL) {
- err = usbd_abort_pipe(sc->sc_pipe_intr);
- if (err)
- printf("%s: abort intr pipe failed: %s\n",
- device_get_nameunit(sc->sc_dev), usbd_errstr(err));
- err = usbd_close_pipe(sc->sc_pipe_intr);
- if (err)
- printf("%s: close intr pipe failed: %s\n",
- device_get_nameunit(sc->sc_dev), usbd_errstr(err));
- sc->sc_pipe_intr = NULL;
- }
-#endif
-
- /* Free RX resources. */
- usb_ether_rx_list_free(&sc->sc_cdata);
- /* Free TX resources. */
- usb_ether_tx_list_free(&sc->sc_cdata);
-
- sc->sc_link = 0;
-#if defined(__FreeBSD__)
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
-#else
- ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
-#endif
-}
-
-/* Set media options */
-static int
-udav_ifmedia_change(struct ifnet *ifp)
-{
- struct udav_softc *sc = ifp->if_softc;
- struct mii_data *mii = GET_MII(sc);
-
- DPRINTF(("%s: %s: enter\n", device_get_nameunit(sc->sc_dev), __func__));
-
- if (sc->sc_dying)
- return (0);
-
- sc->sc_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);
- }
-
- return (mii_mediachg(mii));
-}
-
-/* Report current media status. */
-static void
-udav_ifmedia_status(struct ifnet *ifp, struct ifmediareq *ifmr)
-{
- struct udav_softc *sc = ifp->if_softc;
- struct mii_data *mii = GET_MII(sc);
-
- DPRINTF(("%s: %s: enter\n", device_get_nameunit(sc->sc_dev), __func__));
-
- if (sc->sc_dying)
- return;
-
-#if defined(__FreeBSD__)
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
-#else
- if ((ifp->if_flags & IFF_RUNNING) == 0) {
-#endif
- ifmr->ifm_active = IFM_ETHER | IFM_NONE;
- ifmr->ifm_status = 0;
- return;
- }
-
- mii_pollstat(mii);
- ifmr->ifm_active = mii->mii_media_active;
- ifmr->ifm_status = mii->mii_media_status;
-}
-
-static void
-udav_tick(void *xsc)
-{
- struct udav_softc *sc = xsc;
-
- if (sc == NULL)
- return;
-
- DPRINTFN(0xff, ("%s: %s: enter\n", device_get_nameunit(sc->sc_dev),
- __func__));
-
- if (sc->sc_dying)
- return;
-
- /* Perform periodic stuff in process context */
- usb_add_task(sc->sc_udev, &sc->sc_tick_task, USB_TASKQ_DRIVER);
-}
-
-static void
-udav_tick_task(void *xsc)
-{
- struct udav_softc *sc = xsc;
- struct ifnet *ifp;
- struct mii_data *mii;
-#if defined(__NetBSD__)
- int s;
-#endif
-
- if (sc == NULL)
- return;
-
- DPRINTFN(0xff, ("%s: %s: enter\n", device_get_nameunit(sc->sc_dev),
- __func__));
-
- if (sc->sc_dying)
- return;
-
- ifp = GET_IFP(sc);
- mii = GET_MII(sc);
-
- if (mii == NULL)
- return;
-
-#if defined(__NetBSD__)
- s = splnet();
-#elif defined(__FreeBSD__)
- UDAV_LOCK(sc);
-#endif
-
- mii_tick(mii);
- if (!sc->sc_link) {
- mii_pollstat(mii);
- if (mii->mii_media_status & IFM_ACTIVE &&
- IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
- DPRINTF(("%s: %s: got link\n",
- device_get_nameunit(sc->sc_dev), __func__));
- sc->sc_link++;
-#if defined(__NetBSD__)
- if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
-#elif defined(__FreeBSD__)
- if ( ifp->if_snd.ifq_head != NULL )
-#endif
- udav_start(ifp);
- }
- }
-
- usb_callout(sc->sc_stat_ch, hz, udav_tick, sc);
-
-#if defined(__NetBSD__)
- splx(s);
-#elif defined(__FreeBSD__)
- UDAV_UNLOCK(sc);
-#endif
-}
-
-/* Get exclusive access to the MII registers */
-static void
-udav_lock_mii(struct udav_softc *sc)
-{
- DPRINTFN(0xff, ("%s: %s: enter\n", device_get_nameunit(sc->sc_dev),
- __func__));
-
- sc->sc_refcnt++;
- lockmgr(&sc->sc_mii_lock, LK_EXCLUSIVE, NULL);
-}
-
-static void
-udav_unlock_mii(struct udav_softc *sc)
-{
- DPRINTFN(0xff, ("%s: %s: enter\n", device_get_nameunit(sc->sc_dev),
- __func__));
-
- lockmgr(&sc->sc_mii_lock, LK_RELEASE, NULL);
- if (--sc->sc_refcnt < 0)
- usb_detach_wakeup(sc->sc_dev);
-}
-
-static int
-udav_miibus_readreg(device_t dev, int phy, int reg)
-{
- struct udav_softc *sc;
- u_int8_t val[2];
- u_int16_t data16;
-
- if (dev == NULL)
- return (0);
-
- sc = USBGETSOFTC(dev);
-
- DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x\n",
- device_get_nameunit(sc->sc_dev), __func__, phy, reg));
-
- if (sc->sc_dying) {
-#ifdef DIAGNOSTIC
- printf("%s: %s: dying\n", device_get_nameunit(sc->sc_dev),
- __func__);
-#endif
- return (0);
- }
-
- /* XXX: one PHY only for the internal PHY */
- if (phy != 0) {
- DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n",
- device_get_nameunit(sc->sc_dev), __func__, phy));
- return (0);
- }
-
- udav_lock_mii(sc);
-
- /* select internal PHY and set PHY register address */
- udav_csr_write1(sc, UDAV_EPAR,
- UDAV_EPAR_PHY_ADR0 | (reg & UDAV_EPAR_EROA_MASK));
-
- /* select PHY operation and start read command */
- udav_csr_write1(sc, UDAV_EPCR, UDAV_EPCR_EPOS | UDAV_EPCR_ERPRR);
-
- /* XXX: should be wait? */
-
- /* end read command */
- UDAV_CLRBIT(sc, UDAV_EPCR, UDAV_EPCR_ERPRR);
-
- /* retrieve the result from data registers */
- udav_csr_read(sc, UDAV_EPDRL, val, 2);
-
- udav_unlock_mii(sc);
-
- data16 = val[0] | (val[1] << 8);
-
- DPRINTFN(0xff, ("%s: %s: phy=%d reg=0x%04x => 0x%04x\n",
- device_get_nameunit(sc->sc_dev), __func__, phy, reg, data16));
-
- return (data16);
-}
-
-static int
-udav_miibus_writereg(device_t dev, int phy, int reg, int data)
-{
- struct udav_softc *sc;
- u_int8_t val[2];
-
- if (dev == NULL)
- return (0); /* XXX real error? */
-
- sc = USBGETSOFTC(dev);
-
- DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x data=0x%04x\n",
- device_get_nameunit(sc->sc_dev), __func__, phy, reg, data));
-
- if (sc->sc_dying) {
-#ifdef DIAGNOSTIC
- printf("%s: %s: dying\n", device_get_nameunit(sc->sc_dev),
- __func__);
-#endif
- return (0); /* XXX real error? */
- }
-
- /* XXX: one PHY only for the internal PHY */
- if (phy != 0) {
- DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n",
- device_get_nameunit(sc->sc_dev), __func__, phy));
- return (0); /* XXX real error? */
- }
-
- udav_lock_mii(sc);
-
- /* select internal PHY and set PHY register address */
- udav_csr_write1(sc, UDAV_EPAR,
- UDAV_EPAR_PHY_ADR0 | (reg & UDAV_EPAR_EROA_MASK));
-
- /* put the value to the data registers */
- val[0] = data & 0xff;
- val[1] = (data >> 8) & 0xff;
- udav_csr_write(sc, UDAV_EPDRL, val, 2);
-
- /* select PHY operation and start write command */
- udav_csr_write1(sc, UDAV_EPCR, UDAV_EPCR_EPOS | UDAV_EPCR_ERPRW);
-
- /* XXX: should be wait? */
-
- /* end write command */
- UDAV_CLRBIT(sc, UDAV_EPCR, UDAV_EPCR_ERPRW);
-
- udav_unlock_mii(sc);
-
- return (0);
-}
-
-static void
-udav_miibus_statchg(device_t dev)
-{
-#ifdef UDAV_DEBUG
- struct udav_softc *sc;
-
- if (dev == NULL)
- return;
-
- sc = USBGETSOFTC(dev);
- DPRINTF(("%s: %s: enter\n", device_get_nameunit(sc->sc_dev), __func__));
-#endif
- /* Nothing to do */
-}
-
-#if defined(__FreeBSD__)
-/*
- * Stop all chip I/O so that the kernel's probe routines don't
- * get confused by errant DMAs when rebooting.
- */
-static int
-udav_shutdown(device_t dev)
-{
- struct udav_softc *sc;
-
- sc = device_get_softc(dev);
-
- udav_stop_task(sc);
-
- return (0);
-}
-
-static void
-udav_rxstart(struct ifnet *ifp)
-{
- struct udav_softc *sc;
- struct ue_chain *c;
-
- sc = ifp->if_softc;
- UDAV_LOCK(sc);
- c = &sc->sc_cdata.ue_rx_chain[sc->sc_cdata.ue_rx_prod];
-
- c->ue_mbuf = usb_ether_newbuf();
- if (c->ue_mbuf == NULL) {
- printf("%s: no memory for rx list "
- "-- packet dropped!\n", device_get_nameunit(sc->sc_dev));
- ifp->if_ierrors++;
- UDAV_UNLOCK(sc);
- return;
- }
-
- /* Setup new transfer. */
- usbd_setup_xfer(c->ue_xfer, sc->sc_pipe_rx,
- c, c->ue_buf, UE_BUFSZ,
- USBD_SHORT_XFER_OK | USBD_NO_COPY,
- USBD_NO_TIMEOUT, udav_rxeof);
- usbd_transfer(c->ue_xfer);
-
- UDAV_UNLOCK(sc);
- return;
-}
-#endif
diff --git a/sys/dev/usb/if_udavreg.h b/sys/dev/usb/if_udavreg.h
deleted file mode 100644
index cb7da28..0000000
--- a/sys/dev/usb/if_udavreg.h
+++ /dev/null
@@ -1,210 +0,0 @@
-/* $NetBSD: if_udavreg.h,v 1.2 2003/09/04 15:17:39 tsutsui Exp $ */
-/* $nabe: if_udavreg.h,v 1.2 2003/08/21 16:26:40 nabe Exp $ */
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2003
- * Shingo WATANABE <nabe@nabechan.org>. 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. 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 THE AUTHOR 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 AUTHOR 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.
- *
- */
-
-#define UDAV_IFACE_INDEX 0
-#define UDAV_CONFIG_NO 1
-
-#define UDAV_TX_TIMEOUT 1000
-#define UDAV_TIMEOUT 10000
-
-#define ETHER_ALIGN 2
-
-
-/* Packet length */
-#define UDAV_MIN_FRAME_LEN 60
-
-/* Request */
-#define UDAV_REQ_REG_READ 0x00 /* Read from register(s) */
-#define UDAV_REQ_REG_WRITE 0x01 /* Write to register(s) */
-#define UDAV_REQ_REG_WRITE1 0x03 /* Write to a register */
-
-#define UDAV_REQ_MEM_READ 0x02 /* Read from memory */
-#define UDAV_REQ_MEM_WRITE 0x05 /* Write to memory */
-#define UDAV_REQ_MEM_WRITE1 0x07 /* Write a byte to memory */
-
-/* Registers */
-#define UDAV_NCR 0x00 /* Network Control Register */
-#define UDAV_NCR_EXT_PHY (1<<7) /* Select External PHY */
-#define UDAV_NCR_WAKEEN (1<<6) /* Wakeup Event Enable */
-#define UDAV_NCR_FCOL (1<<4) /* Force Collision Mode */
-#define UDAV_NCR_FDX (1<<3) /* Full-Duplex Mode (RO on Int. PHY) */
-#define UDAV_NCR_LBK1 (1<<2) /* Lookback Mode */
-#define UDAV_NCR_LBK0 (1<<1) /* Lookback Mode */
-#define UDAV_NCR_RST (1<<0) /* Software reset */
-
-#define UDAV_RCR 0x05 /* RX Control Register */
-#define UDAV_RCR_WTDIS (1<<6) /* Watchdog Timer Disable */
-#define UDAV_RCR_DIS_LONG (1<<5) /* Discard Long Packet(over 1522Byte) */
-#define UDAV_RCR_DIS_CRC (1<<4) /* Discard CRC Error Packet */
-#define UDAV_RCR_ALL (1<<3) /* Pass All Multicast */
-#define UDAV_RCR_RUNT (1<<2) /* Pass Runt Packet */
-#define UDAV_RCR_PRMSC (1<<1) /* Promiscuous Mode */
-#define UDAV_RCR_RXEN (1<<0) /* RX Enable */
-
-#define UDAV_RSR 0x06 /* RX Status Register */
-#define UDAV_RSR_RF (1<<7) /* Runt Frame */
-#define UDAV_RSR_MF (1<<6) /* Multicast Frame */
-#define UDAV_RSR_LCS (1<<5) /* Late Collision Seen */
-#define UDAV_RSR_RWTO (1<<4) /* Receive Watchdog Time-Out */
-#define UDAV_RSR_PLE (1<<3) /* Physical Layer Error */
-#define UDAV_RSR_AE (1<<2) /* Alignment Error */
-#define UDAV_RSR_CE (1<<1) /* CRC Error */
-#define UDAV_RSR_FOE (1<<0) /* FIFO Overflow Error */
-#define UDAV_RSR_ERR (UDAV_RSR_RF | UDAV_RSR_LCS | UDAV_RSR_RWTO |\
- UDAV_RSR_PLE | UDAV_RSR_AE | UDAV_RSR_CE |\
- UDAV_RSR_FOE)
-
-#define UDAV_EPCR 0x0b /* EEPROM & PHY Control Register */
-#define UDAV_EPCR_REEP (1<<5) /* Reload EEPROM */
-#define UDAV_EPCR_WEP (1<<4) /* Write EEPROM enable */
-#define UDAV_EPCR_EPOS (1<<3) /* EEPROM or PHY Operation Select */
-#define UDAV_EPCR_ERPRR (1<<2) /* EEPROM/PHY Register Read Command */
-#define UDAV_EPCR_ERPRW (1<<1) /* EEPROM/PHY Register Write Command */
-#define UDAV_EPCR_ERRE (1<<0) /* EEPROM/PHY Access Status */
-
-#define UDAV_EPAR 0x0c /* EEPROM & PHY Control Register */
-#define UDAV_EPAR_PHY_ADR1 (1<<7) /* PHY Address bit 1 */
-#define UDAV_EPAR_PHY_ADR0 (1<<6) /* PHY Address bit 0 */
-#define UDAV_EPAR_EROA (1<<0) /* EEPROM Word/PHY Register Address */
-#define UDAV_EPAR_EROA_MASK (0x1f) /* [5:0] */
-
-#define UDAV_EPDRL 0x0d /* EEPROM & PHY Data Register */
-#define UDAV_EPDRH 0x0e /* EEPROM & PHY Data Register */
-
-#define UDAV_PAR0 0x10 /* Ethernet Address, load from EEPROM */
-#define UDAV_PAR1 0x11 /* Ethernet Address, load from EEPROM */
-#define UDAV_PAR2 0x12 /* Ethernet Address, load from EEPROM */
-#define UDAV_PAR3 0x13 /* Ethernet Address, load from EEPROM */
-#define UDAV_PAR4 0x14 /* Ethernet Address, load from EEPROM */
-#define UDAV_PAR5 0x15 /* Ethernet Address, load from EEPROM */
-#define UDAV_PAR UDAV_PAR0
-
-#define UDAV_MAR0 0x16 /* Multicast Register */
-#define UDAV_MAR1 0x17 /* Multicast Register */
-#define UDAV_MAR2 0x18 /* Multicast Register */
-#define UDAV_MAR3 0x19 /* Multicast Register */
-#define UDAV_MAR4 0x1a /* Multicast Register */
-#define UDAV_MAR5 0x1b /* Multicast Register */
-#define UDAV_MAR6 0x1c /* Multicast Register */
-#define UDAV_MAR7 0x1d /* Multicast Register */
-#define UDAV_MAR UDAV_MAR0
-
-#define UDAV_GPCR 0x1e /* General purpose control register */
-#define UDAV_GPCR_GEP_CNTL6 (1<<6) /* General purpose control 6 */
-#define UDAV_GPCR_GEP_CNTL5 (1<<5) /* General purpose control 5 */
-#define UDAV_GPCR_GEP_CNTL4 (1<<4) /* General purpose control 4 */
-#define UDAV_GPCR_GEP_CNTL3 (1<<3) /* General purpose control 3 */
-#define UDAV_GPCR_GEP_CNTL2 (1<<2) /* General purpose control 2 */
-#define UDAV_GPCR_GEP_CNTL1 (1<<1) /* General purpose control 1 */
-#define UDAV_GPCR_GEP_CNTL0 (1<<0) /* General purpose control 0 */
-
-#define UDAV_GPR 0x1f /* General purpose register */
-#define UDAV_GPR_GEPIO6 (1<<6) /* General purpose 6 */
-#define UDAV_GPR_GEPIO5 (1<<5) /* General purpose 5 */
-#define UDAV_GPR_GEPIO4 (1<<4) /* General purpose 4 */
-#define UDAV_GPR_GEPIO3 (1<<3) /* General purpose 3 */
-#define UDAV_GPR_GEPIO2 (1<<2) /* General purpose 2 */
-#define UDAV_GPR_GEPIO1 (1<<1) /* General purpose 1 */
-#define UDAV_GPR_GEPIO0 (1<<0) /* General purpose 0 */
-
-#if defined(__FreeBSD__)
-#define GET_IFP(sc) ((sc)->sc_ifp)
-#elif defined(__OpenBSD__)
-#define GET_IFP(sc) (&(sc)->sc_ac.ac_if)
-#elif defined(__NetBSD__)
-#define GET_IFP(sc) (&(sc)->sc_ec.ec_if)
-#endif
-#if defined(__FreeBSD__)
-#define GET_MII(sc) (device_get_softc((sc)->sc_miibus))
-#else
-#define GET_MII(sc) (&(sc)->sc_mii)
-#endif
-
-#if defined(__FreeBSD__)
-#if 0
-#define UDAV_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
-#define UDAV_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
-#else
-#define UDAV_LOCK(_sc)
-#define UDAV_UNLOCK(_sc)
-#endif
-#endif
-
-struct udav_softc {
-#if defined(__FreeBSD__)
- struct ifnet *sc_ifp;
-#endif
- device_t sc_dev; /* base device */
- usbd_device_handle sc_udev;
-
- /* USB */
- usbd_interface_handle sc_ctl_iface;
- /* int sc_ctl_iface_no; */
- int sc_bulkin_no; /* bulk in endpoint */
- int sc_bulkout_no; /* bulk out endpoint */
- int sc_intrin_no; /* intr in endpoint */
- usbd_pipe_handle sc_pipe_rx;
- usbd_pipe_handle sc_pipe_tx;
- usbd_pipe_handle sc_pipe_intr;
- usb_callout_t sc_stat_ch;
- u_int sc_rx_errs;
- /* u_int sc_intr_errs; */
- struct timeval sc_rx_notice;
-
- /* Ethernet */
-
-#if defined(__FreeBSD__)
- device_t sc_miibus ;
- struct mtx sc_mtx ;
- struct usb_qdat sc_qdat;
-#elif defined(__NetBSD__)
- struct ethercom sc_ec; /* ethernet common */
- struct mii_data sc_mii;
-#endif
- struct lock sc_mii_lock;
- int sc_link;
-#define sc_media udav_mii.mii_media
-#if defined(NRND) && NRND > 0
- rndsource_element_t rnd_source;
-#endif
- struct ue_cdata sc_cdata;
-
- int sc_attached;
- int sc_dying;
- int sc_refcnt;
-
- struct usb_task sc_tick_task;
- struct usb_task sc_stop_task;
-
- u_int16_t sc_flags;
-};
diff --git a/sys/dev/usb/if_upgt.c b/sys/dev/usb/if_upgt.c
deleted file mode 100644
index 9ab226f..0000000
--- a/sys/dev/usb/if_upgt.c
+++ /dev/null
@@ -1,2375 +0,0 @@
-/* $OpenBSD: if_upgt.c,v 1.35 2008/04/16 18:32:15 damien Exp $ */
-/* $FreeBSD$ */
-
-/*
- * Copyright (c) 2007 Marcus Glocker <mglocker@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/endian.h>
-#include <sys/firmware.h>
-#include <sys/linker.h>
-#include <sys/mbuf.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/socket.h>
-#include <sys/sockio.h>
-#include <sys/sysctl.h>
-
-#include <net/if.h>
-#include <net/if_arp.h>
-#include <net/ethernet.h>
-#include <net/if_dl.h>
-#include <net/if_media.h>
-#include <net/if_types.h>
-
-#include <sys/bus.h>
-#include <machine/bus.h>
-
-#include <net80211/ieee80211_var.h>
-#include <net80211/ieee80211_phy.h>
-#include <net80211/ieee80211_radiotap.h>
-#include <net80211/ieee80211_regdomain.h>
-
-#include <net/bpf.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include <dev/usb/usbdivar.h>
-#include "usbdevs.h"
-#include <dev/usb/usb_ethersubr.h>
-
-#include <dev/usb/if_upgtvar.h>
-
-/*
- * Driver for the USB PrismGT devices.
- *
- * For now just USB 2.0 devices with the GW3887 chipset are supported.
- * The driver has been written based on the firmware version 2.13.1.0_LM87.
- *
- * TODO's:
- * - MONITOR mode test.
- * - Add HOSTAP mode.
- * - Add IBSS mode.
- * - Support the USB 1.0 devices (NET2280, ISL3880, ISL3886 chipsets).
- *
- * Parts of this driver has been influenced by reading the p54u driver
- * written by Jean-Baptiste Note <jean-baptiste.note@m4x.org> and
- * Sebastien Bourdeauducq <lekernel@prism54.org>.
- */
-
-SYSCTL_NODE(_hw, OID_AUTO, upgt, CTLFLAG_RD, 0,
- "USB PrismGT GW3887 driver parameters");
-
-/*
- * NB: normally `upgt_txbuf' value can be increased to maximum 6, mininum 1.
- * However, we're using just 2 txbufs to protect packet losses in some cases
- * so the performance was sacrificed that with this value its speed is about
- * 2.1Mb/s.
- *
- * With setting txbuf value as 6, you can get full speed, 3.0Mb/s, of this
- * device but sometimes you'd meet some packet losses then retransmision.
- */
-static int upgt_txbuf = UPGT_TX_COUNT; /* # tx buffers to allocate */
-SYSCTL_INT(_hw_upgt, OID_AUTO, txbuf, CTLFLAG_RW, &upgt_txbuf,
- 0, "tx buffers allocated");
-TUNABLE_INT("hw.upgt.txbuf", &upgt_txbuf);
-
-#ifdef UPGT_DEBUG
-int upgt_debug = 0;
-SYSCTL_INT(_hw_upgt, OID_AUTO, debug, CTLFLAG_RW, &upgt_debug,
- 0, "control debugging printfs");
-TUNABLE_INT("hw.upgt.debug", &upgt_debug);
-enum {
- UPGT_DEBUG_XMIT = 0x00000001, /* basic xmit operation */
- UPGT_DEBUG_RECV = 0x00000002, /* basic recv operation */
- UPGT_DEBUG_RESET = 0x00000004, /* reset processing */
- UPGT_DEBUG_INTR = 0x00000008, /* INTR */
- UPGT_DEBUG_TX_PROC = 0x00000010, /* tx ISR proc */
- UPGT_DEBUG_RX_PROC = 0x00000020, /* rx ISR proc */
- UPGT_DEBUG_STATE = 0x00000040, /* 802.11 state transitions */
- UPGT_DEBUG_STAT = 0x00000080, /* statistic */
- UPGT_DEBUG_FW = 0x00000100, /* firmware */
- UPGT_DEBUG_ANY = 0xffffffff
-};
-#define DPRINTF(sc, m, fmt, ...) do { \
- if (sc->sc_debug & (m)) \
- printf(fmt, __VA_ARGS__); \
-} while (0)
-#else
-#define DPRINTF(sc, m, fmt, ...) do { \
- (void) sc; \
-} while (0)
-#endif
-
-/*
- * Prototypes.
- */
-static device_probe_t upgt_match;
-static device_attach_t upgt_attach;
-static device_detach_t upgt_detach;
-static int upgt_alloc_tx(struct upgt_softc *);
-static int upgt_alloc_rx(struct upgt_softc *);
-static int upgt_alloc_cmd(struct upgt_softc *);
-static int upgt_attach_hook(device_t);
-static int upgt_device_reset(struct upgt_softc *);
-static int upgt_bulk_xmit(struct upgt_softc *, struct upgt_data *,
- usbd_pipe_handle, uint32_t *, int);
-static int upgt_fw_verify(struct upgt_softc *);
-static int upgt_mem_init(struct upgt_softc *);
-static int upgt_fw_load(struct upgt_softc *);
-static int upgt_fw_copy(const uint8_t *, char *, int);
-static uint32_t upgt_crc32_le(const void *, size_t);
-static void upgt_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
-static void upgt_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
-static int upgt_eeprom_read(struct upgt_softc *);
-static int upgt_eeprom_parse(struct upgt_softc *);
-static void upgt_eeprom_parse_hwrx(struct upgt_softc *, uint8_t *);
-static void upgt_eeprom_parse_freq3(struct upgt_softc *, uint8_t *, int);
-static void upgt_eeprom_parse_freq4(struct upgt_softc *, uint8_t *, int);
-static void upgt_eeprom_parse_freq6(struct upgt_softc *, uint8_t *, int);
-static uint32_t upgt_chksum_le(const uint32_t *, size_t);
-static void upgt_tx_done(struct upgt_softc *, uint8_t *);
-static void upgt_rx(struct upgt_softc *, uint8_t *, int);
-static void upgt_init(void *);
-static void upgt_init_locked(struct upgt_softc *);
-static int upgt_ioctl(struct ifnet *, u_long, caddr_t);
-static void upgt_start(struct ifnet *);
-static int upgt_raw_xmit(struct ieee80211_node *, struct mbuf *,
- const struct ieee80211_bpf_params *);
-static void upgt_scan_start(struct ieee80211com *);
-static void upgt_scan_end(struct ieee80211com *);
-static void upgt_set_channel(struct ieee80211com *);
-static struct ieee80211vap *upgt_vap_create(struct ieee80211com *,
- const char name[IFNAMSIZ], int unit, int opmode,
- int flags, const uint8_t bssid[IEEE80211_ADDR_LEN],
- const uint8_t mac[IEEE80211_ADDR_LEN]);
-static void upgt_vap_delete(struct ieee80211vap *);
-static void upgt_update_mcast(struct ifnet *);
-static uint8_t upgt_rx_rate(struct upgt_softc *, const int);
-static void upgt_set_multi(void *);
-static void upgt_stop(struct upgt_softc *, int);
-static void upgt_setup_rates(struct ieee80211vap *, struct ieee80211com *);
-static int upgt_set_macfilter(struct upgt_softc *, uint8_t);
-static int upgt_newstate(struct ieee80211vap *, enum ieee80211_state, int);
-static void upgt_task(void *);
-static void upgt_scantask(void *);
-static void upgt_set_chan(struct upgt_softc *, struct ieee80211_channel *);
-static void upgt_set_led(struct upgt_softc *, int);
-static void upgt_set_led_blink(void *);
-static void upgt_tx_task(void *);
-static int upgt_get_stats(struct upgt_softc *);
-static void upgt_mem_free(struct upgt_softc *, uint32_t);
-static uint32_t upgt_mem_alloc(struct upgt_softc *);
-static void upgt_free_tx(struct upgt_softc *);
-static void upgt_free_rx(struct upgt_softc *);
-static void upgt_free_cmd(struct upgt_softc *);
-static void upgt_watchdog(void *);
-
-static const char *upgt_fwname = "upgt-gw3887";
-
-static const struct usb_devno upgt_devs_2[] = {
- /* version 2 devices */
- { USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_PRISM_GT },
- { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D7050 },
- { USB_VENDOR_CONCEPTRONIC, USB_PRODUCT_CONCEPTRONIC_PRISM_GT },
- { USB_VENDOR_DELL, USB_PRODUCT_DELL_PRISM_GT_1 },
- { USB_VENDOR_DELL, USB_PRODUCT_DELL_PRISM_GT_2 },
- { USB_VENDOR_FSC, USB_PRODUCT_FSC_E5400 },
- { USB_VENDOR_GLOBESPAN, USB_PRODUCT_GLOBESPAN_PRISM_GT_1 },
- { USB_VENDOR_GLOBESPAN, USB_PRODUCT_GLOBESPAN_PRISM_GT_2 },
- { USB_VENDOR_INTERSIL, USB_PRODUCT_INTERSIL_PRISM_GT },
- { USB_VENDOR_SMC, USB_PRODUCT_SMC_2862WG },
- { USB_VENDOR_WISTRONNEWEB, USB_PRODUCT_WISTRONNEWEB_UR045G },
- { USB_VENDOR_XYRATEX, USB_PRODUCT_XYRATEX_PRISM_GT_1 },
- { USB_VENDOR_XYRATEX, USB_PRODUCT_XYRATEX_PRISM_GT_2 },
- { USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_XG703A }
-};
-
-static int
-upgt_match(device_t dev)
-{
- struct usb_attach_arg *uaa = device_get_ivars(dev);
-
- if (!uaa->iface)
- return UMATCH_NONE;
-
- if (usb_lookup(upgt_devs_2, uaa->vendor, uaa->product) != NULL)
- return (UMATCH_VENDOR_PRODUCT);
-
- return (UMATCH_NONE);
-}
-
-static int
-upgt_attach(device_t dev)
-{
- int i;
- struct upgt_softc *sc = device_get_softc(dev);
- struct usb_attach_arg *uaa = device_get_ivars(dev);
- usb_endpoint_descriptor_t *ed;
- usb_interface_descriptor_t *id;
- usbd_status error;
-
- sc->sc_dev = dev;
- sc->sc_udev = uaa->device;
-#ifdef UPGT_DEBUG
- sc->sc_debug = upgt_debug;
-#endif
-
- /* set configuration number */
- if (usbd_set_config_no(sc->sc_udev, UPGT_CONFIG_NO, 0) != 0) {
- device_printf(dev, "could not set configuration no!\n");
- return ENXIO;
- }
-
- /* get the first interface handle */
- error = usbd_device2interface_handle(sc->sc_udev, UPGT_IFACE_INDEX,
- &sc->sc_iface);
- if (error != 0) {
- device_printf(dev, "could not get interface handle!\n");
- return ENXIO;
- }
-
- /* find endpoints */
- id = usbd_get_interface_descriptor(sc->sc_iface);
- sc->sc_rx_no = sc->sc_tx_no = -1;
- for (i = 0; i < id->bNumEndpoints; i++) {
- ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
- if (ed == NULL) {
- device_printf(dev,
- "no endpoint descriptor for iface %d!\n", i);
- return ENXIO;
- }
-
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
- sc->sc_tx_no = ed->bEndpointAddress;
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
- sc->sc_rx_no = ed->bEndpointAddress;
-
- /*
- * 0x01 TX pipe
- * 0x81 RX pipe
- *
- * Deprecated scheme (not used with fw version >2.5.6.x):
- * 0x02 TX MGMT pipe
- * 0x82 TX MGMT pipe
- */
- if (sc->sc_tx_no != -1 && sc->sc_rx_no != -1)
- break;
- }
- if (sc->sc_rx_no == -1 || sc->sc_tx_no == -1) {
- device_printf(dev, "missing endpoint!\n");
- return ENXIO;
- }
-
- /*
- * Open TX and RX USB bulk pipes.
- */
- error = usbd_open_pipe(sc->sc_iface, sc->sc_tx_no, USBD_EXCLUSIVE_USE,
- &sc->sc_tx_pipeh);
- if (error != 0) {
- device_printf(dev, "could not open TX pipe: %s!\n",
- usbd_errstr(error));
- goto fail;
- }
- error = usbd_open_pipe(sc->sc_iface, sc->sc_rx_no, USBD_EXCLUSIVE_USE,
- &sc->sc_rx_pipeh);
- if (error != 0) {
- device_printf(dev, "could not open RX pipe: %s!\n",
- usbd_errstr(error));
- goto fail;
- }
-
- /* Allocate TX, RX, and CMD xfers. */
- if (upgt_alloc_tx(sc) != 0)
- goto fail;
- if (upgt_alloc_rx(sc) != 0)
- goto fail;
- if (upgt_alloc_cmd(sc) != 0)
- goto fail;
-
- /* We need the firmware loaded to complete the attach. */
- return upgt_attach_hook(dev);
-
-fail:
- device_printf(dev, "%s failed!\n", __func__);
- return ENXIO;
-}
-
-static int
-upgt_attach_hook(device_t dev)
-{
- struct ieee80211com *ic;
- struct ifnet *ifp;
- struct upgt_softc *sc = device_get_softc(dev);
- struct upgt_data *data_rx = &sc->rx_data;
- uint8_t bands;
- usbd_status error;
-
- ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
- if (ifp == NULL) {
- device_printf(dev, "can not if_alloc()\n");
- return ENXIO;
- }
-
- mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
- MTX_DEF | MTX_RECURSE);
- usb_init_task(&sc->sc_mcasttask, upgt_set_multi, sc);
- usb_init_task(&sc->sc_scantask, upgt_scantask, sc);
- usb_init_task(&sc->sc_task, upgt_task, sc);
- usb_init_task(&sc->sc_task_tx, upgt_tx_task, sc);
- callout_init(&sc->sc_led_ch, 0);
- callout_init(&sc->sc_watchdog_ch, 0);
-
- /* Initialize the device. */
- if (upgt_device_reset(sc) != 0)
- goto fail;
-
- /* Verify the firmware. */
- if (upgt_fw_verify(sc) != 0)
- goto fail;
-
- /* Calculate device memory space. */
- if (sc->sc_memaddr_frame_start == 0 || sc->sc_memaddr_frame_end == 0) {
- device_printf(dev,
- "could not find memory space addresses on FW!\n");
- goto fail;
- }
- sc->sc_memaddr_frame_end -= UPGT_MEMSIZE_RX + 1;
- sc->sc_memaddr_rx_start = sc->sc_memaddr_frame_end + 1;
-
- DPRINTF(sc, UPGT_DEBUG_FW, "memory address frame start=0x%08x\n",
- sc->sc_memaddr_frame_start);
- DPRINTF(sc, UPGT_DEBUG_FW, "memory address frame end=0x%08x\n",
- sc->sc_memaddr_frame_end);
- DPRINTF(sc, UPGT_DEBUG_FW, "memory address rx start=0x%08x\n",
- sc->sc_memaddr_rx_start);
-
- upgt_mem_init(sc);
-
- /* Load the firmware. */
- if (upgt_fw_load(sc) != 0)
- goto fail;
-
- /* Startup the RX pipe. */
- usbd_setup_xfer(data_rx->xfer, sc->sc_rx_pipeh, data_rx, data_rx->buf,
- MCLBYTES, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, upgt_rxeof);
- error = usbd_transfer(data_rx->xfer);
- if (error != 0 && error != USBD_IN_PROGRESS) {
- device_printf(dev, "could not queue RX transfer!\n");
- goto fail;
- }
- usbd_delay_ms(sc->sc_udev, 100);
-
- /* Read the whole EEPROM content and parse it. */
- if (upgt_eeprom_read(sc) != 0)
- goto fail;
- if (upgt_eeprom_parse(sc) != 0)
- goto fail;
-
- /* Setup the 802.11 device. */
- ifp->if_softc = sc;
- if_initname(ifp, "upgt", device_get_unit(sc->sc_dev));
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
- IFF_NEEDSGIANT; /* USB stack is still under Giant lock */
- ifp->if_init = upgt_init;
- ifp->if_ioctl = upgt_ioctl;
- ifp->if_start = upgt_start;
- IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
- IFQ_SET_READY(&ifp->if_snd);
-
- ic = ifp->if_l2com;
- ic->ic_ifp = ifp;
- ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
- ic->ic_opmode = IEEE80211_M_STA;
- /* set device capabilities */
- ic->ic_caps =
- IEEE80211_C_STA /* station mode */
- | IEEE80211_C_MONITOR /* monitor mode */
- | IEEE80211_C_SHPREAMBLE /* short preamble supported */
- | IEEE80211_C_SHSLOT /* short slot time supported */
- | IEEE80211_C_BGSCAN /* capable of bg scanning */
- | IEEE80211_C_WPA /* 802.11i */
- ;
-
- bands = 0;
- setbit(&bands, IEEE80211_MODE_11B);
- setbit(&bands, IEEE80211_MODE_11G);
- ieee80211_init_channels(ic, NULL, &bands);
-
- ieee80211_ifattach(ic);
- ic->ic_raw_xmit = upgt_raw_xmit;
- ic->ic_scan_start = upgt_scan_start;
- ic->ic_scan_end = upgt_scan_end;
- ic->ic_set_channel = upgt_set_channel;
-
- ic->ic_vap_create = upgt_vap_create;
- ic->ic_vap_delete = upgt_vap_delete;
- ic->ic_update_mcast = upgt_update_mcast;
-
- bpfattach(ifp, DLT_IEEE802_11_RADIO,
- sizeof(struct ieee80211_frame) + sizeof(sc->sc_txtap));
- sc->sc_rxtap_len = sizeof(sc->sc_rxtap);
- sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
- sc->sc_rxtap.wr_ihdr.it_present = htole32(UPGT_RX_RADIOTAP_PRESENT);
- sc->sc_txtap_len = sizeof(sc->sc_txtap);
- sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
- sc->sc_txtap.wt_ihdr.it_present = htole32(UPGT_TX_RADIOTAP_PRESENT);
-
- if (bootverbose)
- ieee80211_announce(ic);
-
- usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev);
- return 0;
-fail:
- device_printf(dev, "%s failed!\n", __func__);
- mtx_destroy(&sc->sc_mtx);
- if_free(ifp);
- return ENXIO;
-}
-
-static void
-upgt_tx_task(void *arg)
-{
- struct upgt_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211_frame *wh;
- struct ieee80211_key *k;
- struct upgt_data *data_tx;
- struct upgt_lmac_mem *mem;
- struct upgt_lmac_tx_desc *txdesc;
- struct mbuf *m;
- uint32_t addr;
- int len, i;
- usbd_status error;
-
- upgt_set_led(sc, UPGT_LED_BLINK);
-
- UPGT_LOCK(sc);
- for (i = 0; i < upgt_txbuf; i++) {
- data_tx = &sc->tx_data[i];
- if (data_tx->m == NULL)
- continue;
-
- m = data_tx->m;
- addr = data_tx->addr + UPGT_MEMSIZE_FRAME_HEAD;
-
- /*
- * Software crypto.
- */
- wh = mtod(m, struct ieee80211_frame *);
- if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
- k = ieee80211_crypto_encap(data_tx->ni, m);
- if (k == NULL) {
- device_printf(sc->sc_dev,
- "ieee80211_crypto_encap returns NULL.\n");
- goto done;
- }
-
- /* in case packet header moved, reset pointer */
- wh = mtod(m, struct ieee80211_frame *);
- }
-
- /*
- * Transmit the URB containing the TX data.
- */
- bzero(data_tx->buf, MCLBYTES);
-
- mem = (struct upgt_lmac_mem *)data_tx->buf;
- mem->addr = htole32(addr);
-
- txdesc = (struct upgt_lmac_tx_desc *)(mem + 1);
-
- if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
- IEEE80211_FC0_TYPE_MGT) {
- /* mgmt frames */
- txdesc->header1.flags = UPGT_H1_FLAGS_TX_MGMT;
- /* always send mgmt frames at lowest rate (DS1) */
- memset(txdesc->rates, 0x10, sizeof(txdesc->rates));
- } else {
- /* data frames */
- txdesc->header1.flags = UPGT_H1_FLAGS_TX_DATA;
- bcopy(sc->sc_cur_rateset, txdesc->rates,
- sizeof(txdesc->rates));
- }
- txdesc->header1.type = UPGT_H1_TYPE_TX_DATA;
- txdesc->header1.len = htole16(m->m_pkthdr.len);
- txdesc->header2.reqid = htole32(data_tx->addr);
- txdesc->header2.type = htole16(UPGT_H2_TYPE_TX_ACK_YES);
- txdesc->header2.flags = htole16(UPGT_H2_FLAGS_TX_ACK_YES);
- txdesc->type = htole32(UPGT_TX_DESC_TYPE_DATA);
- txdesc->pad3[0] = UPGT_TX_DESC_PAD3_SIZE;
-
- if (bpf_peers_present(ifp->if_bpf)) {
- struct upgt_tx_radiotap_header *tap = &sc->sc_txtap;
-
- tap->wt_flags = 0;
- tap->wt_rate = 0; /* XXX where to get from? */
- tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
- tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
-
- bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m);
- }
-
- /* copy frame below our TX descriptor header */
- m_copydata(m, 0, m->m_pkthdr.len,
- data_tx->buf + (sizeof(*mem) + sizeof(*txdesc)));
- /* calculate frame size */
- len = sizeof(*mem) + sizeof(*txdesc) + m->m_pkthdr.len;
- /* we need to align the frame to a 4 byte boundary */
- len = (len + 3) & ~3;
- /* calculate frame checksum */
- mem->chksum = upgt_chksum_le((uint32_t *)txdesc,
- len - sizeof(*mem));
- /* we do not need the mbuf anymore */
- m_freem(m);
- data_tx->m = NULL;
-
- DPRINTF(sc, UPGT_DEBUG_XMIT, "%s: TX start data sending\n",
- __func__);
- KASSERT(len <= MCLBYTES, ("mbuf is small for saving data"));
-
- usbd_setup_xfer(data_tx->xfer, sc->sc_tx_pipeh, data_tx,
- data_tx->buf, len, USBD_FORCE_SHORT_XFER | USBD_NO_COPY,
- UPGT_USB_TIMEOUT, upgt_txeof);
- UPGT_UNLOCK(sc);
- mtx_lock(&Giant);
- error = usbd_transfer(data_tx->xfer);
- mtx_unlock(&Giant);
- UPGT_LOCK(sc);
- if (error != 0 && error != USBD_IN_PROGRESS) {
- device_printf(sc->sc_dev,
- "could not transmit TX data URB!\n");
- goto done;
- }
-
- DPRINTF(sc, UPGT_DEBUG_XMIT, "TX sent (%d bytes)\n", len);
- }
-done:
- UPGT_UNLOCK(sc);
- /*
- * If we don't regulary read the device statistics, the RX queue
- * will stall. It's strange, but it works, so we keep reading
- * the statistics here. *shrug*
- */
- (void)upgt_get_stats(sc);
-}
-
-static void
-upgt_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- struct upgt_data *data_tx = priv;
- struct upgt_softc *sc = data_tx->sc;
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
- return;
- if (status == USBD_STALLED) {
- usbd_clear_endpoint_stall_async(sc->sc_rx_pipeh);
- return;
- }
-
- device_printf(sc->sc_dev, "TX warning(%s)\n",
- usbd_errstr(status));
- }
-}
-
-static int
-upgt_get_stats(struct upgt_softc *sc)
-{
- struct upgt_data *data_cmd = &sc->cmd_data;
- struct upgt_lmac_mem *mem;
- struct upgt_lmac_stats *stats;
- int len;
-
- /*
- * Transmit the URB containing the CMD data.
- */
- bzero(data_cmd->buf, MCLBYTES);
-
- mem = (struct upgt_lmac_mem *)data_cmd->buf;
- mem->addr = htole32(sc->sc_memaddr_frame_start +
- UPGT_MEMSIZE_FRAME_HEAD);
-
- stats = (struct upgt_lmac_stats *)(mem + 1);
-
- stats->header1.flags = 0;
- stats->header1.type = UPGT_H1_TYPE_CTRL;
- stats->header1.len = htole16(
- sizeof(struct upgt_lmac_stats) - sizeof(struct upgt_lmac_header));
-
- stats->header2.reqid = htole32(sc->sc_memaddr_frame_start);
- stats->header2.type = htole16(UPGT_H2_TYPE_STATS);
- stats->header2.flags = 0;
-
- len = sizeof(*mem) + sizeof(*stats);
-
- mem->chksum = upgt_chksum_le((uint32_t *)stats,
- len - sizeof(*mem));
-
- if (upgt_bulk_xmit(sc, data_cmd, sc->sc_tx_pipeh, &len, 0) != 0) {
- device_printf(sc->sc_dev,
- "could not transmit statistics CMD data URB!\n");
- return (EIO);
- }
-
- return (0);
-}
-
-static int
-upgt_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
-{
- struct upgt_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ifreq *ifr = (struct ifreq *) data;
- int error = 0, startall = 0;
-
- switch (cmd) {
- case SIOCSIFFLAGS:
- mtx_lock(&Giant);
- if (ifp->if_flags & IFF_UP) {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
- if ((ifp->if_flags ^ sc->sc_if_flags) &
- (IFF_ALLMULTI | IFF_PROMISC))
- upgt_set_multi(sc);
- } else {
- upgt_init(sc);
- startall = 1;
- }
- } else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- upgt_stop(sc, 1);
- }
- sc->sc_if_flags = ifp->if_flags;
- if (startall)
- ieee80211_start_all(ic);
- mtx_unlock(&Giant);
- break;
- case SIOCGIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
- break;
- case SIOCGIFADDR:
- error = ether_ioctl(ifp, cmd, data);
- break;
- default:
- error = EINVAL;
- break;
- }
- return error;
-}
-
-static void
-upgt_stop(struct upgt_softc *sc, int disable)
-{
- struct ifnet *ifp = sc->sc_ifp;
-
- /* abort and close TX / RX pipes */
- if (sc->sc_tx_pipeh != NULL)
- usbd_abort_pipe(sc->sc_tx_pipeh);
- if (sc->sc_rx_pipeh != NULL)
- usbd_abort_pipe(sc->sc_rx_pipeh);
-
- /* device down */
- sc->sc_tx_timer = 0;
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
-}
-
-static void
-upgt_task(void *arg)
-{
- struct upgt_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
- struct upgt_vap *uvp = UPGT_VAP(vap);
-
- DPRINTF(sc, UPGT_DEBUG_STATE, "%s: %s -> %s\n", __func__,
- ieee80211_state_name[vap->iv_state],
- ieee80211_state_name[sc->sc_state]);
-
- switch (sc->sc_state) {
- case IEEE80211_S_INIT:
- /* do not accept any frames if the device is down */
- UPGT_LOCK(sc);
- upgt_set_macfilter(sc, sc->sc_state);
- UPGT_UNLOCK(sc);
- upgt_set_led(sc, UPGT_LED_OFF);
- break;
- case IEEE80211_S_SCAN:
- upgt_set_chan(sc, ic->ic_curchan);
- break;
- case IEEE80211_S_AUTH:
- upgt_set_chan(sc, ic->ic_curchan);
- break;
- case IEEE80211_S_ASSOC:
- break;
- case IEEE80211_S_RUN:
- UPGT_LOCK(sc);
- upgt_set_macfilter(sc, sc->sc_state);
- UPGT_UNLOCK(sc);
- upgt_set_led(sc, UPGT_LED_ON);
- break;
- default:
- break;
- }
-
- IEEE80211_LOCK(ic);
- uvp->newstate(vap, sc->sc_state, sc->sc_arg);
- if (vap->iv_newstate_cb != NULL)
- vap->iv_newstate_cb(vap, sc->sc_state, sc->sc_arg);
- IEEE80211_UNLOCK(ic);
-}
-
-static void
-upgt_set_led(struct upgt_softc *sc, int action)
-{
- struct upgt_data *data_cmd = &sc->cmd_data;
- struct upgt_lmac_mem *mem;
- struct upgt_lmac_led *led;
- int len;
-
- /*
- * Transmit the URB containing the CMD data.
- */
- bzero(data_cmd->buf, MCLBYTES);
-
- mem = (struct upgt_lmac_mem *)data_cmd->buf;
- mem->addr = htole32(sc->sc_memaddr_frame_start +
- UPGT_MEMSIZE_FRAME_HEAD);
-
- led = (struct upgt_lmac_led *)(mem + 1);
-
- led->header1.flags = UPGT_H1_FLAGS_TX_NO_CALLBACK;
- led->header1.type = UPGT_H1_TYPE_CTRL;
- led->header1.len = htole16(
- sizeof(struct upgt_lmac_led) -
- sizeof(struct upgt_lmac_header));
-
- led->header2.reqid = htole32(sc->sc_memaddr_frame_start);
- led->header2.type = htole16(UPGT_H2_TYPE_LED);
- led->header2.flags = 0;
-
- switch (action) {
- case UPGT_LED_OFF:
- led->mode = htole16(UPGT_LED_MODE_SET);
- led->action_fix = 0;
- led->action_tmp = htole16(UPGT_LED_ACTION_OFF);
- led->action_tmp_dur = 0;
- break;
- case UPGT_LED_ON:
- led->mode = htole16(UPGT_LED_MODE_SET);
- led->action_fix = 0;
- led->action_tmp = htole16(UPGT_LED_ACTION_ON);
- led->action_tmp_dur = 0;
- break;
- case UPGT_LED_BLINK:
- if (sc->sc_state != IEEE80211_S_RUN)
- return;
- if (sc->sc_led_blink)
- /* previous blink was not finished */
- return;
- led->mode = htole16(UPGT_LED_MODE_SET);
- led->action_fix = htole16(UPGT_LED_ACTION_OFF);
- led->action_tmp = htole16(UPGT_LED_ACTION_ON);
- led->action_tmp_dur = htole16(UPGT_LED_ACTION_TMP_DUR);
- /* lock blink */
- sc->sc_led_blink = 1;
- callout_reset(&sc->sc_led_ch, hz, upgt_set_led_blink, sc);
- break;
- default:
- return;
- }
-
- len = sizeof(*mem) + sizeof(*led);
-
- mem->chksum = upgt_chksum_le((uint32_t *)led,
- len - sizeof(*mem));
-
- if (upgt_bulk_xmit(sc, data_cmd, sc->sc_tx_pipeh, &len, 0) != 0)
- device_printf(sc->sc_dev, "could not transmit led CMD URB!\n");
-}
-
-static void
-upgt_set_led_blink(void *arg)
-{
- struct upgt_softc *sc = arg;
-
- /* blink finished, we are ready for a next one */
- sc->sc_led_blink = 0;
-}
-
-static void
-upgt_init(void *priv)
-{
- struct upgt_softc *sc = priv;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
-
- UPGT_LOCK(sc);
- upgt_init_locked(sc);
- UPGT_UNLOCK(sc);
-
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- ieee80211_start_all(ic); /* start all vap's */
-}
-
-static void
-upgt_init_locked(struct upgt_softc *sc)
-{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
-
- IEEE80211_ADDR_COPY(ic->ic_myaddr, IF_LLADDR(ifp));
- DPRINTF(sc, UPGT_DEBUG_RESET, "setting MAC address to %s\n",
- ether_sprintf(ic->ic_myaddr));
-
- upgt_set_macfilter(sc, IEEE80211_S_SCAN);
-
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
-}
-
-static int
-upgt_set_macfilter(struct upgt_softc *sc, uint8_t state)
-{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
- struct ieee80211_node *ni = vap->iv_bss;
- struct upgt_data *data_cmd = &sc->cmd_data;
- struct upgt_lmac_mem *mem;
- struct upgt_lmac_filter *filter;
- int len;
- uint8_t broadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-
- /*
- * Transmit the URB containing the CMD data.
- */
- bzero(data_cmd->buf, MCLBYTES);
-
- mem = (struct upgt_lmac_mem *)data_cmd->buf;
- mem->addr = htole32(sc->sc_memaddr_frame_start +
- UPGT_MEMSIZE_FRAME_HEAD);
-
- filter = (struct upgt_lmac_filter *)(mem + 1);
-
- filter->header1.flags = UPGT_H1_FLAGS_TX_NO_CALLBACK;
- filter->header1.type = UPGT_H1_TYPE_CTRL;
- filter->header1.len = htole16(
- sizeof(struct upgt_lmac_filter) -
- sizeof(struct upgt_lmac_header));
-
- filter->header2.reqid = htole32(sc->sc_memaddr_frame_start);
- filter->header2.type = htole16(UPGT_H2_TYPE_MACFILTER);
- filter->header2.flags = 0;
-
- switch (state) {
- case IEEE80211_S_INIT:
- DPRINTF(sc, UPGT_DEBUG_STATE, "%s: set MAC filter to INIT\n",
- __func__);
- filter->type = htole16(UPGT_FILTER_TYPE_RESET);
- break;
- case IEEE80211_S_SCAN:
- DPRINTF(sc, UPGT_DEBUG_STATE,
- "set MAC filter to SCAN (bssid %s)\n",
- ether_sprintf(broadcast));
- filter->type = htole16(UPGT_FILTER_TYPE_NONE);
- IEEE80211_ADDR_COPY(filter->dst, ic->ic_myaddr);
- IEEE80211_ADDR_COPY(filter->src, broadcast);
- filter->unknown1 = htole16(UPGT_FILTER_UNKNOWN1);
- filter->rxaddr = htole32(sc->sc_memaddr_rx_start);
- filter->unknown2 = htole16(UPGT_FILTER_UNKNOWN2);
- filter->rxhw = htole32(sc->sc_eeprom_hwrx);
- filter->unknown3 = htole16(UPGT_FILTER_UNKNOWN3);
- break;
- case IEEE80211_S_RUN:
- /* XXX monitor mode isn't tested yet. */
- if (vap->iv_opmode == IEEE80211_M_MONITOR) {
- filter->type = htole16(UPGT_FILTER_TYPE_MONITOR);
- IEEE80211_ADDR_COPY(filter->dst, ic->ic_myaddr);
- IEEE80211_ADDR_COPY(filter->src, ni->ni_bssid);
- filter->unknown1 = htole16(UPGT_FILTER_MONITOR_UNKNOWN1);
- filter->rxaddr = htole32(sc->sc_memaddr_rx_start);
- filter->unknown2 = htole16(UPGT_FILTER_MONITOR_UNKNOWN2);
- filter->rxhw = htole32(sc->sc_eeprom_hwrx);
- filter->unknown3 = htole16(UPGT_FILTER_MONITOR_UNKNOWN3);
- } else {
- DPRINTF(sc, UPGT_DEBUG_STATE,
- "set MAC filter to RUN (bssid %s)\n",
- ether_sprintf(ni->ni_bssid));
- filter->type = htole16(UPGT_FILTER_TYPE_STA);
- IEEE80211_ADDR_COPY(filter->dst, ic->ic_myaddr);
- IEEE80211_ADDR_COPY(filter->src, ni->ni_bssid);
- filter->unknown1 = htole16(UPGT_FILTER_UNKNOWN1);
- filter->rxaddr = htole32(sc->sc_memaddr_rx_start);
- filter->unknown2 = htole16(UPGT_FILTER_UNKNOWN2);
- filter->rxhw = htole32(sc->sc_eeprom_hwrx);
- filter->unknown3 = htole16(UPGT_FILTER_UNKNOWN3);
- }
- break;
- default:
- device_printf(sc->sc_dev,
- "MAC filter does not know that state!\n");
- break;
- }
-
- len = sizeof(*mem) + sizeof(*filter);
-
- mem->chksum = upgt_chksum_le((uint32_t *)filter,
- len - sizeof(*mem));
-
- UPGT_UNLOCK(sc);
- if (upgt_bulk_xmit(sc, data_cmd, sc->sc_tx_pipeh, &len, 0) != 0) {
- device_printf(sc->sc_dev,
- "could not transmit macfilter CMD data URB!\n");
- UPGT_LOCK(sc);
- return (EIO);
- }
- UPGT_LOCK(sc);
-
- return (0);
-}
-
-static void
-upgt_setup_rates(struct ieee80211vap *vap, struct ieee80211com *ic)
-{
- struct ifnet *ifp = ic->ic_ifp;
- struct upgt_softc *sc = ifp->if_softc;
- const struct ieee80211_txparam *tp;
-
- /*
- * 0x01 = OFMD6 0x10 = DS1
- * 0x04 = OFDM9 0x11 = DS2
- * 0x06 = OFDM12 0x12 = DS5
- * 0x07 = OFDM18 0x13 = DS11
- * 0x08 = OFDM24
- * 0x09 = OFDM36
- * 0x0a = OFDM48
- * 0x0b = OFDM54
- */
- const uint8_t rateset_auto_11b[] =
- { 0x13, 0x13, 0x12, 0x11, 0x11, 0x10, 0x10, 0x10 };
- const uint8_t rateset_auto_11g[] =
- { 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x04, 0x01 };
- const uint8_t rateset_fix_11bg[] =
- { 0x10, 0x11, 0x12, 0x13, 0x01, 0x04, 0x06, 0x07,
- 0x08, 0x09, 0x0a, 0x0b };
-
- tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
-
- /* XXX */
- if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE) {
- /*
- * Automatic rate control is done by the device.
- * We just pass the rateset from which the device
- * will pickup a rate.
- */
- if (ic->ic_curmode == IEEE80211_MODE_11B)
- bcopy(rateset_auto_11b, sc->sc_cur_rateset,
- sizeof(sc->sc_cur_rateset));
- if (ic->ic_curmode == IEEE80211_MODE_11G ||
- ic->ic_curmode == IEEE80211_MODE_AUTO)
- bcopy(rateset_auto_11g, sc->sc_cur_rateset,
- sizeof(sc->sc_cur_rateset));
- } else {
- /* set a fixed rate */
- memset(sc->sc_cur_rateset, rateset_fix_11bg[tp->ucastrate],
- sizeof(sc->sc_cur_rateset));
- }
-}
-
-static void
-upgt_set_multi(void *arg)
-{
- struct upgt_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
-
- if (!(ifp->if_flags & IFF_UP))
- return;
-
- /*
- * XXX don't know how to set a device. Lack of docs. Just try to set
- * IFF_ALLMULTI flag here.
- */
- IF_ADDR_LOCK(ifp);
- ifp->if_flags |= IFF_ALLMULTI;
- IF_ADDR_UNLOCK(ifp);
-}
-
-static void
-upgt_start(struct ifnet *ifp)
-{
- struct upgt_softc *sc = ifp->if_softc;
- struct upgt_data *data_tx;
- struct ieee80211_node *ni;
- struct mbuf *m;
- int i;
-
- UPGT_LOCK(sc);
- for (i = 0; i < upgt_txbuf; i++) {
- data_tx = &sc->tx_data[i];
- if (data_tx->use == 1)
- continue;
-
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL)
- break;
-
- ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
- m = ieee80211_encap(ni, m);
- if (m == NULL) {
- ieee80211_free_node(ni);
- ifp->if_oerrors++;
- continue;
- }
-
- if ((data_tx->addr = upgt_mem_alloc(sc)) == 0) {
- device_printf(sc->sc_dev, "no free prism memory!\n");
- UPGT_UNLOCK(sc);
- return;
- }
- data_tx->ni = ni;
- data_tx->m = m;
- data_tx->use = 1;
- sc->tx_queued++;
- }
-
- if (sc->tx_queued > 0) {
- DPRINTF(sc, UPGT_DEBUG_XMIT, "tx_queued=%d\n", sc->tx_queued);
-
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- sc->sc_tx_timer = 5;
- callout_reset(&sc->sc_watchdog_ch, hz, upgt_watchdog, sc);
- /* process the TX queue in process context */
- usb_rem_task(sc->sc_udev, &sc->sc_task_tx);
- usb_add_task(sc->sc_udev, &sc->sc_task_tx, USB_TASKQ_DRIVER);
- }
- UPGT_UNLOCK(sc);
-}
-
-static int
-upgt_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
- const struct ieee80211_bpf_params *params)
-{
- struct ieee80211com *ic = ni->ni_ic;
- struct ifnet *ifp = ic->ic_ifp;
- struct upgt_softc *sc = ifp->if_softc;
- struct upgt_data *data_tx = NULL;
- int i;
-
- /* prevent management frames from being sent if we're not ready */
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
- m_freem(m);
- ieee80211_free_node(ni);
- return ENETDOWN;
- }
-
- UPGT_LOCK(sc);
- if (sc->tx_queued >= upgt_txbuf) {
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- m_freem(m);
- ieee80211_free_node(ni);
- UPGT_UNLOCK(sc);
- return ENOBUFS; /* XXX */
- }
-
- ifp->if_opackets++;
-
- /* choose a unused buffer. */
- for (i = 0; i < upgt_txbuf; i++) {
- data_tx = &sc->tx_data[i];
- if (data_tx->use == 0)
- break;
- }
- KASSERT(data_tx != NULL, ("data_tx is NULL"));
- KASSERT(data_tx->use == 0, ("no empty TX queue"));
- if ((data_tx->addr = upgt_mem_alloc(sc)) == 0) {
- device_printf(sc->sc_dev, "no free prism memory!\n");
- UPGT_UNLOCK(sc);
- return ENOBUFS;
- }
-
- if (bpf_peers_present(ifp->if_bpf)) {
- struct upgt_tx_radiotap_header *tap = &sc->sc_txtap;
-
- tap->wt_flags = 0;
- tap->wt_rate = 0; /* TODO: where to get from? */
- tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
- tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
-
- bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m);
- }
-
- data_tx->ni = ni;
- data_tx->m = m;
- data_tx->use = 1;
- sc->tx_queued++;
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- UPGT_UNLOCK(sc);
-
- sc->sc_tx_timer = 5;
- callout_reset(&sc->sc_watchdog_ch, hz, upgt_watchdog, sc);
- usb_rem_task(sc->sc_udev, &sc->sc_task_tx);
- usb_add_task(sc->sc_udev, &sc->sc_task_tx, USB_TASKQ_DRIVER);
-
- return 0;
-}
-
-static void
-upgt_watchdog(void *arg)
-{
- struct upgt_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
-
- if (sc->sc_tx_timer > 0) {
- if (--sc->sc_tx_timer == 0) {
- device_printf(sc->sc_dev, "watchdog timeout\n");
- /* upgt_init(ifp); XXX needs a process context ? */
- ifp->if_oerrors++;
- return;
- }
- callout_reset(&sc->sc_watchdog_ch, hz, upgt_watchdog, sc);
- }
-}
-
-static uint32_t
-upgt_mem_alloc(struct upgt_softc *sc)
-{
- int i;
-
- for (i = 0; i < sc->sc_memory.pages; i++) {
- if (sc->sc_memory.page[i].used == 0) {
- sc->sc_memory.page[i].used = 1;
- return (sc->sc_memory.page[i].addr);
- }
- }
-
- return (0);
-}
-
-static void
-upgt_scantask(void *arg)
-{
- struct upgt_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
-
- switch (sc->sc_scan_action) {
- case UPGT_SET_CHANNEL:
- upgt_set_chan(sc, ic->ic_curchan);
- break;
- default:
- device_printf(sc->sc_dev, "unknown scan action %d\n",
- sc->sc_scan_action);
- break;
- }
-}
-
-static void
-upgt_scan_start(struct ieee80211com *ic)
-{
- /* do nothing. */
-}
-
-static void
-upgt_scan_end(struct ieee80211com *ic)
-{
- /* do nothing. */
-}
-
-static void
-upgt_set_channel(struct ieee80211com *ic)
-{
- struct upgt_softc *sc = ic->ic_ifp->if_softc;
-
- usb_rem_task(sc->sc_udev, &sc->sc_scantask);
-
- /* do it in a process context */
- sc->sc_scan_action = UPGT_SET_CHANNEL;
- usb_add_task(sc->sc_udev, &sc->sc_scantask, USB_TASKQ_DRIVER);
-}
-
-static void
-upgt_set_chan(struct upgt_softc *sc, struct ieee80211_channel *c)
-{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct upgt_data *data_cmd = &sc->cmd_data;
- struct upgt_lmac_mem *mem;
- struct upgt_lmac_channel *chan;
- int len, channel;
-
- channel = ieee80211_chan2ieee(ic, c);
- if (channel == 0 || channel == IEEE80211_CHAN_ANY) {
- /* XXX should NEVER happen */
- device_printf(sc->sc_dev,
- "%s: invalid channel %x\n", __func__, channel);
- return;
- }
-
- DPRINTF(sc, UPGT_DEBUG_STATE, "%s: channel %d\n", __func__, channel);
-
- /*
- * Transmit the URB containing the CMD data.
- */
- bzero(data_cmd->buf, MCLBYTES);
-
- mem = (struct upgt_lmac_mem *)data_cmd->buf;
- mem->addr = htole32(sc->sc_memaddr_frame_start +
- UPGT_MEMSIZE_FRAME_HEAD);
-
- chan = (struct upgt_lmac_channel *)(mem + 1);
-
- chan->header1.flags = UPGT_H1_FLAGS_TX_NO_CALLBACK;
- chan->header1.type = UPGT_H1_TYPE_CTRL;
- chan->header1.len = htole16(
- sizeof(struct upgt_lmac_channel) - sizeof(struct upgt_lmac_header));
-
- chan->header2.reqid = htole32(sc->sc_memaddr_frame_start);
- chan->header2.type = htole16(UPGT_H2_TYPE_CHANNEL);
- chan->header2.flags = 0;
-
- chan->unknown1 = htole16(UPGT_CHANNEL_UNKNOWN1);
- chan->unknown2 = htole16(UPGT_CHANNEL_UNKNOWN2);
- chan->freq6 = sc->sc_eeprom_freq6[channel];
- chan->settings = sc->sc_eeprom_freq6_settings;
- chan->unknown3 = UPGT_CHANNEL_UNKNOWN3;
-
- bcopy(&sc->sc_eeprom_freq3[channel].data, chan->freq3_1,
- sizeof(chan->freq3_1));
- bcopy(&sc->sc_eeprom_freq4[channel], chan->freq4,
- sizeof(sc->sc_eeprom_freq4[channel]));
- bcopy(&sc->sc_eeprom_freq3[channel].data, chan->freq3_2,
- sizeof(chan->freq3_2));
-
- len = sizeof(*mem) + sizeof(*chan);
-
- mem->chksum = upgt_chksum_le((uint32_t *)chan,
- len - sizeof(*mem));
-
- if (upgt_bulk_xmit(sc, data_cmd, sc->sc_tx_pipeh, &len, 0) != 0)
- device_printf(sc->sc_dev,
- "could not transmit channel CMD data URB!\n");
-}
-
-static struct ieee80211vap *
-upgt_vap_create(struct ieee80211com *ic,
- const char name[IFNAMSIZ], int unit, int opmode, int flags,
- const uint8_t bssid[IEEE80211_ADDR_LEN],
- const uint8_t mac[IEEE80211_ADDR_LEN])
-{
- struct upgt_vap *uvp;
- struct ieee80211vap *vap;
-
- if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */
- return NULL;
- uvp = (struct upgt_vap *) malloc(sizeof(struct upgt_vap),
- M_80211_VAP, M_NOWAIT | M_ZERO);
- if (uvp == NULL)
- return NULL;
- vap = &uvp->vap;
- /* enable s/w bmiss handling for sta mode */
- ieee80211_vap_setup(ic, vap, name, unit, opmode,
- flags | IEEE80211_CLONE_NOBEACONS, bssid, mac);
-
- /* override state transition machine */
- uvp->newstate = vap->iv_newstate;
- vap->iv_newstate = upgt_newstate;
-
- /* setup device rates */
- upgt_setup_rates(vap, ic);
-
- /* complete setup */
- ieee80211_vap_attach(vap, ieee80211_media_change,
- ieee80211_media_status);
- ic->ic_opmode = opmode;
- return vap;
-}
-
-static int
-upgt_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
-{
- struct upgt_vap *uvp = UPGT_VAP(vap);
- struct ieee80211com *ic = vap->iv_ic;
- struct upgt_softc *sc = ic->ic_ifp->if_softc;
-
- usb_rem_task(sc->sc_udev, &sc->sc_task);
-
- /* do it in a process context */
- sc->sc_state = nstate;
- sc->sc_arg = arg;
-
- if (nstate == IEEE80211_S_INIT) {
- uvp->newstate(vap, nstate, arg);
- return 0;
- } else {
- usb_add_task(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER);
- return EINPROGRESS;
- }
-}
-
-static void
-upgt_vap_delete(struct ieee80211vap *vap)
-{
- struct upgt_vap *uvp = UPGT_VAP(vap);
-
- ieee80211_vap_detach(vap);
- free(uvp, M_80211_VAP);
-}
-
-static void
-upgt_update_mcast(struct ifnet *ifp)
-{
- struct upgt_softc *sc = ifp->if_softc;
-
- usb_add_task(sc->sc_udev, &sc->sc_mcasttask, USB_TASKQ_DRIVER);
-}
-
-static int
-upgt_eeprom_parse(struct upgt_softc *sc)
-{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct upgt_eeprom_header *eeprom_header;
- struct upgt_eeprom_option *eeprom_option;
- uint16_t option_len;
- uint16_t option_type;
- uint16_t preamble_len;
- int option_end = 0;
-
- /* calculate eeprom options start offset */
- eeprom_header = (struct upgt_eeprom_header *)sc->sc_eeprom;
- preamble_len = le16toh(eeprom_header->preamble_len);
- eeprom_option = (struct upgt_eeprom_option *)(sc->sc_eeprom +
- (sizeof(struct upgt_eeprom_header) + preamble_len));
-
- while (!option_end) {
- /* the eeprom option length is stored in words */
- option_len =
- (le16toh(eeprom_option->len) - 1) * sizeof(uint16_t);
- option_type =
- le16toh(eeprom_option->type);
-
- switch (option_type) {
- case UPGT_EEPROM_TYPE_NAME:
- DPRINTF(sc, UPGT_DEBUG_FW,
- "EEPROM name len=%d\n", option_len);
- break;
- case UPGT_EEPROM_TYPE_SERIAL:
- DPRINTF(sc, UPGT_DEBUG_FW,
- "EEPROM serial len=%d\n", option_len);
- break;
- case UPGT_EEPROM_TYPE_MAC:
- DPRINTF(sc, UPGT_DEBUG_FW,
- "EEPROM mac len=%d\n", option_len);
-
- IEEE80211_ADDR_COPY(ic->ic_myaddr, eeprom_option->data);
- break;
- case UPGT_EEPROM_TYPE_HWRX:
- DPRINTF(sc, UPGT_DEBUG_FW,
- "EEPROM hwrx len=%d\n", option_len);
-
- upgt_eeprom_parse_hwrx(sc, eeprom_option->data);
- break;
- case UPGT_EEPROM_TYPE_CHIP:
- DPRINTF(sc, UPGT_DEBUG_FW,
- "EEPROM chip len=%d\n", option_len);
- break;
- case UPGT_EEPROM_TYPE_FREQ3:
- DPRINTF(sc, UPGT_DEBUG_FW,
- "EEPROM freq3 len=%d\n", option_len);
-
- upgt_eeprom_parse_freq3(sc, eeprom_option->data,
- option_len);
- break;
- case UPGT_EEPROM_TYPE_FREQ4:
- DPRINTF(sc, UPGT_DEBUG_FW,
- "EEPROM freq4 len=%d\n", option_len);
-
- upgt_eeprom_parse_freq4(sc, eeprom_option->data,
- option_len);
- break;
- case UPGT_EEPROM_TYPE_FREQ5:
- DPRINTF(sc, UPGT_DEBUG_FW,
- "EEPROM freq5 len=%d\n", option_len);
- break;
- case UPGT_EEPROM_TYPE_FREQ6:
- DPRINTF(sc, UPGT_DEBUG_FW,
- "EEPROM freq6 len=%d\n", option_len);
-
- upgt_eeprom_parse_freq6(sc, eeprom_option->data,
- option_len);
- break;
- case UPGT_EEPROM_TYPE_END:
- DPRINTF(sc, UPGT_DEBUG_FW,
- "EEPROM end len=%d\n", option_len);
- option_end = 1;
- break;
- case UPGT_EEPROM_TYPE_OFF:
- DPRINTF(sc, UPGT_DEBUG_FW,
- "%s: EEPROM off without end option!\n", __func__);
- return (EIO);
- default:
- DPRINTF(sc, UPGT_DEBUG_FW,
- "EEPROM unknown type 0x%04x len=%d\n",
- option_type, option_len);
- break;
- }
-
- /* jump to next EEPROM option */
- eeprom_option = (struct upgt_eeprom_option *)
- (eeprom_option->data + option_len);
- }
-
- return (0);
-}
-
-static void
-upgt_eeprom_parse_freq3(struct upgt_softc *sc, uint8_t *data, int len)
-{
- struct upgt_eeprom_freq3_header *freq3_header;
- struct upgt_lmac_freq3 *freq3;
- int i, elements, flags;
- unsigned channel;
-
- freq3_header = (struct upgt_eeprom_freq3_header *)data;
- freq3 = (struct upgt_lmac_freq3 *)(freq3_header + 1);
-
- flags = freq3_header->flags;
- elements = freq3_header->elements;
-
- DPRINTF(sc, UPGT_DEBUG_FW, "flags=0x%02x elements=%d\n",
- flags, elements);
-
- for (i = 0; i < elements; i++) {
- channel = ieee80211_mhz2ieee(le16toh(freq3[i].freq), 0);
- if (!(channel >= 0 && channel < IEEE80211_CHAN_MAX))
- continue;
-
- sc->sc_eeprom_freq3[channel] = freq3[i];
-
- DPRINTF(sc, UPGT_DEBUG_FW, "frequence=%d, channel=%d\n",
- le16toh(sc->sc_eeprom_freq3[channel].freq), channel);
- }
-}
-
-void
-upgt_eeprom_parse_freq4(struct upgt_softc *sc, uint8_t *data, int len)
-{
- struct upgt_eeprom_freq4_header *freq4_header;
- struct upgt_eeprom_freq4_1 *freq4_1;
- struct upgt_eeprom_freq4_2 *freq4_2;
- int i, j, elements, settings, flags;
- unsigned channel;
-
- freq4_header = (struct upgt_eeprom_freq4_header *)data;
- freq4_1 = (struct upgt_eeprom_freq4_1 *)(freq4_header + 1);
- flags = freq4_header->flags;
- elements = freq4_header->elements;
- settings = freq4_header->settings;
-
- /* we need this value later */
- sc->sc_eeprom_freq6_settings = freq4_header->settings;
-
- DPRINTF(sc, UPGT_DEBUG_FW, "flags=0x%02x elements=%d settings=%d\n",
- flags, elements, settings);
-
- for (i = 0; i < elements; i++) {
- channel = ieee80211_mhz2ieee(le16toh(freq4_1[i].freq), 0);
- if (!(channel >= 0 && channel < IEEE80211_CHAN_MAX))
- continue;
-
- freq4_2 = (struct upgt_eeprom_freq4_2 *)freq4_1[i].data;
- for (j = 0; j < settings; j++) {
- sc->sc_eeprom_freq4[channel][j].cmd = freq4_2[j];
- sc->sc_eeprom_freq4[channel][j].pad = 0;
- }
-
- DPRINTF(sc, UPGT_DEBUG_FW, "frequence=%d, channel=%d\n",
- le16toh(freq4_1[i].freq), channel);
- }
-}
-
-void
-upgt_eeprom_parse_freq6(struct upgt_softc *sc, uint8_t *data, int len)
-{
- struct upgt_lmac_freq6 *freq6;
- int i, elements;
- unsigned channel;
-
- freq6 = (struct upgt_lmac_freq6 *)data;
- elements = len / sizeof(struct upgt_lmac_freq6);
-
- DPRINTF(sc, UPGT_DEBUG_FW, "elements=%d\n", elements);
-
- for (i = 0; i < elements; i++) {
- channel = ieee80211_mhz2ieee(le16toh(freq6[i].freq), 0);
- if (!(channel >= 0 && channel < IEEE80211_CHAN_MAX))
- continue;
-
- sc->sc_eeprom_freq6[channel] = freq6[i];
-
- DPRINTF(sc, UPGT_DEBUG_FW, "frequence=%d, channel=%d\n",
- le16toh(sc->sc_eeprom_freq6[channel].freq), channel);
- }
-}
-
-static void
-upgt_eeprom_parse_hwrx(struct upgt_softc *sc, uint8_t *data)
-{
- struct upgt_eeprom_option_hwrx *option_hwrx;
-
- option_hwrx = (struct upgt_eeprom_option_hwrx *)data;
-
- sc->sc_eeprom_hwrx = option_hwrx->rxfilter - UPGT_EEPROM_RX_CONST;
-
- DPRINTF(sc, UPGT_DEBUG_FW, "hwrx option value=0x%04x\n",
- sc->sc_eeprom_hwrx);
-}
-
-static int
-upgt_eeprom_read(struct upgt_softc *sc)
-{
- struct upgt_data *data_cmd = &sc->cmd_data;
- struct upgt_lmac_mem *mem;
- struct upgt_lmac_eeprom *eeprom;
- int offset, block, len;
-
- offset = 0;
- block = UPGT_EEPROM_BLOCK_SIZE;
- while (offset < UPGT_EEPROM_SIZE) {
- DPRINTF(sc, UPGT_DEBUG_FW,
- "request EEPROM block (offset=%d, len=%d)\n", offset, block);
-
- /*
- * Transmit the URB containing the CMD data.
- */
- bzero(data_cmd->buf, MCLBYTES);
-
- mem = (struct upgt_lmac_mem *)data_cmd->buf;
- mem->addr = htole32(sc->sc_memaddr_frame_start +
- UPGT_MEMSIZE_FRAME_HEAD);
-
- eeprom = (struct upgt_lmac_eeprom *)(mem + 1);
- eeprom->header1.flags = 0;
- eeprom->header1.type = UPGT_H1_TYPE_CTRL;
- eeprom->header1.len = htole16((
- sizeof(struct upgt_lmac_eeprom) -
- sizeof(struct upgt_lmac_header)) + block);
-
- eeprom->header2.reqid = htole32(sc->sc_memaddr_frame_start);
- eeprom->header2.type = htole16(UPGT_H2_TYPE_EEPROM);
- eeprom->header2.flags = 0;
-
- eeprom->offset = htole16(offset);
- eeprom->len = htole16(block);
-
- len = sizeof(*mem) + sizeof(*eeprom) + block;
-
- mem->chksum = upgt_chksum_le((uint32_t *)eeprom,
- len - sizeof(*mem));
-
- if (upgt_bulk_xmit(sc, data_cmd, sc->sc_tx_pipeh, &len,
- USBD_FORCE_SHORT_XFER) != 0) {
- device_printf(sc->sc_dev,
- "could not transmit EEPROM data URB!\n");
- return (EIO);
- }
- if (tsleep(sc, 0, "eeprom_request", UPGT_USB_TIMEOUT)) {
- device_printf(sc->sc_dev,
- "timeout while waiting for EEPROM data!\n");
- return (EIO);
- }
-
- offset += block;
- if (UPGT_EEPROM_SIZE - offset < block)
- block = UPGT_EEPROM_SIZE - offset;
- }
-
- return (0);
-}
-
-/*
- * The firmware awaits a checksum for each frame we send to it.
- * The algorithm used therefor is uncommon but somehow similar to CRC32.
- */
-static uint32_t
-upgt_chksum_le(const uint32_t *buf, size_t size)
-{
- int i;
- uint32_t crc = 0;
-
- for (i = 0; i < size; i += sizeof(uint32_t)) {
- crc = htole32(crc ^ *buf++);
- crc = htole32((crc >> 5) ^ (crc << 3));
- }
-
- return (crc);
-}
-
-static void
-upgt_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- struct upgt_data *data_rx = priv;
- struct upgt_softc *sc = data_rx->sc;
- int len;
- struct upgt_lmac_header *header;
- struct upgt_lmac_eeprom *eeprom;
- uint8_t h1_type;
- uint16_t h2_type;
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
- return;
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall_async(sc->sc_rx_pipeh);
- goto skip;
- }
- usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL);
-
- /*
- * Check what type of frame came in.
- */
- header = (struct upgt_lmac_header *)(data_rx->buf + 4);
-
- h1_type = header->header1.type;
- h2_type = le16toh(header->header2.type);
-
- if (h1_type == UPGT_H1_TYPE_CTRL && h2_type == UPGT_H2_TYPE_EEPROM) {
- eeprom = (struct upgt_lmac_eeprom *)(data_rx->buf + 4);
- uint16_t eeprom_offset = le16toh(eeprom->offset);
- uint16_t eeprom_len = le16toh(eeprom->len);
-
- DPRINTF(sc, UPGT_DEBUG_FW,
- "received EEPROM block (offset=%d, len=%d)\n",
- eeprom_offset, eeprom_len);
-
- bcopy(data_rx->buf + sizeof(struct upgt_lmac_eeprom) + 4,
- sc->sc_eeprom + eeprom_offset, eeprom_len);
-
- /* EEPROM data has arrived in time, wakeup tsleep() */
- wakeup(sc);
- } else if (h1_type == UPGT_H1_TYPE_CTRL &&
- h2_type == UPGT_H2_TYPE_TX_DONE) {
- DPRINTF(sc, UPGT_DEBUG_XMIT, "%s: received 802.11 TX done\n",
- __func__);
- upgt_tx_done(sc, data_rx->buf + 4);
- } else if (h1_type == UPGT_H1_TYPE_RX_DATA ||
- h1_type == UPGT_H1_TYPE_RX_DATA_MGMT) {
- DPRINTF(sc, UPGT_DEBUG_RECV, "%s: received 802.11 RX data\n",
- __func__);
- upgt_rx(sc, data_rx->buf + 4, le16toh(header->header1.len));
- } else if (h1_type == UPGT_H1_TYPE_CTRL &&
- h2_type == UPGT_H2_TYPE_STATS) {
- DPRINTF(sc, UPGT_DEBUG_STAT, "%s: received statistic data\n",
- __func__);
- /* TODO: what could we do with the statistic data? */
- } else {
- /* ignore unknown frame types */
- DPRINTF(sc, UPGT_DEBUG_INTR,
- "received unknown frame type 0x%02x\n",
- header->header1.type);
- }
-
-skip: /* setup new transfer */
- usbd_setup_xfer(xfer, sc->sc_rx_pipeh, data_rx, data_rx->buf, MCLBYTES,
- USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, upgt_rxeof);
- (void)usbd_transfer(xfer);
-}
-
-static void
-upgt_rx(struct upgt_softc *sc, uint8_t *data, int pkglen)
-{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct upgt_lmac_rx_desc *rxdesc;
- struct ieee80211_node *ni;
- struct mbuf *m;
- int nf;
-
- /*
- * don't pass packets to the ieee80211 framework if the driver isn't
- * RUNNING.
- */
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
- return;
-
- /* access RX packet descriptor */
- rxdesc = (struct upgt_lmac_rx_desc *)data;
-
- /* create mbuf which is suitable for strict alignment archs */
- KASSERT((pkglen + ETHER_ALIGN) < MCLBYTES,
- ("A current mbuf storage is small (%d)", pkglen + ETHER_ALIGN));
- m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
- if (m == NULL) {
- device_printf(sc->sc_dev, "could not create RX mbuf!\n");
- return;
- }
- m_adj(m, ETHER_ALIGN);
- bcopy(rxdesc->data, mtod(m, char *), pkglen);
- /* trim FCS */
- m->m_len = m->m_pkthdr.len = pkglen - IEEE80211_CRC_LEN;
- m->m_pkthdr.rcvif = ifp;
-
- if (bpf_peers_present(ifp->if_bpf)) {
- struct upgt_rx_radiotap_header *tap = &sc->sc_rxtap;
-
- tap->wr_flags = 0;
- tap->wr_rate = upgt_rx_rate(sc, rxdesc->rate);
- tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
- tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
- tap->wr_antsignal = rxdesc->rssi;
-
- bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m);
- }
- ifp->if_ipackets++;
-
- nf = -95; /* XXX */
- ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *));
- if (ni != NULL) {
- (void)ieee80211_input(ni, m, rxdesc->rssi, nf, 0);
- ieee80211_free_node(ni);
- } else
- (void)ieee80211_input_all(ic, m, rxdesc->rssi, nf, 0);
-
- DPRINTF(sc, UPGT_DEBUG_RX_PROC, "%s: RX done\n", __func__);
-}
-
-static uint8_t
-upgt_rx_rate(struct upgt_softc *sc, const int rate)
-{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- static const uint8_t cck_upgt2rate[4] = { 2, 4, 11, 22 };
- static const uint8_t ofdm_upgt2rate[12] =
- { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 };
-
- if (ic->ic_curmode == IEEE80211_MODE_11B &&
- !(rate < 0 || rate > 3))
- return cck_upgt2rate[rate & 0xf];
-
- if (ic->ic_curmode == IEEE80211_MODE_11G &&
- !(rate < 0 || rate > 11))
- return ofdm_upgt2rate[rate & 0xf];
-
- return (0);
-}
-
-static void
-upgt_tx_done(struct upgt_softc *sc, uint8_t *data)
-{
- struct ifnet *ifp = sc->sc_ifp;
- struct upgt_lmac_tx_done_desc *desc;
- int i;
-
- desc = (struct upgt_lmac_tx_done_desc *)data;
-
- UPGT_LOCK(sc);
- for (i = 0; i < upgt_txbuf; i++) {
- struct upgt_data *data_tx = &sc->tx_data[i];
-
- if (data_tx->addr == le32toh(desc->header2.reqid)) {
- upgt_mem_free(sc, data_tx->addr);
- ieee80211_free_node(data_tx->ni);
- data_tx->ni = NULL;
- data_tx->addr = 0;
- data_tx->m = NULL;
- data_tx->use = 0;
-
- sc->tx_queued--;
- ifp->if_opackets++;
-
- DPRINTF(sc, UPGT_DEBUG_TX_PROC,
- "TX done: memaddr=0x%08x, status=0x%04x, rssi=%d, ",
- le32toh(desc->header2.reqid),
- le16toh(desc->status), le16toh(desc->rssi));
- DPRINTF(sc, UPGT_DEBUG_TX_PROC, "seq=%d\n",
- le16toh(desc->seq));
- break;
- }
- }
- if (sc->tx_queued == 0) {
- /* TX queued was processed, continue */
- sc->sc_tx_timer = 0;
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- UPGT_UNLOCK(sc);
- upgt_start(ifp);
- return;
- }
- UPGT_UNLOCK(sc);
-}
-
-static void
-upgt_mem_free(struct upgt_softc *sc, uint32_t addr)
-{
- int i;
-
- for (i = 0; i < sc->sc_memory.pages; i++) {
- if (sc->sc_memory.page[i].addr == addr) {
- sc->sc_memory.page[i].used = 0;
- return;
- }
- }
-
- device_printf(sc->sc_dev,
- "could not free memory address 0x%08x!\n", addr);
-}
-
-static int
-upgt_fw_load(struct upgt_softc *sc)
-{
- const struct firmware *fw;
- struct upgt_data *data_cmd = &sc->cmd_data;
- struct upgt_data *data_rx = &sc->rx_data;
- struct upgt_fw_x2_header *x2;
- char start_fwload_cmd[] = { 0x3c, 0x0d };
- int error = 0, offset, bsize, n, i, len;
- uint32_t crc32;
-
- fw = firmware_get(upgt_fwname);
- if (fw == NULL) {
- device_printf(sc->sc_dev, "could not read microcode %s!\n",
- upgt_fwname);
- return EIO;
- }
-
- /* send firmware start load command */
- len = sizeof(start_fwload_cmd);
- bcopy(start_fwload_cmd, data_cmd->buf, len);
- if (upgt_bulk_xmit(sc, data_cmd, sc->sc_tx_pipeh, &len, 0) != 0) {
- device_printf(sc->sc_dev,
- "could not send start_firmware_load command!\n");
- error = EIO;
- goto fail;
- }
-
- /* send X2 header */
- len = sizeof(struct upgt_fw_x2_header);
- x2 = (struct upgt_fw_x2_header *)data_cmd->buf;
- bcopy(UPGT_X2_SIGNATURE, x2->signature, UPGT_X2_SIGNATURE_SIZE);
- x2->startaddr = htole32(UPGT_MEMADDR_FIRMWARE_START);
- x2->len = htole32(fw->datasize);
- x2->crc = upgt_crc32_le((uint8_t *)data_cmd->buf +
- UPGT_X2_SIGNATURE_SIZE,
- sizeof(struct upgt_fw_x2_header) - UPGT_X2_SIGNATURE_SIZE -
- sizeof(uint32_t));
- if (upgt_bulk_xmit(sc, data_cmd, sc->sc_tx_pipeh, &len, 0) != 0) {
- device_printf(sc->sc_dev,
- "could not send firmware X2 header!\n");
- error = EIO;
- goto fail;
- }
-
- /* download firmware */
- for (offset = 0; offset < fw->datasize; offset += bsize) {
- if (fw->datasize - offset > UPGT_FW_BLOCK_SIZE)
- bsize = UPGT_FW_BLOCK_SIZE;
- else
- bsize = fw->datasize - offset;
-
- n = upgt_fw_copy((const uint8_t *)fw->data + offset,
- data_cmd->buf, bsize);
-
- DPRINTF(sc, UPGT_DEBUG_FW, "FW offset=%d, read=%d, sent=%d\n",
- offset, n, bsize);
-
- if (upgt_bulk_xmit(sc, data_cmd, sc->sc_tx_pipeh, &bsize, 0)
- != 0) {
- device_printf(sc->sc_dev,
- "error while downloading firmware block!\n");
- error = EIO;
- goto fail;
- }
-
- bsize = n;
- }
- DPRINTF(sc, UPGT_DEBUG_FW, "%s: firmware downloaded\n", __func__);
-
- /* load firmware */
- crc32 = upgt_crc32_le(fw->data, fw->datasize);
- *((uint32_t *)(data_cmd->buf) ) = crc32;
- *((uint8_t *)(data_cmd->buf) + 4) = 'g';
- *((uint8_t *)(data_cmd->buf) + 5) = '\r';
- len = 6;
- if (upgt_bulk_xmit(sc, data_cmd, sc->sc_tx_pipeh, &len, 0) != 0) {
- device_printf(sc->sc_dev,
- "could not send load_firmware command!\n");
- error = EIO;
- goto fail;
- }
-
- for (i = 0; i < UPGT_FIRMWARE_TIMEOUT; i++) {
- len = UPGT_FW_BLOCK_SIZE;
- bzero(data_rx->buf, MCLBYTES);
- if (upgt_bulk_xmit(sc, data_rx, sc->sc_rx_pipeh, &len,
- USBD_SHORT_XFER_OK) != 0) {
- device_printf(sc->sc_dev,
- "could not read firmware response!\n");
- error = EIO;
- goto fail;
- }
-
- if (memcmp(data_rx->buf, "OK", 2) == 0)
- break; /* firmware load was successful */
- }
- if (i == UPGT_FIRMWARE_TIMEOUT) {
- device_printf(sc->sc_dev, "firmware load failed!\n");
- error = EIO;
- }
-
- DPRINTF(sc, UPGT_DEBUG_FW, "%s: firmware loaded\n", __func__);
-fail:
- firmware_put(fw, FIRMWARE_UNLOAD);
- return (error);
-}
-
-static uint32_t
-upgt_crc32_le(const void *buf, size_t size)
-{
- uint32_t crc;
-
- crc = ether_crc32_le(buf, size);
-
- /* apply final XOR value as common for CRC-32 */
- crc = htole32(crc ^ 0xffffffffU);
-
- return (crc);
-}
-
-/*
- * While copying the version 2 firmware, we need to replace two characters:
- *
- * 0x7e -> 0x7d 0x5e
- * 0x7d -> 0x7d 0x5d
- */
-static int
-upgt_fw_copy(const uint8_t *src, char *dst, int size)
-{
- int i, j;
-
- for (i = 0, j = 0; i < size && j < size; i++) {
- switch (src[i]) {
- case 0x7e:
- dst[j] = 0x7d;
- j++;
- dst[j] = 0x5e;
- j++;
- break;
- case 0x7d:
- dst[j] = 0x7d;
- j++;
- dst[j] = 0x5d;
- j++;
- break;
- default:
- dst[j] = src[i];
- j++;
- break;
- }
- }
-
- return (i);
-}
-
-static int
-upgt_mem_init(struct upgt_softc *sc)
-{
- int i;
-
- for (i = 0; i < UPGT_MEMORY_MAX_PAGES; i++) {
- sc->sc_memory.page[i].used = 0;
-
- if (i == 0) {
- /*
- * The first memory page is always reserved for
- * command data.
- */
- sc->sc_memory.page[i].addr =
- sc->sc_memaddr_frame_start + MCLBYTES;
- } else {
- sc->sc_memory.page[i].addr =
- sc->sc_memory.page[i - 1].addr + MCLBYTES;
- }
-
- if (sc->sc_memory.page[i].addr + MCLBYTES >=
- sc->sc_memaddr_frame_end)
- break;
-
- DPRINTF(sc, UPGT_DEBUG_FW, "memory address page %d=0x%08x\n",
- i, sc->sc_memory.page[i].addr);
- }
-
- sc->sc_memory.pages = i;
- if (upgt_txbuf > sc->sc_memory.pages)
-
- DPRINTF(sc, UPGT_DEBUG_FW, "memory pages=%d\n", sc->sc_memory.pages);
- return (0);
-}
-
-static int
-upgt_fw_verify(struct upgt_softc *sc)
-{
- const struct firmware *fw;
- const struct upgt_fw_bra_option *bra_opt;
- const struct upgt_fw_bra_descr *descr;
- const uint8_t *p;
- const uint32_t *uc;
- uint32_t bra_option_type, bra_option_len;
- int offset, bra_end = 0, error = 0;
-
- fw = firmware_get(upgt_fwname);
- if (fw == NULL) {
- device_printf(sc->sc_dev, "could not read microcode %s!\n",
- upgt_fwname);
- return EIO;
- }
-
- /*
- * Seek to beginning of Boot Record Area (BRA).
- */
- for (offset = 0; offset < fw->datasize; offset += sizeof(*uc)) {
- uc = (const uint32_t *)((const uint8_t *)fw->data + offset);
- if (*uc == 0)
- break;
- }
- for (; offset < fw->datasize; offset += sizeof(*uc)) {
- uc = (const uint32_t *)((const uint8_t *)fw->data + offset);
- if (*uc != 0)
- break;
- }
- if (offset == fw->datasize) {
- device_printf(sc->sc_dev,
- "firmware Boot Record Area not found!\n");
- error = EIO;
- goto fail;
- }
-
- DPRINTF(sc, UPGT_DEBUG_FW,
- "firmware Boot Record Area found at offset %d\n", offset);
-
- /*
- * Parse Boot Record Area (BRA) options.
- */
- while (offset < fw->datasize && bra_end == 0) {
- /* get current BRA option */
- p = (const uint8_t *)fw->data + offset;
- bra_opt = (const struct upgt_fw_bra_option *)p;
- bra_option_type = le32toh(bra_opt->type);
- bra_option_len = le32toh(bra_opt->len) * sizeof(*uc);
-
- switch (bra_option_type) {
- case UPGT_BRA_TYPE_FW:
- DPRINTF(sc, UPGT_DEBUG_FW, "UPGT_BRA_TYPE_FW len=%d\n",
- bra_option_len);
-
- if (bra_option_len != UPGT_BRA_FWTYPE_SIZE) {
- device_printf(sc->sc_dev,
- "wrong UPGT_BRA_TYPE_FW len!\n");
- error = EIO;
- goto fail;
- }
- if (memcmp(UPGT_BRA_FWTYPE_LM86, bra_opt->data,
- bra_option_len) == 0) {
- sc->sc_fw_type = UPGT_FWTYPE_LM86;
- break;
- }
- if (memcmp(UPGT_BRA_FWTYPE_LM87, bra_opt->data,
- bra_option_len) == 0) {
- sc->sc_fw_type = UPGT_FWTYPE_LM87;
- break;
- }
- device_printf(sc->sc_dev,
- "unsupported firmware type!\n");
- error = EIO;
- goto fail;
- case UPGT_BRA_TYPE_VERSION:
- DPRINTF(sc, UPGT_DEBUG_FW,
- "UPGT_BRA_TYPE_VERSION len=%d\n", bra_option_len);
- break;
- case UPGT_BRA_TYPE_DEPIF:
- DPRINTF(sc, UPGT_DEBUG_FW,
- "UPGT_BRA_TYPE_DEPIF len=%d\n", bra_option_len);
- break;
- case UPGT_BRA_TYPE_EXPIF:
- DPRINTF(sc, UPGT_DEBUG_FW,
- "UPGT_BRA_TYPE_EXPIF len=%d\n", bra_option_len);
- break;
- case UPGT_BRA_TYPE_DESCR:
- DPRINTF(sc, UPGT_DEBUG_FW,
- "UPGT_BRA_TYPE_DESCR len=%d\n", bra_option_len);
-
- descr = (const struct upgt_fw_bra_descr *)bra_opt->data;
-
- sc->sc_memaddr_frame_start =
- le32toh(descr->memaddr_space_start);
- sc->sc_memaddr_frame_end =
- le32toh(descr->memaddr_space_end);
-
- DPRINTF(sc, UPGT_DEBUG_FW,
- "memory address space start=0x%08x\n",
- sc->sc_memaddr_frame_start);
- DPRINTF(sc, UPGT_DEBUG_FW,
- "memory address space end=0x%08x\n",
- sc->sc_memaddr_frame_end);
- break;
- case UPGT_BRA_TYPE_END:
- DPRINTF(sc, UPGT_DEBUG_FW, "UPGT_BRA_TYPE_END len=%d\n",
- bra_option_len);
- bra_end = 1;
- break;
- default:
- DPRINTF(sc, UPGT_DEBUG_FW, "unknown BRA option len=%d\n",
- bra_option_len);
- error = EIO;
- goto fail;
- }
-
- /* jump to next BRA option */
- offset += sizeof(struct upgt_fw_bra_option) + bra_option_len;
- }
-
- DPRINTF(sc, UPGT_DEBUG_FW, "%s: firmware verified", __func__);
-fail:
- firmware_put(fw, FIRMWARE_UNLOAD);
- return (error);
-}
-
-static int
-upgt_bulk_xmit(struct upgt_softc *sc, struct upgt_data *data,
- usbd_pipe_handle pipeh, uint32_t *size, int flags)
-{
- usbd_status status;
-
- mtx_lock(&Giant);
- status = usbd_bulk_transfer(data->xfer, pipeh,
- USBD_NO_COPY | flags, UPGT_USB_TIMEOUT, data->buf, size,
- "upgt_bulk_xmit");
- if (status != USBD_NORMAL_COMPLETION) {
- device_printf(sc->sc_dev, "%s: error %s!\n",
- __func__, usbd_errstr(status));
- mtx_unlock(&Giant);
- return (EIO);
- }
- mtx_unlock(&Giant);
-
- return (0);
-}
-
-static int
-upgt_device_reset(struct upgt_softc *sc)
-{
- struct upgt_data *data_cmd = &sc->cmd_data;
- char init_cmd[] = { 0x7e, 0x7e, 0x7e, 0x7e };
- int len;
-
- len = sizeof(init_cmd);
- bcopy(init_cmd, data_cmd->buf, len);
- if (upgt_bulk_xmit(sc, data_cmd, sc->sc_tx_pipeh, &len, 0) != 0) {
- device_printf(sc->sc_dev,
- "could not send device init string!\n");
- return (EIO);
- }
- usbd_delay_ms(sc->sc_udev, 100);
-
- DPRINTF(sc, UPGT_DEBUG_FW, "%s: device initialized\n", __func__);
- return (0);
-}
-
-static int
-upgt_alloc_tx(struct upgt_softc *sc)
-{
- int i;
-
- sc->tx_queued = 0;
-
- for (i = 0; i < upgt_txbuf; i++) {
- struct upgt_data *data_tx = &sc->tx_data[i];
-
- data_tx->sc = sc;
- data_tx->xfer = usbd_alloc_xfer(sc->sc_udev);
- if (data_tx->xfer == NULL) {
- device_printf(sc->sc_dev,
- "could not allocate TX xfer!\n");
- return (ENOMEM);
- }
-
- data_tx->buf = usbd_alloc_buffer(data_tx->xfer, MCLBYTES);
- if (data_tx->buf == NULL) {
- device_printf(sc->sc_dev,
- "could not allocate TX buffer!\n");
- return (ENOMEM);
- }
-
- bzero(data_tx->buf, MCLBYTES);
- }
-
- return (0);
-}
-
-static int
-upgt_alloc_rx(struct upgt_softc *sc)
-{
- struct upgt_data *data_rx = &sc->rx_data;
-
- data_rx->sc = sc;
- data_rx->xfer = usbd_alloc_xfer(sc->sc_udev);
- if (data_rx->xfer == NULL) {
- device_printf(sc->sc_dev, "could not allocate RX xfer!\n");
- return (ENOMEM);
- }
-
- data_rx->buf = usbd_alloc_buffer(data_rx->xfer, MCLBYTES);
- if (data_rx->buf == NULL) {
- device_printf(sc->sc_dev, "could not allocate RX buffer!\n");
- return (ENOMEM);
- }
-
- bzero(data_rx->buf, MCLBYTES);
-
- return (0);
-}
-
-static int
-upgt_alloc_cmd(struct upgt_softc *sc)
-{
- struct upgt_data *data_cmd = &sc->cmd_data;
-
- data_cmd->sc = sc;
- data_cmd->xfer = usbd_alloc_xfer(sc->sc_udev);
- if (data_cmd->xfer == NULL) {
- device_printf(sc->sc_dev, "could not allocate RX xfer!\n");
- return (ENOMEM);
- }
-
- data_cmd->buf = usbd_alloc_buffer(data_cmd->xfer, MCLBYTES);
- if (data_cmd->buf == NULL) {
- device_printf(sc->sc_dev, "could not allocate RX buffer!\n");
- return (ENOMEM);
- }
-
- bzero(data_cmd->buf, MCLBYTES);
-
- return (0);
-}
-
-static int
-upgt_detach(device_t dev)
-{
- struct upgt_softc *sc = device_get_softc(dev);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
-
- if (!device_is_attached(dev))
- return 0;
-
- upgt_stop(sc, 1);
-
- /* abort and close TX / RX pipes */
- if (sc->sc_tx_pipeh != NULL)
- usbd_close_pipe(sc->sc_tx_pipeh);
- if (sc->sc_rx_pipeh != NULL)
- usbd_close_pipe(sc->sc_rx_pipeh);
-
- mtx_destroy(&sc->sc_mtx);
- usb_rem_task(sc->sc_udev, &sc->sc_mcasttask);
- usb_rem_task(sc->sc_udev, &sc->sc_scantask);
- usb_rem_task(sc->sc_udev, &sc->sc_task);
- usb_rem_task(sc->sc_udev, &sc->sc_task_tx);
- callout_stop(&sc->sc_led_ch);
- callout_stop(&sc->sc_watchdog_ch);
-
- /* free xfers */
- upgt_free_tx(sc);
- upgt_free_rx(sc);
- upgt_free_cmd(sc);
-
- bpfdetach(ifp);
- ieee80211_ifdetach(ic);
- if_free(ifp);
-
- usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev);
-
- return 0;
-}
-
-static void
-upgt_free_rx(struct upgt_softc *sc)
-{
- struct upgt_data *data_rx = &sc->rx_data;
-
- if (data_rx->xfer != NULL) {
- usbd_free_xfer(data_rx->xfer);
- data_rx->xfer = NULL;
- }
-
- data_rx->ni = NULL;
-}
-
-static void
-upgt_free_tx(struct upgt_softc *sc)
-{
- int i;
-
- for (i = 0; i < upgt_txbuf; i++) {
- struct upgt_data *data_tx = &sc->tx_data[i];
-
- if (data_tx->xfer != NULL) {
- usbd_free_xfer(data_tx->xfer);
- data_tx->xfer = NULL;
- }
-
- data_tx->ni = NULL;
- }
-}
-
-static void
-upgt_free_cmd(struct upgt_softc *sc)
-{
- struct upgt_data *data_cmd = &sc->cmd_data;
-
- if (data_cmd->xfer != NULL) {
- usbd_free_xfer(data_cmd->xfer);
- data_cmd->xfer = NULL;
- }
-}
-
-static device_method_t upgt_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, upgt_match),
- DEVMETHOD(device_attach, upgt_attach),
- DEVMETHOD(device_detach, upgt_detach),
-
- { 0, 0 }
-};
-
-static driver_t upgt_driver = {
- "upgt",
- upgt_methods,
- sizeof(struct upgt_softc)
-};
-
-static devclass_t upgt_devclass;
-
-DRIVER_MODULE(if_upgt, uhub, upgt_driver, upgt_devclass, usbd_driver_load, 0);
-MODULE_VERSION(if_upgt, 1);
-MODULE_DEPEND(if_upgt, usb, 1, 1, 1);
-MODULE_DEPEND(if_upgt, wlan, 1, 1, 1);
-MODULE_DEPEND(if_upgt, upgtfw_fw, 1, 1, 1);
diff --git a/sys/dev/usb/if_upgtvar.h b/sys/dev/usb/if_upgtvar.h
deleted file mode 100644
index 298fb63..0000000
--- a/sys/dev/usb/if_upgtvar.h
+++ /dev/null
@@ -1,462 +0,0 @@
-/* $OpenBSD: if_upgtvar.h,v 1.14 2008/02/02 13:48:44 mglocker Exp $ */
-/* $FreeBSD$ */
-
-/*
- * Copyright (c) 2007 Marcus Glocker <mglocker@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-struct upgt_softc;
-
-/*
- * General values.
- */
-#define UPGT_IFACE_INDEX 0
-#define UPGT_CONFIG_NO 1
-#define UPGT_USB_TIMEOUT 1000
-#define UPGT_FIRMWARE_TIMEOUT 10
-
-#define UPGT_MEMADDR_FIRMWARE_START 0x00020000 /* 512 bytes large */
-#define UPGT_MEMSIZE_FRAME_HEAD 0x0070
-#define UPGT_MEMSIZE_RX 0x3500
-
-#define UPGT_TX_COUNT 2
-
-/* device flags */
-#define UPGT_DEVICE_ATTACHED (1 << 0)
-
-/* leds */
-#define UPGT_LED_OFF 0
-#define UPGT_LED_ON 1
-#define UPGT_LED_BLINK 2
-
-/*
- * Firmware.
- */
-#define UPGT_FW_BLOCK_SIZE 512
-
-#define UPGT_BRA_FWTYPE_SIZE 4
-#define UPGT_BRA_FWTYPE_LM86 "LM86"
-#define UPGT_BRA_FWTYPE_LM87 "LM87"
-enum upgt_fw_type {
- UPGT_FWTYPE_LM86,
- UPGT_FWTYPE_LM87
-};
-
-#define UPGT_BRA_TYPE_FW 0x80000001
-#define UPGT_BRA_TYPE_VERSION 0x80000002
-#define UPGT_BRA_TYPE_DEPIF 0x80000003
-#define UPGT_BRA_TYPE_EXPIF 0x80000004
-#define UPGT_BRA_TYPE_DESCR 0x80000101
-#define UPGT_BRA_TYPE_END 0xff0000ff
-struct upgt_fw_bra_option {
- uint32_t type;
- uint32_t len;
- uint8_t data[];
-} __packed;
-
-struct upgt_fw_bra_descr {
- uint32_t unknown1;
- uint32_t memaddr_space_start;
- uint32_t memaddr_space_end;
- uint32_t unknown2;
- uint32_t unknown3;
- uint8_t rates[20];
-} __packed;
-
-#define UPGT_X2_SIGNATURE_SIZE 4
-#define UPGT_X2_SIGNATURE "x2 "
-struct upgt_fw_x2_header {
- uint8_t signature[4];
- uint32_t startaddr;
- uint32_t len;
- uint32_t crc;
-} __packed;
-
-/*
- * EEPROM.
- */
-#define UPGT_EEPROM_SIZE 8192
-#define UPGT_EEPROM_BLOCK_SIZE 1020
-
-struct upgt_eeprom_header {
- /* 14 bytes */
- uint32_t magic;
- uint16_t pad1;
- uint16_t preamble_len;
- uint32_t pad2;
- /* data */
-} __packed;
-
-#define UPGT_EEPROM_TYPE_END 0x0000
-#define UPGT_EEPROM_TYPE_NAME 0x0001
-#define UPGT_EEPROM_TYPE_SERIAL 0x0003
-#define UPGT_EEPROM_TYPE_MAC 0x0101
-#define UPGT_EEPROM_TYPE_HWRX 0x1001
-#define UPGT_EEPROM_TYPE_CHIP 0x1002
-#define UPGT_EEPROM_TYPE_FREQ3 0x1903
-#define UPGT_EEPROM_TYPE_FREQ4 0x1904
-#define UPGT_EEPROM_TYPE_FREQ5 0x1905
-#define UPGT_EEPROM_TYPE_FREQ6 0x1906
-#define UPGT_EEPROM_TYPE_OFF 0xffff
-struct upgt_eeprom_option {
- uint16_t len;
- uint16_t type;
- uint8_t data[];
- /* data */
-} __packed;
-
-#define UPGT_EEPROM_RX_CONST 0x88
-struct upgt_eeprom_option_hwrx {
- uint32_t pad1;
- uint8_t rxfilter;
- uint8_t pad2[15];
-} __packed;
-
-struct upgt_eeprom_freq3_header {
- uint8_t flags;
- uint8_t elements;
-} __packed;
-
-struct upgt_eeprom_freq4_header {
- uint8_t flags;
- uint8_t elements;
- uint8_t settings;
- uint8_t type;
-} __packed;
-
-struct upgt_eeprom_freq4_1 {
- uint16_t freq;
- uint8_t data[50];
-} __packed;
-
-struct upgt_eeprom_freq4_2 {
- uint16_t head;
- uint8_t subtails[4];
- uint8_t tail;
-} __packed;
-
-/*
- * LMAC protocol.
- */
-struct upgt_lmac_mem {
- uint32_t addr;
- uint32_t chksum;
-} __packed;
-
-#define UPGT_H1_FLAGS_TX_MGMT 0x00 /* for TX: mgmt frame */
-#define UPGT_H1_FLAGS_TX_NO_CALLBACK 0x01 /* for TX: no USB callback */
-#define UPGT_H1_FLAGS_TX_DATA 0x10 /* for TX: data frame */
-#define UPGT_H1_TYPE_RX_DATA 0x00 /* 802.11 RX data frame */
-#define UPGT_H1_TYPE_RX_DATA_MGMT 0x04 /* 802.11 RX mgmt frame */
-#define UPGT_H1_TYPE_TX_DATA 0x40 /* 802.11 TX data frame */
-#define UPGT_H1_TYPE_CTRL 0x80 /* control frame */
-struct upgt_lmac_h1 {
- /* 4 bytes */
- uint8_t flags;
- uint8_t type;
- uint16_t len;
-} __packed;
-
-#define UPGT_H2_TYPE_TX_ACK_NO 0x0000
-#define UPGT_H2_TYPE_TX_ACK_YES 0x0001
-#define UPGT_H2_TYPE_MACFILTER 0x0000
-#define UPGT_H2_TYPE_CHANNEL 0x0001
-#define UPGT_H2_TYPE_TX_DONE 0x0008
-#define UPGT_H2_TYPE_STATS 0x000a
-#define UPGT_H2_TYPE_EEPROM 0x000c
-#define UPGT_H2_TYPE_LED 0x000d
-#define UPGT_H2_FLAGS_TX_ACK_NO 0x0101
-#define UPGT_H2_FLAGS_TX_ACK_YES 0x0707
-struct upgt_lmac_h2 {
- /* 8 bytes */
- uint32_t reqid;
- uint16_t type;
- uint16_t flags;
-} __packed;
-
-struct upgt_lmac_header {
- /* 12 bytes */
- struct upgt_lmac_h1 header1;
- struct upgt_lmac_h2 header2;
-} __packed;
-
-struct upgt_lmac_eeprom {
- /* 16 bytes */
- struct upgt_lmac_h1 header1;
- struct upgt_lmac_h2 header2;
- uint16_t offset;
- uint16_t len;
- /* data */
-} __packed;
-
-#define UPGT_FILTER_TYPE_NONE 0x0000
-#define UPGT_FILTER_TYPE_STA 0x0001
-#define UPGT_FILTER_TYPE_IBSS 0x0002
-#define UPGT_FILTER_TYPE_HOSTAP 0x0004
-#define UPGT_FILTER_TYPE_MONITOR 0x0010
-#define UPGT_FILTER_TYPE_RESET 0x0020
-#define UPGT_FILTER_UNKNOWN1 0x0002
-#define UPGT_FILTER_UNKNOWN2 0x0ca8
-#define UPGT_FILTER_UNKNOWN3 0xffff
-#define UPGT_FILTER_MONITOR_UNKNOWN1 0x0000
-#define UPGT_FILTER_MONITOR_UNKNOWN2 0x0000
-#define UPGT_FILTER_MONITOR_UNKNOWN3 0x0000
-struct upgt_lmac_filter {
- struct upgt_lmac_h1 header1;
- struct upgt_lmac_h2 header2;
- /* 32 bytes */
- uint16_t type;
- uint8_t dst[IEEE80211_ADDR_LEN];
- uint8_t src[IEEE80211_ADDR_LEN];
- uint16_t unknown1;
- uint32_t rxaddr;
- uint16_t unknown2;
- uint32_t rxhw;
- uint16_t unknown3;
- uint32_t unknown4;
-} __packed;
-
-/* frequence 3 data */
-struct upgt_lmac_freq3 {
- uint16_t freq;
- uint8_t data[6];
-} __packed;
-
-/* frequence 4 data */
-struct upgt_lmac_freq4 {
- struct upgt_eeprom_freq4_2 cmd;
- uint8_t pad;
-};
-
-/* frequence 6 data */
-struct upgt_lmac_freq6 {
- uint16_t freq;
- uint8_t data[8];
-} __packed;
-
-#define UPGT_CHANNEL_UNKNOWN1 0x0001
-#define UPGT_CHANNEL_UNKNOWN2 0x0000
-#define UPGT_CHANNEL_UNKNOWN3 0x48
-struct upgt_lmac_channel {
- struct upgt_lmac_h1 header1;
- struct upgt_lmac_h2 header2;
- /* 112 bytes */
- uint16_t unknown1;
- uint16_t unknown2;
- uint8_t pad1[20];
- struct upgt_lmac_freq6 freq6;
- uint8_t settings;
- uint8_t unknown3;
- uint8_t freq3_1[4];
- struct upgt_lmac_freq4 freq4[8];
- uint8_t freq3_2[4];
- uint32_t pad2;
-} __packed;
-
-#define UPGT_LED_MODE_SET 0x0003
-#define UPGT_LED_ACTION_OFF 0x0002
-#define UPGT_LED_ACTION_ON 0x0003
-#define UPGT_LED_ACTION_TMP_DUR 100 /* ms */
-struct upgt_lmac_led {
- struct upgt_lmac_h1 header1;
- struct upgt_lmac_h2 header2;
- uint16_t mode;
- uint16_t action_fix;
- uint16_t action_tmp;
- uint16_t action_tmp_dur;
-} __packed;
-
-struct upgt_lmac_stats {
- struct upgt_lmac_h1 header1;
- struct upgt_lmac_h2 header2;
- uint8_t data[76];
-} __packed;
-
-struct upgt_lmac_rx_desc {
- struct upgt_lmac_h1 header1;
- /* 16 bytes */
- uint16_t freq;
- uint8_t unknown1;
- uint8_t rate;
- uint8_t rssi;
- uint8_t pad;
- uint16_t unknown2;
- uint32_t timestamp;
- uint32_t unknown3;
- uint8_t data[];
-} __packed;
-
-#define UPGT_TX_DESC_KEY_EXISTS 0x01
-struct upgt_lmac_tx_desc_wep {
- uint8_t key_exists;
- uint8_t key_len;
- uint8_t key_val[16];
-} __packed;
-
-#define UPGT_TX_DESC_TYPE_BEACON 0x00000000
-#define UPGT_TX_DESC_TYPE_PROBE 0x00000001
-#define UPGT_TX_DESC_TYPE_MGMT 0x00000002
-#define UPGT_TX_DESC_TYPE_DATA 0x00000004
-#define UPGT_TX_DESC_PAD3_SIZE 2
-struct upgt_lmac_tx_desc {
- struct upgt_lmac_h1 header1;
- struct upgt_lmac_h2 header2;
- uint8_t rates[8];
- uint16_t pad1;
- struct upgt_lmac_tx_desc_wep wep_key;
- uint32_t type;
- uint32_t pad2;
- uint32_t unknown1;
- uint32_t unknown2;
- uint8_t pad3[2];
- /* 802.11 frame data */
-} __packed;
-
-#define UPGT_TX_DONE_DESC_STATUS_OK 0x0001
-struct upgt_lmac_tx_done_desc {
- struct upgt_lmac_h1 header1;
- struct upgt_lmac_h2 header2;
- uint16_t status;
- uint16_t rssi;
- uint16_t seq;
- uint16_t unknown;
-} __packed;
-
-/*
- * USB xfers.
- */
-struct upgt_data {
- struct upgt_softc *sc;
- usbd_xfer_handle xfer;
- uint8_t *buf;
- struct ieee80211_node *ni;
- struct mbuf *m;
- uint32_t addr;
- uint8_t use;
-};
-
-/*
- * Prism memory.
- */
-struct upgt_memory_page {
- uint8_t used;
- uint32_t addr;
-} __packed;
-
-#define UPGT_MEMORY_MAX_PAGES 8
-struct upgt_memory {
- uint8_t pages;
- struct upgt_memory_page page[UPGT_MEMORY_MAX_PAGES];
-} __packed;
-
-/*
- * BPF
- */
-struct upgt_rx_radiotap_header {
- struct ieee80211_radiotap_header wr_ihdr;
- uint8_t wr_flags;
- uint8_t wr_rate;
- uint16_t wr_chan_freq;
- uint16_t wr_chan_flags;
- int8_t wr_antsignal;
-} __packed;
-
-#define UPGT_RX_RADIOTAP_PRESENT \
- ((1 << IEEE80211_RADIOTAP_FLAGS) | \
- (1 << IEEE80211_RADIOTAP_RATE) | \
- (1 << IEEE80211_RADIOTAP_CHANNEL) | \
- (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL))
-
-struct upgt_tx_radiotap_header {
- struct ieee80211_radiotap_header wt_ihdr;
- uint8_t wt_flags;
- uint8_t wt_rate;
- uint16_t wt_chan_freq;
- uint16_t wt_chan_flags;
-} __packed;
-
-#define UPGT_TX_RADIOTAP_PRESENT \
- ((1 << IEEE80211_RADIOTAP_FLAGS) | \
- (1 << IEEE80211_RADIOTAP_RATE) | \
- (1 << IEEE80211_RADIOTAP_CHANNEL))
-
-struct upgt_vap {
- struct ieee80211vap vap;
- int (*newstate)(struct ieee80211vap *,
- enum ieee80211_state, int);
-};
-#define UPGT_VAP(vap) ((struct upgt_vap *)(vap))
-
-struct upgt_softc {
- device_t sc_dev;
- struct ifnet *sc_ifp;
- usbd_device_handle sc_udev;
- usbd_interface_handle sc_iface;
- struct mtx sc_mtx;
- int sc_if_flags;
- int sc_debug;
-
- struct usb_task sc_mcasttask;
- struct usb_task sc_task;
- struct usb_task sc_scantask;
-#define UPGT_SET_CHANNEL 2
- int sc_scan_action;
- enum ieee80211_state sc_state;
- int sc_arg;
- int sc_led_blink;
- struct callout sc_led_ch;
- uint8_t sc_cur_rateset[8];
-
- /* watchdog */
- int sc_tx_timer;
- struct callout sc_watchdog_ch;
-
- /* Firmware. */
- int sc_fw_type;
- /* memory addresses on device */
- uint32_t sc_memaddr_frame_start;
- uint32_t sc_memaddr_frame_end;
- uint32_t sc_memaddr_rx_start;
- struct upgt_memory sc_memory;
-
- /* data which we found in the EEPROM */
- uint8_t sc_eeprom[UPGT_EEPROM_SIZE];
- uint16_t sc_eeprom_hwrx;
- struct upgt_lmac_freq3 sc_eeprom_freq3[IEEE80211_CHAN_MAX];
- struct upgt_lmac_freq4 sc_eeprom_freq4[IEEE80211_CHAN_MAX][8];
- struct upgt_lmac_freq6 sc_eeprom_freq6[IEEE80211_CHAN_MAX];
- uint8_t sc_eeprom_freq6_settings;
-
- /* RX/TX */
- int sc_rx_no;
- int sc_tx_no;
- usbd_pipe_handle sc_rx_pipeh;
- usbd_pipe_handle sc_tx_pipeh;
- struct upgt_data tx_data[UPGT_TX_COUNT];
- struct upgt_data rx_data;
- struct upgt_data cmd_data;
- int tx_queued;
- struct usb_task sc_task_tx;
-
- /* BPF */
- struct upgt_rx_radiotap_header sc_rxtap;
- int sc_rxtap_len;
-
- struct upgt_tx_radiotap_header sc_txtap;
- int sc_txtap_len;
-};
-
-#define UPGT_LOCK(sc) mtx_lock(&(sc)->sc_mtx)
-#define UPGT_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx)
diff --git a/sys/dev/usb/if_ural.c b/sys/dev/usb/if_ural.c
deleted file mode 100644
index 4595761..0000000
--- a/sys/dev/usb/if_ural.c
+++ /dev/null
@@ -1,2505 +0,0 @@
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 2005, 2006
- * Damien Bergamini <damien.bergamini@free.fr>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*-
- * Ralink Technology RT2500USB chipset driver
- * http://www.ralinktech.com/
- */
-
-#include <sys/param.h>
-#include <sys/sysctl.h>
-#include <sys/sockio.h>
-#include <sys/mbuf.h>
-#include <sys/kernel.h>
-#include <sys/socket.h>
-#include <sys/systm.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/endian.h>
-
-#include <machine/bus.h>
-#include <machine/resource.h>
-#include <sys/rman.h>
-
-#include <net/bpf.h>
-#include <net/if.h>
-#include <net/if_arp.h>
-#include <net/ethernet.h>
-#include <net/if_dl.h>
-#include <net/if_media.h>
-#include <net/if_types.h>
-
-#include <net80211/ieee80211_var.h>
-#include <net80211/ieee80211_amrr.h>
-#include <net80211/ieee80211_phy.h>
-#include <net80211/ieee80211_radiotap.h>
-#include <net80211/ieee80211_regdomain.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include "usbdevs.h"
-
-#include <dev/usb/if_uralreg.h>
-#include <dev/usb/if_uralvar.h>
-
-#ifdef USB_DEBUG
-#define DPRINTF(x) do { if (uraldebug > 0) printf x; } while (0)
-#define DPRINTFN(n, x) do { if (uraldebug >= (n)) printf x; } while (0)
-int uraldebug = 0;
-SYSCTL_NODE(_hw_usb, OID_AUTO, ural, CTLFLAG_RW, 0, "USB ural");
-SYSCTL_INT(_hw_usb_ural, OID_AUTO, debug, CTLFLAG_RW, &uraldebug, 0,
- "ural debug level");
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n, x)
-#endif
-
-#define URAL_RSSI(rssi) \
- ((rssi) > (RAL_NOISE_FLOOR + RAL_RSSI_CORR) ? \
- ((rssi) - (RAL_NOISE_FLOOR + RAL_RSSI_CORR)) : 0)
-
-/* various supported device vendors/products */
-static const struct usb_devno ural_devs[] = {
- { USB_VENDOR_ASUS, USB_PRODUCT_ASUS_WL167G },
- { USB_VENDOR_ASUS, USB_PRODUCT_RALINK_RT2570 },
- { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D7050 },
- { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D7051 },
- { USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_C54RU },
- { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWLG122 },
- { USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNWBKG },
- { USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GN54G },
- { USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWGUSB254 },
- { USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSB54G },
- { USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSB54GP },
- { USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_HU200TS },
- { USB_VENDOR_MELCO, USB_PRODUCT_MELCO_KG54 },
- { USB_VENDOR_MELCO, USB_PRODUCT_MELCO_KG54AI },
- { USB_VENDOR_MELCO, USB_PRODUCT_MELCO_KG54YB },
- { USB_VENDOR_MELCO, USB_PRODUCT_MELCO_NINWIFI },
- { USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2570 },
- { USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2570_2 },
- { USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2570_3 },
- { USB_VENDOR_NOVATECH, USB_PRODUCT_NOVATECH_NV902 },
- { USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2570 },
- { USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2570_2 },
- { USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2570_3 },
- { USB_VENDOR_SIEMENS2, USB_PRODUCT_SIEMENS2_WL54G },
- { USB_VENDOR_SMC, USB_PRODUCT_SMC_2862WG },
- { USB_VENDOR_SPHAIRON, USB_PRODUCT_SPHAIRON_UB801R},
- { USB_VENDOR_SURECOM, USB_PRODUCT_SURECOM_RT2570 },
- { USB_VENDOR_VTECH, USB_PRODUCT_VTECH_RT2570 },
- { USB_VENDOR_ZINWELL, USB_PRODUCT_ZINWELL_RT2570 }
-};
-
-MODULE_DEPEND(ural, wlan, 1, 1, 1);
-MODULE_DEPEND(ural, wlan_amrr, 1, 1, 1);
-MODULE_DEPEND(ural, usb, 1, 1, 1);
-
-static struct ieee80211vap *ural_vap_create(struct ieee80211com *,
- const char name[IFNAMSIZ], int unit, int opmode,
- int flags, const uint8_t bssid[IEEE80211_ADDR_LEN],
- const uint8_t mac[IEEE80211_ADDR_LEN]);
-static void ural_vap_delete(struct ieee80211vap *);
-static int ural_alloc_tx_list(struct ural_softc *);
-static void ural_free_tx_list(struct ural_softc *);
-static int ural_alloc_rx_list(struct ural_softc *);
-static void ural_free_rx_list(struct ural_softc *);
-static void ural_task(void *);
-static void ural_scantask(void *);
-static int ural_newstate(struct ieee80211vap *,
- enum ieee80211_state, int);
-static void ural_txeof(usbd_xfer_handle, usbd_private_handle,
- usbd_status);
-static void ural_rxeof(usbd_xfer_handle, usbd_private_handle,
- usbd_status);
-static void ural_setup_tx_desc(struct ural_softc *,
- struct ural_tx_desc *, uint32_t, int, int);
-static int ural_tx_bcn(struct ural_softc *, struct mbuf *,
- struct ieee80211_node *);
-static int ural_tx_mgt(struct ural_softc *, struct mbuf *,
- struct ieee80211_node *);
-static int ural_tx_data(struct ural_softc *, struct mbuf *,
- struct ieee80211_node *);
-static void ural_start(struct ifnet *);
-static void ural_watchdog(void *);
-static int ural_ioctl(struct ifnet *, u_long, caddr_t);
-static void ural_set_testmode(struct ural_softc *);
-static void ural_eeprom_read(struct ural_softc *, uint16_t, void *,
- int);
-static uint16_t ural_read(struct ural_softc *, uint16_t);
-static void ural_read_multi(struct ural_softc *, uint16_t, void *,
- int);
-static void ural_write(struct ural_softc *, uint16_t, uint16_t);
-static void ural_write_multi(struct ural_softc *, uint16_t, void *,
- int) __unused;
-static void ural_bbp_write(struct ural_softc *, uint8_t, uint8_t);
-static uint8_t ural_bbp_read(struct ural_softc *, uint8_t);
-static void ural_rf_write(struct ural_softc *, uint8_t, uint32_t);
-static struct ieee80211_node *ural_node_alloc(struct ieee80211vap *,
- const uint8_t mac[IEEE80211_ADDR_LEN]);
-static void ural_newassoc(struct ieee80211_node *, int);
-static void ural_scan_start(struct ieee80211com *);
-static void ural_scan_end(struct ieee80211com *);
-static void ural_set_channel(struct ieee80211com *);
-static void ural_set_chan(struct ural_softc *,
- struct ieee80211_channel *);
-static void ural_disable_rf_tune(struct ural_softc *);
-static void ural_enable_tsf_sync(struct ural_softc *);
-static void ural_update_slot(struct ifnet *);
-static void ural_set_txpreamble(struct ural_softc *);
-static void ural_set_basicrates(struct ural_softc *,
- const struct ieee80211_channel *);
-static void ural_set_bssid(struct ural_softc *, const uint8_t *);
-static void ural_set_macaddr(struct ural_softc *, uint8_t *);
-static void ural_update_promisc(struct ural_softc *);
-static const char *ural_get_rf(int);
-static void ural_read_eeprom(struct ural_softc *);
-static int ural_bbp_init(struct ural_softc *);
-static void ural_set_txantenna(struct ural_softc *, int);
-static void ural_set_rxantenna(struct ural_softc *, int);
-static void ural_init_locked(struct ural_softc *);
-static void ural_init(void *);
-static void ural_stop(void *);
-static int ural_raw_xmit(struct ieee80211_node *, struct mbuf *,
- const struct ieee80211_bpf_params *);
-static void ural_amrr_start(struct ural_softc *,
- struct ieee80211_node *);
-static void ural_amrr_timeout(void *);
-static void ural_amrr_update(usbd_xfer_handle, usbd_private_handle,
- usbd_status status);
-
-/*
- * Default values for MAC registers; values taken from the reference driver.
- */
-static const struct {
- uint16_t reg;
- uint16_t val;
-} ural_def_mac[] = {
- { RAL_TXRX_CSR5, 0x8c8d },
- { RAL_TXRX_CSR6, 0x8b8a },
- { RAL_TXRX_CSR7, 0x8687 },
- { RAL_TXRX_CSR8, 0x0085 },
- { RAL_MAC_CSR13, 0x1111 },
- { RAL_MAC_CSR14, 0x1e11 },
- { RAL_TXRX_CSR21, 0xe78f },
- { RAL_MAC_CSR9, 0xff1d },
- { RAL_MAC_CSR11, 0x0002 },
- { RAL_MAC_CSR22, 0x0053 },
- { RAL_MAC_CSR15, 0x0000 },
- { RAL_MAC_CSR8, 0x0780 },
- { RAL_TXRX_CSR19, 0x0000 },
- { RAL_TXRX_CSR18, 0x005a },
- { RAL_PHY_CSR2, 0x0000 },
- { RAL_TXRX_CSR0, 0x1ec0 },
- { RAL_PHY_CSR4, 0x000f }
-};
-
-/*
- * Default values for BBP registers; values taken from the reference driver.
- */
-static const struct {
- uint8_t reg;
- uint8_t val;
-} ural_def_bbp[] = {
- { 3, 0x02 },
- { 4, 0x19 },
- { 14, 0x1c },
- { 15, 0x30 },
- { 16, 0xac },
- { 17, 0x48 },
- { 18, 0x18 },
- { 19, 0xff },
- { 20, 0x1e },
- { 21, 0x08 },
- { 22, 0x08 },
- { 23, 0x08 },
- { 24, 0x80 },
- { 25, 0x50 },
- { 26, 0x08 },
- { 27, 0x23 },
- { 30, 0x10 },
- { 31, 0x2b },
- { 32, 0xb9 },
- { 34, 0x12 },
- { 35, 0x50 },
- { 39, 0xc4 },
- { 40, 0x02 },
- { 41, 0x60 },
- { 53, 0x10 },
- { 54, 0x18 },
- { 56, 0x08 },
- { 57, 0x10 },
- { 58, 0x08 },
- { 61, 0x60 },
- { 62, 0x10 },
- { 75, 0xff }
-};
-
-/*
- * Default values for RF register R2 indexed by channel numbers.
- */
-static const uint32_t ural_rf2522_r2[] = {
- 0x307f6, 0x307fb, 0x30800, 0x30805, 0x3080a, 0x3080f, 0x30814,
- 0x30819, 0x3081e, 0x30823, 0x30828, 0x3082d, 0x30832, 0x3083e
-};
-
-static const uint32_t ural_rf2523_r2[] = {
- 0x00327, 0x00328, 0x00329, 0x0032a, 0x0032b, 0x0032c, 0x0032d,
- 0x0032e, 0x0032f, 0x00340, 0x00341, 0x00342, 0x00343, 0x00346
-};
-
-static const uint32_t ural_rf2524_r2[] = {
- 0x00327, 0x00328, 0x00329, 0x0032a, 0x0032b, 0x0032c, 0x0032d,
- 0x0032e, 0x0032f, 0x00340, 0x00341, 0x00342, 0x00343, 0x00346
-};
-
-static const uint32_t ural_rf2525_r2[] = {
- 0x20327, 0x20328, 0x20329, 0x2032a, 0x2032b, 0x2032c, 0x2032d,
- 0x2032e, 0x2032f, 0x20340, 0x20341, 0x20342, 0x20343, 0x20346
-};
-
-static const uint32_t ural_rf2525_hi_r2[] = {
- 0x2032f, 0x20340, 0x20341, 0x20342, 0x20343, 0x20344, 0x20345,
- 0x20346, 0x20347, 0x20348, 0x20349, 0x2034a, 0x2034b, 0x2034e
-};
-
-static const uint32_t ural_rf2525e_r2[] = {
- 0x2044d, 0x2044e, 0x2044f, 0x20460, 0x20461, 0x20462, 0x20463,
- 0x20464, 0x20465, 0x20466, 0x20467, 0x20468, 0x20469, 0x2046b
-};
-
-static const uint32_t ural_rf2526_hi_r2[] = {
- 0x0022a, 0x0022b, 0x0022b, 0x0022c, 0x0022c, 0x0022d, 0x0022d,
- 0x0022e, 0x0022e, 0x0022f, 0x0022d, 0x00240, 0x00240, 0x00241
-};
-
-static const uint32_t ural_rf2526_r2[] = {
- 0x00226, 0x00227, 0x00227, 0x00228, 0x00228, 0x00229, 0x00229,
- 0x0022a, 0x0022a, 0x0022b, 0x0022b, 0x0022c, 0x0022c, 0x0022d
-};
-
-/*
- * For dual-band RF, RF registers R1 and R4 also depend on channel number;
- * values taken from the reference driver.
- */
-static const struct {
- uint8_t chan;
- uint32_t r1;
- uint32_t r2;
- uint32_t r4;
-} ural_rf5222[] = {
- { 1, 0x08808, 0x0044d, 0x00282 },
- { 2, 0x08808, 0x0044e, 0x00282 },
- { 3, 0x08808, 0x0044f, 0x00282 },
- { 4, 0x08808, 0x00460, 0x00282 },
- { 5, 0x08808, 0x00461, 0x00282 },
- { 6, 0x08808, 0x00462, 0x00282 },
- { 7, 0x08808, 0x00463, 0x00282 },
- { 8, 0x08808, 0x00464, 0x00282 },
- { 9, 0x08808, 0x00465, 0x00282 },
- { 10, 0x08808, 0x00466, 0x00282 },
- { 11, 0x08808, 0x00467, 0x00282 },
- { 12, 0x08808, 0x00468, 0x00282 },
- { 13, 0x08808, 0x00469, 0x00282 },
- { 14, 0x08808, 0x0046b, 0x00286 },
-
- { 36, 0x08804, 0x06225, 0x00287 },
- { 40, 0x08804, 0x06226, 0x00287 },
- { 44, 0x08804, 0x06227, 0x00287 },
- { 48, 0x08804, 0x06228, 0x00287 },
- { 52, 0x08804, 0x06229, 0x00287 },
- { 56, 0x08804, 0x0622a, 0x00287 },
- { 60, 0x08804, 0x0622b, 0x00287 },
- { 64, 0x08804, 0x0622c, 0x00287 },
-
- { 100, 0x08804, 0x02200, 0x00283 },
- { 104, 0x08804, 0x02201, 0x00283 },
- { 108, 0x08804, 0x02202, 0x00283 },
- { 112, 0x08804, 0x02203, 0x00283 },
- { 116, 0x08804, 0x02204, 0x00283 },
- { 120, 0x08804, 0x02205, 0x00283 },
- { 124, 0x08804, 0x02206, 0x00283 },
- { 128, 0x08804, 0x02207, 0x00283 },
- { 132, 0x08804, 0x02208, 0x00283 },
- { 136, 0x08804, 0x02209, 0x00283 },
- { 140, 0x08804, 0x0220a, 0x00283 },
-
- { 149, 0x08808, 0x02429, 0x00281 },
- { 153, 0x08808, 0x0242b, 0x00281 },
- { 157, 0x08808, 0x0242d, 0x00281 },
- { 161, 0x08808, 0x0242f, 0x00281 }
-};
-
-static device_probe_t ural_match;
-static device_attach_t ural_attach;
-static device_detach_t ural_detach;
-
-static device_method_t ural_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, ural_match),
- DEVMETHOD(device_attach, ural_attach),
- DEVMETHOD(device_detach, ural_detach),
-
- { 0, 0 }
-};
-
-static driver_t ural_driver = {
- "ural",
- ural_methods,
- sizeof(struct ural_softc)
-};
-
-static devclass_t ural_devclass;
-
-DRIVER_MODULE(ural, uhub, ural_driver, ural_devclass, usbd_driver_load, 0);
-
-static int
-ural_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
-
- if (uaa->iface != NULL)
- return UMATCH_NONE;
-
- return (usb_lookup(ural_devs, uaa->vendor, uaa->product) != NULL) ?
- UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
-}
-
-static int
-ural_attach(device_t self)
-{
- struct ural_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- struct ifnet *ifp;
- struct ieee80211com *ic;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
- usbd_status error;
- int i;
- uint8_t bands;
-
- sc->sc_udev = uaa->device;
- sc->sc_dev = self;
-
- if (usbd_set_config_no(sc->sc_udev, RAL_CONFIG_NO, 0) != 0) {
- device_printf(self, "could not set configuration no\n");
- return ENXIO;
- }
-
- /* get the first interface handle */
- error = usbd_device2interface_handle(sc->sc_udev, RAL_IFACE_INDEX,
- &sc->sc_iface);
- if (error != 0) {
- device_printf(self, "could not get interface handle\n");
- return ENXIO;
- }
-
- /*
- * Find endpoints.
- */
- id = usbd_get_interface_descriptor(sc->sc_iface);
-
- sc->sc_rx_no = sc->sc_tx_no = -1;
- for (i = 0; i < id->bNumEndpoints; i++) {
- ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
- if (ed == NULL) {
- device_printf(self, "no endpoint descriptor for %d\n",
- i);
- return ENXIO;
- }
-
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
- sc->sc_rx_no = ed->bEndpointAddress;
- else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
- sc->sc_tx_no = ed->bEndpointAddress;
- }
- if (sc->sc_rx_no == -1 || sc->sc_tx_no == -1) {
- device_printf(self, "missing endpoint\n");
- return ENXIO;
- }
-
- ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
- if (ifp == NULL) {
- device_printf(sc->sc_dev, "can not if_alloc()\n");
- return ENXIO;
- }
- ic = ifp->if_l2com;
-
- mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev), MTX_NETWORK_LOCK,
- MTX_DEF | MTX_RECURSE);
-
- usb_init_task(&sc->sc_task, ural_task, sc);
- usb_init_task(&sc->sc_scantask, ural_scantask, sc);
- callout_init(&sc->watchdog_ch, 0);
-
- /* retrieve RT2570 rev. no */
- sc->asic_rev = ural_read(sc, RAL_MAC_CSR0);
-
- /* retrieve MAC address and various other things from EEPROM */
- ural_read_eeprom(sc);
-
- device_printf(sc->sc_dev, "MAC/BBP RT2570 (rev 0x%02x), RF %s\n",
- sc->asic_rev, ural_get_rf(sc->rf_rev));
-
- ifp->if_softc = sc;
- if_initname(ifp, "ural", device_get_unit(sc->sc_dev));
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
- IFF_NEEDSGIANT; /* USB stack is still under Giant lock */
- ifp->if_init = ural_init;
- ifp->if_ioctl = ural_ioctl;
- ifp->if_start = ural_start;
- IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
- ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
- IFQ_SET_READY(&ifp->if_snd);
-
- ic->ic_ifp = ifp;
- ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
-
- /* set device capabilities */
- ic->ic_caps =
- IEEE80211_C_STA /* station mode supported */
- | IEEE80211_C_IBSS /* IBSS mode supported */
- | IEEE80211_C_MONITOR /* monitor mode supported */
- | IEEE80211_C_HOSTAP /* HostAp mode supported */
- | IEEE80211_C_TXPMGT /* tx power management */
- | IEEE80211_C_SHPREAMBLE /* short preamble supported */
- | IEEE80211_C_SHSLOT /* short slot time supported */
- | IEEE80211_C_BGSCAN /* bg scanning supported */
- | IEEE80211_C_WPA /* 802.11i */
- ;
-
- bands = 0;
- setbit(&bands, IEEE80211_MODE_11B);
- setbit(&bands, IEEE80211_MODE_11G);
- if (sc->rf_rev == RAL_RF_5222)
- setbit(&bands, IEEE80211_MODE_11A);
- ieee80211_init_channels(ic, NULL, &bands);
-
- ieee80211_ifattach(ic);
- ic->ic_newassoc = ural_newassoc;
- ic->ic_raw_xmit = ural_raw_xmit;
- ic->ic_node_alloc = ural_node_alloc;
- ic->ic_scan_start = ural_scan_start;
- ic->ic_scan_end = ural_scan_end;
- ic->ic_set_channel = ural_set_channel;
-
- ic->ic_vap_create = ural_vap_create;
- ic->ic_vap_delete = ural_vap_delete;
-
- sc->sc_rates = ieee80211_get_ratetable(ic->ic_curchan);
-
- bpfattach(ifp, DLT_IEEE802_11_RADIO,
- sizeof (struct ieee80211_frame) + sizeof(sc->sc_txtap));
-
- sc->sc_rxtap_len = sizeof sc->sc_rxtap;
- sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
- sc->sc_rxtap.wr_ihdr.it_present = htole32(RAL_RX_RADIOTAP_PRESENT);
-
- sc->sc_txtap_len = sizeof sc->sc_txtap;
- sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
- sc->sc_txtap.wt_ihdr.it_present = htole32(RAL_TX_RADIOTAP_PRESENT);
-
- if (bootverbose)
- ieee80211_announce(ic);
-
- return 0;
-}
-
-static int
-ural_detach(device_t self)
-{
- struct ural_softc *sc = device_get_softc(self);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
-
- ural_stop(sc);
- bpfdetach(ifp);
- ieee80211_ifdetach(ic);
-
- usb_rem_task(sc->sc_udev, &sc->sc_task);
- usb_rem_task(sc->sc_udev, &sc->sc_scantask);
- callout_stop(&sc->watchdog_ch);
-
- if (sc->amrr_xfer != NULL) {
- usbd_free_xfer(sc->amrr_xfer);
- sc->amrr_xfer = NULL;
- }
-
- if (sc->sc_rx_pipeh != NULL) {
- usbd_abort_pipe(sc->sc_rx_pipeh);
- usbd_close_pipe(sc->sc_rx_pipeh);
- }
-
- if (sc->sc_tx_pipeh != NULL) {
- usbd_abort_pipe(sc->sc_tx_pipeh);
- usbd_close_pipe(sc->sc_tx_pipeh);
- }
-
- ural_free_rx_list(sc);
- ural_free_tx_list(sc);
-
- if_free(ifp);
- mtx_destroy(&sc->sc_mtx);
-
- return 0;
-}
-
-static struct ieee80211vap *
-ural_vap_create(struct ieee80211com *ic,
- const char name[IFNAMSIZ], int unit, int opmode, int flags,
- const uint8_t bssid[IEEE80211_ADDR_LEN],
- const uint8_t mac[IEEE80211_ADDR_LEN])
-{
- struct ural_vap *uvp;
- struct ieee80211vap *vap;
-
- if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */
- return NULL;
- uvp = (struct ural_vap *) malloc(sizeof(struct ural_vap),
- M_80211_VAP, M_NOWAIT | M_ZERO);
- if (uvp == NULL)
- return NULL;
- vap = &uvp->vap;
- /* enable s/w bmiss handling for sta mode */
- ieee80211_vap_setup(ic, vap, name, unit, opmode,
- flags | IEEE80211_CLONE_NOBEACONS, bssid, mac);
-
- /* override state transition machine */
- uvp->newstate = vap->iv_newstate;
- vap->iv_newstate = ural_newstate;
-
- callout_init(&uvp->amrr_ch, 0);
- ieee80211_amrr_init(&uvp->amrr, vap,
- IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
- IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD,
- 1000 /* 1 sec */);
-
- /* complete setup */
- ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status);
- ic->ic_opmode = opmode;
- return vap;
-}
-
-static void
-ural_vap_delete(struct ieee80211vap *vap)
-{
- struct ural_vap *uvp = URAL_VAP(vap);
-
- callout_stop(&uvp->amrr_ch);
- ieee80211_amrr_cleanup(&uvp->amrr);
- ieee80211_vap_detach(vap);
- free(uvp, M_80211_VAP);
-}
-
-static int
-ural_alloc_tx_list(struct ural_softc *sc)
-{
- struct ural_tx_data *data;
- int i, error;
-
- sc->tx_queued = sc->tx_cur = 0;
-
- for (i = 0; i < RAL_TX_LIST_COUNT; i++) {
- data = &sc->tx_data[i];
-
- data->sc = sc;
-
- data->xfer = usbd_alloc_xfer(sc->sc_udev);
- if (data->xfer == NULL) {
- device_printf(sc->sc_dev,
- "could not allocate tx xfer\n");
- error = ENOMEM;
- goto fail;
- }
-
- data->buf = usbd_alloc_buffer(data->xfer,
- RAL_TX_DESC_SIZE + MCLBYTES);
- if (data->buf == NULL) {
- device_printf(sc->sc_dev,
- "could not allocate tx buffer\n");
- error = ENOMEM;
- goto fail;
- }
- }
-
- return 0;
-
-fail: ural_free_tx_list(sc);
- return error;
-}
-
-static void
-ural_free_tx_list(struct ural_softc *sc)
-{
- struct ural_tx_data *data;
- int i;
-
- for (i = 0; i < RAL_TX_LIST_COUNT; i++) {
- data = &sc->tx_data[i];
-
- if (data->xfer != NULL) {
- usbd_free_xfer(data->xfer);
- data->xfer = NULL;
- }
-
- if (data->ni != NULL) {
- ieee80211_free_node(data->ni);
- data->ni = NULL;
- }
- }
-}
-
-static int
-ural_alloc_rx_list(struct ural_softc *sc)
-{
- struct ural_rx_data *data;
- int i, error;
-
- for (i = 0; i < RAL_RX_LIST_COUNT; i++) {
- data = &sc->rx_data[i];
-
- data->sc = sc;
-
- data->xfer = usbd_alloc_xfer(sc->sc_udev);
- if (data->xfer == NULL) {
- device_printf(sc->sc_dev,
- "could not allocate rx xfer\n");
- error = ENOMEM;
- goto fail;
- }
-
- if (usbd_alloc_buffer(data->xfer, MCLBYTES) == NULL) {
- device_printf(sc->sc_dev,
- "could not allocate rx buffer\n");
- error = ENOMEM;
- goto fail;
- }
-
- data->m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
- if (data->m == NULL) {
- device_printf(sc->sc_dev,
- "could not allocate rx mbuf\n");
- error = ENOMEM;
- goto fail;
- }
-
- data->buf = mtod(data->m, uint8_t *);
- }
-
- return 0;
-
-fail: ural_free_rx_list(sc);
- return error;
-}
-
-static void
-ural_free_rx_list(struct ural_softc *sc)
-{
- struct ural_rx_data *data;
- int i;
-
- for (i = 0; i < RAL_RX_LIST_COUNT; i++) {
- data = &sc->rx_data[i];
-
- if (data->xfer != NULL) {
- usbd_free_xfer(data->xfer);
- data->xfer = NULL;
- }
-
- if (data->m != NULL) {
- m_freem(data->m);
- data->m = NULL;
- }
- }
-}
-
-static void
-ural_task(void *xarg)
-{
- struct ural_softc *sc = xarg;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
- struct ural_vap *uvp = URAL_VAP(vap);
- const struct ieee80211_txparam *tp;
- enum ieee80211_state ostate;
- struct ieee80211_node *ni;
- struct mbuf *m;
-
- ostate = vap->iv_state;
-
- RAL_LOCK(sc);
- switch (sc->sc_state) {
- case IEEE80211_S_INIT:
- if (ostate == IEEE80211_S_RUN) {
- /* abort TSF synchronization */
- ural_write(sc, RAL_TXRX_CSR19, 0);
-
- /* force tx led to stop blinking */
- ural_write(sc, RAL_MAC_CSR20, 0);
- }
- break;
-
- case IEEE80211_S_RUN:
- ni = vap->iv_bss;
-
- if (vap->iv_opmode != IEEE80211_M_MONITOR) {
- ural_update_slot(ic->ic_ifp);
- ural_set_txpreamble(sc);
- ural_set_basicrates(sc, ic->ic_bsschan);
- ural_set_bssid(sc, ni->ni_bssid);
- }
-
- if (vap->iv_opmode == IEEE80211_M_HOSTAP ||
- vap->iv_opmode == IEEE80211_M_IBSS) {
- m = ieee80211_beacon_alloc(ni, &uvp->bo);
- if (m == NULL) {
- device_printf(sc->sc_dev,
- "could not allocate beacon\n");
- return;
- }
-
- if (ural_tx_bcn(sc, m, ni) != 0) {
- device_printf(sc->sc_dev,
- "could not send beacon\n");
- return;
- }
- }
-
- /* make tx led blink on tx (controlled by ASIC) */
- ural_write(sc, RAL_MAC_CSR20, 1);
-
- if (vap->iv_opmode != IEEE80211_M_MONITOR)
- ural_enable_tsf_sync(sc);
-
- /* enable automatic rate adaptation */
- tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_bsschan)];
- if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE)
- ural_amrr_start(sc, ni);
-
- break;
-
- default:
- break;
- }
-
- RAL_UNLOCK(sc);
-
- IEEE80211_LOCK(ic);
- uvp->newstate(vap, sc->sc_state, sc->sc_arg);
- if (vap->iv_newstate_cb != NULL)
- vap->iv_newstate_cb(vap, sc->sc_state, sc->sc_arg);
- IEEE80211_UNLOCK(ic);
-}
-
-static void
-ural_scantask(void *arg)
-{
- struct ural_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
-
- RAL_LOCK(sc);
- if (sc->sc_scan_action == URAL_SCAN_START) {
- /* abort TSF synchronization */
- ural_write(sc, RAL_TXRX_CSR19, 0);
- ural_set_bssid(sc, ifp->if_broadcastaddr);
- } else if (sc->sc_scan_action == URAL_SET_CHANNEL) {
- mtx_lock(&Giant);
- ural_set_chan(sc, ic->ic_curchan);
- mtx_unlock(&Giant);
- } else {
- ural_enable_tsf_sync(sc);
- /* XXX keep local copy */
- ural_set_bssid(sc, vap->iv_bss->ni_bssid);
- }
- RAL_UNLOCK(sc);
-}
-
-static int
-ural_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
-{
- struct ural_vap *uvp = URAL_VAP(vap);
- struct ieee80211com *ic = vap->iv_ic;
- struct ural_softc *sc = ic->ic_ifp->if_softc;
-
- callout_stop(&uvp->amrr_ch);
-
- /* do it in a process context */
- sc->sc_state = nstate;
- sc->sc_arg = arg;
-
- usb_rem_task(sc->sc_udev, &sc->sc_task);
- if (nstate == IEEE80211_S_INIT) {
- uvp->newstate(vap, nstate, arg);
- return 0;
- } else {
- usb_add_task(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER);
- return EINPROGRESS;
- }
-}
-
-#define RAL_RXTX_TURNAROUND 5 /* us */
-
-static void
-ural_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- struct ural_tx_data *data = priv;
- struct ural_softc *sc = data->sc;
- struct ifnet *ifp = sc->sc_ifp;
-
- if (data->m->m_flags & M_TXCB)
- ieee80211_process_callback(data->ni, data->m,
- status == USBD_NORMAL_COMPLETION ? 0 : ETIMEDOUT);
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
- return;
-
- device_printf(sc->sc_dev, "could not transmit buffer: %s\n",
- usbd_errstr(status));
-
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall_async(sc->sc_rx_pipeh);
-
- ifp->if_oerrors++;
- /* XXX mbuf leak? */
- return;
- }
-
- m_freem(data->m);
- data->m = NULL;
- ieee80211_free_node(data->ni);
- data->ni = NULL;
-
- sc->tx_queued--;
- ifp->if_opackets++;
-
- DPRINTFN(10, ("tx done\n"));
-
- sc->sc_tx_timer = 0;
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- ural_start(ifp);
-}
-
-static void
-ural_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- struct ural_rx_data *data = priv;
- struct ural_softc *sc = data->sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ural_rx_desc *desc;
- struct ieee80211_node *ni;
- struct mbuf *mnew, *m;
- int len, rssi;
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
- return;
-
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall_async(sc->sc_rx_pipeh);
- goto skip;
- }
-
- usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL);
-
- if (len < RAL_RX_DESC_SIZE + IEEE80211_MIN_LEN) {
- DPRINTF(("%s: xfer too short %d\n", device_get_nameunit(sc->sc_dev),
- len));
- ifp->if_ierrors++;
- goto skip;
- }
-
- /* rx descriptor is located at the end */
- desc = (struct ural_rx_desc *)(data->buf + len - RAL_RX_DESC_SIZE);
-
- if ((le32toh(desc->flags) & RAL_RX_PHY_ERROR) ||
- (le32toh(desc->flags) & RAL_RX_CRC_ERROR)) {
- /*
- * This should not happen since we did not request to receive
- * those frames when we filled RAL_TXRX_CSR2.
- */
- DPRINTFN(5, ("PHY or CRC error\n"));
- ifp->if_ierrors++;
- goto skip;
- }
-
- mnew = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
- if (mnew == NULL) {
- ifp->if_ierrors++;
- goto skip;
- }
-
- m = data->m;
- data->m = mnew;
- data->buf = mtod(data->m, uint8_t *);
-
- /* finalize mbuf */
- m->m_pkthdr.rcvif = ifp;
- m->m_pkthdr.len = m->m_len = (le32toh(desc->flags) >> 16) & 0xfff;
-
- if (bpf_peers_present(ifp->if_bpf)) {
- struct ural_rx_radiotap_header *tap = &sc->sc_rxtap;
-
- tap->wr_flags = IEEE80211_RADIOTAP_F_FCS;
- tap->wr_rate = ieee80211_plcp2rate(desc->rate,
- (desc->flags & htole32(RAL_RX_OFDM)) ?
- IEEE80211_T_OFDM : IEEE80211_T_CCK);
- tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
- tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
- tap->wr_antenna = sc->rx_ant;
- tap->wr_antsignal = URAL_RSSI(desc->rssi);
-
- bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m);
- }
-
- /* Strip trailing 802.11 MAC FCS. */
- m_adj(m, -IEEE80211_CRC_LEN);
-
- rssi = URAL_RSSI(desc->rssi);
- ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *));
- if (ni != NULL) {
- (void) ieee80211_input(ni, m, rssi, RAL_NOISE_FLOOR, 0);
- ieee80211_free_node(ni);
- } else
- (void) ieee80211_input_all(ic, m, rssi, RAL_NOISE_FLOOR, 0);
-
- DPRINTFN(15, ("rx done\n"));
-
-skip: /* setup a new transfer */
- usbd_setup_xfer(xfer, sc->sc_rx_pipeh, data, data->buf, MCLBYTES,
- USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, ural_rxeof);
- usbd_transfer(xfer);
-}
-
-static uint8_t
-ural_plcp_signal(int rate)
-{
- switch (rate) {
- /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
- case 12: return 0xb;
- case 18: return 0xf;
- case 24: return 0xa;
- case 36: return 0xe;
- case 48: return 0x9;
- case 72: return 0xd;
- case 96: return 0x8;
- case 108: return 0xc;
-
- /* CCK rates (NB: not IEEE std, device-specific) */
- case 2: return 0x0;
- case 4: return 0x1;
- case 11: return 0x2;
- case 22: return 0x3;
- }
- return 0xff; /* XXX unsupported/unknown rate */
-}
-
-static void
-ural_setup_tx_desc(struct ural_softc *sc, struct ural_tx_desc *desc,
- uint32_t flags, int len, int rate)
-{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- uint16_t plcp_length;
- int remainder;
-
- desc->flags = htole32(flags);
- desc->flags |= htole32(RAL_TX_NEWSEQ);
- desc->flags |= htole32(len << 16);
-
- desc->wme = htole16(RAL_AIFSN(2) | RAL_LOGCWMIN(3) | RAL_LOGCWMAX(5));
- desc->wme |= htole16(RAL_IVOFFSET(sizeof (struct ieee80211_frame)));
-
- /* setup PLCP fields */
- desc->plcp_signal = ural_plcp_signal(rate);
- desc->plcp_service = 4;
-
- len += IEEE80211_CRC_LEN;
- if (ieee80211_rate2phytype(sc->sc_rates, rate) == IEEE80211_T_OFDM) {
- desc->flags |= htole32(RAL_TX_OFDM);
-
- plcp_length = len & 0xfff;
- desc->plcp_length_hi = plcp_length >> 6;
- desc->plcp_length_lo = plcp_length & 0x3f;
- } else {
- plcp_length = (16 * len + rate - 1) / rate;
- if (rate == 22) {
- remainder = (16 * len) % 22;
- if (remainder != 0 && remainder < 7)
- desc->plcp_service |= RAL_PLCP_LENGEXT;
- }
- desc->plcp_length_hi = plcp_length >> 8;
- desc->plcp_length_lo = plcp_length & 0xff;
-
- if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
- desc->plcp_signal |= 0x08;
- }
-
- desc->iv = 0;
- desc->eiv = 0;
-}
-
-#define RAL_TX_TIMEOUT 5000
-
-static int
-ural_tx_bcn(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
-{
- struct ieee80211vap *vap = ni->ni_vap;
- struct ieee80211com *ic = ni->ni_ic;
- const struct ieee80211_txparam *tp;
- struct ural_tx_desc *desc;
- usbd_xfer_handle xfer;
- uint8_t cmd;
- usbd_status error;
- uint8_t *buf;
- int xferlen;
-
- tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_bsschan)];
-
- xfer = usbd_alloc_xfer(sc->sc_udev);
- if (xfer == NULL)
- return ENOMEM;
-
- /* xfer length needs to be a multiple of two! */
- xferlen = (RAL_TX_DESC_SIZE + m0->m_pkthdr.len + 1) & ~1;
-
- buf = usbd_alloc_buffer(xfer, xferlen);
- if (buf == NULL) {
- usbd_free_xfer(xfer);
- return ENOMEM;
- }
-
- cmd = 0;
- usbd_setup_xfer(xfer, sc->sc_tx_pipeh, NULL, &cmd, sizeof cmd,
- USBD_FORCE_SHORT_XFER, RAL_TX_TIMEOUT, NULL);
-
- error = usbd_sync_transfer(xfer);
- if (error != 0) {
- usbd_free_xfer(xfer);
- return error;
- }
-
- desc = (struct ural_tx_desc *)buf;
-
- m_copydata(m0, 0, m0->m_pkthdr.len, buf + RAL_TX_DESC_SIZE);
- ural_setup_tx_desc(sc, desc, RAL_TX_IFS_NEWBACKOFF | RAL_TX_TIMESTAMP,
- m0->m_pkthdr.len, tp->mgmtrate);
-
- DPRINTFN(10, ("sending beacon frame len=%u rate=%u xfer len=%u\n",
- m0->m_pkthdr.len, tp->mgmtrate, xferlen));
-
- usbd_setup_xfer(xfer, sc->sc_tx_pipeh, NULL, buf, xferlen,
- USBD_FORCE_SHORT_XFER | USBD_NO_COPY, RAL_TX_TIMEOUT, NULL);
-
- error = usbd_sync_transfer(xfer);
- usbd_free_xfer(xfer);
-
- return error;
-}
-
-static int
-ural_tx_mgt(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
-{
- struct ieee80211vap *vap = ni->ni_vap;
- struct ieee80211com *ic = ni->ni_ic;
- struct ifnet *ifp = sc->sc_ifp;
- const struct ieee80211_txparam *tp;
- struct ural_tx_desc *desc;
- struct ural_tx_data *data;
- struct ieee80211_frame *wh;
- struct ieee80211_key *k;
- uint32_t flags;
- uint16_t dur;
- usbd_status error;
- int xferlen;
-
- data = &sc->tx_data[sc->tx_cur];
- desc = (struct ural_tx_desc *)data->buf;
-
- tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
-
- wh = mtod(m0, struct ieee80211_frame *);
- if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
- k = ieee80211_crypto_encap(ni, m0);
- if (k == NULL) {
- m_freem(m0);
- return ENOBUFS;
- }
- wh = mtod(m0, struct ieee80211_frame *);
- }
-
- data->m = m0;
- data->ni = ni;
-
- flags = 0;
- if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
- flags |= RAL_TX_ACK;
-
- dur = ieee80211_ack_duration(sc->sc_rates, tp->mgmtrate,
- ic->ic_flags & IEEE80211_F_SHPREAMBLE);
- *(uint16_t *)wh->i_dur = htole16(dur);
-
- /* tell hardware to add timestamp for probe responses */
- if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
- IEEE80211_FC0_TYPE_MGT &&
- (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) ==
- IEEE80211_FC0_SUBTYPE_PROBE_RESP)
- flags |= RAL_TX_TIMESTAMP;
- }
-
- if (bpf_peers_present(ifp->if_bpf)) {
- struct ural_tx_radiotap_header *tap = &sc->sc_txtap;
-
- tap->wt_flags = 0;
- tap->wt_rate = tp->mgmtrate;
- tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
- tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
- tap->wt_antenna = sc->tx_ant;
-
- bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0);
- }
-
- m_copydata(m0, 0, m0->m_pkthdr.len, data->buf + RAL_TX_DESC_SIZE);
- ural_setup_tx_desc(sc, desc, flags, m0->m_pkthdr.len, tp->mgmtrate);
-
- /* align end on a 2-bytes boundary */
- xferlen = (RAL_TX_DESC_SIZE + m0->m_pkthdr.len + 1) & ~1;
-
- /*
- * No space left in the last URB to store the extra 2 bytes, force
- * sending of another URB.
- */
- if ((xferlen % 64) == 0)
- xferlen += 2;
-
- DPRINTFN(10, ("sending mgt frame len=%u rate=%u xfer len=%u\n",
- m0->m_pkthdr.len, tp->mgmtrate, xferlen));
-
- usbd_setup_xfer(data->xfer, sc->sc_tx_pipeh, data, data->buf,
- xferlen, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, RAL_TX_TIMEOUT,
- ural_txeof);
-
- error = usbd_transfer(data->xfer);
- if (error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS) {
- m_freem(m0);
- data->m = NULL;
- data->ni = NULL;
- return error;
- }
-
- sc->tx_queued++;
- sc->tx_cur = (sc->tx_cur + 1) % RAL_TX_LIST_COUNT;
-
- return 0;
-}
-
-static int
-ural_sendprot(struct ural_softc *sc,
- const struct mbuf *m, struct ieee80211_node *ni, int prot, int rate)
-{
- struct ieee80211com *ic = ni->ni_ic;
- const struct ieee80211_frame *wh;
- struct ural_tx_desc *desc;
- struct ural_tx_data *data;
- struct mbuf *mprot;
- int protrate, ackrate, pktlen, flags, isshort;
- uint16_t dur;
- usbd_status error;
-
- KASSERT(prot == IEEE80211_PROT_RTSCTS || prot == IEEE80211_PROT_CTSONLY,
- ("protection %d", prot));
-
- wh = mtod(m, const struct ieee80211_frame *);
- pktlen = m->m_pkthdr.len + IEEE80211_CRC_LEN;
-
- protrate = ieee80211_ctl_rate(sc->sc_rates, rate);
- ackrate = ieee80211_ack_rate(sc->sc_rates, rate);
-
- isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0;
- dur = ieee80211_compute_duration(sc->sc_rates, pktlen, rate, isshort);
- + ieee80211_ack_duration(sc->sc_rates, rate, isshort);
- flags = RAL_TX_RETRY(7);
- if (prot == IEEE80211_PROT_RTSCTS) {
- /* NB: CTS is the same size as an ACK */
- dur += ieee80211_ack_duration(sc->sc_rates, rate, isshort);
- flags |= RAL_TX_ACK;
- mprot = ieee80211_alloc_rts(ic, wh->i_addr1, wh->i_addr2, dur);
- } else {
- mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, dur);
- }
- if (mprot == NULL) {
- /* XXX stat + msg */
- return ENOBUFS;
- }
- data = &sc->tx_data[sc->tx_cur];
- desc = (struct ural_tx_desc *)data->buf;
-
- data->m = mprot;
- data->ni = ieee80211_ref_node(ni);
- m_copydata(mprot, 0, mprot->m_pkthdr.len, data->buf + RAL_TX_DESC_SIZE);
- ural_setup_tx_desc(sc, desc, flags, mprot->m_pkthdr.len, protrate);
-
- usbd_setup_xfer(data->xfer, sc->sc_tx_pipeh, data, data->buf,
- /* NB: no roundup necessary */
- RAL_TX_DESC_SIZE + mprot->m_pkthdr.len,
- USBD_FORCE_SHORT_XFER | USBD_NO_COPY, RAL_TX_TIMEOUT, ural_txeof);
-
- error = usbd_transfer(data->xfer);
- if (error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS) {
- data->m = NULL;
- data->ni = NULL;
- return error;
- }
-
- sc->tx_queued++;
- sc->tx_cur = (sc->tx_cur + 1) % RAL_TX_LIST_COUNT;
-
- return 0;
-}
-
-static int
-ural_tx_raw(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
- const struct ieee80211_bpf_params *params)
-{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ural_tx_desc *desc;
- struct ural_tx_data *data;
- uint32_t flags;
- usbd_status error;
- int xferlen, rate;
-
- KASSERT(params != NULL, ("no raw xmit params"));
-
- data = &sc->tx_data[sc->tx_cur];
- desc = (struct ural_tx_desc *)data->buf;
-
- rate = params->ibp_rate0 & IEEE80211_RATE_VAL;
- /* XXX validate */
- if (rate == 0) {
- m_freem(m0);
- return EINVAL;
- }
- flags = 0;
- if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0)
- flags |= RAL_TX_ACK;
- if (params->ibp_flags & (IEEE80211_BPF_RTS|IEEE80211_BPF_CTS)) {
- error = ural_sendprot(sc, m0, ni,
- params->ibp_flags & IEEE80211_BPF_RTS ?
- IEEE80211_PROT_RTSCTS : IEEE80211_PROT_CTSONLY,
- rate);
- if (error) {
- m_freem(m0);
- return error;
- }
- flags |= RAL_TX_IFS_SIFS;
- }
-
- if (bpf_peers_present(ifp->if_bpf)) {
- struct ural_tx_radiotap_header *tap = &sc->sc_txtap;
-
- tap->wt_flags = 0;
- tap->wt_rate = rate;
- tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
- tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
- tap->wt_antenna = sc->tx_ant;
-
- bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0);
- }
-
- data->m = m0;
- data->ni = ni;
-
- m_copydata(m0, 0, m0->m_pkthdr.len, data->buf + RAL_TX_DESC_SIZE);
- /* XXX need to setup descriptor ourself */
- ural_setup_tx_desc(sc, desc, flags, m0->m_pkthdr.len, rate);
-
- /* align end on a 2-bytes boundary */
- xferlen = (RAL_TX_DESC_SIZE + m0->m_pkthdr.len + 1) & ~1;
-
- /*
- * No space left in the last URB to store the extra 2 bytes, force
- * sending of another URB.
- */
- if ((xferlen % 64) == 0)
- xferlen += 2;
-
- DPRINTFN(10, ("sending raw frame len=%u rate=%u xfer len=%u\n",
- m0->m_pkthdr.len, rate, xferlen));
-
- usbd_setup_xfer(data->xfer, sc->sc_tx_pipeh, data, data->buf,
- xferlen, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, RAL_TX_TIMEOUT,
- ural_txeof);
-
- error = usbd_transfer(data->xfer);
- if (error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS) {
- m_freem(m0);
- data->m = NULL;
- data->ni = NULL;
- return error;
- }
-
- sc->tx_queued++;
- sc->tx_cur = (sc->tx_cur + 1) % RAL_TX_LIST_COUNT;
-
- return 0;
-}
-
-static int
-ural_tx_data(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
-{
- struct ieee80211vap *vap = ni->ni_vap;
- struct ieee80211com *ic = ni->ni_ic;
- struct ifnet *ifp = sc->sc_ifp;
- struct ural_tx_desc *desc;
- struct ural_tx_data *data;
- struct ieee80211_frame *wh;
- const struct ieee80211_txparam *tp;
- struct ieee80211_key *k;
- uint32_t flags = 0;
- uint16_t dur;
- usbd_status error;
- int xferlen, rate;
-
- wh = mtod(m0, struct ieee80211_frame *);
-
- tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)];
- if (IEEE80211_IS_MULTICAST(wh->i_addr1))
- rate = tp->mcastrate;
- else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
- rate = tp->ucastrate;
- else
- rate = ni->ni_txrate;
-
- if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
- k = ieee80211_crypto_encap(ni, m0);
- if (k == NULL) {
- m_freem(m0);
- return ENOBUFS;
- }
- /* packet header may have moved, reset our local pointer */
- wh = mtod(m0, struct ieee80211_frame *);
- }
-
- if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
- int prot = IEEE80211_PROT_NONE;
- if (m0->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold)
- prot = IEEE80211_PROT_RTSCTS;
- else if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
- ieee80211_rate2phytype(sc->sc_rates, rate) == IEEE80211_T_OFDM)
- prot = ic->ic_protmode;
- if (prot != IEEE80211_PROT_NONE) {
- error = ural_sendprot(sc, m0, ni, prot, rate);
- if (error) {
- m_freem(m0);
- return error;
- }
- flags |= RAL_TX_IFS_SIFS;
- }
- }
-
- data = &sc->tx_data[sc->tx_cur];
- desc = (struct ural_tx_desc *)data->buf;
-
- data->m = m0;
- data->ni = ni;
-
- if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
- flags |= RAL_TX_ACK;
- flags |= RAL_TX_RETRY(7);
-
- dur = ieee80211_ack_duration(sc->sc_rates, rate,
- ic->ic_flags & IEEE80211_F_SHPREAMBLE);
- *(uint16_t *)wh->i_dur = htole16(dur);
- }
-
- if (bpf_peers_present(ifp->if_bpf)) {
- struct ural_tx_radiotap_header *tap = &sc->sc_txtap;
-
- tap->wt_flags = 0;
- tap->wt_rate = rate;
- tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
- tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
- tap->wt_antenna = sc->tx_ant;
-
- bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0);
- }
-
- m_copydata(m0, 0, m0->m_pkthdr.len, data->buf + RAL_TX_DESC_SIZE);
- ural_setup_tx_desc(sc, desc, flags, m0->m_pkthdr.len, rate);
-
- /* align end on a 2-bytes boundary */
- xferlen = (RAL_TX_DESC_SIZE + m0->m_pkthdr.len + 1) & ~1;
-
- /*
- * No space left in the last URB to store the extra 2 bytes, force
- * sending of another URB.
- */
- if ((xferlen % 64) == 0)
- xferlen += 2;
-
- DPRINTFN(10, ("sending data frame len=%u rate=%u xfer len=%u\n",
- m0->m_pkthdr.len, rate, xferlen));
-
- usbd_setup_xfer(data->xfer, sc->sc_tx_pipeh, data, data->buf,
- xferlen, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, RAL_TX_TIMEOUT,
- ural_txeof);
-
- error = usbd_transfer(data->xfer);
- if (error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS) {
- m_freem(m0);
- data->m = NULL;
- data->ni = NULL;
- return error;
- }
-
- sc->tx_queued++;
- sc->tx_cur = (sc->tx_cur + 1) % RAL_TX_LIST_COUNT;
-
- return 0;
-}
-
-static void
-ural_start(struct ifnet *ifp)
-{
- struct ural_softc *sc = ifp->if_softc;
- struct ieee80211_node *ni;
- struct mbuf *m;
-
- for (;;) {
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL)
- break;
- if (sc->tx_queued >= RAL_TX_LIST_COUNT-1) {
- IFQ_DRV_PREPEND(&ifp->if_snd, m);
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- break;
- }
- ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
- m = ieee80211_encap(ni, m);
- if (m == NULL) {
- ieee80211_free_node(ni);
- continue;
- }
- if (ural_tx_data(sc, m, ni) != 0) {
- ieee80211_free_node(ni);
- ifp->if_oerrors++;
- break;
- }
- sc->sc_tx_timer = 5;
- callout_reset(&sc->watchdog_ch, hz, ural_watchdog, sc);
- }
-}
-
-static void
-ural_watchdog(void *arg)
-{
- struct ural_softc *sc = (struct ural_softc *)arg;
-
- RAL_LOCK(sc);
-
- if (sc->sc_tx_timer > 0) {
- if (--sc->sc_tx_timer == 0) {
- device_printf(sc->sc_dev, "device timeout\n");
- /*ural_init(sc); XXX needs a process context! */
- sc->sc_ifp->if_oerrors++;
- RAL_UNLOCK(sc);
- return;
- }
- callout_reset(&sc->watchdog_ch, hz, ural_watchdog, sc);
- }
-
- RAL_UNLOCK(sc);
-}
-
-static int
-ural_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
-{
- struct ural_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ifreq *ifr = (struct ifreq *) data;
- int error = 0, startall = 0;
-
- switch (cmd) {
- case SIOCSIFFLAGS:
- RAL_LOCK(sc);
- if (ifp->if_flags & IFF_UP) {
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
- ural_init_locked(sc);
- startall = 1;
- } else
- ural_update_promisc(sc);
- } else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- ural_stop(sc);
- }
- RAL_UNLOCK(sc);
- if (startall)
- ieee80211_start_all(ic);
- break;
- case SIOCGIFMEDIA:
- case SIOCSIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
- break;
- default:
- error = ether_ioctl(ifp, cmd, data);
- break;
- }
- return error;
-}
-
-static void
-ural_set_testmode(struct ural_softc *sc)
-{
- usb_device_request_t req;
- usbd_status error;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = RAL_VENDOR_REQUEST;
- USETW(req.wValue, 4);
- USETW(req.wIndex, 1);
- USETW(req.wLength, 0);
-
- error = usbd_do_request(sc->sc_udev, &req, NULL);
- if (error != 0) {
- device_printf(sc->sc_dev, "could not set test mode: %s\n",
- usbd_errstr(error));
- }
-}
-
-static void
-ural_eeprom_read(struct ural_softc *sc, uint16_t addr, void *buf, int len)
-{
- usb_device_request_t req;
- usbd_status error;
-
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = RAL_READ_EEPROM;
- USETW(req.wValue, 0);
- USETW(req.wIndex, addr);
- USETW(req.wLength, len);
-
- error = usbd_do_request(sc->sc_udev, &req, buf);
- if (error != 0) {
- device_printf(sc->sc_dev, "could not read EEPROM: %s\n",
- usbd_errstr(error));
- }
-}
-
-static uint16_t
-ural_read(struct ural_softc *sc, uint16_t reg)
-{
- usb_device_request_t req;
- usbd_status error;
- uint16_t val;
-
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = RAL_READ_MAC;
- USETW(req.wValue, 0);
- USETW(req.wIndex, reg);
- USETW(req.wLength, sizeof (uint16_t));
-
- error = usbd_do_request(sc->sc_udev, &req, &val);
- if (error != 0) {
- device_printf(sc->sc_dev, "could not read MAC register: %s\n",
- usbd_errstr(error));
- return 0;
- }
-
- return le16toh(val);
-}
-
-static void
-ural_read_multi(struct ural_softc *sc, uint16_t reg, void *buf, int len)
-{
- usb_device_request_t req;
- usbd_status error;
-
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = RAL_READ_MULTI_MAC;
- USETW(req.wValue, 0);
- USETW(req.wIndex, reg);
- USETW(req.wLength, len);
-
- error = usbd_do_request(sc->sc_udev, &req, buf);
- if (error != 0) {
- device_printf(sc->sc_dev, "could not read MAC register: %s\n",
- usbd_errstr(error));
- }
-}
-
-static void
-ural_write(struct ural_softc *sc, uint16_t reg, uint16_t val)
-{
- usb_device_request_t req;
- usbd_status error;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = RAL_WRITE_MAC;
- USETW(req.wValue, val);
- USETW(req.wIndex, reg);
- USETW(req.wLength, 0);
-
- error = usbd_do_request(sc->sc_udev, &req, NULL);
- if (error != 0) {
- device_printf(sc->sc_dev, "could not write MAC register: %s\n",
- usbd_errstr(error));
- }
-}
-
-static void
-ural_write_multi(struct ural_softc *sc, uint16_t reg, void *buf, int len)
-{
- usb_device_request_t req;
- usbd_status error;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = RAL_WRITE_MULTI_MAC;
- USETW(req.wValue, 0);
- USETW(req.wIndex, reg);
- USETW(req.wLength, len);
-
- error = usbd_do_request(sc->sc_udev, &req, buf);
- if (error != 0) {
- device_printf(sc->sc_dev, "could not write MAC register: %s\n",
- usbd_errstr(error));
- }
-}
-
-static void
-ural_bbp_write(struct ural_softc *sc, uint8_t reg, uint8_t val)
-{
- uint16_t tmp;
- int ntries;
-
- for (ntries = 0; ntries < 5; ntries++) {
- if (!(ural_read(sc, RAL_PHY_CSR8) & RAL_BBP_BUSY))
- break;
- }
- if (ntries == 5) {
- device_printf(sc->sc_dev, "could not write to BBP\n");
- return;
- }
-
- tmp = reg << 8 | val;
- ural_write(sc, RAL_PHY_CSR7, tmp);
-}
-
-static uint8_t
-ural_bbp_read(struct ural_softc *sc, uint8_t reg)
-{
- uint16_t val;
- int ntries;
-
- val = RAL_BBP_WRITE | reg << 8;
- ural_write(sc, RAL_PHY_CSR7, val);
-
- for (ntries = 0; ntries < 5; ntries++) {
- if (!(ural_read(sc, RAL_PHY_CSR8) & RAL_BBP_BUSY))
- break;
- }
- if (ntries == 5) {
- device_printf(sc->sc_dev, "could not read BBP\n");
- return 0;
- }
-
- return ural_read(sc, RAL_PHY_CSR7) & 0xff;
-}
-
-static void
-ural_rf_write(struct ural_softc *sc, uint8_t reg, uint32_t val)
-{
- uint32_t tmp;
- int ntries;
-
- for (ntries = 0; ntries < 5; ntries++) {
- if (!(ural_read(sc, RAL_PHY_CSR10) & RAL_RF_LOBUSY))
- break;
- }
- if (ntries == 5) {
- device_printf(sc->sc_dev, "could not write to RF\n");
- return;
- }
-
- tmp = RAL_RF_BUSY | RAL_RF_20BIT | (val & 0xfffff) << 2 | (reg & 0x3);
- ural_write(sc, RAL_PHY_CSR9, tmp & 0xffff);
- ural_write(sc, RAL_PHY_CSR10, tmp >> 16);
-
- /* remember last written value in sc */
- sc->rf_regs[reg] = val;
-
- DPRINTFN(15, ("RF R[%u] <- 0x%05x\n", reg & 0x3, val & 0xfffff));
-}
-
-/* ARGUSED */
-static struct ieee80211_node *
-ural_node_alloc(struct ieee80211vap *vap __unused,
- const uint8_t mac[IEEE80211_ADDR_LEN] __unused)
-{
- struct ural_node *un;
-
- un = malloc(sizeof(struct ural_node), M_80211_NODE, M_NOWAIT | M_ZERO);
- return un != NULL ? &un->ni : NULL;
-}
-
-static void
-ural_newassoc(struct ieee80211_node *ni, int isnew)
-{
- struct ieee80211vap *vap = ni->ni_vap;
-
- ieee80211_amrr_node_init(&URAL_VAP(vap)->amrr, &URAL_NODE(ni)->amn, ni);
-}
-
-static void
-ural_scan_start(struct ieee80211com *ic)
-{
- struct ural_softc *sc = ic->ic_ifp->if_softc;
-
- usb_rem_task(sc->sc_udev, &sc->sc_scantask);
-
- /* do it in a process context */
- sc->sc_scan_action = URAL_SCAN_START;
- usb_add_task(sc->sc_udev, &sc->sc_scantask, USB_TASKQ_DRIVER);
-
-}
-
-static void
-ural_scan_end(struct ieee80211com *ic)
-{
- struct ural_softc *sc = ic->ic_ifp->if_softc;
-
- usb_rem_task(sc->sc_udev, &sc->sc_scantask);
-
- /* do it in a process context */
- sc->sc_scan_action = URAL_SCAN_END;
- usb_add_task(sc->sc_udev, &sc->sc_scantask, USB_TASKQ_DRIVER);
-
-}
-
-static void
-ural_set_channel(struct ieee80211com *ic)
-{
-
- struct ural_softc *sc = ic->ic_ifp->if_softc;
-
- usb_rem_task(sc->sc_udev, &sc->sc_scantask);
-
- /* do it in a process context */
- sc->sc_scan_action = URAL_SET_CHANNEL;
- usb_add_task(sc->sc_udev, &sc->sc_scantask, USB_TASKQ_DRIVER);
-
- sc->sc_rates = ieee80211_get_ratetable(ic->ic_curchan);
-}
-
-static void
-ural_set_chan(struct ural_softc *sc, struct ieee80211_channel *c)
-{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- uint8_t power, tmp;
- u_int i, chan;
-
- chan = ieee80211_chan2ieee(ic, c);
- if (chan == 0 || chan == IEEE80211_CHAN_ANY)
- return;
-
- if (IEEE80211_IS_CHAN_2GHZ(c))
- power = min(sc->txpow[chan - 1], 31);
- else
- power = 31;
-
- /* adjust txpower using ifconfig settings */
- power -= (100 - ic->ic_txpowlimit) / 8;
-
- DPRINTFN(2, ("setting channel to %u, txpower to %u\n", chan, power));
-
- switch (sc->rf_rev) {
- case RAL_RF_2522:
- ural_rf_write(sc, RAL_RF1, 0x00814);
- ural_rf_write(sc, RAL_RF2, ural_rf2522_r2[chan - 1]);
- ural_rf_write(sc, RAL_RF3, power << 7 | 0x00040);
- break;
-
- case RAL_RF_2523:
- ural_rf_write(sc, RAL_RF1, 0x08804);
- ural_rf_write(sc, RAL_RF2, ural_rf2523_r2[chan - 1]);
- ural_rf_write(sc, RAL_RF3, power << 7 | 0x38044);
- ural_rf_write(sc, RAL_RF4, (chan == 14) ? 0x00280 : 0x00286);
- break;
-
- case RAL_RF_2524:
- ural_rf_write(sc, RAL_RF1, 0x0c808);
- ural_rf_write(sc, RAL_RF2, ural_rf2524_r2[chan - 1]);
- ural_rf_write(sc, RAL_RF3, power << 7 | 0x00040);
- ural_rf_write(sc, RAL_RF4, (chan == 14) ? 0x00280 : 0x00286);
- break;
-
- case RAL_RF_2525:
- ural_rf_write(sc, RAL_RF1, 0x08808);
- ural_rf_write(sc, RAL_RF2, ural_rf2525_hi_r2[chan - 1]);
- ural_rf_write(sc, RAL_RF3, power << 7 | 0x18044);
- ural_rf_write(sc, RAL_RF4, (chan == 14) ? 0x00280 : 0x00286);
-
- ural_rf_write(sc, RAL_RF1, 0x08808);
- ural_rf_write(sc, RAL_RF2, ural_rf2525_r2[chan - 1]);
- ural_rf_write(sc, RAL_RF3, power << 7 | 0x18044);
- ural_rf_write(sc, RAL_RF4, (chan == 14) ? 0x00280 : 0x00286);
- break;
-
- case RAL_RF_2525E:
- ural_rf_write(sc, RAL_RF1, 0x08808);
- ural_rf_write(sc, RAL_RF2, ural_rf2525e_r2[chan - 1]);
- ural_rf_write(sc, RAL_RF3, power << 7 | 0x18044);
- ural_rf_write(sc, RAL_RF4, (chan == 14) ? 0x00286 : 0x00282);
- break;
-
- case RAL_RF_2526:
- ural_rf_write(sc, RAL_RF2, ural_rf2526_hi_r2[chan - 1]);
- ural_rf_write(sc, RAL_RF4, (chan & 1) ? 0x00386 : 0x00381);
- ural_rf_write(sc, RAL_RF1, 0x08804);
-
- ural_rf_write(sc, RAL_RF2, ural_rf2526_r2[chan - 1]);
- ural_rf_write(sc, RAL_RF3, power << 7 | 0x18044);
- ural_rf_write(sc, RAL_RF4, (chan & 1) ? 0x00386 : 0x00381);
- break;
-
- /* dual-band RF */
- case RAL_RF_5222:
- for (i = 0; ural_rf5222[i].chan != chan; i++);
-
- ural_rf_write(sc, RAL_RF1, ural_rf5222[i].r1);
- ural_rf_write(sc, RAL_RF2, ural_rf5222[i].r2);
- ural_rf_write(sc, RAL_RF3, power << 7 | 0x00040);
- ural_rf_write(sc, RAL_RF4, ural_rf5222[i].r4);
- break;
- }
-
- if (ic->ic_opmode != IEEE80211_M_MONITOR &&
- (ic->ic_flags & IEEE80211_F_SCAN) == 0) {
- /* set Japan filter bit for channel 14 */
- tmp = ural_bbp_read(sc, 70);
-
- tmp &= ~RAL_JAPAN_FILTER;
- if (chan == 14)
- tmp |= RAL_JAPAN_FILTER;
-
- ural_bbp_write(sc, 70, tmp);
-
- /* clear CRC errors */
- ural_read(sc, RAL_STA_CSR0);
-
- DELAY(10000);
- ural_disable_rf_tune(sc);
- }
-
- /* XXX doesn't belong here */
- /* update basic rate set */
- ural_set_basicrates(sc, c);
-}
-
-/*
- * Disable RF auto-tuning.
- */
-static void
-ural_disable_rf_tune(struct ural_softc *sc)
-{
- uint32_t tmp;
-
- if (sc->rf_rev != RAL_RF_2523) {
- tmp = sc->rf_regs[RAL_RF1] & ~RAL_RF1_AUTOTUNE;
- ural_rf_write(sc, RAL_RF1, tmp);
- }
-
- tmp = sc->rf_regs[RAL_RF3] & ~RAL_RF3_AUTOTUNE;
- ural_rf_write(sc, RAL_RF3, tmp);
-
- DPRINTFN(2, ("disabling RF autotune\n"));
-}
-
-/*
- * Refer to IEEE Std 802.11-1999 pp. 123 for more information on TSF
- * synchronization.
- */
-static void
-ural_enable_tsf_sync(struct ural_softc *sc)
-{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
- uint16_t logcwmin, preload, tmp;
-
- /* first, disable TSF synchronization */
- ural_write(sc, RAL_TXRX_CSR19, 0);
-
- tmp = (16 * vap->iv_bss->ni_intval) << 4;
- ural_write(sc, RAL_TXRX_CSR18, tmp);
-
- logcwmin = (ic->ic_opmode == IEEE80211_M_IBSS) ? 2 : 0;
- preload = (ic->ic_opmode == IEEE80211_M_IBSS) ? 320 : 6;
- tmp = logcwmin << 12 | preload;
- ural_write(sc, RAL_TXRX_CSR20, tmp);
-
- /* finally, enable TSF synchronization */
- tmp = RAL_ENABLE_TSF | RAL_ENABLE_TBCN;
- if (ic->ic_opmode == IEEE80211_M_STA)
- tmp |= RAL_ENABLE_TSF_SYNC(1);
- else
- tmp |= RAL_ENABLE_TSF_SYNC(2) | RAL_ENABLE_BEACON_GENERATOR;
- ural_write(sc, RAL_TXRX_CSR19, tmp);
-
- DPRINTF(("enabling TSF synchronization\n"));
-}
-
-static void
-ural_update_slot(struct ifnet *ifp)
-{
- struct ural_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
- uint16_t slottime, sifs, eifs;
-
- slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20;
-
- /*
- * These settings may sound a bit inconsistent but this is what the
- * reference driver does.
- */
- if (ic->ic_curmode == IEEE80211_MODE_11B) {
- sifs = 16 - RAL_RXTX_TURNAROUND;
- eifs = 364;
- } else {
- sifs = 10 - RAL_RXTX_TURNAROUND;
- eifs = 64;
- }
-
- ural_write(sc, RAL_MAC_CSR10, slottime);
- ural_write(sc, RAL_MAC_CSR11, sifs);
- ural_write(sc, RAL_MAC_CSR12, eifs);
-}
-
-static void
-ural_set_txpreamble(struct ural_softc *sc)
-{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- uint16_t tmp;
-
- tmp = ural_read(sc, RAL_TXRX_CSR10);
-
- tmp &= ~RAL_SHORT_PREAMBLE;
- if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
- tmp |= RAL_SHORT_PREAMBLE;
-
- ural_write(sc, RAL_TXRX_CSR10, tmp);
-}
-
-static void
-ural_set_basicrates(struct ural_softc *sc, const struct ieee80211_channel *c)
-{
- /* XXX wrong, take from rate set */
- /* update basic rate set */
- if (IEEE80211_IS_CHAN_5GHZ(c)) {
- /* 11a basic rates: 6, 12, 24Mbps */
- ural_write(sc, RAL_TXRX_CSR11, 0x150);
- } else if (IEEE80211_IS_CHAN_ANYG(c)) {
- /* 11g basic rates: 1, 2, 5.5, 11, 6, 12, 24Mbps */
- ural_write(sc, RAL_TXRX_CSR11, 0x15f);
- } else {
- /* 11b basic rates: 1, 2Mbps */
- ural_write(sc, RAL_TXRX_CSR11, 0x3);
- }
-}
-
-static void
-ural_set_bssid(struct ural_softc *sc, const uint8_t *bssid)
-{
- uint16_t tmp;
-
- tmp = bssid[0] | bssid[1] << 8;
- ural_write(sc, RAL_MAC_CSR5, tmp);
-
- tmp = bssid[2] | bssid[3] << 8;
- ural_write(sc, RAL_MAC_CSR6, tmp);
-
- tmp = bssid[4] | bssid[5] << 8;
- ural_write(sc, RAL_MAC_CSR7, tmp);
-
- DPRINTF(("setting BSSID to %6D\n", bssid, ":"));
-}
-
-static void
-ural_set_macaddr(struct ural_softc *sc, uint8_t *addr)
-{
- uint16_t tmp;
-
- tmp = addr[0] | addr[1] << 8;
- ural_write(sc, RAL_MAC_CSR2, tmp);
-
- tmp = addr[2] | addr[3] << 8;
- ural_write(sc, RAL_MAC_CSR3, tmp);
-
- tmp = addr[4] | addr[5] << 8;
- ural_write(sc, RAL_MAC_CSR4, tmp);
-
- DPRINTF(("setting MAC address to %6D\n", addr, ":"));
-}
-
-static void
-ural_update_promisc(struct ural_softc *sc)
-{
- struct ifnet *ifp = sc->sc_ifp;
- uint32_t tmp;
-
- tmp = ural_read(sc, RAL_TXRX_CSR2);
-
- tmp &= ~RAL_DROP_NOT_TO_ME;
- if (!(ifp->if_flags & IFF_PROMISC))
- tmp |= RAL_DROP_NOT_TO_ME;
-
- ural_write(sc, RAL_TXRX_CSR2, tmp);
-
- DPRINTF(("%s promiscuous mode\n", (ifp->if_flags & IFF_PROMISC) ?
- "entering" : "leaving"));
-}
-
-static const char *
-ural_get_rf(int rev)
-{
- switch (rev) {
- case RAL_RF_2522: return "RT2522";
- case RAL_RF_2523: return "RT2523";
- case RAL_RF_2524: return "RT2524";
- case RAL_RF_2525: return "RT2525";
- case RAL_RF_2525E: return "RT2525e";
- case RAL_RF_2526: return "RT2526";
- case RAL_RF_5222: return "RT5222";
- default: return "unknown";
- }
-}
-
-static void
-ural_read_eeprom(struct ural_softc *sc)
-{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- uint16_t val;
-
- ural_eeprom_read(sc, RAL_EEPROM_CONFIG0, &val, 2);
- val = le16toh(val);
- sc->rf_rev = (val >> 11) & 0x7;
- sc->hw_radio = (val >> 10) & 0x1;
- sc->led_mode = (val >> 6) & 0x7;
- sc->rx_ant = (val >> 4) & 0x3;
- sc->tx_ant = (val >> 2) & 0x3;
- sc->nb_ant = val & 0x3;
-
- /* read MAC address */
- ural_eeprom_read(sc, RAL_EEPROM_ADDRESS, ic->ic_myaddr, 6);
-
- /* read default values for BBP registers */
- ural_eeprom_read(sc, RAL_EEPROM_BBP_BASE, sc->bbp_prom, 2 * 16);
-
- /* read Tx power for all b/g channels */
- ural_eeprom_read(sc, RAL_EEPROM_TXPOWER, sc->txpow, 14);
-}
-
-static int
-ural_bbp_init(struct ural_softc *sc)
-{
-#define N(a) (sizeof (a) / sizeof ((a)[0]))
- int i, ntries;
-
- /* wait for BBP to be ready */
- for (ntries = 0; ntries < 100; ntries++) {
- if (ural_bbp_read(sc, RAL_BBP_VERSION) != 0)
- break;
- DELAY(1000);
- }
- if (ntries == 100) {
- device_printf(sc->sc_dev, "timeout waiting for BBP\n");
- return EIO;
- }
-
- /* initialize BBP registers to default values */
- for (i = 0; i < N(ural_def_bbp); i++)
- ural_bbp_write(sc, ural_def_bbp[i].reg, ural_def_bbp[i].val);
-
-#if 0
- /* initialize BBP registers to values stored in EEPROM */
- for (i = 0; i < 16; i++) {
- if (sc->bbp_prom[i].reg == 0xff)
- continue;
- ural_bbp_write(sc, sc->bbp_prom[i].reg, sc->bbp_prom[i].val);
- }
-#endif
-
- return 0;
-#undef N
-}
-
-static void
-ural_set_txantenna(struct ural_softc *sc, int antenna)
-{
- uint16_t tmp;
- uint8_t tx;
-
- tx = ural_bbp_read(sc, RAL_BBP_TX) & ~RAL_BBP_ANTMASK;
- if (antenna == 1)
- tx |= RAL_BBP_ANTA;
- else if (antenna == 2)
- tx |= RAL_BBP_ANTB;
- else
- tx |= RAL_BBP_DIVERSITY;
-
- /* need to force I/Q flip for RF 2525e, 2526 and 5222 */
- if (sc->rf_rev == RAL_RF_2525E || sc->rf_rev == RAL_RF_2526 ||
- sc->rf_rev == RAL_RF_5222)
- tx |= RAL_BBP_FLIPIQ;
-
- ural_bbp_write(sc, RAL_BBP_TX, tx);
-
- /* update values in PHY_CSR5 and PHY_CSR6 */
- tmp = ural_read(sc, RAL_PHY_CSR5) & ~0x7;
- ural_write(sc, RAL_PHY_CSR5, tmp | (tx & 0x7));
-
- tmp = ural_read(sc, RAL_PHY_CSR6) & ~0x7;
- ural_write(sc, RAL_PHY_CSR6, tmp | (tx & 0x7));
-}
-
-static void
-ural_set_rxantenna(struct ural_softc *sc, int antenna)
-{
- uint8_t rx;
-
- rx = ural_bbp_read(sc, RAL_BBP_RX) & ~RAL_BBP_ANTMASK;
- if (antenna == 1)
- rx |= RAL_BBP_ANTA;
- else if (antenna == 2)
- rx |= RAL_BBP_ANTB;
- else
- rx |= RAL_BBP_DIVERSITY;
-
- /* need to force no I/Q flip for RF 2525e and 2526 */
- if (sc->rf_rev == RAL_RF_2525E || sc->rf_rev == RAL_RF_2526)
- rx &= ~RAL_BBP_FLIPIQ;
-
- ural_bbp_write(sc, RAL_BBP_RX, rx);
-}
-
-static void
-ural_init_locked(struct ural_softc *sc)
-{
-#define N(a) (sizeof (a) / sizeof ((a)[0]))
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ural_rx_data *data;
- uint16_t tmp;
- usbd_status error;
- int i, ntries;
-
- ural_set_testmode(sc);
- ural_write(sc, 0x308, 0x00f0); /* XXX magic */
-
- ural_stop(sc);
-
- /* initialize MAC registers to default values */
- for (i = 0; i < N(ural_def_mac); i++)
- ural_write(sc, ural_def_mac[i].reg, ural_def_mac[i].val);
-
- /* wait for BBP and RF to wake up (this can take a long time!) */
- for (ntries = 0; ntries < 100; ntries++) {
- tmp = ural_read(sc, RAL_MAC_CSR17);
- if ((tmp & (RAL_BBP_AWAKE | RAL_RF_AWAKE)) ==
- (RAL_BBP_AWAKE | RAL_RF_AWAKE))
- break;
- DELAY(1000);
- }
- if (ntries == 100) {
- device_printf(sc->sc_dev,
- "timeout waiting for BBP/RF to wakeup\n");
- goto fail;
- }
-
- /* we're ready! */
- ural_write(sc, RAL_MAC_CSR1, RAL_HOST_READY);
-
- /* set basic rate set (will be updated later) */
- ural_write(sc, RAL_TXRX_CSR11, 0x15f);
-
- if (ural_bbp_init(sc) != 0)
- goto fail;
-
- ural_set_chan(sc, ic->ic_curchan);
-
- /* clear statistic registers (STA_CSR0 to STA_CSR10) */
- ural_read_multi(sc, RAL_STA_CSR0, sc->sta, sizeof sc->sta);
-
- ural_set_txantenna(sc, sc->tx_ant);
- ural_set_rxantenna(sc, sc->rx_ant);
-
- IEEE80211_ADDR_COPY(ic->ic_myaddr, IF_LLADDR(ifp));
- ural_set_macaddr(sc, ic->ic_myaddr);
-
- /*
- * Allocate xfer for AMRR statistics requests.
- */
- sc->amrr_xfer = usbd_alloc_xfer(sc->sc_udev);
- if (sc->amrr_xfer == NULL) {
- device_printf(sc->sc_dev, "could not allocate AMRR xfer\n");
- goto fail;
- }
-
- /*
- * Open Tx and Rx USB bulk pipes.
- */
- error = usbd_open_pipe(sc->sc_iface, sc->sc_tx_no, USBD_EXCLUSIVE_USE,
- &sc->sc_tx_pipeh);
- if (error != 0) {
- device_printf(sc->sc_dev, "could not open Tx pipe: %s\n",
- usbd_errstr(error));
- goto fail;
- }
-
- error = usbd_open_pipe(sc->sc_iface, sc->sc_rx_no, USBD_EXCLUSIVE_USE,
- &sc->sc_rx_pipeh);
- if (error != 0) {
- device_printf(sc->sc_dev, "could not open Rx pipe: %s\n",
- usbd_errstr(error));
- goto fail;
- }
-
- /*
- * Allocate Tx and Rx xfer queues.
- */
- error = ural_alloc_tx_list(sc);
- if (error != 0) {
- device_printf(sc->sc_dev, "could not allocate Tx list\n");
- goto fail;
- }
-
- error = ural_alloc_rx_list(sc);
- if (error != 0) {
- device_printf(sc->sc_dev, "could not allocate Rx list\n");
- goto fail;
- }
-
- /*
- * Start up the receive pipe.
- */
- for (i = 0; i < RAL_RX_LIST_COUNT; i++) {
- data = &sc->rx_data[i];
-
- usbd_setup_xfer(data->xfer, sc->sc_rx_pipeh, data, data->buf,
- MCLBYTES, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, ural_rxeof);
- usbd_transfer(data->xfer);
- }
-
- /* kick Rx */
- tmp = RAL_DROP_PHY | RAL_DROP_CRC;
- if (ic->ic_opmode != IEEE80211_M_MONITOR) {
- tmp |= RAL_DROP_CTL | RAL_DROP_BAD_VERSION;
- if (ic->ic_opmode != IEEE80211_M_HOSTAP)
- tmp |= RAL_DROP_TODS;
- if (!(ifp->if_flags & IFF_PROMISC))
- tmp |= RAL_DROP_NOT_TO_ME;
- }
- ural_write(sc, RAL_TXRX_CSR2, tmp);
-
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
- return;
-
-fail: ural_stop(sc);
-#undef N
-}
-
-static void
-ural_init(void *priv)
-{
- struct ural_softc *sc = priv;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
-
- RAL_LOCK(sc);
- ural_init_locked(sc);
- RAL_UNLOCK(sc);
-
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- ieee80211_start_all(ic); /* start all vap's */
-}
-
-static void
-ural_stop(void *priv)
-{
- struct ural_softc *sc = priv;
- struct ifnet *ifp = sc->sc_ifp;
-
- sc->sc_tx_timer = 0;
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
-
- /* disable Rx */
- ural_write(sc, RAL_TXRX_CSR2, RAL_DISABLE_RX);
-
- /* reset ASIC and BBP (but won't reset MAC registers!) */
- ural_write(sc, RAL_MAC_CSR1, RAL_RESET_ASIC | RAL_RESET_BBP);
- ural_write(sc, RAL_MAC_CSR1, 0);
-
- if (sc->amrr_xfer != NULL) {
- usbd_free_xfer(sc->amrr_xfer);
- sc->amrr_xfer = NULL;
- }
-
- if (sc->sc_rx_pipeh != NULL) {
- usbd_abort_pipe(sc->sc_rx_pipeh);
- usbd_close_pipe(sc->sc_rx_pipeh);
- sc->sc_rx_pipeh = NULL;
- }
-
- if (sc->sc_tx_pipeh != NULL) {
- usbd_abort_pipe(sc->sc_tx_pipeh);
- usbd_close_pipe(sc->sc_tx_pipeh);
- sc->sc_tx_pipeh = NULL;
- }
-
- ural_free_rx_list(sc);
- ural_free_tx_list(sc);
-}
-
-static int
-ural_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
- const struct ieee80211_bpf_params *params)
-{
- struct ieee80211com *ic = ni->ni_ic;
- struct ifnet *ifp = ic->ic_ifp;
- struct ural_softc *sc = ifp->if_softc;
-
- /* prevent management frames from being sent if we're not ready */
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
- m_freem(m);
- ieee80211_free_node(ni);
- return ENETDOWN;
- }
- if (sc->tx_queued >= RAL_TX_LIST_COUNT) {
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- m_freem(m);
- ieee80211_free_node(ni);
- return EIO;
- }
-
- ifp->if_opackets++;
-
- if (params == NULL) {
- /*
- * Legacy path; interpret frame contents to decide
- * precisely how to send the frame.
- */
- if (ural_tx_mgt(sc, m, ni) != 0)
- goto bad;
- } else {
- /*
- * Caller supplied explicit parameters to use in
- * sending the frame.
- */
- if (ural_tx_raw(sc, m, ni, params) != 0)
- goto bad;
- }
- sc->sc_tx_timer = 5;
- callout_reset(&sc->watchdog_ch, hz, ural_watchdog, sc);
-
- return 0;
-bad:
- ifp->if_oerrors++;
- ieee80211_free_node(ni);
- return EIO; /* XXX */
-}
-
-static void
-ural_amrr_start(struct ural_softc *sc, struct ieee80211_node *ni)
-{
- struct ieee80211vap *vap = ni->ni_vap;
- struct ural_vap *uvp = URAL_VAP(vap);
-
- /* clear statistic registers (STA_CSR0 to STA_CSR10) */
- ural_read_multi(sc, RAL_STA_CSR0, sc->sta, sizeof sc->sta);
-
- ieee80211_amrr_node_init(&uvp->amrr, &URAL_NODE(ni)->amn, ni);
-
- callout_reset(&uvp->amrr_ch, hz, ural_amrr_timeout, vap);
-}
-
-static void
-ural_amrr_timeout(void *arg)
-{
- struct ieee80211vap *vap = arg;
- struct ural_softc *sc = vap->iv_ic->ic_ifp->if_softc;
- usb_device_request_t req;
-
- /*
- * Asynchronously read statistic registers (cleared by read).
- */
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = RAL_READ_MULTI_MAC;
- USETW(req.wValue, 0);
- USETW(req.wIndex, RAL_STA_CSR0);
- USETW(req.wLength, sizeof sc->sta);
-
- usbd_setup_default_xfer(sc->amrr_xfer, sc->sc_udev, vap,
- USBD_DEFAULT_TIMEOUT, &req, sc->sta, sizeof sc->sta, 0,
- ural_amrr_update);
- (void)usbd_transfer(sc->amrr_xfer);
-}
-
-static void
-ural_amrr_update(usbd_xfer_handle xfer, usbd_private_handle priv,
- usbd_status status)
-{
- struct ieee80211vap *vap = priv;
- struct ural_vap *uvp = URAL_VAP(vap);
- struct ifnet *ifp = vap->iv_ic->ic_ifp;
- struct ural_softc *sc = ifp->if_softc;
- struct ieee80211_node *ni = vap->iv_bss;
- int ok, fail;
-
- if (status != USBD_NORMAL_COMPLETION) {
- device_printf(sc->sc_dev, "could not retrieve Tx statistics - "
- "cancelling automatic rate control\n");
- return;
- }
-
- ok = sc->sta[7] + /* TX ok w/o retry */
- sc->sta[8]; /* TX ok w/ retry */
- fail = sc->sta[9]; /* TX retry-fail count */
-
- ieee80211_amrr_tx_update(&URAL_NODE(ni)->amn,
- ok+fail, ok, sc->sta[8] + fail);
- (void) ieee80211_amrr_choose(ni, &URAL_NODE(ni)->amn);
-
- ifp->if_oerrors += fail; /* count TX retry-fail as Tx errors */
-
- callout_reset(&uvp->amrr_ch, hz, ural_amrr_timeout, vap);
-}
diff --git a/sys/dev/usb/if_uralreg.h b/sys/dev/usb/if_uralreg.h
deleted file mode 100644
index 428089f..0000000
--- a/sys/dev/usb/if_uralreg.h
+++ /dev/null
@@ -1,210 +0,0 @@
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 2005, 2006
- * Damien Bergamini <damien.bergamini@free.fr>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#define RAL_NOISE_FLOOR -95
-#define RAL_RSSI_CORR 120
-
-#define RAL_RX_DESC_SIZE (sizeof (struct ural_rx_desc))
-#define RAL_TX_DESC_SIZE (sizeof (struct ural_tx_desc))
-
-#define RAL_CONFIG_NO 1
-#define RAL_IFACE_INDEX 0
-
-#define RAL_VENDOR_REQUEST 0x01
-#define RAL_WRITE_MAC 0x02
-#define RAL_READ_MAC 0x03
-#define RAL_WRITE_MULTI_MAC 0x06
-#define RAL_READ_MULTI_MAC 0x07
-#define RAL_READ_EEPROM 0x09
-
-/*
- * MAC registers.
- */
-#define RAL_MAC_CSR0 0x0400 /* ASIC Version */
-#define RAL_MAC_CSR1 0x0402 /* System control */
-#define RAL_MAC_CSR2 0x0404 /* MAC addr0 */
-#define RAL_MAC_CSR3 0x0406 /* MAC addr1 */
-#define RAL_MAC_CSR4 0x0408 /* MAC addr2 */
-#define RAL_MAC_CSR5 0x040a /* BSSID0 */
-#define RAL_MAC_CSR6 0x040c /* BSSID1 */
-#define RAL_MAC_CSR7 0x040e /* BSSID2 */
-#define RAL_MAC_CSR8 0x0410 /* Max frame length */
-#define RAL_MAC_CSR9 0x0412 /* Timer control */
-#define RAL_MAC_CSR10 0x0414 /* Slot time */
-#define RAL_MAC_CSR11 0x0416 /* IFS */
-#define RAL_MAC_CSR12 0x0418 /* EIFS */
-#define RAL_MAC_CSR13 0x041a /* Power mode0 */
-#define RAL_MAC_CSR14 0x041c /* Power mode1 */
-#define RAL_MAC_CSR15 0x041e /* Power saving transition0 */
-#define RAL_MAC_CSR16 0x0420 /* Power saving transition1 */
-#define RAL_MAC_CSR17 0x0422 /* Power state control */
-#define RAL_MAC_CSR18 0x0424 /* Auto wake-up control */
-#define RAL_MAC_CSR19 0x0426 /* GPIO control */
-#define RAL_MAC_CSR20 0x0428 /* LED control0 */
-#define RAL_MAC_CSR22 0x042c /* XXX not documented */
-
-/*
- * Tx/Rx Registers.
- */
-#define RAL_TXRX_CSR0 0x0440 /* Security control */
-#define RAL_TXRX_CSR2 0x0444 /* Rx control */
-#define RAL_TXRX_CSR5 0x044a /* CCK Tx BBP ID0 */
-#define RAL_TXRX_CSR6 0x044c /* CCK Tx BBP ID1 */
-#define RAL_TXRX_CSR7 0x044e /* OFDM Tx BBP ID0 */
-#define RAL_TXRX_CSR8 0x0450 /* OFDM Tx BBP ID1 */
-#define RAL_TXRX_CSR10 0x0454 /* Auto responder control */
-#define RAL_TXRX_CSR11 0x0456 /* Auto responder basic rate */
-#define RAL_TXRX_CSR18 0x0464 /* Beacon interval */
-#define RAL_TXRX_CSR19 0x0466 /* Beacon/sync control */
-#define RAL_TXRX_CSR20 0x0468 /* Beacon alignment */
-#define RAL_TXRX_CSR21 0x046a /* XXX not documented */
-
-/*
- * Security registers.
- */
-#define RAL_SEC_CSR0 0x0480 /* Shared key 0, word 0 */
-
-/*
- * PHY registers.
- */
-#define RAL_PHY_CSR2 0x04c4 /* Tx MAC configuration */
-#define RAL_PHY_CSR4 0x04c8 /* Interface configuration */
-#define RAL_PHY_CSR5 0x04ca /* BBP Pre-Tx CCK */
-#define RAL_PHY_CSR6 0x04cc /* BBP Pre-Tx OFDM */
-#define RAL_PHY_CSR7 0x04ce /* BBP serial control */
-#define RAL_PHY_CSR8 0x04d0 /* BBP serial status */
-#define RAL_PHY_CSR9 0x04d2 /* RF serial control0 */
-#define RAL_PHY_CSR10 0x04d4 /* RF serial control1 */
-
-/*
- * Statistics registers.
- */
-#define RAL_STA_CSR0 0x04e0 /* FCS error */
-
-
-#define RAL_DISABLE_RX (1 << 0)
-#define RAL_DROP_CRC (1 << 1)
-#define RAL_DROP_PHY (1 << 2)
-#define RAL_DROP_CTL (1 << 3)
-#define RAL_DROP_NOT_TO_ME (1 << 4)
-#define RAL_DROP_TODS (1 << 5)
-#define RAL_DROP_BAD_VERSION (1 << 6)
-#define RAL_DROP_MULTICAST (1 << 9)
-#define RAL_DROP_BROADCAST (1 << 10)
-
-#define RAL_SHORT_PREAMBLE (1 << 2)
-
-#define RAL_RESET_ASIC (1 << 0)
-#define RAL_RESET_BBP (1 << 1)
-#define RAL_HOST_READY (1 << 2)
-
-#define RAL_ENABLE_TSF (1 << 0)
-#define RAL_ENABLE_TSF_SYNC(x) (((x) & 0x3) << 1)
-#define RAL_ENABLE_TBCN (1 << 3)
-#define RAL_ENABLE_BEACON_GENERATOR (1 << 4)
-
-#define RAL_RF_AWAKE (3 << 7)
-#define RAL_BBP_AWAKE (3 << 5)
-
-#define RAL_BBP_WRITE (1 << 15)
-#define RAL_BBP_BUSY (1 << 0)
-
-#define RAL_RF1_AUTOTUNE 0x08000
-#define RAL_RF3_AUTOTUNE 0x00040
-
-#define RAL_RF_2522 0x00
-#define RAL_RF_2523 0x01
-#define RAL_RF_2524 0x02
-#define RAL_RF_2525 0x03
-#define RAL_RF_2525E 0x04
-#define RAL_RF_2526 0x05
-/* dual-band RF */
-#define RAL_RF_5222 0x10
-
-#define RAL_BBP_VERSION 0
-#define RAL_BBP_TX 2
-#define RAL_BBP_RX 14
-
-#define RAL_BBP_ANTA 0x00
-#define RAL_BBP_DIVERSITY 0x01
-#define RAL_BBP_ANTB 0x02
-#define RAL_BBP_ANTMASK 0x03
-#define RAL_BBP_FLIPIQ 0x04
-
-#define RAL_JAPAN_FILTER 0x08
-
-struct ural_tx_desc {
- uint32_t flags;
-#define RAL_TX_RETRY(x) ((x) << 4)
-#define RAL_TX_MORE_FRAG (1 << 8)
-#define RAL_TX_ACK (1 << 9)
-#define RAL_TX_TIMESTAMP (1 << 10)
-#define RAL_TX_OFDM (1 << 11)
-#define RAL_TX_NEWSEQ (1 << 12)
-
-#define RAL_TX_IFS_MASK 0x00006000
-#define RAL_TX_IFS_BACKOFF (0 << 13)
-#define RAL_TX_IFS_SIFS (1 << 13)
-#define RAL_TX_IFS_NEWBACKOFF (2 << 13)
-#define RAL_TX_IFS_NONE (3 << 13)
-
- uint16_t wme;
-#define RAL_LOGCWMAX(x) (((x) & 0xf) << 12)
-#define RAL_LOGCWMIN(x) (((x) & 0xf) << 8)
-#define RAL_AIFSN(x) (((x) & 0x3) << 6)
-#define RAL_IVOFFSET(x) (((x) & 0x3f))
-
- uint16_t reserved1;
- uint8_t plcp_signal;
- uint8_t plcp_service;
-#define RAL_PLCP_LENGEXT 0x80
-
- uint8_t plcp_length_lo;
- uint8_t plcp_length_hi;
- uint32_t iv;
- uint32_t eiv;
-} __packed;
-
-struct ural_rx_desc {
- uint32_t flags;
-#define RAL_RX_CRC_ERROR (1 << 5)
-#define RAL_RX_OFDM (1 << 6)
-#define RAL_RX_PHY_ERROR (1 << 7)
-
- uint8_t rssi;
- uint8_t rate;
- uint16_t reserved;
-
- uint32_t iv;
- uint32_t eiv;
-} __packed;
-
-#define RAL_RF_LOBUSY (1 << 15)
-#define RAL_RF_BUSY (1 << 31)
-#define RAL_RF_20BIT (20 << 24)
-
-#define RAL_RF1 0
-#define RAL_RF2 2
-#define RAL_RF3 1
-#define RAL_RF4 3
-
-#define RAL_EEPROM_ADDRESS 0x0004
-#define RAL_EEPROM_TXPOWER 0x003c
-#define RAL_EEPROM_CONFIG0 0x0016
-#define RAL_EEPROM_BBP_BASE 0x001c
diff --git a/sys/dev/usb/if_uralvar.h b/sys/dev/usb/if_uralvar.h
deleted file mode 100644
index 39aef9e..0000000
--- a/sys/dev/usb/if_uralvar.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 2005
- * Damien Bergamini <damien.bergamini@free.fr>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#define RAL_RX_LIST_COUNT 1
-#define RAL_TX_LIST_COUNT 8
-
-#define URAL_SCAN_START 1
-#define URAL_SCAN_END 2
-#define URAL_SET_CHANNEL 3
-
-
-struct ural_rx_radiotap_header {
- struct ieee80211_radiotap_header wr_ihdr;
- uint8_t wr_flags;
- uint8_t wr_rate;
- uint16_t wr_chan_freq;
- uint16_t wr_chan_flags;
- uint8_t wr_antenna;
- uint8_t wr_antsignal;
-};
-
-#define RAL_RX_RADIOTAP_PRESENT \
- ((1 << IEEE80211_RADIOTAP_FLAGS) | \
- (1 << IEEE80211_RADIOTAP_RATE) | \
- (1 << IEEE80211_RADIOTAP_CHANNEL) | \
- (1 << IEEE80211_RADIOTAP_ANTENNA) | \
- (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL))
-
-struct ural_tx_radiotap_header {
- struct ieee80211_radiotap_header wt_ihdr;
- uint8_t wt_flags;
- uint8_t wt_rate;
- uint16_t wt_chan_freq;
- uint16_t wt_chan_flags;
- uint8_t wt_antenna;
-};
-
-#define RAL_TX_RADIOTAP_PRESENT \
- ((1 << IEEE80211_RADIOTAP_FLAGS) | \
- (1 << IEEE80211_RADIOTAP_RATE) | \
- (1 << IEEE80211_RADIOTAP_CHANNEL) | \
- (1 << IEEE80211_RADIOTAP_ANTENNA))
-
-struct ural_softc;
-
-struct ural_tx_data {
- struct ural_softc *sc;
- usbd_xfer_handle xfer;
- uint8_t *buf;
- struct mbuf *m;
- struct ieee80211_node *ni;
-};
-
-struct ural_rx_data {
- struct ural_softc *sc;
- usbd_xfer_handle xfer;
- uint8_t *buf;
- struct mbuf *m;
-};
-
-struct ural_node {
- struct ieee80211_node ni;
- struct ieee80211_amrr_node amn;
-};
-#define URAL_NODE(ni) ((struct ural_node *)(ni))
-
-struct ural_vap {
- struct ieee80211vap vap;
- struct ieee80211_beacon_offsets bo;
- struct ieee80211_amrr amrr;
- struct callout amrr_ch;
-
- int (*newstate)(struct ieee80211vap *,
- enum ieee80211_state, int);
-};
-#define URAL_VAP(vap) ((struct ural_vap *)(vap))
-
-struct ural_softc {
- struct ifnet *sc_ifp;
- device_t sc_dev;
- usbd_device_handle sc_udev;
- usbd_interface_handle sc_iface;
-
- const struct ieee80211_rate_table *sc_rates;
-
- int sc_rx_no;
- int sc_tx_no;
-
- uint32_t asic_rev;
- uint8_t rf_rev;
-
- usbd_xfer_handle amrr_xfer;
-
- usbd_pipe_handle sc_rx_pipeh;
- usbd_pipe_handle sc_tx_pipeh;
-
- enum ieee80211_state sc_state;
- int sc_arg;
- int sc_scan_action; /* should be an enum */
- struct usb_task sc_task;
- struct usb_task sc_scantask;
-
- struct ural_rx_data rx_data[RAL_RX_LIST_COUNT];
- struct ural_tx_data tx_data[RAL_TX_LIST_COUNT];
- int tx_queued;
- int tx_cur;
-
- struct mtx sc_mtx;
-
- struct callout watchdog_ch;
- int sc_tx_timer;
-
- uint16_t sta[11];
- uint32_t rf_regs[4];
- uint8_t txpow[14];
-
- struct {
- uint8_t val;
- uint8_t reg;
- } __packed bbp_prom[16];
-
- int led_mode;
- int hw_radio;
- int rx_ant;
- int tx_ant;
- int nb_ant;
-
- struct ural_rx_radiotap_header sc_rxtap;
- int sc_rxtap_len;
-
- struct ural_tx_radiotap_header sc_txtap;
- int sc_txtap_len;
-};
-
-#if 0
-#define RAL_LOCK(sc) mtx_lock(&(sc)->sc_mtx)
-#define RAL_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx)
-#else
-#define RAL_LOCK(sc) do { ((sc) = (sc)); mtx_lock(&Giant); } while (0)
-#define RAL_UNLOCK(sc) mtx_unlock(&Giant)
-#endif
diff --git a/sys/dev/usb/if_urtw.c b/sys/dev/usb/if_urtw.c
deleted file mode 100644
index d1a3a84..0000000
--- a/sys/dev/usb/if_urtw.c
+++ /dev/null
@@ -1,3324 +0,0 @@
-/*-
- * Copyright (c) 2008 Weongyo Jeong <weongyo@FreeBSD.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-#include <sys/param.h>
-#include <sys/sockio.h>
-#include <sys/sysctl.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/mbuf.h>
-#include <sys/kernel.h>
-#include <sys/socket.h>
-#include <sys/systm.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/endian.h>
-#include <sys/kdb.h>
-
-#include <machine/bus.h>
-#include <machine/resource.h>
-#include <sys/rman.h>
-
-#include <net/bpf.h>
-#include <net/if.h>
-#include <net/if_arp.h>
-#include <net/ethernet.h>
-#include <net/if_dl.h>
-#include <net/if_media.h>
-#include <net/if_types.h>
-
-#ifdef INET
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/in_var.h>
-#include <netinet/if_ether.h>
-#include <netinet/ip.h>
-#endif
-
-#include <net80211/ieee80211_var.h>
-#include <net80211/ieee80211_regdomain.h>
-#include <net80211/ieee80211_radiotap.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include "usbdevs.h"
-
-#include <dev/usb/if_urtwreg.h>
-#include <dev/usb/if_urtwvar.h>
-
-SYSCTL_NODE(_hw_usb, OID_AUTO, urtw, CTLFLAG_RW, 0, "USB Realtek 8187L");
-#ifdef URTW_DEBUG
-int urtw_debug = 0;
-SYSCTL_INT(_hw_usb_urtw, OID_AUTO, debug, CTLFLAG_RW, &urtw_debug, 0,
- "control debugging printfs");
-TUNABLE_INT("hw.usb.urtw.debug", &urtw_debug);
-enum {
- URTW_DEBUG_XMIT = 0x00000001, /* basic xmit operation */
- URTW_DEBUG_RECV = 0x00000002, /* basic recv operation */
- URTW_DEBUG_RESET = 0x00000004, /* reset processing */
- URTW_DEBUG_TX_PROC = 0x00000008, /* tx ISR proc */
- URTW_DEBUG_RX_PROC = 0x00000010, /* rx ISR proc */
- URTW_DEBUG_STATE = 0x00000020, /* 802.11 state transitions */
- URTW_DEBUG_STAT = 0x00000040, /* statistic */
- URTW_DEBUG_ANY = 0xffffffff
-};
-#define DPRINTF(sc, m, fmt, ...) do { \
- if (sc->sc_debug & (m)) \
- printf(fmt, __VA_ARGS__); \
-} while (0)
-#else
-#define DPRINTF(sc, m, fmt, ...) do { \
- (void) sc; \
-} while (0)
-#endif
-int urtw_preamble_mode = URTW_PREAMBLE_MODE_LONG;
-SYSCTL_INT(_hw_usb_urtw, OID_AUTO, preamble_mode, CTLFLAG_RW,
- &urtw_preamble_mode, 0, "set the preable mode (long or short)");
-TUNABLE_INT("hw.usb.urtw.preamble_mode", &urtw_preamble_mode);
-
-/* recognized device vendors/products */
-static const struct usb_devno urtw_devs[] = {
-#define URTW_DEV(v,p) { USB_VENDOR_##v, USB_PRODUCT_##v##_##p }
- URTW_DEV(REALTEK, RTL8187),
- URTW_DEV(NETGEAR, WG111V2)
-#undef URTW_DEV
-};
-
-#define urtw_read8_m(sc, val, data) do { \
- error = urtw_read8_c(sc, val, data); \
- if (error != 0) \
- goto fail; \
-} while (0)
-#define urtw_write8_m(sc, val, data) do { \
- error = urtw_write8_c(sc, val, data); \
- if (error != 0) \
- goto fail; \
-} while (0)
-#define urtw_read16_m(sc, val, data) do { \
- error = urtw_read16_c(sc, val, data); \
- if (error != 0) \
- goto fail; \
-} while (0)
-#define urtw_write16_m(sc, val, data) do { \
- error = urtw_write16_c(sc, val, data); \
- if (error != 0) \
- goto fail; \
-} while (0)
-#define urtw_read32_m(sc, val, data) do { \
- error = urtw_read32_c(sc, val, data); \
- if (error != 0) \
- goto fail; \
-} while (0)
-#define urtw_write32_m(sc, val, data) do { \
- error = urtw_write32_c(sc, val, data); \
- if (error != 0) \
- goto fail; \
-} while (0)
-#define urtw_8187_write_phy_ofdm(sc, val, data) do { \
- error = urtw_8187_write_phy_ofdm_c(sc, val, data); \
- if (error != 0) \
- goto fail; \
-} while (0)
-#define urtw_8187_write_phy_cck(sc, val, data) do { \
- error = urtw_8187_write_phy_cck_c(sc, val, data); \
- if (error != 0) \
- goto fail; \
-} while (0)
-#define urtw_8225_write(sc, val, data) do { \
- error = urtw_8225_write_c(sc, val, data); \
- if (error != 0) \
- goto fail; \
-} while (0)
-
-struct urtw_pair {
- uint32_t reg;
- uint32_t val;
-};
-
-static uint8_t urtw_8225_agc[] = {
- 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9d, 0x9c, 0x9b,
- 0x9a, 0x99, 0x98, 0x97, 0x96, 0x95, 0x94, 0x93, 0x92, 0x91, 0x90,
- 0x8f, 0x8e, 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86, 0x85,
- 0x84, 0x83, 0x82, 0x81, 0x80, 0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a,
- 0x39, 0x38, 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f,
- 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24,
- 0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19,
- 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e,
- 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03,
- 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
-};
-
-static uint32_t urtw_8225_channel[] = {
- 0x0000, /* dummy channel 0 */
- 0x085c, /* 1 */
- 0x08dc, /* 2 */
- 0x095c, /* 3 */
- 0x09dc, /* 4 */
- 0x0a5c, /* 5 */
- 0x0adc, /* 6 */
- 0x0b5c, /* 7 */
- 0x0bdc, /* 8 */
- 0x0c5c, /* 9 */
- 0x0cdc, /* 10 */
- 0x0d5c, /* 11 */
- 0x0ddc, /* 12 */
- 0x0e5c, /* 13 */
- 0x0f72, /* 14 */
-};
-
-static uint8_t urtw_8225_gain[] = {
- 0x23, 0x88, 0x7c, 0xa5, /* -82dbm */
- 0x23, 0x88, 0x7c, 0xb5, /* -82dbm */
- 0x23, 0x88, 0x7c, 0xc5, /* -82dbm */
- 0x33, 0x80, 0x79, 0xc5, /* -78dbm */
- 0x43, 0x78, 0x76, 0xc5, /* -74dbm */
- 0x53, 0x60, 0x73, 0xc5, /* -70dbm */
- 0x63, 0x58, 0x70, 0xc5, /* -66dbm */
-};
-
-static struct urtw_pair urtw_8225_rf_part1[] = {
- { 0x00, 0x0067 }, { 0x01, 0x0fe0 }, { 0x02, 0x044d }, { 0x03, 0x0441 },
- { 0x04, 0x0486 }, { 0x05, 0x0bc0 }, { 0x06, 0x0ae6 }, { 0x07, 0x082a },
- { 0x08, 0x001f }, { 0x09, 0x0334 }, { 0x0a, 0x0fd4 }, { 0x0b, 0x0391 },
- { 0x0c, 0x0050 }, { 0x0d, 0x06db }, { 0x0e, 0x0029 }, { 0x0f, 0x0914 },
-};
-
-static struct urtw_pair urtw_8225_rf_part2[] = {
- { 0x00, 0x01 }, { 0x01, 0x02 }, { 0x02, 0x42 }, { 0x03, 0x00 },
- { 0x04, 0x00 }, { 0x05, 0x00 }, { 0x06, 0x40 }, { 0x07, 0x00 },
- { 0x08, 0x40 }, { 0x09, 0xfe }, { 0x0a, 0x09 }, { 0x0b, 0x80 },
- { 0x0c, 0x01 }, { 0x0e, 0xd3 }, { 0x0f, 0x38 }, { 0x10, 0x84 },
- { 0x11, 0x06 }, { 0x12, 0x20 }, { 0x13, 0x20 }, { 0x14, 0x00 },
- { 0x15, 0x40 }, { 0x16, 0x00 }, { 0x17, 0x40 }, { 0x18, 0xef },
- { 0x19, 0x19 }, { 0x1a, 0x20 }, { 0x1b, 0x76 }, { 0x1c, 0x04 },
- { 0x1e, 0x95 }, { 0x1f, 0x75 }, { 0x20, 0x1f }, { 0x21, 0x27 },
- { 0x22, 0x16 }, { 0x24, 0x46 }, { 0x25, 0x20 }, { 0x26, 0x90 },
- { 0x27, 0x88 }
-};
-
-static struct urtw_pair urtw_8225_rf_part3[] = {
- { 0x00, 0x98 }, { 0x03, 0x20 }, { 0x04, 0x7e }, { 0x05, 0x12 },
- { 0x06, 0xfc }, { 0x07, 0x78 }, { 0x08, 0x2e }, { 0x10, 0x9b },
- { 0x11, 0x88 }, { 0x12, 0x47 }, { 0x13, 0xd0 }, { 0x19, 0x00 },
- { 0x1a, 0xa0 }, { 0x1b, 0x08 }, { 0x40, 0x86 }, { 0x41, 0x8d },
- { 0x42, 0x15 }, { 0x43, 0x18 }, { 0x44, 0x1f }, { 0x45, 0x1e },
- { 0x46, 0x1a }, { 0x47, 0x15 }, { 0x48, 0x10 }, { 0x49, 0x0a },
- { 0x4a, 0x05 }, { 0x4b, 0x02 }, { 0x4c, 0x05 }
-};
-
-static uint16_t urtw_8225_rxgain[] = {
- 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
- 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
- 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
- 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
- 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
- 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
- 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
- 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
- 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
- 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
- 0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3,
- 0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb
-};
-
-static uint8_t urtw_8225_threshold[] = {
- 0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd,
-};
-
-static uint8_t urtw_8225_tx_gain_cck_ofdm[] = {
- 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e
-};
-
-static uint8_t urtw_8225_txpwr_cck[] = {
- 0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02,
- 0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02,
- 0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02,
- 0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02,
- 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03,
- 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03
-};
-
-static uint8_t urtw_8225_txpwr_cck_ch14[] = {
- 0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00,
- 0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00,
- 0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00,
- 0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00,
- 0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00,
- 0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00
-};
-
-static uint8_t urtw_8225_txpwr_ofdm[]={
- 0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4
-};
-
-static uint8_t urtw_8225v2_gain_bg[]={
- 0x23, 0x15, 0xa5, /* -82-1dbm */
- 0x23, 0x15, 0xb5, /* -82-2dbm */
- 0x23, 0x15, 0xc5, /* -82-3dbm */
- 0x33, 0x15, 0xc5, /* -78dbm */
- 0x43, 0x15, 0xc5, /* -74dbm */
- 0x53, 0x15, 0xc5, /* -70dbm */
- 0x63, 0x15, 0xc5, /* -66dbm */
-};
-
-static struct urtw_pair urtw_8225v2_rf_part1[] = {
- { 0x00, 0x02bf }, { 0x01, 0x0ee0 }, { 0x02, 0x044d }, { 0x03, 0x0441 },
- { 0x04, 0x08c3 }, { 0x05, 0x0c72 }, { 0x06, 0x00e6 }, { 0x07, 0x082a },
- { 0x08, 0x003f }, { 0x09, 0x0335 }, { 0x0a, 0x09d4 }, { 0x0b, 0x07bb },
- { 0x0c, 0x0850 }, { 0x0d, 0x0cdf }, { 0x0e, 0x002b }, { 0x0f, 0x0114 }
-};
-
-static struct urtw_pair urtw_8225v2_rf_part2[] = {
- { 0x00, 0x01 }, { 0x01, 0x02 }, { 0x02, 0x42 }, { 0x03, 0x00 },
- { 0x04, 0x00 }, { 0x05, 0x00 }, { 0x06, 0x40 }, { 0x07, 0x00 },
- { 0x08, 0x40 }, { 0x09, 0xfe }, { 0x0a, 0x08 }, { 0x0b, 0x80 },
- { 0x0c, 0x01 }, { 0x0d, 0x43 }, { 0x0e, 0xd3 }, { 0x0f, 0x38 },
- { 0x10, 0x84 }, { 0x11, 0x07 }, { 0x12, 0x20 }, { 0x13, 0x20 },
- { 0x14, 0x00 }, { 0x15, 0x40 }, { 0x16, 0x00 }, { 0x17, 0x40 },
- { 0x18, 0xef }, { 0x19, 0x19 }, { 0x1a, 0x20 }, { 0x1b, 0x15 },
- { 0x1c, 0x04 }, { 0x1d, 0xc5 }, { 0x1e, 0x95 }, { 0x1f, 0x75 },
- { 0x20, 0x1f }, { 0x21, 0x17 }, { 0x22, 0x16 }, { 0x23, 0x80 },
- { 0x24, 0x46 }, { 0x25, 0x00 }, { 0x26, 0x90 }, { 0x27, 0x88 }
-};
-
-static struct urtw_pair urtw_8225v2_rf_part3[] = {
- { 0x00, 0x98 }, { 0x03, 0x20 }, { 0x04, 0x7e }, { 0x05, 0x12 },
- { 0x06, 0xfc }, { 0x07, 0x78 }, { 0x08, 0x2e }, { 0x09, 0x11 },
- { 0x0a, 0x17 }, { 0x0b, 0x11 }, { 0x10, 0x9b }, { 0x11, 0x88 },
- { 0x12, 0x47 }, { 0x13, 0xd0 }, { 0x19, 0x00 }, { 0x1a, 0xa0 },
- { 0x1b, 0x08 }, { 0x1d, 0x00 }, { 0x40, 0x86 }, { 0x41, 0x9d },
- { 0x42, 0x15 }, { 0x43, 0x18 }, { 0x44, 0x36 }, { 0x45, 0x35 },
- { 0x46, 0x2e }, { 0x47, 0x25 }, { 0x48, 0x1c }, { 0x49, 0x12 },
- { 0x4a, 0x09 }, { 0x4b, 0x04 }, { 0x4c, 0x05 }
-};
-
-static uint16_t urtw_8225v2_rxgain[] = {
- 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0008, 0x0009,
- 0x000a, 0x000b, 0x0102, 0x0103, 0x0104, 0x0105, 0x0140, 0x0141,
- 0x0142, 0x0143, 0x0144, 0x0145, 0x0180, 0x0181, 0x0182, 0x0183,
- 0x0184, 0x0185, 0x0188, 0x0189, 0x018a, 0x018b, 0x0243, 0x0244,
- 0x0245, 0x0280, 0x0281, 0x0282, 0x0283, 0x0284, 0x0285, 0x0288,
- 0x0289, 0x028a, 0x028b, 0x028c, 0x0342, 0x0343, 0x0344, 0x0345,
- 0x0380, 0x0381, 0x0382, 0x0383, 0x0384, 0x0385, 0x0388, 0x0389,
- 0x038a, 0x038b, 0x038c, 0x038d, 0x0390, 0x0391, 0x0392, 0x0393,
- 0x0394, 0x0395, 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d,
- 0x03a0, 0x03a1, 0x03a2, 0x03a3, 0x03a4, 0x03a5, 0x03a8, 0x03a9,
- 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
- 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
-};
-
-static uint8_t urtw_8225v2_tx_gain_cck_ofdm[] = {
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
- 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
- 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
- 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
- 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
-};
-
-static uint8_t urtw_8225v2_txpwr_cck[] = {
- 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04
-};
-
-static uint8_t urtw_8225v2_txpwr_cck_ch14[] = {
- 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00
-};
-
-static struct urtw_pair urtw_ratetable[] = {
- { 2, 0 }, { 4, 1 }, { 11, 2 }, { 12, 4 }, { 18, 5 },
- { 22, 3 }, { 24, 6 }, { 36, 7 }, { 48, 8 }, { 72, 9 },
- { 96, 10 }, { 108, 11 }
-};
-
-static struct ieee80211vap *urtw_vap_create(struct ieee80211com *,
- const char name[IFNAMSIZ], int unit, int opmode,
- int flags, const uint8_t bssid[IEEE80211_ADDR_LEN],
- const uint8_t mac[IEEE80211_ADDR_LEN]);
-static void urtw_vap_delete(struct ieee80211vap *);
-static void urtw_init(void *);
-static void urtw_stop(struct ifnet *, int);
-static int urtw_ioctl(struct ifnet *, u_long, caddr_t);
-static void urtw_start(struct ifnet *);
-static int urtw_alloc_rx_data_list(struct urtw_softc *);
-static int urtw_alloc_tx_data_list(struct urtw_softc *);
-static void urtw_free_data_list(struct urtw_softc *,
- usbd_pipe_handle, usbd_pipe_handle,
- struct urtw_data data[], int);
-static int urtw_raw_xmit(struct ieee80211_node *, struct mbuf *,
- const struct ieee80211_bpf_params *);
-static void urtw_scan_start(struct ieee80211com *);
-static void urtw_scan_end(struct ieee80211com *);
-static void urtw_set_channel(struct ieee80211com *);
-static void urtw_update_mcast(struct ifnet *);
-static void urtw_rxeof(usbd_xfer_handle, usbd_private_handle,
- usbd_status);
-static int urtw_tx_start(struct urtw_softc *,
- struct ieee80211_node *, struct mbuf *, int);
-static void urtw_txeof_low(usbd_xfer_handle, usbd_private_handle,
- usbd_status);
-static void urtw_txeof_normal(usbd_xfer_handle,
- usbd_private_handle, usbd_status);
-static int urtw_newstate(struct ieee80211vap *,
- enum ieee80211_state, int);
-static void urtw_ledtask(void *);
-static void urtw_ledusbtask(void *);
-static void urtw_ctxtask(void *);
-static void urtw_task(void *);
-static void urtw_watchdog(void *);
-static void urtw_set_multi(void *);
-static int urtw_isbmode(uint16_t);
-static uint16_t urtw_rate2rtl(int);
-static uint16_t urtw_rtl2rate(int);
-static usbd_status urtw_set_rate(struct urtw_softc *);
-static usbd_status urtw_update_msr(struct urtw_softc *);
-static usbd_status urtw_read8_c(struct urtw_softc *, int, uint8_t *);
-static usbd_status urtw_read16_c(struct urtw_softc *, int, uint16_t *);
-static usbd_status urtw_read32_c(struct urtw_softc *, int, uint32_t *);
-static usbd_status urtw_write8_c(struct urtw_softc *, int, uint8_t);
-static usbd_status urtw_write16_c(struct urtw_softc *, int, uint16_t);
-static usbd_status urtw_write32_c(struct urtw_softc *, int, uint32_t);
-static usbd_status urtw_eprom_cs(struct urtw_softc *, int);
-static usbd_status urtw_eprom_ck(struct urtw_softc *);
-static usbd_status urtw_eprom_sendbits(struct urtw_softc *, int16_t *,
- int);
-static usbd_status urtw_eprom_read32(struct urtw_softc *, uint32_t,
- uint32_t *);
-static usbd_status urtw_eprom_readbit(struct urtw_softc *, int16_t *);
-static usbd_status urtw_eprom_writebit(struct urtw_softc *, int16_t);
-static usbd_status urtw_get_macaddr(struct urtw_softc *);
-static usbd_status urtw_get_txpwr(struct urtw_softc *);
-static usbd_status urtw_get_rfchip(struct urtw_softc *);
-static usbd_status urtw_led_init(struct urtw_softc *);
-static usbd_status urtw_8185_rf_pins_enable(struct urtw_softc *);
-static usbd_status urtw_8185_tx_antenna(struct urtw_softc *, uint8_t);
-static usbd_status urtw_8187_write_phy(struct urtw_softc *, uint8_t,
- uint32_t);
-static usbd_status urtw_8187_write_phy_ofdm_c(struct urtw_softc *,
- uint8_t, uint32_t);
-static usbd_status urtw_8187_write_phy_cck_c(struct urtw_softc *, uint8_t,
- uint32_t);
-static usbd_status urtw_8225_setgain(struct urtw_softc *, int16_t);
-static usbd_status urtw_8225_usb_init(struct urtw_softc *);
-static usbd_status urtw_8225_write_c(struct urtw_softc *, uint8_t,
- uint16_t);
-static usbd_status urtw_8225_write_s16(struct urtw_softc *, uint8_t, int,
- uint16_t *);
-static usbd_status urtw_8225_read(struct urtw_softc *, uint8_t,
- uint32_t *);
-static usbd_status urtw_8225_rf_init(struct urtw_softc *);
-static usbd_status urtw_8225_rf_set_chan(struct urtw_softc *, int);
-static usbd_status urtw_8225_rf_set_sens(struct urtw_softc *, int);
-static usbd_status urtw_8225_set_txpwrlvl(struct urtw_softc *, int);
-static usbd_status urtw_8225v2_rf_init(struct urtw_softc *);
-static usbd_status urtw_8225v2_rf_set_chan(struct urtw_softc *, int);
-static usbd_status urtw_8225v2_set_txpwrlvl(struct urtw_softc *, int);
-static usbd_status urtw_8225v2_setgain(struct urtw_softc *, int16_t);
-static usbd_status urtw_8225_isv2(struct urtw_softc *, int *);
-static usbd_status urtw_read8e(struct urtw_softc *, int, uint8_t *);
-static usbd_status urtw_write8e(struct urtw_softc *, int, uint8_t);
-static usbd_status urtw_8180_set_anaparam(struct urtw_softc *, uint32_t);
-static usbd_status urtw_8185_set_anaparam2(struct urtw_softc *, uint32_t);
-static usbd_status urtw_open_pipes(struct urtw_softc *);
-static usbd_status urtw_close_pipes(struct urtw_softc *);
-static usbd_status urtw_intr_enable(struct urtw_softc *);
-static usbd_status urtw_intr_disable(struct urtw_softc *);
-static usbd_status urtw_reset(struct urtw_softc *);
-static usbd_status urtw_led_on(struct urtw_softc *, int);
-static usbd_status urtw_led_ctl(struct urtw_softc *, int);
-static usbd_status urtw_led_blink(struct urtw_softc *);
-static usbd_status urtw_led_mode0(struct urtw_softc *, int);
-static usbd_status urtw_led_mode1(struct urtw_softc *, int);
-static usbd_status urtw_led_mode2(struct urtw_softc *, int);
-static usbd_status urtw_led_mode3(struct urtw_softc *, int);
-static usbd_status urtw_rx_setconf(struct urtw_softc *);
-static usbd_status urtw_rx_enable(struct urtw_softc *);
-static usbd_status urtw_tx_enable(struct urtw_softc *sc);
-
-static int
-urtw_match(device_t dev)
-{
- struct usb_attach_arg *uaa = device_get_ivars(dev);
- const struct usb_devno *ud;
-
- if (uaa->iface != NULL)
- return UMATCH_NONE;
- ud = usb_lookup(urtw_devs, uaa->vendor, uaa->product);
-
- return (ud != NULL ? UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
-}
-
-static int
-urtw_attach(device_t dev)
-{
- int ret = 0;
- struct urtw_softc *sc = device_get_softc(dev);
- struct usb_attach_arg *uaa = device_get_ivars(dev);
- struct ieee80211com *ic;
- struct ifnet *ifp;
- uint8_t bands;
- uint32_t data;
- usbd_status error;
-
- sc->sc_dev = dev;
- sc->sc_udev = uaa->device;
-#ifdef URTW_DEBUG
- sc->sc_debug = urtw_debug;
-#endif
-
- mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev), MTX_NETWORK_LOCK,
- MTX_DEF);
- callout_init(&sc->sc_led_ch, 0);
- callout_init(&sc->sc_watchdog_ch, 0);
- usb_init_task(&sc->sc_ledtask, urtw_ledusbtask, sc);
- usb_init_task(&sc->sc_ctxtask, urtw_ctxtask, sc);
- usb_init_task(&sc->sc_task, urtw_task, sc);
-
- urtw_read32_m(sc, URTW_RX, &data);
- sc->sc_epromtype = (data & URTW_RX_9356SEL) ? URTW_EEPROM_93C56 :
- URTW_EEPROM_93C46;
-
- error = urtw_get_rfchip(sc);
- if (error != 0)
- goto fail;
- error = urtw_get_macaddr(sc);
- if (error != 0)
- goto fail;
- error = urtw_get_txpwr(sc);
- if (error != 0)
- goto fail;
- error = urtw_led_init(sc);
- if (error != 0)
- goto fail;
-
- sc->sc_rts_retry = URTW_DEFAULT_RTS_RETRY;
- sc->sc_tx_retry = URTW_DEFAULT_TX_RETRY;
- sc->sc_currate = 3;
- sc->sc_preamble_mode = urtw_preamble_mode;
-
- ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
- if (ifp == NULL) {
- device_printf(sc->sc_dev, "can not allocate ifnet\n");
- ret = ENXIO;
- goto fail;
- }
-
- ifp->if_softc = sc;
- if_initname(ifp, "urtw", device_get_unit(sc->sc_dev));
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
- IFF_NEEDSGIANT; /* USB stack is still under Giant lock */
- ifp->if_init = urtw_init;
- ifp->if_ioctl = urtw_ioctl;
- ifp->if_start = urtw_start;
- /* XXX URTW_TX_DATA_LIST_COUNT */
- IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
- ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
- IFQ_SET_READY(&ifp->if_snd);
-
- ic = ifp->if_l2com;
- ic->ic_ifp = ifp;
- ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
- ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
-
- /* set device capabilities */
- ic->ic_caps =
- IEEE80211_C_STA | /* station mode */
- IEEE80211_C_MONITOR | /* monitor mode supported */
- IEEE80211_C_TXPMGT | /* tx power management */
- IEEE80211_C_SHPREAMBLE | /* short preamble supported */
- IEEE80211_C_SHSLOT | /* short slot time supported */
- IEEE80211_C_BGSCAN | /* capable of bg scanning */
- IEEE80211_C_WPA; /* 802.11i */
-
- IEEE80211_ADDR_COPY(ic->ic_myaddr, sc->sc_bssid);
-
- bands = 0;
- setbit(&bands, IEEE80211_MODE_11B);
- setbit(&bands, IEEE80211_MODE_11G);
- ieee80211_init_channels(ic, NULL, &bands);
-
- ieee80211_ifattach(ic);
- ic->ic_raw_xmit = urtw_raw_xmit;
- ic->ic_scan_start = urtw_scan_start;
- ic->ic_scan_end = urtw_scan_end;
- ic->ic_set_channel = urtw_set_channel;
-
- ic->ic_vap_create = urtw_vap_create;
- ic->ic_vap_delete = urtw_vap_delete;
- ic->ic_update_mcast = urtw_update_mcast;
-
- bpfattach(ifp, DLT_IEEE802_11_RADIO,
- sizeof (struct ieee80211_frame) + sizeof(sc->sc_txtap));
-
- sc->sc_rxtap_len = sizeof sc->sc_rxtap;
- sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
- sc->sc_rxtap.wr_ihdr.it_present = htole32(URTW_RX_RADIOTAP_PRESENT);
-
- sc->sc_txtap_len = sizeof sc->sc_txtap;
- sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
- sc->sc_txtap.wt_ihdr.it_present = htole32(URTW_TX_RADIOTAP_PRESENT);
-
- if (bootverbose)
- ieee80211_announce(ic);
-
- usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev);
-fail:
- return (ret);
-}
-
-static usbd_status
-urtw_open_pipes(struct urtw_softc *sc)
-{
- usbd_status error;
-
- /*
- * NB: there is no way to distinguish each pipes so we need to hardcode
- * pipe numbers
- */
-
- /* tx pipe - low priority packets */
- error = usbd_open_pipe(sc->sc_iface, 0x2, USBD_EXCLUSIVE_USE,
- &sc->sc_txpipe_low);
- if (error != 0) {
- device_printf(sc->sc_dev, "could not open Tx low pipe: %s\n",
- usbd_errstr(error));
- goto fail;
- }
- /* tx pipe - normal priority packets */
- error = usbd_open_pipe(sc->sc_iface, 0x3, USBD_EXCLUSIVE_USE,
- &sc->sc_txpipe_normal);
- if (error != 0) {
- device_printf(sc->sc_dev, "could not open Tx normal pipe: %s\n",
- usbd_errstr(error));
- goto fail;
- }
- /* rx pipe */
- error = usbd_open_pipe(sc->sc_iface, 0x81, USBD_EXCLUSIVE_USE,
- &sc->sc_rxpipe);
- if (error != 0) {
- device_printf(sc->sc_dev, "could not open Rx pipe: %s\n",
- usbd_errstr(error));
- goto fail;
- }
-
- return (0);
-fail:
- (void)urtw_close_pipes(sc);
- return (error);
-}
-
-static usbd_status
-urtw_close_pipes(struct urtw_softc *sc)
-{
- usbd_status error = 0;
-
- if (sc->sc_rxpipe != NULL) {
- error = usbd_close_pipe(sc->sc_rxpipe);
- if (error != 0)
- goto fail;
- sc->sc_rxpipe = NULL;
- }
- if (sc->sc_txpipe_low != NULL) {
- error = usbd_close_pipe(sc->sc_txpipe_low);
- if (error != 0)
- goto fail;
- sc->sc_txpipe_low = NULL;
- }
- if (sc->sc_txpipe_normal != NULL) {
- error = usbd_close_pipe(sc->sc_txpipe_normal);
- if (error != 0)
- goto fail;
- sc->sc_txpipe_normal = NULL;
- }
-fail:
- return (error);
-}
-
-static int
-urtw_alloc_data_list(struct urtw_softc *sc, struct urtw_data data[],
- int ndata, int maxsz, int fillmbuf)
-{
- int i, error;
-
- for (i = 0; i < ndata; i++) {
- struct urtw_data *dp = &data[i];
-
- dp->sc = sc;
- dp->xfer = usbd_alloc_xfer(sc->sc_udev);
- if (dp->xfer == NULL) {
- device_printf(sc->sc_dev, "could not allocate xfer\n");
- error = ENOMEM;
- goto fail;
- }
- if (fillmbuf) {
- dp->m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
- if (dp->m == NULL) {
- device_printf(sc->sc_dev,
- "could not allocate rx mbuf\n");
- error = ENOMEM;
- goto fail;
- }
- dp->buf = mtod(dp->m, uint8_t *);
- } else {
- dp->m = NULL;
- dp->buf = usbd_alloc_buffer(dp->xfer, maxsz);
- if (dp->buf == NULL) {
- device_printf(sc->sc_dev,
- "could not allocate buffer\n");
- error = ENOMEM;
- goto fail;
- }
- if (((unsigned long)dp->buf) % 4)
- device_printf(sc->sc_dev,
- "warn: unaligned buffer %p\n", dp->buf);
- }
- dp->ni = NULL;
- }
-
- return 0;
-
-fail: urtw_free_data_list(sc, NULL, NULL, data, ndata);
- return error;
-}
-
-static void
-urtw_free_data_list(struct urtw_softc *sc, usbd_pipe_handle pipe1,
- usbd_pipe_handle pipe2, struct urtw_data data[], int ndata)
-{
- int i;
-
- /* make sure no transfers are pending */
- if (pipe1 != NULL)
- usbd_abort_pipe(pipe1);
- if (pipe2 != NULL)
- usbd_abort_pipe(pipe2);
-
- for (i = 0; i < ndata; i++) {
- struct urtw_data *dp = &data[i];
-
- if (dp->xfer != NULL) {
- usbd_free_xfer(dp->xfer);
- dp->xfer = NULL;
- }
- if (dp->m != NULL) {
- m_freem(dp->m);
- dp->m = NULL;
- }
- if (dp->ni != NULL) {
- ieee80211_free_node(dp->ni);
- dp->ni = NULL;
- }
- }
-}
-
-static int
-urtw_alloc_rx_data_list(struct urtw_softc *sc)
-{
-
- return urtw_alloc_data_list(sc,
- sc->sc_rxdata, URTW_RX_DATA_LIST_COUNT, MCLBYTES, 1 /* mbufs */);
-}
-
-static void
-urtw_free_rx_data_list(struct urtw_softc *sc)
-{
-
- urtw_free_data_list(sc, sc->sc_rxpipe, NULL, sc->sc_rxdata,
- URTW_RX_DATA_LIST_COUNT);
-}
-
-static int
-urtw_alloc_tx_data_list(struct urtw_softc *sc)
-{
-
- return urtw_alloc_data_list(sc,
- sc->sc_txdata, URTW_TX_DATA_LIST_COUNT, URTW_TX_MAXSIZE,
- 0 /* no mbufs */);
-}
-
-static void
-urtw_free_tx_data_list(struct urtw_softc *sc)
-{
-
- urtw_free_data_list(sc, sc->sc_txpipe_low, sc->sc_txpipe_normal,
- sc->sc_txdata, URTW_TX_DATA_LIST_COUNT);
-}
-
-static usbd_status
-urtw_led_init(struct urtw_softc *sc)
-{
- uint32_t rev;
- usbd_status error;
-
- urtw_read8_m(sc, URTW_PSR, &sc->sc_psr);
- error = urtw_eprom_read32(sc, URTW_EPROM_SWREV, &rev);
- if (error != 0)
- goto fail;
-
- switch (rev & URTW_EPROM_CID_MASK) {
- case URTW_EPROM_CID_ALPHA0:
- sc->sc_strategy = URTW_SW_LED_MODE1;
- break;
- case URTW_EPROM_CID_SERCOMM_PS:
- sc->sc_strategy = URTW_SW_LED_MODE3;
- break;
- case URTW_EPROM_CID_HW_LED:
- sc->sc_strategy = URTW_HW_LED;
- break;
- case URTW_EPROM_CID_RSVD0:
- case URTW_EPROM_CID_RSVD1:
- default:
- sc->sc_strategy = URTW_SW_LED_MODE0;
- break;
- }
-
- sc->sc_gpio_ledpin = URTW_LED_PIN_GPIO0;
-
-fail:
- return (error);
-}
-
-/* XXX why we should allocalte memory buffer instead of using memory stack? */
-static usbd_status
-urtw_8225_write_s16(struct urtw_softc *sc, uint8_t addr, int index,
- uint16_t *data)
-{
- uint8_t *buf;
- uint16_t data16;
- usb_device_request_t *req;
- usbd_status error = 0;
-
- data16 = *data;
- req = (usb_device_request_t *)malloc(sizeof(usb_device_request_t),
- M_80211_VAP, M_NOWAIT | M_ZERO);
- if (req == NULL) {
- device_printf(sc->sc_dev, "could not allocate a memory\n");
- goto fail0;
- }
- buf = (uint8_t *)malloc(2, M_80211_VAP, M_NOWAIT | M_ZERO);
- if (req == NULL) {
- device_printf(sc->sc_dev, "could not allocate a memory\n");
- goto fail1;
- }
-
- req->bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req->bRequest = URTW_8187_SETREGS_REQ;
- USETW(req->wValue, addr);
- USETW(req->wIndex, index);
- USETW(req->wLength, sizeof(uint16_t));
- buf[0] = (data16 & 0x00ff);
- buf[1] = (data16 & 0xff00) >> 8;
-
- error = usbd_do_request(sc->sc_udev, req, buf);
-
- free(buf, M_80211_VAP);
-fail1: free(req, M_80211_VAP);
-fail0: return (error);
-}
-
-static usbd_status
-urtw_8225_read(struct urtw_softc *sc, uint8_t addr, uint32_t *data)
-{
- int i;
- int16_t bit;
- uint8_t rlen = 12, wlen = 6;
- uint16_t o1, o2, o3, tmp;
- uint32_t d2w = ((uint32_t)(addr & 0x1f)) << 27;
- uint32_t mask = 0x80000000, value = 0;
- usbd_status error;
-
- urtw_read16_m(sc, URTW_RF_PINS_OUTPUT, &o1);
- urtw_read16_m(sc, URTW_RF_PINS_ENABLE, &o2);
- urtw_read16_m(sc, URTW_RF_PINS_SELECT, &o3);
- urtw_write16_m(sc, URTW_RF_PINS_ENABLE, o2 | URTW_RF_PINS_MAGIC4);
- urtw_write16_m(sc, URTW_RF_PINS_SELECT, o3 | URTW_RF_PINS_MAGIC4);
- o1 &= ~URTW_RF_PINS_MAGIC4;
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1 | URTW_BB_HOST_BANG_EN);
- DELAY(5);
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1);
- DELAY(5);
-
- for (i = 0; i < (wlen / 2); i++, mask = mask >> 1) {
- bit = ((d2w & mask) != 0) ? 1 : 0;
-
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1);
- DELAY(2);
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
- URTW_BB_HOST_BANG_CLK);
- DELAY(2);
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
- URTW_BB_HOST_BANG_CLK);
- DELAY(2);
- mask = mask >> 1;
- if (i == 2)
- break;
- bit = ((d2w & mask) != 0) ? 1 : 0;
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
- URTW_BB_HOST_BANG_CLK);
- DELAY(2);
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 |
- URTW_BB_HOST_BANG_CLK);
- DELAY(2);
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1);
- DELAY(1);
- }
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 | URTW_BB_HOST_BANG_RW |
- URTW_BB_HOST_BANG_CLK);
- DELAY(2);
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, bit | o1 | URTW_BB_HOST_BANG_RW);
- DELAY(2);
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1 | URTW_BB_HOST_BANG_RW);
- DELAY(2);
-
- mask = 0x800;
- for (i = 0; i < rlen; i++, mask = mask >> 1) {
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
- o1 | URTW_BB_HOST_BANG_RW);
- DELAY(2);
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
- o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK);
- DELAY(2);
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
- o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK);
- DELAY(2);
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
- o1 | URTW_BB_HOST_BANG_RW | URTW_BB_HOST_BANG_CLK);
- DELAY(2);
-
- urtw_read16_m(sc, URTW_RF_PINS_INPUT, &tmp);
- value |= ((tmp & URTW_BB_HOST_BANG_CLK) ? mask : 0);
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT,
- o1 | URTW_BB_HOST_BANG_RW);
- DELAY(2);
- }
-
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, o1 | URTW_BB_HOST_BANG_EN |
- URTW_BB_HOST_BANG_RW);
- DELAY(2);
-
- urtw_write16_m(sc, URTW_RF_PINS_ENABLE, o2);
- urtw_write16_m(sc, URTW_RF_PINS_SELECT, o3);
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, URTW_RF_PINS_OUTPUT_MAGIC1);
-
- if (data != NULL)
- *data = value;
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_8225_write_c(struct urtw_softc *sc, uint8_t addr, uint16_t data)
-{
- uint16_t d80, d82, d84;
- usbd_status error;
-
- urtw_read16_m(sc, URTW_RF_PINS_OUTPUT, &d80);
- d80 &= URTW_RF_PINS_MAGIC1;
- urtw_read16_m(sc, URTW_RF_PINS_ENABLE, &d82);
- urtw_read16_m(sc, URTW_RF_PINS_SELECT, &d84);
- d84 &= URTW_RF_PINS_MAGIC2;
- urtw_write16_m(sc, URTW_RF_PINS_ENABLE, d82 | URTW_RF_PINS_MAGIC3);
- urtw_write16_m(sc, URTW_RF_PINS_SELECT, d84 | URTW_RF_PINS_MAGIC3);
- DELAY(10);
-
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80 | URTW_BB_HOST_BANG_EN);
- DELAY(2);
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80);
- DELAY(10);
-
- error = urtw_8225_write_s16(sc, addr, 0x8225, &data);
- if (error != 0)
- goto fail;
-
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80 | URTW_BB_HOST_BANG_EN);
- DELAY(10);
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, d80 | URTW_BB_HOST_BANG_EN);
- urtw_write16_m(sc, URTW_RF_PINS_SELECT, d84);
- usbd_delay_ms(sc->sc_udev, 2);
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_8225_isv2(struct urtw_softc *sc, int *ret)
-{
- uint32_t data;
- usbd_status error;
-
- *ret = 1;
-
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, URTW_RF_PINS_MAGIC5);
- urtw_write16_m(sc, URTW_RF_PINS_SELECT, URTW_RF_PINS_MAGIC5);
- urtw_write16_m(sc, URTW_RF_PINS_ENABLE, URTW_RF_PINS_MAGIC5);
- usbd_delay_ms(sc->sc_udev, 500);
-
- urtw_8225_write(sc, URTW_8225_ADDR_0_MAGIC,
- URTW_8225_ADDR_0_DATA_MAGIC1);
-
- error = urtw_8225_read(sc, URTW_8225_ADDR_8_MAGIC, &data);
- if (error != 0)
- goto fail;
- if (data != URTW_8225_ADDR_8_DATA_MAGIC1)
- *ret = 0;
- else {
- error = urtw_8225_read(sc, URTW_8225_ADDR_9_MAGIC, &data);
- if (error != 0)
- goto fail;
- if (data != URTW_8225_ADDR_9_DATA_MAGIC1)
- *ret = 0;
- }
-
- urtw_8225_write(sc, URTW_8225_ADDR_0_MAGIC,
- URTW_8225_ADDR_0_DATA_MAGIC2);
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_get_rfchip(struct urtw_softc *sc)
-{
- int ret;
- uint32_t data;
- usbd_status error;
-
- error = urtw_eprom_read32(sc, URTW_EPROM_RFCHIPID, &data);
- if (error != 0)
- goto fail;
- switch (data & 0xff) {
- case URTW_EPROM_RFCHIPID_RTL8225U:
- error = urtw_8225_isv2(sc, &ret);
- if (error != 0)
- goto fail;
- if (ret == 0) {
- sc->sc_rf_init = urtw_8225_rf_init;
- sc->sc_rf_set_sens = urtw_8225_rf_set_sens;
- sc->sc_rf_set_chan = urtw_8225_rf_set_chan;
- } else {
- sc->sc_rf_init = urtw_8225v2_rf_init;
- sc->sc_rf_set_chan = urtw_8225v2_rf_set_chan;
- }
- sc->sc_max_sens = URTW_8225_RF_MAX_SENS;
- sc->sc_sens = URTW_8225_RF_DEF_SENS;
- break;
- default:
- panic("unsupported RF chip %d\n", data & 0xff);
- /* never reach */
- }
-
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_get_txpwr(struct urtw_softc *sc)
-{
- int i, j;
- uint32_t data;
- usbd_status error;
-
- error = urtw_eprom_read32(sc, URTW_EPROM_TXPW_BASE, &data);
- if (error != 0)
- goto fail;
- sc->sc_txpwr_cck_base = data & 0xf;
- sc->sc_txpwr_ofdm_base = (data >> 4) & 0xf;
-
- for (i = 1, j = 0; i < 6; i += 2, j++) {
- error = urtw_eprom_read32(sc, URTW_EPROM_TXPW0 + j, &data);
- if (error != 0)
- goto fail;
- sc->sc_txpwr_cck[i] = data & 0xf;
- sc->sc_txpwr_cck[i + 1] = (data & 0xf00) >> 8;
- sc->sc_txpwr_ofdm[i] = (data & 0xf0) >> 4;
- sc->sc_txpwr_ofdm[i + 1] = (data & 0xf000) >> 12;
- }
- for (i = 1, j = 0; i < 4; i += 2, j++) {
- error = urtw_eprom_read32(sc, URTW_EPROM_TXPW1 + j, &data);
- if (error != 0)
- goto fail;
- sc->sc_txpwr_cck[i + 6] = data & 0xf;
- sc->sc_txpwr_cck[i + 6 + 1] = (data & 0xf00) >> 8;
- sc->sc_txpwr_ofdm[i + 6] = (data & 0xf0) >> 4;
- sc->sc_txpwr_ofdm[i + 6 + 1] = (data & 0xf000) >> 12;
- }
- for (i = 1, j = 0; i < 4; i += 2, j++) {
- error = urtw_eprom_read32(sc, URTW_EPROM_TXPW2 + j, &data);
- if (error != 0)
- goto fail;
- sc->sc_txpwr_cck[i + 6 + 4] = data & 0xf;
- sc->sc_txpwr_cck[i + 6 + 4 + 1] = (data & 0xf00) >> 8;
- sc->sc_txpwr_ofdm[i + 6 + 4] = (data & 0xf0) >> 4;
- sc->sc_txpwr_ofdm[i + 6 + 4 + 1] = (data & 0xf000) >> 12;
- }
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_get_macaddr(struct urtw_softc *sc)
-{
- uint32_t data;
- usbd_status error;
-
- error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR, &data);
- if (error != 0)
- goto fail;
- sc->sc_bssid[0] = data & 0xff;
- sc->sc_bssid[1] = (data & 0xff00) >> 8;
- error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR + 1, &data);
- if (error != 0)
- goto fail;
- sc->sc_bssid[2] = data & 0xff;
- sc->sc_bssid[3] = (data & 0xff00) >> 8;
- error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR + 2, &data);
- if (error != 0)
- goto fail;
- sc->sc_bssid[4] = data & 0xff;
- sc->sc_bssid[5] = (data & 0xff00) >> 8;
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_eprom_read32(struct urtw_softc *sc, uint32_t addr, uint32_t *data)
-{
-#define URTW_READCMD_LEN 3
- int addrlen, i;
- int16_t addrstr[8], data16, readcmd[] = { 1, 1, 0 };
- usbd_status error;
-
- /* NB: make sure the buffer is initialized */
- *data = 0;
-
- /* enable EPROM programming */
- urtw_write8_m(sc, URTW_EPROM_CMD, URTW_EPROM_CMD_PROGRAM_MODE);
- DELAY(URTW_EPROM_DELAY);
-
- error = urtw_eprom_cs(sc, URTW_EPROM_ENABLE);
- if (error != 0)
- goto fail;
- error = urtw_eprom_ck(sc);
- if (error != 0)
- goto fail;
- error = urtw_eprom_sendbits(sc, readcmd, URTW_READCMD_LEN);
- if (error != 0)
- goto fail;
- if (sc->sc_epromtype == URTW_EEPROM_93C56) {
- addrlen = 8;
- addrstr[0] = addr & (1 << 7);
- addrstr[1] = addr & (1 << 6);
- addrstr[2] = addr & (1 << 5);
- addrstr[3] = addr & (1 << 4);
- addrstr[4] = addr & (1 << 3);
- addrstr[5] = addr & (1 << 2);
- addrstr[6] = addr & (1 << 1);
- addrstr[7] = addr & (1 << 0);
- } else {
- addrlen=6;
- addrstr[0] = addr & (1 << 5);
- addrstr[1] = addr & (1 << 4);
- addrstr[2] = addr & (1 << 3);
- addrstr[3] = addr & (1 << 2);
- addrstr[4] = addr & (1 << 1);
- addrstr[5] = addr & (1 << 0);
- }
- error = urtw_eprom_sendbits(sc, addrstr, addrlen);
- if (error != 0)
- goto fail;
-
- error = urtw_eprom_writebit(sc, 0);
- if (error != 0)
- goto fail;
-
- for (i = 0; i < 16; i++) {
- error = urtw_eprom_ck(sc);
- if (error != 0)
- goto fail;
- error = urtw_eprom_readbit(sc, &data16);
- if (error != 0)
- goto fail;
-
- (*data) |= (data16 << (15 - i));
- }
-
- error = urtw_eprom_cs(sc, URTW_EPROM_DISABLE);
- if (error != 0)
- goto fail;
- error = urtw_eprom_ck(sc);
- if (error != 0)
- goto fail;
-
- /* now disable EPROM programming */
- urtw_write8_m(sc, URTW_EPROM_CMD, URTW_EPROM_CMD_NORMAL_MODE);
-fail:
- return (error);
-#undef URTW_READCMD_LEN
-}
-
-static usbd_status
-urtw_eprom_readbit(struct urtw_softc *sc, int16_t *data)
-{
- uint8_t data8;
- usbd_status error;
-
- urtw_read8_m(sc, URTW_EPROM_CMD, &data8);
- *data = (data8 & URTW_EPROM_READBIT) ? 1 : 0;
- DELAY(URTW_EPROM_DELAY);
-
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_eprom_sendbits(struct urtw_softc *sc, int16_t *buf, int buflen)
-{
- int i = 0;
- usbd_status error = 0;
-
- for (i = 0; i < buflen; i++) {
- error = urtw_eprom_writebit(sc, buf[i]);
- if (error != 0)
- goto fail;
- error = urtw_eprom_ck(sc);
- if (error != 0)
- goto fail;
- }
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_eprom_writebit(struct urtw_softc *sc, int16_t bit)
-{
- uint8_t data;
- usbd_status error;
-
- urtw_read8_m(sc, URTW_EPROM_CMD, &data);
- if (bit != 0)
- urtw_write8_m(sc, URTW_EPROM_CMD, data | URTW_EPROM_WRITEBIT);
- else
- urtw_write8_m(sc, URTW_EPROM_CMD, data & ~URTW_EPROM_WRITEBIT);
- DELAY(URTW_EPROM_DELAY);
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_eprom_ck(struct urtw_softc *sc)
-{
- uint8_t data;
- usbd_status error;
-
- /* masking */
- urtw_read8_m(sc, URTW_EPROM_CMD, &data);
- urtw_write8_m(sc, URTW_EPROM_CMD, data | URTW_EPROM_CK);
- DELAY(URTW_EPROM_DELAY);
- /* unmasking */
- urtw_read8_m(sc, URTW_EPROM_CMD, &data);
- urtw_write8_m(sc, URTW_EPROM_CMD, data & ~URTW_EPROM_CK);
- DELAY(URTW_EPROM_DELAY);
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_eprom_cs(struct urtw_softc *sc, int able)
-{
- uint8_t data;
- usbd_status error;
-
- urtw_read8_m(sc, URTW_EPROM_CMD, &data);
- if (able == URTW_EPROM_ENABLE)
- urtw_write8_m(sc, URTW_EPROM_CMD, data | URTW_EPROM_CS);
- else
- urtw_write8_m(sc, URTW_EPROM_CMD, data & ~URTW_EPROM_CS);
- DELAY(URTW_EPROM_DELAY);
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_read8_c(struct urtw_softc *sc, int val, uint8_t *data)
-{
- usb_device_request_t req;
- usbd_status error;
-
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = URTW_8187_GETREGS_REQ;
- USETW(req.wValue, val | 0xff00);
- USETW(req.wIndex, 0);
- USETW(req.wLength, sizeof(uint8_t));
-
- error = usbd_do_request(sc->sc_udev, &req, data);
- return (error);
-}
-
-static usbd_status
-urtw_read8e(struct urtw_softc *sc, int val, uint8_t *data)
-{
- usb_device_request_t req;
- usbd_status error;
-
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = URTW_8187_GETREGS_REQ;
- USETW(req.wValue, val | 0xfe00);
- USETW(req.wIndex, 0);
- USETW(req.wLength, sizeof(uint8_t));
-
- error = usbd_do_request(sc->sc_udev, &req, data);
- return (error);
-}
-
-static usbd_status
-urtw_read16_c(struct urtw_softc *sc, int val, uint16_t *data)
-{
- usb_device_request_t req;
- usbd_status error;
-
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = URTW_8187_GETREGS_REQ;
- USETW(req.wValue, val | 0xff00);
- USETW(req.wIndex, 0);
- USETW(req.wLength, sizeof(uint16_t));
-
- error = usbd_do_request(sc->sc_udev, &req, data);
- return (error);
-}
-
-static usbd_status
-urtw_read32_c(struct urtw_softc *sc, int val, uint32_t *data)
-{
- usb_device_request_t req;
- usbd_status error;
-
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = URTW_8187_GETREGS_REQ;
- USETW(req.wValue, val | 0xff00);
- USETW(req.wIndex, 0);
- USETW(req.wLength, sizeof(uint32_t));
-
- error = usbd_do_request(sc->sc_udev, &req, data);
- return (error);
-}
-
-static usbd_status
-urtw_write8_c(struct urtw_softc *sc, int val, uint8_t data)
-{
- usb_device_request_t req;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = URTW_8187_SETREGS_REQ;
- USETW(req.wValue, val | 0xff00);
- USETW(req.wIndex, 0);
- USETW(req.wLength, sizeof(uint8_t));
-
- return (usbd_do_request(sc->sc_udev, &req, &data));
-}
-
-static usbd_status
-urtw_write8e(struct urtw_softc *sc, int val, uint8_t data)
-{
- usb_device_request_t req;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = URTW_8187_SETREGS_REQ;
- USETW(req.wValue, val | 0xfe00);
- USETW(req.wIndex, 0);
- USETW(req.wLength, sizeof(uint8_t));
-
- return (usbd_do_request(sc->sc_udev, &req, &data));
-}
-
-static usbd_status
-urtw_write16_c(struct urtw_softc *sc, int val, uint16_t data)
-{
- usb_device_request_t req;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = URTW_8187_SETREGS_REQ;
- USETW(req.wValue, val | 0xff00);
- USETW(req.wIndex, 0);
- USETW(req.wLength, sizeof(uint16_t));
-
- return (usbd_do_request(sc->sc_udev, &req, &data));
-}
-
-static usbd_status
-urtw_write32_c(struct urtw_softc *sc, int val, uint32_t data)
-{
- usb_device_request_t req;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = URTW_8187_SETREGS_REQ;
- USETW(req.wValue, val | 0xff00);
- USETW(req.wIndex, 0);
- USETW(req.wLength, sizeof(uint32_t));
-
- return (usbd_do_request(sc->sc_udev, &req, &data));
-}
-
-static int
-urtw_detach(device_t dev)
-{
- struct urtw_softc *sc = device_get_softc(dev);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
-
- if (!device_is_attached(dev))
- return 0;
-
- urtw_stop(ifp, 1);
-
- callout_drain(&sc->sc_led_ch);
- callout_drain(&sc->sc_watchdog_ch);
- usb_rem_task(sc->sc_udev, &sc->sc_ledtask);
- usb_rem_task(sc->sc_udev, &sc->sc_ctxtask);
- usb_rem_task(sc->sc_udev, &sc->sc_task);
-
- /* abort and free xfers */
- urtw_free_tx_data_list(sc);
- urtw_free_rx_data_list(sc);
- urtw_close_pipes(sc);
-
- bpfdetach(ifp);
- ieee80211_ifdetach(ic);
- if_free(ifp);
- mtx_destroy(&sc->sc_mtx);
-
- usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev);
-
- return (0);
-}
-
-static struct ieee80211vap *
-urtw_vap_create(struct ieee80211com *ic,
- const char name[IFNAMSIZ], int unit, int opmode, int flags,
- const uint8_t bssid[IEEE80211_ADDR_LEN],
- const uint8_t mac[IEEE80211_ADDR_LEN])
-{
- struct urtw_vap *uvp;
- struct ieee80211vap *vap;
-
- if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */
- return (NULL);
- uvp = (struct urtw_vap *) malloc(sizeof(struct urtw_vap),
- M_80211_VAP, M_NOWAIT | M_ZERO);
- if (uvp == NULL)
- return (NULL);
- vap = &uvp->vap;
- /* enable s/w bmiss handling for sta mode */
- ieee80211_vap_setup(ic, vap, name, unit, opmode,
- flags | IEEE80211_CLONE_NOBEACONS, bssid, mac);
-
- /* override state transition machine */
- uvp->newstate = vap->iv_newstate;
- vap->iv_newstate = urtw_newstate;
-
- /* complete setup */
- ieee80211_vap_attach(vap, ieee80211_media_change,
- ieee80211_media_status);
- ic->ic_opmode = opmode;
- return (vap);
-}
-
-static void
-urtw_vap_delete(struct ieee80211vap *vap)
-{
- struct urtw_vap *uvp = URTW_VAP(vap);
-
- ieee80211_vap_detach(vap);
- free(uvp, M_80211_VAP);
-}
-
-static usbd_status
-urtw_set_mode(struct urtw_softc *sc, uint32_t mode)
-{
- uint8_t data;
- usbd_status error;
-
- urtw_read8_m(sc, URTW_EPROM_CMD, &data);
- data = (data & ~URTW_EPROM_CMD_MASK) | (mode << URTW_EPROM_CMD_SHIFT);
- data = data & ~(URTW_EPROM_CS | URTW_EPROM_CK);
- urtw_write8_m(sc, URTW_EPROM_CMD, data);
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_8180_set_anaparam(struct urtw_softc *sc, uint32_t val)
-{
- uint8_t data;
- usbd_status error;
-
- error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
- if (error)
- goto fail;
-
- urtw_read8_m(sc, URTW_CONFIG3, &data);
- urtw_write8_m(sc, URTW_CONFIG3, data | URTW_CONFIG3_ANAPARAM_WRITE);
- urtw_write32_m(sc, URTW_ANAPARAM, val);
- urtw_read8_m(sc, URTW_CONFIG3, &data);
- urtw_write8_m(sc, URTW_CONFIG3, data & ~URTW_CONFIG3_ANAPARAM_WRITE);
-
- error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
- if (error)
- goto fail;
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_8185_set_anaparam2(struct urtw_softc *sc, uint32_t val)
-{
- uint8_t data;
- usbd_status error;
-
- error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
- if (error)
- goto fail;
-
- urtw_read8_m(sc, URTW_CONFIG3, &data);
- urtw_write8_m(sc, URTW_CONFIG3, data | URTW_CONFIG3_ANAPARAM_WRITE);
- urtw_write32_m(sc, URTW_ANAPARAM2, val);
- urtw_read8_m(sc, URTW_CONFIG3, &data);
- urtw_write8_m(sc, URTW_CONFIG3, data & ~URTW_CONFIG3_ANAPARAM_WRITE);
-
- error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
- if (error)
- goto fail;
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_intr_disable(struct urtw_softc *sc)
-{
- usbd_status error;
-
- urtw_write16_m(sc, URTW_INTR_MASK, 0);
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_reset(struct urtw_softc *sc)
-{
- uint8_t data;
- usbd_status error;
-
- error = urtw_8180_set_anaparam(sc, URTW_8225_ANAPARAM_ON);
- if (error)
- goto fail;
- error = urtw_8185_set_anaparam2(sc, URTW_8225_ANAPARAM2_ON);
- if (error)
- goto fail;
-
- error = urtw_intr_disable(sc);
- if (error)
- goto fail;
- usbd_delay_ms(sc->sc_udev, 100);
-
- error = urtw_write8e(sc, 0x18, 0x10);
- if (error != 0)
- goto fail;
- error = urtw_write8e(sc, 0x18, 0x11);
- if (error != 0)
- goto fail;
- error = urtw_write8e(sc, 0x18, 0x00);
- if (error != 0)
- goto fail;
- usbd_delay_ms(sc->sc_udev, 100);
-
- urtw_read8_m(sc, URTW_CMD, &data);
- data = (data & 0x2) | URTW_CMD_RST;
- urtw_write8_m(sc, URTW_CMD, data);
- usbd_delay_ms(sc->sc_udev, 100);
-
- urtw_read8_m(sc, URTW_CMD, &data);
- if (data & URTW_CMD_RST) {
- device_printf(sc->sc_dev, "reset timeout\n");
- goto fail;
- }
-
- error = urtw_set_mode(sc, URTW_EPROM_CMD_LOAD);
- if (error)
- goto fail;
- usbd_delay_ms(sc->sc_udev, 100);
-
- error = urtw_8180_set_anaparam(sc, URTW_8225_ANAPARAM_ON);
- if (error)
- goto fail;
- error = urtw_8185_set_anaparam2(sc, URTW_8225_ANAPARAM2_ON);
- if (error)
- goto fail;
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_led_on(struct urtw_softc *sc, int type)
-{
- usbd_status error;
-
- if (type == URTW_LED_GPIO) {
- switch (sc->sc_gpio_ledpin) {
- case URTW_LED_PIN_GPIO0:
- urtw_write8_m(sc, URTW_GPIO, 0x01);
- urtw_write8_m(sc, URTW_GP_ENABLE, 0x00);
- break;
- default:
- panic("unsupported LED PIN type 0x%x",
- sc->sc_gpio_ledpin);
- /* never reach */
- }
- } else {
- panic("unsupported LED type 0x%x", type);
- /* never reach */
- }
-
- sc->sc_gpio_ledon = 1;
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_led_off(struct urtw_softc *sc, int type)
-{
- usbd_status error;
-
- if (type == URTW_LED_GPIO) {
- switch (sc->sc_gpio_ledpin) {
- case URTW_LED_PIN_GPIO0:
- urtw_write8_m(sc, URTW_GPIO, URTW_GPIO_DATA_MAGIC1);
- urtw_write8_m(sc,
- URTW_GP_ENABLE, URTW_GP_ENABLE_DATA_MAGIC1);
- break;
- default:
- panic("unsupported LED PIN type 0x%x",
- sc->sc_gpio_ledpin);
- /* never reach */
- }
- } else {
- panic("unsupported LED type 0x%x", type);
- /* never reach */
- }
-
- sc->sc_gpio_ledon = 0;
-
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_led_mode0(struct urtw_softc *sc, int mode)
-{
-
- switch (mode) {
- case URTW_LED_CTL_POWER_ON:
- sc->sc_gpio_ledstate = URTW_LED_POWER_ON_BLINK;
- break;
- case URTW_LED_CTL_TX:
- if (sc->sc_gpio_ledinprogress == 1)
- return (0);
-
- sc->sc_gpio_ledstate = URTW_LED_BLINK_NORMAL;
- sc->sc_gpio_blinktime = 2;
- break;
- case URTW_LED_CTL_LINK:
- sc->sc_gpio_ledstate = URTW_LED_ON;
- break;
- default:
- panic("unsupported LED mode 0x%x", mode);
- /* never reach */
- }
-
- switch (sc->sc_gpio_ledstate) {
- case URTW_LED_ON:
- if (sc->sc_gpio_ledinprogress != 0)
- break;
- urtw_led_on(sc, URTW_LED_GPIO);
- break;
- case URTW_LED_BLINK_NORMAL:
- if (sc->sc_gpio_ledinprogress != 0)
- break;
- sc->sc_gpio_ledinprogress = 1;
- sc->sc_gpio_blinkstate = (sc->sc_gpio_ledon != 0) ?
- URTW_LED_OFF : URTW_LED_ON;
- callout_reset(&sc->sc_led_ch, hz, urtw_ledtask, sc);
- break;
- case URTW_LED_POWER_ON_BLINK:
- urtw_led_on(sc, URTW_LED_GPIO);
- usbd_delay_ms(sc->sc_udev, 100);
- urtw_led_off(sc, URTW_LED_GPIO);
- break;
- default:
- panic("unknown LED status 0x%x", sc->sc_gpio_ledstate);
- /* never reach */
- }
- return (0);
-}
-
-static usbd_status
-urtw_led_mode1(struct urtw_softc *sc, int mode)
-{
-
- return (USBD_INVAL);
-}
-
-static usbd_status
-urtw_led_mode2(struct urtw_softc *sc, int mode)
-{
-
- return (USBD_INVAL);
-}
-
-static usbd_status
-urtw_led_mode3(struct urtw_softc *sc, int mode)
-{
-
- return (USBD_INVAL);
-}
-
-static usbd_status
-urtw_led_blink(struct urtw_softc *sc)
-{
- uint8_t ing = 0;
- usbd_status error;
-
- if (sc->sc_gpio_blinkstate == URTW_LED_ON)
- error = urtw_led_on(sc, URTW_LED_GPIO);
- else
- error = urtw_led_off(sc, URTW_LED_GPIO);
- sc->sc_gpio_blinktime--;
- if (sc->sc_gpio_blinktime == 0)
- ing = 1;
- else {
- if (sc->sc_gpio_ledstate != URTW_LED_BLINK_NORMAL &&
- sc->sc_gpio_ledstate != URTW_LED_BLINK_SLOWLY &&
- sc->sc_gpio_ledstate != URTW_LED_BLINK_CM3)
- ing = 1;
- }
- if (ing == 1) {
- if (sc->sc_gpio_ledstate == URTW_LED_ON &&
- sc->sc_gpio_ledon == 0)
- error = urtw_led_on(sc, URTW_LED_GPIO);
- else if (sc->sc_gpio_ledstate == URTW_LED_OFF &&
- sc->sc_gpio_ledon == 1)
- error = urtw_led_off(sc, URTW_LED_GPIO);
-
- sc->sc_gpio_blinktime = 0;
- sc->sc_gpio_ledinprogress = 0;
- return (0);
- }
-
- sc->sc_gpio_blinkstate = (sc->sc_gpio_blinkstate != URTW_LED_ON) ?
- URTW_LED_ON : URTW_LED_OFF;
-
- switch (sc->sc_gpio_ledstate) {
- case URTW_LED_BLINK_NORMAL:
- callout_reset(&sc->sc_led_ch, hz, urtw_ledtask, sc);
- break;
- default:
- panic("unknown LED status 0x%x", sc->sc_gpio_ledstate);
- /* never reach */
- }
- return (0);
-}
-
-static void
-urtw_ledusbtask(void *arg)
-{
- struct urtw_softc *sc = arg;
-
- if (sc->sc_strategy != URTW_SW_LED_MODE0)
- panic("could not process a LED strategy 0x%x", sc->sc_strategy);
-
- urtw_led_blink(sc);
-}
-
-static void
-urtw_ledtask(void *arg)
-{
- struct urtw_softc *sc = arg;
-
- /*
- * NB: to change a status of the led we need at least a sleep so we
- * can't do it here
- */
- usb_add_task(sc->sc_udev, &sc->sc_ledtask, USB_TASKQ_DRIVER);
-}
-
-static usbd_status
-urtw_led_ctl(struct urtw_softc *sc, int mode)
-{
- usbd_status error = 0;
-
- switch (sc->sc_strategy) {
- case URTW_SW_LED_MODE0:
- error = urtw_led_mode0(sc, mode);
- break;
- case URTW_SW_LED_MODE1:
- error = urtw_led_mode1(sc, mode);
- break;
- case URTW_SW_LED_MODE2:
- error = urtw_led_mode2(sc, mode);
- break;
- case URTW_SW_LED_MODE3:
- error = urtw_led_mode3(sc, mode);
- break;
- default:
- panic("unsupported LED mode %d\n", sc->sc_strategy);
- /* never reach */
- }
-
- return (error);
-}
-
-static usbd_status
-urtw_update_msr(struct urtw_softc *sc)
-{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- uint8_t data;
- usbd_status error;
-
- urtw_read8_m(sc, URTW_MSR, &data);
- data &= ~URTW_MSR_LINK_MASK;
-
- if (sc->sc_state == IEEE80211_S_RUN) {
- switch (ic->ic_opmode) {
- case IEEE80211_M_STA:
- case IEEE80211_M_MONITOR:
- data |= URTW_MSR_LINK_STA;
- break;
- case IEEE80211_M_IBSS:
- data |= URTW_MSR_LINK_ADHOC;
- break;
- case IEEE80211_M_HOSTAP:
- data |= URTW_MSR_LINK_HOSTAP;
- break;
- default:
- panic("unsupported operation mode 0x%x\n",
- ic->ic_opmode);
- /* never reach */
- }
- } else
- data |= URTW_MSR_LINK_NONE;
-
- urtw_write8_m(sc, URTW_MSR, data);
-fail:
- return (error);
-}
-
-static uint16_t
-urtw_rate2rtl(int rate)
-{
-#define N(a) (sizeof(a) / sizeof((a)[0]))
- int i;
-
- for (i = 0; i < N(urtw_ratetable); i++) {
- if (rate == urtw_ratetable[i].reg)
- return urtw_ratetable[i].val;
- }
-
- return (3);
-#undef N
-}
-
-static uint16_t
-urtw_rtl2rate(int rate)
-{
-#define N(a) (sizeof(a) / sizeof((a)[0]))
- int i;
-
- for (i = 0; i < N(urtw_ratetable); i++) {
- if (rate == urtw_ratetable[i].val)
- return urtw_ratetable[i].reg;
- }
-
- return (0);
-#undef N
-}
-
-static usbd_status
-urtw_set_rate(struct urtw_softc *sc)
-{
- int i, basic_rate, min_rr_rate, max_rr_rate;
- uint16_t data;
- usbd_status error;
-
- basic_rate = urtw_rate2rtl(48);
- min_rr_rate = urtw_rate2rtl(12);
- max_rr_rate = urtw_rate2rtl(48);
-
- urtw_write8_m(sc, URTW_RESP_RATE,
- max_rr_rate << URTW_RESP_MAX_RATE_SHIFT |
- min_rr_rate << URTW_RESP_MIN_RATE_SHIFT);
-
- urtw_read16_m(sc, URTW_BRSR, &data);
- data &= ~URTW_BRSR_MBR_8185;
-
- for (i = 0; i <= basic_rate; i++)
- data |= (1 << i);
-
- urtw_write16_m(sc, URTW_BRSR, data);
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_intr_enable(struct urtw_softc *sc)
-{
- usbd_status error;
-
- urtw_write16_m(sc, URTW_INTR_MASK, 0xffff);
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_adapter_start(struct urtw_softc *sc)
-{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- usbd_status error;
-
- error = urtw_reset(sc);
- if (error)
- goto fail;
-
- urtw_write8_m(sc, URTW_ADDR_MAGIC1, 0);
- urtw_write8_m(sc, URTW_GPIO, 0);
-
- /* for led */
- urtw_write8_m(sc, URTW_ADDR_MAGIC1, 4);
- error = urtw_led_ctl(sc, URTW_LED_CTL_POWER_ON);
- if (error != 0)
- goto fail;
-
- error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
- if (error)
- goto fail;
- /* applying MAC address again. */
- urtw_write32_m(sc, URTW_MAC0, ((uint32_t *)ic->ic_myaddr)[0]);
- urtw_write16_m(sc, URTW_MAC4, ((uint32_t *)ic->ic_myaddr)[1] & 0xffff);
- error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
- if (error)
- goto fail;
-
- error = urtw_update_msr(sc);
- if (error)
- goto fail;
-
- urtw_write32_m(sc, URTW_INT_TIMEOUT, 0);
- urtw_write8_m(sc, URTW_WPA_CONFIG, 0);
- urtw_write8_m(sc, URTW_RATE_FALLBACK, 0x81);
- error = urtw_set_rate(sc);
- if (error != 0)
- goto fail;
-
- error = sc->sc_rf_init(sc);
- if (error != 0)
- goto fail;
- if (sc->sc_rf_set_sens != NULL)
- sc->sc_rf_set_sens(sc, sc->sc_sens);
-
- /* XXX correct? to call write16 */
- urtw_write16_m(sc, URTW_PSR, 1);
- urtw_write16_m(sc, URTW_ADDR_MAGIC2, 0x10);
- urtw_write8_m(sc, URTW_TALLY_SEL, 0x80);
- urtw_write8_m(sc, URTW_ADDR_MAGIC3, 0x60);
- /* XXX correct? to call write16 */
- urtw_write16_m(sc, URTW_PSR, 0);
- urtw_write8_m(sc, URTW_ADDR_MAGIC1, 4);
-
- error = urtw_intr_enable(sc);
- if (error != 0)
- goto fail;
-
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_rx_setconf(struct urtw_softc *sc)
-{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- uint32_t data;
- usbd_status error;
-
- urtw_read32_m(sc, URTW_RX, &data);
- data = data &~ URTW_RX_FILTER_MASK;
-#if 0
- data = data | URTW_RX_FILTER_CTL;
-#endif
- data = data | URTW_RX_FILTER_MNG | URTW_RX_FILTER_DATA;
- data = data | URTW_RX_FILTER_BCAST | URTW_RX_FILTER_MCAST;
-
- if (ic->ic_opmode == IEEE80211_M_MONITOR) {
- data = data | URTW_RX_FILTER_ICVERR;
- data = data | URTW_RX_FILTER_PWR;
- }
- if (sc->sc_crcmon == 1 && ic->ic_opmode == IEEE80211_M_MONITOR)
- data = data | URTW_RX_FILTER_CRCERR;
-
- if (ic->ic_opmode == IEEE80211_M_MONITOR ||
- (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC))) {
- data = data | URTW_RX_FILTER_ALLMAC;
- } else {
- data = data | URTW_RX_FILTER_NICMAC;
- data = data | URTW_RX_CHECK_BSSID;
- }
-
- data = data &~ URTW_RX_FIFO_THRESHOLD_MASK;
- data = data | URTW_RX_FIFO_THRESHOLD_NONE | URTW_RX_AUTORESETPHY;
- data = data &~ URTW_MAX_RX_DMA_MASK;
- data = data | URTW_MAX_RX_DMA_2048 | URTW_RCR_ONLYERLPKT;
-
- urtw_write32_m(sc, URTW_RX, data);
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_rx_enable(struct urtw_softc *sc)
-{
- int i;
- struct urtw_data *rxdata;
- uint8_t data;
- usbd_status error;
-
- /*
- * Start up the receive pipe.
- */
- for (i = 0; i < URTW_RX_DATA_LIST_COUNT; i++) {
- rxdata = &sc->sc_rxdata[i];
-
- usbd_setup_xfer(rxdata->xfer, sc->sc_rxpipe, rxdata,
- rxdata->buf, MCLBYTES, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT,
- urtw_rxeof);
- error = usbd_transfer(rxdata->xfer);
- if (error != USBD_IN_PROGRESS && error != 0) {
- device_printf(sc->sc_dev,
- "could not queue Rx transfer\n");
- goto fail;
- }
- }
-
- error = urtw_rx_setconf(sc);
- if (error != 0)
- goto fail;
-
- urtw_read8_m(sc, URTW_CMD, &data);
- urtw_write8_m(sc, URTW_CMD, data | URTW_CMD_RX_ENABLE);
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_tx_enable(struct urtw_softc *sc)
-{
- uint8_t data8;
- uint32_t data;
- usbd_status error;
-
- urtw_read8_m(sc, URTW_CW_CONF, &data8);
- data8 &= ~(URTW_CW_CONF_PERPACKET_CW | URTW_CW_CONF_PERPACKET_RETRY);
- urtw_write8_m(sc, URTW_CW_CONF, data8);
-
- urtw_read8_m(sc, URTW_TX_AGC_CTL, &data8);
- data8 &= ~URTW_TX_AGC_CTL_PERPACKET_GAIN;
- data8 &= ~URTW_TX_AGC_CTL_PERPACKET_ANTSEL;
- data8 &= ~URTW_TX_AGC_CTL_FEEDBACK_ANT;
- urtw_write8_m(sc, URTW_TX_AGC_CTL, data8);
-
- urtw_read32_m(sc, URTW_TX_CONF, &data);
- data &= ~URTW_TX_LOOPBACK_MASK;
- data |= URTW_TX_LOOPBACK_NONE;
- data &= ~(URTW_TX_DPRETRY_MASK | URTW_TX_RTSRETRY_MASK);
- data |= sc->sc_tx_retry << URTW_TX_DPRETRY_SHIFT;
- data |= sc->sc_rts_retry << URTW_TX_RTSRETRY_SHIFT;
- data &= ~(URTW_TX_NOCRC | URTW_TX_MXDMA_MASK);
- data |= URTW_TX_MXDMA_2048 | URTW_TX_CWMIN | URTW_TX_DISCW;
- data &= ~URTW_TX_SWPLCPLEN;
- data |= URTW_TX_NOICV;
- urtw_write32_m(sc, URTW_TX_CONF, data);
-
- urtw_read8_m(sc, URTW_CMD, &data8);
- urtw_write8_m(sc, URTW_CMD, data8 | URTW_CMD_TX_ENABLE);
-fail:
- return (error);
-}
-
-static void
-urtw_init(void *arg)
-{
- int ret;
- struct urtw_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
- usbd_status error;
-
- urtw_stop(ifp, 0);
-
- error = urtw_adapter_start(sc);
- if (error != 0)
- goto fail;
-
- /* reset softc variables */
- sc->sc_txidx = sc->sc_tx_low_queued = sc->sc_tx_normal_queued = 0;
- sc->sc_txtimer = 0;
-
- if (!(sc->sc_flags & URTW_INIT_ONCE)) {
- error = usbd_set_config_no(sc->sc_udev, URTW_CONFIG_NO, 0);
- if (error != 0) {
- device_printf(sc->sc_dev,
- "could not set configuration no\n");
- goto fail;
- }
- /* get the first interface handle */
- error = usbd_device2interface_handle(sc->sc_udev,
- URTW_IFACE_INDEX, &sc->sc_iface);
- if (error != 0) {
- device_printf(sc->sc_dev,
- "could not get interface handle\n");
- goto fail;
- }
- error = urtw_open_pipes(sc);
- if (error != 0)
- goto fail;
- ret = urtw_alloc_rx_data_list(sc);
- if (error != 0)
- goto fail;
- ret = urtw_alloc_tx_data_list(sc);
- if (error != 0)
- goto fail;
- sc->sc_flags |= URTW_INIT_ONCE;
- }
-
- error = urtw_rx_enable(sc);
- if (error != 0)
- goto fail;
- error = urtw_tx_enable(sc);
- if (error != 0)
- goto fail;
-
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
-
- callout_reset(&sc->sc_watchdog_ch, hz, urtw_watchdog, sc);
-fail:
- return;
-}
-
-static void
-urtw_set_multi(void *arg)
-{
- struct urtw_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
-
- if (!(ifp->if_flags & IFF_UP))
- return;
-
- /*
- * XXX don't know how to set a device. Lack of docs. Just try to set
- * IFF_ALLMULTI flag here.
- */
- IF_ADDR_LOCK(ifp);
- ifp->if_flags |= IFF_ALLMULTI;
- IF_ADDR_UNLOCK(ifp);
-}
-
-static int
-urtw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
-{
- struct urtw_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ifreq *ifr = (struct ifreq *) data;
- int error = 0, startall = 0;
-
- switch (cmd) {
- case SIOCSIFFLAGS:
- mtx_lock(&Giant);
- if (ifp->if_flags & IFF_UP) {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
- if ((ifp->if_flags ^ sc->sc_if_flags) &
- (IFF_ALLMULTI | IFF_PROMISC))
- urtw_set_multi(sc);
- } else {
- urtw_init(ifp->if_softc);
- startall = 1;
- }
- } else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- urtw_stop(ifp, 1);
- }
- sc->sc_if_flags = ifp->if_flags;
- mtx_unlock(&Giant);
- if (startall)
- ieee80211_start_all(ic);
- break;
- case SIOCGIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
- break;
- case SIOCGIFADDR:
- error = ether_ioctl(ifp, cmd, data);
- break;
- default:
- error = EINVAL;
- break;
- }
-
- return error;
-}
-
-static void
-urtw_start(struct ifnet *ifp)
-{
- struct urtw_softc *sc = ifp->if_softc;
- struct ieee80211_node *ni;
- struct mbuf *m;
-
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
- return;
-
- URTW_LOCK(sc);
- for (;;) {
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL)
- break;
- if (sc->sc_tx_low_queued >= URTW_TX_DATA_LIST_COUNT ||
- sc->sc_tx_normal_queued >= URTW_TX_DATA_LIST_COUNT) {
- IFQ_DRV_PREPEND(&ifp->if_snd, m);
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- break;
- }
-
- ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
- m->m_pkthdr.rcvif = NULL;
- m = ieee80211_encap(ni, m);
- if (m == NULL) {
- ieee80211_free_node(ni);
- ifp->if_oerrors++;
- continue;
- }
-
- if (urtw_tx_start(sc, ni, m, URTW_PRIORITY_NORMAL) != 0) {
- ieee80211_free_node(ni);
- ifp->if_oerrors++;
- break;
- }
-
- sc->sc_txtimer = 5;
- }
- URTW_UNLOCK(sc);
-}
-
-static void
-urtw_txeof_low(usbd_xfer_handle xfer, usbd_private_handle priv,
- usbd_status status)
-{
- struct urtw_data *data = priv;
- struct urtw_softc *sc = data->sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct mbuf *m;
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
- return;
-
- device_printf(sc->sc_dev, "could not transmit buffer: %s\n",
- usbd_errstr(status));
-
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall_async(sc->sc_txpipe_low);
-
- ifp->if_oerrors++;
- return;
- }
-
- /*
- * Do any tx complete callback. Note this must be done before releasing
- * the node reference.
- */
- m = data->m;
- if (m != NULL && m->m_flags & M_TXCB) {
- ieee80211_process_callback(data->ni, m, 0); /* XXX status? */
- m_freem(m);
- data->m = NULL;
- }
-
- ieee80211_free_node(data->ni);
- data->ni = NULL;
-
- sc->sc_txtimer = 0;
- ifp->if_opackets++;
-
- URTW_LOCK(sc);
- sc->sc_tx_low_queued--;
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- URTW_UNLOCK(sc);
-
- urtw_start(ifp);
-}
-
-static void
-urtw_txeof_normal(usbd_xfer_handle xfer, usbd_private_handle priv,
- usbd_status status)
-{
- struct urtw_data *data = priv;
- struct urtw_softc *sc = data->sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct mbuf *m;
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
- return;
-
- device_printf(sc->sc_dev, "could not transmit buffer: %s\n",
- usbd_errstr(status));
-
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall_async(sc->sc_txpipe_normal);
-
- ifp->if_oerrors++;
- return;
- }
-
- /*
- * Do any tx complete callback. Note this must be done before releasing
- * the node reference.
- */
- m = data->m;
- if (m != NULL && m->m_flags & M_TXCB) {
- ieee80211_process_callback(data->ni, m, 0); /* XXX status? */
- m_freem(m);
- data->m = NULL;
- }
-
- ieee80211_free_node(data->ni);
- data->ni = NULL;
-
- sc->sc_txtimer = 0;
- ifp->if_opackets++;
-
- URTW_LOCK(sc);
- sc->sc_tx_normal_queued--;
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- URTW_UNLOCK(sc);
-
- urtw_start(ifp);
-}
-
-static int
-urtw_tx_start(struct urtw_softc *sc, struct ieee80211_node *ni, struct mbuf *m0,
- int prior)
-{
- int xferlen;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211_frame *wh = mtod(m0, struct ieee80211_frame *);
- struct ieee80211_key *k;
- const struct ieee80211_txparam *tp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211vap *vap = ni->ni_vap;
- struct urtw_data *data;
- usbd_status error;
-
- URTW_ASSERT_LOCKED(sc);
-
- /*
- * Software crypto.
- */
- if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
- k = ieee80211_crypto_encap(ni, m0);
- if (k == NULL) {
- device_printf(sc->sc_dev,
- "ieee80211_crypto_encap returns NULL.\n");
- /* XXX we don't expect the fragmented frames */
- m_freem(m0);
- return (ENOBUFS);
- }
-
- /* in case packet header moved, reset pointer */
- wh = mtod(m0, struct ieee80211_frame *);
- }
-
- if (bpf_peers_present(ifp->if_bpf)) {
- struct urtw_tx_radiotap_header *tap = &sc->sc_txtap;
-
- /* XXX Are variables correct? */
- tap->wt_flags = 0;
- tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
- tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
-
- bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0);
- }
-
- xferlen = m0->m_pkthdr.len + 4 * 3;
- if((0 == xferlen % 64) || (0 == xferlen % 512))
- xferlen += 1;
-
- data = &sc->sc_txdata[sc->sc_txidx];
- sc->sc_txidx = (sc->sc_txidx + 1) % URTW_TX_DATA_LIST_COUNT;
-
- bzero(data->buf, URTW_TX_MAXSIZE);
- data->buf[0] = m0->m_pkthdr.len & 0xff;
- data->buf[1] = (m0->m_pkthdr.len & 0x0f00) >> 8;
- data->buf[1] |= (1 << 7);
-
- if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
- (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE) &&
- (sc->sc_preamble_mode == URTW_PREAMBLE_MODE_SHORT) &&
- (sc->sc_currate != 0))
- data->buf[2] |= 1;
- if ((m0->m_pkthdr.len > vap->iv_rtsthreshold) &&
- prior == URTW_PRIORITY_LOW)
- panic("TODO tx.");
- if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG)
- data->buf[2] |= (1 << 1);
- /* RTS rate - 10 means we use a basic rate. */
- data->buf[2] |= (urtw_rate2rtl(2) << 3);
- /*
- * XXX currently TX rate control depends on the rate value of
- * RX descriptor because I don't know how to we can control TX rate
- * in more smart way. Please fix me you find a thing.
- */
- data->buf[3] = sc->sc_currate;
- if (prior == URTW_PRIORITY_NORMAL) {
- tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)];
- if (IEEE80211_IS_MULTICAST(wh->i_addr1))
- data->buf[3] = urtw_rate2rtl(tp->mcastrate);
- else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
- data->buf[3] = urtw_rate2rtl(tp->ucastrate);
- }
- data->buf[8] = 3; /* CW minimum */
- data->buf[8] |= (7 << 4); /* CW maximum */
- data->buf[9] |= 11; /* retry limitation */
-
- m_copydata(m0, 0, m0->m_pkthdr.len, (uint8_t *)&data->buf[12]);
- data->ni = ni;
- data->m = m0;
-
- usbd_setup_xfer(data->xfer,
- (prior == URTW_PRIORITY_LOW) ? sc->sc_txpipe_low :
- sc->sc_txpipe_normal, data, data->buf, xferlen,
- USBD_FORCE_SHORT_XFER | USBD_NO_COPY, URTW_DATA_TIMEOUT,
- (prior == URTW_PRIORITY_LOW) ? urtw_txeof_low : urtw_txeof_normal);
- error = usbd_transfer(data->xfer);
- if (error != USBD_IN_PROGRESS && error != USBD_NORMAL_COMPLETION) {
- device_printf(sc->sc_dev, "could not send frame: %s\n",
- usbd_errstr(error));
- return EIO;
- }
-
- error = urtw_led_ctl(sc, URTW_LED_CTL_TX);
- if (error != 0)
- device_printf(sc->sc_dev, "could not control LED (%d)\n", error);
-
- if (prior == URTW_PRIORITY_LOW)
- sc->sc_tx_low_queued++;
- else
- sc->sc_tx_normal_queued++;
-
- return (0);
-}
-
-static int
-urtw_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
- const struct ieee80211_bpf_params *params)
-{
- struct ieee80211com *ic = ni->ni_ic;
- struct ifnet *ifp = ic->ic_ifp;
- struct urtw_softc *sc = ifp->if_softc;
-
- /* prevent management frames from being sent if we're not ready */
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
- m_freem(m);
- ieee80211_free_node(ni);
- return ENETDOWN;
- }
- URTW_LOCK(sc);
- if (sc->sc_tx_low_queued >= URTW_TX_DATA_LIST_COUNT ||
- sc->sc_tx_normal_queued >= URTW_TX_DATA_LIST_COUNT) {
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- m_freem(m);
- ieee80211_free_node(ni);
- URTW_UNLOCK(sc);
- return (ENOBUFS); /* XXX */
- }
-
- ifp->if_opackets++;
- if (urtw_tx_start(sc, ni, m, URTW_PRIORITY_LOW) != 0) {
- ieee80211_free_node(ni);
- ifp->if_oerrors++;
- URTW_UNLOCK(sc);
- return (EIO);
- }
-
- sc->sc_txtimer = 5;
- URTW_UNLOCK(sc);
- return (0);
-}
-
-static void
-urtw_scan_start(struct ieee80211com *ic)
-{
-
- /* XXX do nothing? */
-}
-
-static void
-urtw_scan_end(struct ieee80211com *ic)
-{
-
- /* XXX do nothing? */
-}
-
-static void
-urtw_set_channel(struct ieee80211com *ic)
-{
- struct urtw_softc *sc = ic->ic_ifp->if_softc;
- struct ifnet *ifp = sc->sc_ifp;
-
- /*
- * if the user set a channel explicitly using ifconfig(8) this function
- * can be called earlier than we're expected that in some cases the
- * initialization would be failed if setting a channel is called before
- * the init have done.
- */
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
- return;
-
- sc->sc_ctxarg = URTW_SET_CHANNEL;
- usb_add_task(sc->sc_udev, &sc->sc_ctxtask, USB_TASKQ_DRIVER);
-}
-
-static void
-urtw_update_mcast(struct ifnet *ifp)
-{
-
- /* XXX do nothing? */
-}
-
-static usbd_status
-urtw_8225_usb_init(struct urtw_softc *sc)
-{
- uint8_t data;
- usbd_status error;
-
- urtw_write8_m(sc, URTW_RF_PINS_SELECT + 1, 0);
- urtw_write8_m(sc, URTW_GPIO, 0);
- error = urtw_read8e(sc, 0x53, &data);
- if (error)
- goto fail;
- error = urtw_write8e(sc, 0x53, data | (1 << 7));
- if (error)
- goto fail;
- urtw_write8_m(sc, URTW_RF_PINS_SELECT + 1, 4);
- urtw_write8_m(sc, URTW_GPIO, 0x20);
- urtw_write8_m(sc, URTW_GP_ENABLE, 0);
-
- urtw_write16_m(sc, URTW_RF_PINS_OUTPUT, 0x80);
- urtw_write16_m(sc, URTW_RF_PINS_SELECT, 0x80);
- urtw_write16_m(sc, URTW_RF_PINS_ENABLE, 0x80);
-
- usbd_delay_ms(sc->sc_udev, 500);
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_8185_rf_pins_enable(struct urtw_softc *sc)
-{
- usbd_status error = 0;
-
- urtw_write16_m(sc, URTW_RF_PINS_ENABLE, 0x1ff7);
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_8187_write_phy(struct urtw_softc *sc, uint8_t addr, uint32_t data)
-{
- uint32_t phyw;
- usbd_status error;
-
- phyw = ((data << 8) | (addr | 0x80));
- urtw_write8_m(sc, URTW_PHY_MAGIC4, ((phyw & 0xff000000) >> 24));
- urtw_write8_m(sc, URTW_PHY_MAGIC3, ((phyw & 0x00ff0000) >> 16));
- urtw_write8_m(sc, URTW_PHY_MAGIC2, ((phyw & 0x0000ff00) >> 8));
- urtw_write8_m(sc, URTW_PHY_MAGIC1, ((phyw & 0x000000ff)));
- usbd_delay_ms(sc->sc_udev, 1);
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_8187_write_phy_ofdm_c(struct urtw_softc *sc, uint8_t addr, uint32_t data)
-{
-
- data = data & 0xff;
- return urtw_8187_write_phy(sc, addr, data);
-}
-
-static usbd_status
-urtw_8187_write_phy_cck_c(struct urtw_softc *sc, uint8_t addr, uint32_t data)
-{
-
- data = data & 0xff;
- return urtw_8187_write_phy(sc, addr, data | 0x10000);
-}
-
-static usbd_status
-urtw_8225_setgain(struct urtw_softc *sc, int16_t gain)
-{
- usbd_status error;
-
- urtw_8187_write_phy_ofdm(sc, 0x0d, urtw_8225_gain[gain * 4]);
- urtw_8187_write_phy_ofdm(sc, 0x1b, urtw_8225_gain[gain * 4 + 2]);
- urtw_8187_write_phy_ofdm(sc, 0x1d, urtw_8225_gain[gain * 4 + 3]);
- urtw_8187_write_phy_ofdm(sc, 0x23, urtw_8225_gain[gain * 4 + 1]);
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_8225_set_txpwrlvl(struct urtw_softc *sc, int chan)
-{
- int i, idx, set;
- uint8_t *cck_pwltable;
- uint8_t cck_pwrlvl_max, ofdm_pwrlvl_min, ofdm_pwrlvl_max;
- uint8_t cck_pwrlvl = sc->sc_txpwr_cck[chan] & 0xff;
- uint8_t ofdm_pwrlvl = sc->sc_txpwr_ofdm[chan] & 0xff;
- usbd_status error;
-
- cck_pwrlvl_max = 11;
- ofdm_pwrlvl_max = 25; /* 12 -> 25 */
- ofdm_pwrlvl_min = 10;
-
- /* CCK power setting */
- cck_pwrlvl = (cck_pwrlvl > cck_pwrlvl_max) ? cck_pwrlvl_max : cck_pwrlvl;
- idx = cck_pwrlvl % 6;
- set = cck_pwrlvl / 6;
- cck_pwltable = (chan == 14) ? urtw_8225_txpwr_cck_ch14 :
- urtw_8225_txpwr_cck;
-
- urtw_write8_m(sc, URTW_TX_GAIN_CCK,
- urtw_8225_tx_gain_cck_ofdm[set] >> 1);
- for (i = 0; i < 8; i++) {
- urtw_8187_write_phy_cck(sc, 0x44 + i,
- cck_pwltable[idx * 8 + i]);
- }
- usbd_delay_ms(sc->sc_udev, 1);
-
- /* OFDM power setting */
- ofdm_pwrlvl = (ofdm_pwrlvl > (ofdm_pwrlvl_max - ofdm_pwrlvl_min)) ?
- ofdm_pwrlvl_max : ofdm_pwrlvl + ofdm_pwrlvl_min;
- ofdm_pwrlvl = (ofdm_pwrlvl > 35) ? 35 : ofdm_pwrlvl;
-
- idx = ofdm_pwrlvl % 6;
- set = ofdm_pwrlvl / 6;
-
- error = urtw_8185_set_anaparam2(sc, URTW_8225_ANAPARAM2_ON);
- if (error)
- goto fail;
- urtw_8187_write_phy_ofdm(sc, 2, 0x42);
- urtw_8187_write_phy_ofdm(sc, 6, 0);
- urtw_8187_write_phy_ofdm(sc, 8, 0);
-
- urtw_write8_m(sc, URTW_TX_GAIN_OFDM,
- urtw_8225_tx_gain_cck_ofdm[set] >> 1);
- urtw_8187_write_phy_ofdm(sc, 0x5, urtw_8225_txpwr_ofdm[idx]);
- urtw_8187_write_phy_ofdm(sc, 0x7, urtw_8225_txpwr_ofdm[idx]);
- usbd_delay_ms(sc->sc_udev, 1);
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_8185_tx_antenna(struct urtw_softc *sc, uint8_t ant)
-{
- usbd_status error;
-
- urtw_write8_m(sc, URTW_TX_ANTENNA, ant);
- usbd_delay_ms(sc->sc_udev, 1);
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_8225_rf_init(struct urtw_softc *sc)
-{
-#define N(a) (sizeof(a) / sizeof((a)[0]))
- int i;
- uint16_t data;
- usbd_status error;
-
- error = urtw_8180_set_anaparam(sc, URTW_8225_ANAPARAM_ON);
- if (error)
- goto fail;
-
- error = urtw_8225_usb_init(sc);
- if (error)
- goto fail;
-
- urtw_write32_m(sc, URTW_RF_TIMING, 0x000a8008);
- urtw_read16_m(sc, URTW_BRSR, &data); /* XXX ??? */
- urtw_write16_m(sc, URTW_BRSR, 0xffff);
- urtw_write32_m(sc, URTW_RF_PARA, 0x100044);
-
- error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
- if (error)
- goto fail;
- urtw_write8_m(sc, URTW_CONFIG3, 0x44);
- error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
- if (error)
- goto fail;
-
- error = urtw_8185_rf_pins_enable(sc);
- if (error)
- goto fail;
- usbd_delay_ms(sc->sc_udev, 1000);
-
- for (i = 0; i < N(urtw_8225_rf_part1); i++) {
- urtw_8225_write(sc, urtw_8225_rf_part1[i].reg,
- urtw_8225_rf_part1[i].val);
- usbd_delay_ms(sc->sc_udev, 1);
- }
- usbd_delay_ms(sc->sc_udev, 100);
- urtw_8225_write(sc,
- URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC1);
- usbd_delay_ms(sc->sc_udev, 200);
- urtw_8225_write(sc,
- URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC2);
- usbd_delay_ms(sc->sc_udev, 200);
- urtw_8225_write(sc,
- URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC3);
-
- for (i = 0; i < 95; i++) {
- urtw_8225_write(sc, URTW_8225_ADDR_1_MAGIC, (uint8_t)(i + 1));
- urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC, urtw_8225_rxgain[i]);
- }
-
- urtw_8225_write(sc,
- URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC4);
- urtw_8225_write(sc,
- URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC5);
-
- for (i = 0; i < 128; i++) {
- urtw_8187_write_phy_ofdm(sc, 0xb, urtw_8225_agc[i]);
- usbd_delay_ms(sc->sc_udev, 1);
- urtw_8187_write_phy_ofdm(sc, 0xa, (uint8_t)i + 0x80);
- usbd_delay_ms(sc->sc_udev, 1);
- }
-
- for (i = 0; i < N(urtw_8225_rf_part2); i++) {
- urtw_8187_write_phy_ofdm(sc, urtw_8225_rf_part2[i].reg,
- urtw_8225_rf_part2[i].val);
- usbd_delay_ms(sc->sc_udev, 1);
- }
-
- error = urtw_8225_setgain(sc, 4);
- if (error)
- goto fail;
-
- for (i = 0; i < N(urtw_8225_rf_part3); i++) {
- urtw_8187_write_phy_cck(sc, urtw_8225_rf_part3[i].reg,
- urtw_8225_rf_part3[i].val);
- usbd_delay_ms(sc->sc_udev, 1);
- }
-
- urtw_write8_m(sc, URTW_ADDR_MAGIC4, 0x0d);
-
- error = urtw_8225_set_txpwrlvl(sc, 1);
- if (error)
- goto fail;
-
- urtw_8187_write_phy_cck(sc, 0x10, 0x9b);
- usbd_delay_ms(sc->sc_udev, 1);
- urtw_8187_write_phy_ofdm(sc, 0x26, 0x90);
- usbd_delay_ms(sc->sc_udev, 1);
-
- /* TX ant A, 0x0 for B */
- error = urtw_8185_tx_antenna(sc, 0x3);
- if (error)
- goto fail;
- urtw_write32_m(sc, URTW_ADDR_MAGIC5, 0x3dc00002);
-
- error = urtw_8225_rf_set_chan(sc, 1);
-fail:
- return (error);
-#undef N
-}
-
-static usbd_status
-urtw_8225_rf_set_chan(struct urtw_softc *sc, int chan)
-{
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
- struct ieee80211_channel *c = ic->ic_curchan;
- usbd_status error;
-
- error = urtw_8225_set_txpwrlvl(sc, chan);
- if (error)
- goto fail;
- urtw_8225_write(sc, URTW_8225_ADDR_7_MAGIC, urtw_8225_channel[chan]);
- usbd_delay_ms(sc->sc_udev, 10);
-
- urtw_write8_m(sc, URTW_SIFS, 0x22);
-
- if (sc->sc_state == IEEE80211_S_ASSOC &&
- ic->ic_flags & IEEE80211_F_SHSLOT)
- urtw_write8_m(sc, URTW_SLOT, 0x9);
- else
- urtw_write8_m(sc, URTW_SLOT, 0x14);
-
- if (IEEE80211_IS_CHAN_G(c)) {
- /* for G */
- urtw_write8_m(sc, URTW_DIFS, 0x14);
- urtw_write8_m(sc, URTW_EIFS, 0x5b - 0x14);
- urtw_write8_m(sc, URTW_CW_VAL, 0x73);
- } else {
- /* for B */
- urtw_write8_m(sc, URTW_DIFS, 0x24);
- urtw_write8_m(sc, URTW_EIFS, 0x5b - 0x24);
- urtw_write8_m(sc, URTW_CW_VAL, 0xa5);
- }
-
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_8225_rf_set_sens(struct urtw_softc *sc, int sens)
-{
- usbd_status error;
-
- if (sens < 0 || sens > 6)
- return -1;
-
- if (sens > 4)
- urtw_8225_write(sc,
- URTW_8225_ADDR_C_MAGIC, URTW_8225_ADDR_C_DATA_MAGIC1);
- else
- urtw_8225_write(sc,
- URTW_8225_ADDR_C_MAGIC, URTW_8225_ADDR_C_DATA_MAGIC2);
-
- sens = 6 - sens;
- error = urtw_8225_setgain(sc, sens);
- if (error)
- goto fail;
-
- urtw_8187_write_phy_cck(sc, 0x41, urtw_8225_threshold[sens]);
-
-fail:
- return (error);
-}
-
-static void
-urtw_stop(struct ifnet *ifp, int disable)
-{
- struct urtw_softc *sc = ifp->if_softc;
-
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
-
- callout_stop(&sc->sc_led_ch);
- callout_stop(&sc->sc_watchdog_ch);
-
- if (sc->sc_rxpipe != NULL)
- usbd_abort_pipe(sc->sc_rxpipe);
- if (sc->sc_txpipe_low != NULL)
- usbd_abort_pipe(sc->sc_txpipe_low);
- if (sc->sc_txpipe_normal != NULL)
- usbd_abort_pipe(sc->sc_txpipe_normal);
-}
-
-static int
-urtw_isbmode(uint16_t rate)
-{
-
- rate = urtw_rtl2rate(rate);
-
- return ((rate <= 22 && rate != 12 && rate != 18) ||
- rate == 44) ? (1) : (0);
-}
-
-static void
-urtw_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- int actlen, flen, len, nf, rssi;
- struct ieee80211_frame *wh;
- struct ieee80211_node *ni;
- struct mbuf *m, *mnew;
- struct urtw_data *data = priv;
- struct urtw_softc *sc = data->sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- uint8_t *desc, quality, rate;
- usbd_status error;
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
- return;
-
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall_async(sc->sc_rxpipe);
- ifp->if_ierrors++;
- goto skip;
- }
-
- usbd_get_xfer_status(xfer, NULL, NULL, &actlen, NULL);
- if (actlen < URTW_MIN_RXBUFSZ) {
- ifp->if_ierrors++;
- goto skip;
- }
-
- /* 4 dword and 4 byte CRC */
- len = actlen - (4 * 4);
- desc = data->buf + len;
- flen = ((desc[1] & 0x0f) << 8) + (desc[0] & 0xff);
- if (flen > actlen) {
- ifp->if_ierrors++;
- goto skip;
- }
-
- rate = (desc[2] & 0xf0) >> 4;
- quality = desc[4] & 0xff;
- /* XXX correct? */
- rssi = (desc[6] & 0xfe) >> 1;
- if (!urtw_isbmode(rate)) {
- rssi = (rssi > 90) ? 90 : ((rssi < 25) ? 25 : rssi);
- rssi = ((90 - rssi) * 100) / 65;
- } else {
- rssi = (rssi > 90) ? 95 : ((rssi < 30) ? 30 : rssi);
- rssi = ((95 - rssi) * 100) / 65;
- }
-
- mnew = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
- if (mnew == NULL) {
- ifp->if_ierrors++;
- goto skip;
- }
-
- m = data->m;
- data->m = mnew;
- data->buf = mtod(mnew, uint8_t *);
-
- /* finalize mbuf */
- m->m_pkthdr.rcvif = ifp;
- m->m_pkthdr.len = m->m_len = flen - 4;
-
- if (bpf_peers_present(ifp->if_bpf)) {
- struct urtw_rx_radiotap_header *tap = &sc->sc_rxtap;
-
- /* XXX Are variables correct? */
- tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
- tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
- tap->wr_dbm_antsignal = (int8_t)rssi;
-
- bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m);
- }
-
- wh = mtod(m, struct ieee80211_frame *);
- if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_DATA)
- sc->sc_currate = (rate > 0) ? rate : sc->sc_currate;
- ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh);
- /* XXX correct? */
- nf = (quality > 64) ? 0 : ((64 - quality) * 100) / 64;
- /* send the frame to the 802.11 layer */
- if (ni != NULL) {
- (void) ieee80211_input(ni, m, rssi, -nf, 0);
- /* node is no longer needed */
- ieee80211_free_node(ni);
- } else
- (void) ieee80211_input_all(ic, m, rssi, -nf, 0);
-
-skip: /* setup a new transfer */
- usbd_setup_xfer(xfer, sc->sc_rxpipe, data, data->buf, MCLBYTES,
- USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, urtw_rxeof);
- error = usbd_transfer(xfer);
- if (error != USBD_IN_PROGRESS && error != 0)
- device_printf(sc->sc_dev, "could not queue Rx transfer\n");
-}
-
-static int
-urtw_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
-{
- struct urtw_vap *rvp = URTW_VAP(vap);
- struct ieee80211com *ic = vap->iv_ic;
- struct urtw_softc *sc = ic->ic_ifp->if_softc;
-
- DPRINTF(sc, URTW_DEBUG_STATE, "%s: %s -> %s\n", __func__,
- ieee80211_state_name[vap->iv_state],
- ieee80211_state_name[nstate]);
-
- /* do it in a process context */
- sc->sc_state = nstate;
- sc->sc_arg = arg;
-
- if (nstate == IEEE80211_S_INIT) {
- rvp->newstate(vap, nstate, arg);
- return (0);
- } else {
- usb_add_task(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER);
- return (EINPROGRESS);
- }
-}
-
-static usbd_status
-urtw_8225v2_setgain(struct urtw_softc *sc, int16_t gain)
-{
- uint8_t *gainp;
- usbd_status error;
-
- /* XXX for A? */
- gainp = urtw_8225v2_gain_bg;
- urtw_8187_write_phy_ofdm(sc, 0x0d, gainp[gain * 3]);
- usbd_delay_ms(sc->sc_udev, 1);
- urtw_8187_write_phy_ofdm(sc, 0x1b, gainp[gain * 3 + 1]);
- usbd_delay_ms(sc->sc_udev, 1);
- urtw_8187_write_phy_ofdm(sc, 0x1d, gainp[gain * 3 + 2]);
- usbd_delay_ms(sc->sc_udev, 1);
- urtw_8187_write_phy_ofdm(sc, 0x21, 0x17);
- usbd_delay_ms(sc->sc_udev, 1);
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_8225v2_set_txpwrlvl(struct urtw_softc *sc, int chan)
-{
- int i;
- uint8_t *cck_pwrtable;
- uint8_t cck_pwrlvl_max = 15, ofdm_pwrlvl_max = 25, ofdm_pwrlvl_min = 10;
- uint8_t cck_pwrlvl = sc->sc_txpwr_cck[chan] & 0xff;
- uint8_t ofdm_pwrlvl = sc->sc_txpwr_ofdm[chan] & 0xff;
- usbd_status error;
-
- /* CCK power setting */
- cck_pwrlvl = (cck_pwrlvl > cck_pwrlvl_max) ? cck_pwrlvl_max : cck_pwrlvl;
- cck_pwrlvl += sc->sc_txpwr_cck_base;
- cck_pwrlvl = (cck_pwrlvl > 35) ? 35 : cck_pwrlvl;
- cck_pwrtable = (chan == 14) ? urtw_8225v2_txpwr_cck_ch14 :
- urtw_8225v2_txpwr_cck;
-
- for (i = 0; i < 8; i++)
- urtw_8187_write_phy_cck(sc, 0x44 + i, cck_pwrtable[i]);
-
- urtw_write8_m(sc, URTW_TX_GAIN_CCK,
- urtw_8225v2_tx_gain_cck_ofdm[cck_pwrlvl]);
- usbd_delay_ms(sc->sc_udev, 1);
-
- /* OFDM power setting */
- ofdm_pwrlvl = (ofdm_pwrlvl > (ofdm_pwrlvl_max - ofdm_pwrlvl_min)) ?
- ofdm_pwrlvl_max : ofdm_pwrlvl + ofdm_pwrlvl_min;
- ofdm_pwrlvl += sc->sc_txpwr_ofdm_base;
- ofdm_pwrlvl = (ofdm_pwrlvl > 35) ? 35 : ofdm_pwrlvl;
-
- error = urtw_8185_set_anaparam2(sc, URTW_8225_ANAPARAM2_ON);
- if (error)
- goto fail;
-
- urtw_8187_write_phy_ofdm(sc, 2, 0x42);
- urtw_8187_write_phy_ofdm(sc, 5, 0x0);
- urtw_8187_write_phy_ofdm(sc, 6, 0x40);
- urtw_8187_write_phy_ofdm(sc, 7, 0x0);
- urtw_8187_write_phy_ofdm(sc, 8, 0x40);
-
- urtw_write8_m(sc, URTW_TX_GAIN_OFDM,
- urtw_8225v2_tx_gain_cck_ofdm[ofdm_pwrlvl]);
- usbd_delay_ms(sc->sc_udev, 1);
-fail:
- return (error);
-}
-
-static usbd_status
-urtw_8225v2_rf_init(struct urtw_softc *sc)
-{
-#define N(a) (sizeof(a) / sizeof((a)[0]))
- int i;
- uint16_t data;
- uint32_t data32;
- usbd_status error;
-
- error = urtw_8180_set_anaparam(sc, URTW_8225_ANAPARAM_ON);
- if (error)
- goto fail;
-
- error = urtw_8225_usb_init(sc);
- if (error)
- goto fail;
-
- urtw_write32_m(sc, URTW_RF_TIMING, 0x000a8008);
- urtw_read16_m(sc, URTW_BRSR, &data); /* XXX ??? */
- urtw_write16_m(sc, URTW_BRSR, 0xffff);
- urtw_write32_m(sc, URTW_RF_PARA, 0x100044);
-
- error = urtw_set_mode(sc, URTW_EPROM_CMD_CONFIG);
- if (error)
- goto fail;
- urtw_write8_m(sc, URTW_CONFIG3, 0x44);
- error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
- if (error)
- goto fail;
-
- error = urtw_8185_rf_pins_enable(sc);
- if (error)
- goto fail;
-
- usbd_delay_ms(sc->sc_udev, 500);
-
- for (i = 0; i < N(urtw_8225v2_rf_part1); i++) {
- urtw_8225_write(sc, urtw_8225v2_rf_part1[i].reg,
- urtw_8225v2_rf_part1[i].val);
- }
- usbd_delay_ms(sc->sc_udev, 50);
-
- urtw_8225_write(sc,
- URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC1);
-
- for (i = 0; i < 95; i++) {
- urtw_8225_write(sc, URTW_8225_ADDR_1_MAGIC, (uint8_t)(i + 1));
- urtw_8225_write(sc, URTW_8225_ADDR_2_MAGIC,
- urtw_8225v2_rxgain[i]);
- }
-
- urtw_8225_write(sc,
- URTW_8225_ADDR_3_MAGIC, URTW_8225_ADDR_3_DATA_MAGIC1);
- urtw_8225_write(sc,
- URTW_8225_ADDR_5_MAGIC, URTW_8225_ADDR_5_DATA_MAGIC1);
- urtw_8225_write(sc,
- URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC2);
- urtw_8225_write(sc,
- URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC1);
- usbd_delay_ms(sc->sc_udev, 100);
- urtw_8225_write(sc,
- URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC2);
- usbd_delay_ms(sc->sc_udev, 100);
-
- error = urtw_8225_read(sc, URTW_8225_ADDR_6_MAGIC, &data32);
- if (error != 0)
- goto fail;
- if (data32 != URTW_8225_ADDR_6_DATA_MAGIC1)
- device_printf(sc->sc_dev, "expect 0xe6!! (0x%x)\n", data32);
- if (!(data32 & URTW_8225_ADDR_6_DATA_MAGIC2)) {
- urtw_8225_write(sc,
- URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC1);
- usbd_delay_ms(sc->sc_udev, 100);
- urtw_8225_write(sc,
- URTW_8225_ADDR_2_MAGIC, URTW_8225_ADDR_2_DATA_MAGIC2);
- usbd_delay_ms(sc->sc_udev, 50);
- error = urtw_8225_read(sc, URTW_8225_ADDR_6_MAGIC, &data32);
- if (error != 0)
- goto fail;
- if (!(data32 & URTW_8225_ADDR_6_DATA_MAGIC2))
- device_printf(sc->sc_dev, "RF calibration failed\n");
- }
- usbd_delay_ms(sc->sc_udev, 100);
-
- urtw_8225_write(sc,
- URTW_8225_ADDR_0_MAGIC, URTW_8225_ADDR_0_DATA_MAGIC6);
- for (i = 0; i < 128; i++) {
- urtw_8187_write_phy_ofdm(sc, 0xb, urtw_8225_agc[i]);
- urtw_8187_write_phy_ofdm(sc, 0xa, (uint8_t)i + 0x80);
- }
-
- for (i = 0; i < N(urtw_8225v2_rf_part2); i++) {
- urtw_8187_write_phy_ofdm(sc, urtw_8225v2_rf_part2[i].reg,
- urtw_8225v2_rf_part2[i].val);
- }
-
- error = urtw_8225v2_setgain(sc, 4);
- if (error)
- goto fail;
-
- for (i = 0; i < N(urtw_8225v2_rf_part3); i++) {
- urtw_8187_write_phy_cck(sc, urtw_8225v2_rf_part3[i].reg,
- urtw_8225v2_rf_part3[i].val);
- }
-
- urtw_write8_m(sc, URTW_ADDR_MAGIC4, 0x0d);
-
- error = urtw_8225v2_set_txpwrlvl(sc, 1);
- if (error)
- goto fail;
-
- urtw_8187_write_phy_cck(sc, 0x10, 0x9b);
- urtw_8187_write_phy_ofdm(sc, 0x26, 0x90);
-
- /* TX ant A, 0x0 for B */
- error = urtw_8185_tx_antenna(sc, 0x3);
- if (error)
- goto fail;
- urtw_write32_m(sc, URTW_ADDR_MAGIC5, 0x3dc00002);
-
- error = urtw_8225_rf_set_chan(sc, 1);
-fail:
- return (error);
-#undef N
-}
-
-static usbd_status
-urtw_8225v2_rf_set_chan(struct urtw_softc *sc, int chan)
-{
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
- struct ieee80211_channel *c = ic->ic_curchan;
- usbd_status error;
-
- error = urtw_8225v2_set_txpwrlvl(sc, chan);
- if (error)
- goto fail;
-
- urtw_8225_write(sc, URTW_8225_ADDR_7_MAGIC, urtw_8225_channel[chan]);
- usbd_delay_ms(sc->sc_udev, 10);
-
- urtw_write8_m(sc, URTW_SIFS, 0x22);
-
- if(sc->sc_state == IEEE80211_S_ASSOC &&
- ic->ic_flags & IEEE80211_F_SHSLOT)
- urtw_write8_m(sc, URTW_SLOT, 0x9);
- else
- urtw_write8_m(sc, URTW_SLOT, 0x14);
-
- if (IEEE80211_IS_CHAN_G(c)) {
- /* for G */
- urtw_write8_m(sc, URTW_DIFS, 0x14);
- urtw_write8_m(sc, URTW_EIFS, 0x5b - 0x14);
- urtw_write8_m(sc, URTW_CW_VAL, 0x73);
- } else {
- /* for B */
- urtw_write8_m(sc, URTW_DIFS, 0x24);
- urtw_write8_m(sc, URTW_EIFS, 0x5b - 0x24);
- urtw_write8_m(sc, URTW_CW_VAL, 0xa5);
- }
-
-fail:
- return (error);
-}
-
-static void
-urtw_ctxtask(void *arg)
-{
- struct urtw_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- uint32_t data;
- usbd_status error;
-
- switch (sc->sc_ctxarg) {
- case URTW_SET_CHANNEL:
- /*
- * during changing th channel we need to temporarily be disable
- * TX.
- */
- urtw_read32_m(sc, URTW_TX_CONF, &data);
- data &= ~URTW_TX_LOOPBACK_MASK;
- urtw_write32_m(sc, URTW_TX_CONF, data | URTW_TX_LOOPBACK_MAC);
- error = sc->sc_rf_set_chan(sc,
- ieee80211_chan2ieee(ic, ic->ic_curchan));
- if (error != 0)
- goto fail;
- usbd_delay_ms(sc->sc_udev, 10);
- urtw_write32_m(sc, URTW_TX_CONF, data | URTW_TX_LOOPBACK_NONE);
- break;
- default:
- panic("unknown argument.\n");
- }
-
-fail:
- if (error != 0)
- device_printf(sc->sc_dev, "could not change the channel\n");
- return;
-}
-
-static void
-urtw_task(void *arg)
-{
- struct urtw_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
- struct ieee80211_node *ni = vap->iv_bss;
- struct urtw_vap *uvp = URTW_VAP(vap);
- usbd_status error = 0;
-
- switch (sc->sc_state) {
- case IEEE80211_S_RUN:
- /* setting bssid. */
- urtw_write32_m(sc, URTW_BSSID, ((uint32_t *)ni->ni_bssid)[0]);
- urtw_write16_m(sc, URTW_BSSID + 4,
- ((uint16_t *)ni->ni_bssid)[2]);
- urtw_update_msr(sc);
- /* XXX maybe the below would be incorrect. */
- urtw_write16_m(sc, URTW_ATIM_WND, 2);
- urtw_write16_m(sc, URTW_ATIM_TR_ITV, 100);
- urtw_write16_m(sc, URTW_BEACON_INTERVAL, 0x64);
- urtw_write16_m(sc, URTW_BEACON_INTERVAL_TIME, 100);
- error = urtw_led_ctl(sc, URTW_LED_CTL_LINK);
- if (error != 0)
- device_printf(sc->sc_dev,
- "could not control LED (%d)\n", error);
- break;
- default:
- break;
- }
-
-fail:
- if (error != 0)
- printf("error duing processing RUN state.");
-
- IEEE80211_LOCK(ic);
- uvp->newstate(vap, sc->sc_state, sc->sc_arg);
- if (vap->iv_newstate_cb != NULL)
- vap->iv_newstate_cb(vap, sc->sc_state, sc->sc_arg);
- IEEE80211_UNLOCK(ic);
-}
-
-static void
-urtw_watchdog(void *arg)
-{
- struct urtw_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
-
- if (sc->sc_txtimer > 0) {
- if (--sc->sc_txtimer == 0) {
- device_printf(sc->sc_dev, "device timeout\n");
- ifp->if_oerrors++;
- return;
- }
- callout_reset(&sc->sc_watchdog_ch, hz, urtw_watchdog, sc);
- }
-}
-
-static device_method_t urtw_methods[] = {
- DEVMETHOD(device_probe, urtw_match),
- DEVMETHOD(device_attach, urtw_attach),
- DEVMETHOD(device_detach, urtw_detach),
- { 0, 0 }
-};
-static driver_t urtw_driver = {
- "urtw",
- urtw_methods,
- sizeof(struct urtw_softc)
-};
-static devclass_t urtw_devclass;
-
-DRIVER_MODULE(urtw, uhub, urtw_driver, urtw_devclass, usbd_driver_load, 0);
-MODULE_DEPEND(urtw, wlan, 1, 1, 1);
-MODULE_DEPEND(urtw, usb, 1, 1, 1);
diff --git a/sys/dev/usb/if_urtwreg.h b/sys/dev/usb/if_urtwreg.h
deleted file mode 100644
index 7a9baa3..0000000
--- a/sys/dev/usb/if_urtwreg.h
+++ /dev/null
@@ -1,256 +0,0 @@
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 2008 Weongyo Jeong <weongyo@FreeBSD.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#define URTW_CONFIG_NO 1
-#define URTW_IFACE_INDEX 0
-
-/* for 8187 */
-#define URTW_MAC0 0x0000 /* 1 byte */
-#define URTW_MAC1 0x0001 /* 1 byte */
-#define URTW_MAC2 0x0002 /* 1 byte */
-#define URTW_MAC3 0x0003 /* 1 byte */
-#define URTW_MAC4 0x0004 /* 1 byte */
-#define URTW_MAC5 0x0005 /* 1 byte */
-#define URTW_BRSR 0x002c /* 2 byte */
-#define URTW_BRSR_MBR_8185 (0x0fff)
-#define URTW_BSSID 0x002e /* 6 byte */
-#define URTW_RESP_RATE 0x0034 /* 1 byte */
-#define URTW_RESP_MAX_RATE_SHIFT (4)
-#define URTW_RESP_MIN_RATE_SHIFT (0)
-#define URTW_EIFS 0x0035 /* 1 byte */
-#define URTW_INTR_MASK 0x003c /* 2 byte */
-#define URTW_CMD 0x0037 /* 1 byte */
-#define URTW_CMD_TX_ENABLE (0x4)
-#define URTW_CMD_RX_ENABLE (0x8)
-#define URTW_CMD_RST (0x10)
-#define URTW_TX_CONF 0x0040 /* 4 byte */
-#define URTW_TX_LOOPBACK_SHIFT (17)
-#define URTW_TX_LOOPBACK_NONE (0 << URTW_TX_LOOPBACK_SHIFT)
-#define URTW_TX_LOOPBACK_MAC (1 << URTW_TX_LOOPBACK_SHIFT)
-#define URTW_TX_LOOPBACK_BASEBAND (2 << URTW_TX_LOOPBACK_SHIFT)
-#define URTW_TX_LOOPBACK_CONTINUE (3 << URTW_TX_LOOPBACK_SHIFT)
-#define URTW_TX_LOOPBACK_MASK (0x60000)
-#define URTW_TX_DPRETRY_MASK (0xff00)
-#define URTW_TX_RTSRETRY_MASK (0xff)
-#define URTW_TX_DPRETRY_SHIFT (0)
-#define URTW_TX_RTSRETRY_SHIFT (8)
-#define URTW_TX_NOCRC (0x10000)
-#define URTW_TX_MXDMA_MASK (0xe00000)
-#define URTW_TX_MXDMA_1024 (6 << URTW_TX_MXDMA_SHIFT)
-#define URTW_TX_MXDMA_2048 (7 << URTW_TX_MXDMA_SHIFT)
-#define URTW_TX_MXDMA_SHIFT (21)
-#define URTW_TX_CWMIN (1 << 31)
-#define URTW_TX_DISCW (1 << 20)
-#define URTW_TX_SWPLCPLEN (1 << 24)
-#define URTW_TX_NOICV (0x80000)
-#define URTW_RX 0x0044 /* 4 byte */
-#define URTW_RX_9356SEL (1 << 6)
-#define URTW_RX_FILTER_MASK \
- (URTW_RX_FILTER_ALLMAC | URTW_RX_FILTER_NICMAC | URTW_RX_FILTER_MCAST | \
- URTW_RX_FILTER_BCAST | URTW_RX_FILTER_CRCERR | URTW_RX_FILTER_ICVERR | \
- URTW_RX_FILTER_DATA | URTW_RX_FILTER_CTL | URTW_RX_FILTER_MNG | \
- (1 << 21) | \
- URTW_RX_FILTER_PWR | URTW_RX_CHECK_BSSID)
-#define URTW_RX_FILTER_ALLMAC (0x00000001)
-#define URTW_RX_FILTER_NICMAC (0x00000002)
-#define URTW_RX_FILTER_MCAST (0x00000004)
-#define URTW_RX_FILTER_BCAST (0x00000008)
-#define URTW_RX_FILTER_CRCERR (0x00000020)
-#define URTW_RX_FILTER_ICVERR (0x00001000)
-#define URTW_RX_FILTER_DATA (0x00040000)
-#define URTW_RX_FILTER_CTL (0x00080000)
-#define URTW_RX_FILTER_MNG (0x00100000)
-#define URTW_RX_FILTER_PWR (0x00400000)
-#define URTW_RX_CHECK_BSSID (0x00800000)
-#define URTW_RX_FIFO_THRESHOLD_MASK ((1 << 13) | (1 << 14) | (1 << 15))
-#define URTW_RX_FIFO_THRESHOLD_SHIFT (13)
-#define URTW_RX_FIFO_THRESHOLD_128 (3)
-#define URTW_RX_FIFO_THRESHOLD_256 (4)
-#define URTW_RX_FIFO_THRESHOLD_512 (5)
-#define URTW_RX_FIFO_THRESHOLD_1024 (6)
-#define URTW_RX_FIFO_THRESHOLD_NONE (7 << URTW_RX_FIFO_THRESHOLD_SHIFT)
-#define URTW_RX_AUTORESETPHY (1 << URTW_RX_AUTORESETPHY_SHIFT)
-#define URTW_RX_AUTORESETPHY_SHIFT (28)
-#define URTW_MAX_RX_DMA_MASK ((1<<8) | (1<<9) | (1<<10))
-#define URTW_MAX_RX_DMA_2048 (7 << URTW_MAX_RX_DMA_SHIFT)
-#define URTW_MAX_RX_DMA_1024 (6)
-#define URTW_MAX_RX_DMA_SHIFT (10)
-#define URTW_RCR_ONLYERLPKT (1 << 31)
-#define URTW_INT_TIMEOUT 0x0048 /* 4 byte */
-#define URTW_EPROM_CMD 0x0050 /* 1 byte */
-#define URTW_EPROM_CMD_NORMAL (0x0)
-#define URTW_EPROM_CMD_NORMAL_MODE \
- (URTW_EPROM_CMD_NORMAL << URTW_EPROM_CMD_SHIFT)
-#define URTW_EPROM_CMD_LOAD (0x1)
-#define URTW_EPROM_CMD_PROGRAM (0x2)
-#define URTW_EPROM_CMD_PROGRAM_MODE \
- (URTW_EPROM_CMD_PROGRAM << URTW_EPROM_CMD_SHIFT)
-#define URTW_EPROM_CMD_CONFIG (0x3)
-#define URTW_EPROM_CMD_SHIFT (6)
-#define URTW_EPROM_CMD_MASK ((1 << 7) | (1 << 6))
-#define URTW_EPROM_READBIT (0x1)
-#define URTW_EPROM_WRITEBIT (0x2)
-#define URTW_EPROM_CK (0x4)
-#define URTW_EPROM_CS (0x8)
-#define URTW_CONFIG2 0x0053
-#define URTW_ANAPARAM 0x0054 /* 4 byte */
-#define URTW_8225_ANAPARAM_ON (0xa0000a59)
-#define URTW_MSR 0x0058 /* 1 byte */
-#define URTW_MSR_LINK_MASK ((1 << 2) | (1 << 3))
-#define URTW_MSR_LINK_SHIFT (2)
-#define URTW_MSR_LINK_NONE (0 << URTW_MSR_LINK_SHIFT)
-#define URTW_MSR_LINK_ADHOC (1 << URTW_MSR_LINK_SHIFT)
-#define URTW_MSR_LINK_STA (2 << URTW_MSR_LINK_SHIFT)
-#define URTW_MSR_LINK_HOSTAP (3 << URTW_MSR_LINK_SHIFT)
-#define URTW_CONFIG3 0x0059 /* 1 byte */
-#define URTW_CONFIG3_ANAPARAM_WRITE (0x40)
-#define URTW_CONFIG3_ANAPARAM_W_SHIFT (6)
-#define URTW_ADDR_MAGIC4 0x005b /* 1 byte */
-#define URTW_PSR 0x005e /* 1 byte */
-#define URTW_ANAPARAM2 0x0060 /* 4 byte */
-#define URTW_8225_ANAPARAM2_ON (0x860c7312)
-#define URTW_BEACON_INTERVAL 0x0070 /* 2 byte */
-#define URTW_ATIM_WND 0x0072 /* 2 byte */
-#define URTW_BEACON_INTERVAL_TIME 0x0074 /* 2 byte */
-#define URTW_ATIM_TR_ITV 0x0076 /* 2 byte */
-#define URTW_PHY_MAGIC1 0x007c /* 1 byte */
-#define URTW_PHY_MAGIC2 0x007d /* 1 byte */
-#define URTW_PHY_MAGIC3 0x007e /* 1 byte */
-#define URTW_PHY_MAGIC4 0x007f /* 1 byte */
-#define URTW_RF_PINS_OUTPUT 0x0080 /* 2 byte */
-#define URTW_RF_PINS_OUTPUT_MAGIC1 (0x3a0)
-#define URTW_BB_HOST_BANG_CLK (1 << 1)
-#define URTW_BB_HOST_BANG_EN (1 << 2)
-#define URTW_BB_HOST_BANG_RW (1 << 3)
-#define URTW_RF_PINS_ENABLE 0x0082 /* 2 byte */
-#define URTW_RF_PINS_SELECT 0x0084 /* 2 byte */
-#define URTW_ADDR_MAGIC1 0x0085 /* broken? */
-#define URTW_RF_PINS_INPUT 0x0086 /* 2 byte */
-#define URTW_RF_PINS_MAGIC1 (0xfff3)
-#define URTW_RF_PINS_MAGIC2 (0xfff0)
-#define URTW_RF_PINS_MAGIC3 (0x0007)
-#define URTW_RF_PINS_MAGIC4 (0xf)
-#define URTW_RF_PINS_MAGIC5 (0x0080)
-#define URTW_RF_PARA 0x0088 /* 4 byte */
-#define URTW_RF_TIMING 0x008c /* 4 byte */
-#define URTW_GP_ENABLE 0x0090 /* 1 byte */
-#define URTW_GP_ENABLE_DATA_MAGIC1 (0x1)
-#define URTW_GPIO 0x0091 /* 1 byte */
-#define URTW_GPIO_DATA_MAGIC1 (0x1)
-#define URTW_ADDR_MAGIC5 0x0094 /* 4 byte */
-#define URTW_TX_AGC_CTL 0x009c /* 1 byte */
-#define URTW_TX_AGC_CTL_PERPACKET_GAIN (0x1)
-#define URTW_TX_AGC_CTL_PERPACKET_ANTSEL (0x2)
-#define URTW_TX_AGC_CTL_FEEDBACK_ANT (0x4)
-#define URTW_TX_GAIN_CCK 0x009d /* 1 byte */
-#define URTW_TX_GAIN_OFDM 0x009e /* 1 byte */
-#define URTW_TX_ANTENNA 0x009f /* 1 byte */
-#define URTW_WPA_CONFIG 0x00b0 /* 1 byte */
-#define URTW_SIFS 0x00b4 /* 1 byte */
-#define URTW_DIFS 0x00b5 /* 1 byte */
-#define URTW_SLOT 0x00b6 /* 1 byte */
-#define URTW_CW_CONF 0x00bc /* 1 byte */
-#define URTW_CW_CONF_PERPACKET_RETRY (0x2)
-#define URTW_CW_CONF_PERPACKET_CW (0x1)
-#define URTW_CW_VAL 0x00bd /* 1 byte */
-#define URTW_RATE_FALLBACK 0x00be /* 1 byte */
-#define URTW_TALLY_SEL 0x00fc /* 1 byte */
-#define URTW_ADDR_MAGIC2 0x00fe /* 2 byte */
-#define URTW_ADDR_MAGIC3 0x00ff /* 1 byte */
-
-/* for 8225 */
-#define URTW_8225_ADDR_0_MAGIC 0x0
-#define URTW_8225_ADDR_0_DATA_MAGIC1 (0x1b7)
-#define URTW_8225_ADDR_0_DATA_MAGIC2 (0x0b7)
-#define URTW_8225_ADDR_0_DATA_MAGIC3 (0x127)
-#define URTW_8225_ADDR_0_DATA_MAGIC4 (0x027)
-#define URTW_8225_ADDR_0_DATA_MAGIC5 (0x22f)
-#define URTW_8225_ADDR_0_DATA_MAGIC6 (0x2bf)
-#define URTW_8225_ADDR_1_MAGIC 0x1
-#define URTW_8225_ADDR_2_MAGIC 0x2
-#define URTW_8225_ADDR_2_DATA_MAGIC1 (0xc4d)
-#define URTW_8225_ADDR_2_DATA_MAGIC2 (0x44d)
-#define URTW_8225_ADDR_3_MAGIC 0x3
-#define URTW_8225_ADDR_3_DATA_MAGIC1 (0x2)
-#define URTW_8225_ADDR_5_MAGIC 0x5
-#define URTW_8225_ADDR_5_DATA_MAGIC1 (0x4)
-#define URTW_8225_ADDR_6_MAGIC 0x6
-#define URTW_8225_ADDR_6_DATA_MAGIC1 (0xe6)
-#define URTW_8225_ADDR_6_DATA_MAGIC2 (0x80)
-#define URTW_8225_ADDR_7_MAGIC 0x7
-#define URTW_8225_ADDR_8_MAGIC 0x8
-#define URTW_8225_ADDR_8_DATA_MAGIC1 (0x588)
-#define URTW_8225_ADDR_9_MAGIC 0x9
-#define URTW_8225_ADDR_9_DATA_MAGIC1 (0x700)
-#define URTW_8225_ADDR_C_MAGIC 0xc
-#define URTW_8225_ADDR_C_DATA_MAGIC1 (0x850)
-#define URTW_8225_ADDR_C_DATA_MAGIC2 (0x050)
-
-/* for EEPROM */
-#define URTW_EPROM_TXPW_BASE 0x05
-#define URTW_EPROM_RFCHIPID 0x06
-#define URTW_EPROM_RFCHIPID_RTL8225U (5)
-#define URTW_EPROM_MACADDR 0x07
-#define URTW_EPROM_TXPW0 0x16
-#define URTW_EPROM_TXPW2 0x1b
-#define URTW_EPROM_TXPW1 0x3d
-#define URTW_EPROM_SWREV 0x3f
-#define URTW_EPROM_CID_MASK (0xff)
-#define URTW_EPROM_CID_RSVD0 (0x00)
-#define URTW_EPROM_CID_RSVD1 (0xff)
-#define URTW_EPROM_CID_ALPHA0 (0x01)
-#define URTW_EPROM_CID_SERCOMM_PS (0x02)
-#define URTW_EPROM_CID_HW_LED (0x03)
-
-/* LED */
-#define URTW_CID_DEFAULT 0
-#define URTW_CID_8187_ALPHA0 1
-#define URTW_CID_8187_SERCOMM_PS 2
-#define URTW_CID_8187_HW_LED 3
-#define URTW_SW_LED_MODE0 0
-#define URTW_SW_LED_MODE1 1
-#define URTW_SW_LED_MODE2 2
-#define URTW_SW_LED_MODE3 3
-#define URTW_HW_LED 4
-#define URTW_LED_CTL_POWER_ON 0
-#define URTW_LED_CTL_LINK 2
-#define URTW_LED_CTL_TX 4
-#define URTW_LED_PIN_GPIO0 0
-#define URTW_LED_PIN_LED0 1
-#define URTW_LED_PIN_LED1 2
-#define URTW_LED_UNKNOWN 0
-#define URTW_LED_ON 1
-#define URTW_LED_OFF 2
-#define URTW_LED_BLINK_NORMAL 3
-#define URTW_LED_BLINK_SLOWLY 4
-#define URTW_LED_POWER_ON_BLINK 5
-#define URTW_LED_SCAN_BLINK 6
-#define URTW_LED_NO_LINK_BLINK 7
-#define URTW_LED_BLINK_CM3 8
-
-/* for extra area */
-#define URTW_EPROM_DISABLE 0
-#define URTW_EPROM_ENABLE 1
-#define URTW_EPROM_DELAY 10
-#define URTW_8187_GETREGS_REQ 5
-#define URTW_8187_SETREGS_REQ 5
-#define URTW_8225_RF_MAX_SENS 6
-#define URTW_8225_RF_DEF_SENS 4
-#define URTW_DEFAULT_RTS_RETRY 7
-#define URTW_DEFAULT_TX_RETRY 7
-#define URTW_DEFAULT_RTS_THRESHOLD 2342U
diff --git a/sys/dev/usb/if_urtwvar.h b/sys/dev/usb/if_urtwvar.h
deleted file mode 100644
index 77c09ef..0000000
--- a/sys/dev/usb/if_urtwvar.h
+++ /dev/null
@@ -1,151 +0,0 @@
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 2008 Weongyo Jeong <weongyo@FreeBSD.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* XXX no definition at net80211? */
-#define URTW_MAX_CHANNELS 15
-
-struct urtw_data {
- struct urtw_softc *sc;
- usbd_xfer_handle xfer;
- uint8_t *buf;
- struct mbuf *m;
- struct ieee80211_node *ni; /* NB: tx only */
-};
-
-/* XXX not correct.. */
-#define URTW_MIN_RXBUFSZ \
- (sizeof(struct ieee80211_frame_min))
-
-#define URTW_RX_DATA_LIST_COUNT 1
-#define URTW_TX_DATA_LIST_COUNT 16
-#define URTW_RX_MAXSIZE 0x9c4
-#define URTW_TX_MAXSIZE 0x9c4
-
-struct urtw_rx_radiotap_header {
- struct ieee80211_radiotap_header wr_ihdr;
- uint8_t wr_flags;
- uint16_t wr_chan_freq;
- uint16_t wr_chan_flags;
- int8_t wr_dbm_antsignal;
-} __packed;
-
-#define URTW_RX_RADIOTAP_PRESENT \
- ((1 << IEEE80211_RADIOTAP_FLAGS) | \
- (1 << IEEE80211_RADIOTAP_CHANNEL) | \
- (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL))
-
-struct urtw_tx_radiotap_header {
- struct ieee80211_radiotap_header wt_ihdr;
- uint8_t wt_flags;
- uint16_t wt_chan_freq;
- uint16_t wt_chan_flags;
-} __packed;
-
-#define URTW_TX_RADIOTAP_PRESENT \
- ((1 << IEEE80211_RADIOTAP_FLAGS) | \
- (1 << IEEE80211_RADIOTAP_CHANNEL))
-
-struct urtw_vap {
- struct ieee80211vap vap;
- int (*newstate)(struct ieee80211vap *,
- enum ieee80211_state, int);
-};
-#define URTW_VAP(vap) ((struct urtw_vap *)(vap))
-
-struct urtw_softc {
- struct ifnet *sc_ifp;
- device_t sc_dev;
- usbd_device_handle sc_udev;
- usbd_interface_handle sc_iface;
- struct mtx sc_mtx;
-
- int sc_debug;
- int sc_if_flags;
- int sc_flags;
-#define URTW_INIT_ONCE (1 << 1)
- struct usb_task sc_task;
- struct usb_task sc_ctxtask;
- int sc_ctxarg;
-#define URTW_SET_CHANNEL 1
- enum ieee80211_state sc_state;
- int sc_arg;
- int (*sc_newstate)(struct ieee80211com *,
- enum ieee80211_state, int);
-
- int sc_epromtype;
-#define URTW_EEPROM_93C46 0
-#define URTW_EEPROM_93C56 1
- uint8_t sc_crcmon;
- uint8_t sc_bssid[IEEE80211_ADDR_LEN];
-
- /* for RF */
- usbd_status (*sc_rf_init)(struct urtw_softc *);
- usbd_status (*sc_rf_set_chan)(struct urtw_softc *,
- int);
- usbd_status (*sc_rf_set_sens)(struct urtw_softc *,
- int);
- uint8_t sc_rfchip;
- uint32_t sc_max_sens;
- uint32_t sc_sens;
- /* for LED */
- struct callout sc_led_ch;
- struct usb_task sc_ledtask;
- uint8_t sc_psr;
- uint8_t sc_strategy;
-#define URTW_LED_GPIO 1
- uint8_t sc_gpio_ledon;
- uint8_t sc_gpio_ledinprogress;
- uint8_t sc_gpio_ledstate;
- uint8_t sc_gpio_ledpin;
- uint8_t sc_gpio_blinktime;
- uint8_t sc_gpio_blinkstate;
- /* RX/TX */
- usbd_pipe_handle sc_rxpipe;
- usbd_pipe_handle sc_txpipe_low;
- usbd_pipe_handle sc_txpipe_normal;
-#define URTW_PRIORITY_LOW 0
-#define URTW_PRIORITY_NORMAL 1
-#define URTW_DATA_TIMEOUT 10000 /* 10 sec */
- struct urtw_data sc_rxdata[URTW_RX_DATA_LIST_COUNT];
- struct urtw_data sc_txdata[URTW_TX_DATA_LIST_COUNT];
- uint32_t sc_tx_low_queued;
- uint32_t sc_tx_normal_queued;
- uint32_t sc_txidx;
- uint8_t sc_rts_retry;
- uint8_t sc_tx_retry;
- uint8_t sc_preamble_mode;
-#define URTW_PREAMBLE_MODE_SHORT 1
-#define URTW_PREAMBLE_MODE_LONG 2
- struct callout sc_watchdog_ch;
- int sc_txtimer;
- int sc_currate;
- /* TX power */
- uint8_t sc_txpwr_cck[URTW_MAX_CHANNELS];
- uint8_t sc_txpwr_cck_base;
- uint8_t sc_txpwr_ofdm[URTW_MAX_CHANNELS];
- uint8_t sc_txpwr_ofdm_base;
-
- struct urtw_rx_radiotap_header sc_rxtap;
- int sc_rxtap_len;
- struct urtw_tx_radiotap_header sc_txtap;
- int sc_txtap_len;
-};
-
-#define URTW_LOCK(sc) mtx_lock(&(sc)->sc_mtx)
-#define URTW_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx)
-#define URTW_ASSERT_LOCKED(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED)
diff --git a/sys/dev/usb/if_zyd.c b/sys/dev/usb/if_zyd.c
deleted file mode 100644
index 3a4abce..0000000
--- a/sys/dev/usb/if_zyd.c
+++ /dev/null
@@ -1,3126 +0,0 @@
-/* $OpenBSD: if_zyd.c,v 1.52 2007/02/11 00:08:04 jsg Exp $ */
-/* $NetBSD: if_zyd.c,v 1.7 2007/06/21 04:04:29 kiyohara Exp $ */
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 2006 by Damien Bergamini <damien.bergamini@free.fr>
- * Copyright (c) 2006 by Florian Stoehr <ich@florian-stoehr.de>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * ZyDAS ZD1211/ZD1211B USB WLAN driver.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/sockio.h>
-#include <sys/mbuf.h>
-#include <sys/malloc.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/socket.h>
-#include <sys/sysctl.h>
-#include <sys/endian.h>
-#include <sys/linker.h>
-
-#include <net/if.h>
-#include <net/if_arp.h>
-#include <net/ethernet.h>
-#include <net/if_dl.h>
-#include <net/if_media.h>
-#include <net/if_types.h>
-
-#include <sys/bus.h>
-#include <machine/bus.h>
-
-#include <net80211/ieee80211_var.h>
-#include <net80211/ieee80211_amrr.h>
-#include <net80211/ieee80211_phy.h>
-#include <net80211/ieee80211_radiotap.h>
-#include <net80211/ieee80211_regdomain.h>
-
-#include <net/bpf.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include <dev/usb/usbdivar.h>
-#include "usbdevs.h"
-#include <dev/usb/usb_ethersubr.h>
-
-#include <dev/mii/mii.h>
-#include <dev/mii/miivar.h>
-
-#include <dev/usb/if_zydreg.h>
-#include <dev/usb/if_zydfw.h>
-
-#ifdef ZYD_DEBUG
-SYSCTL_NODE(_hw_usb, OID_AUTO, zyd, CTLFLAG_RW, 0, "ZyDAS zd1211/zd1211b");
-int zyd_debug = 0;
-SYSCTL_INT(_hw_usb_zyd, OID_AUTO, debug, CTLFLAG_RW, &zyd_debug, 0,
- "control debugging printfs");
-TUNABLE_INT("hw.usb.zyd.debug", &zyd_debug);
-enum {
- ZYD_DEBUG_XMIT = 0x00000001, /* basic xmit operation */
- ZYD_DEBUG_RECV = 0x00000002, /* basic recv operation */
- ZYD_DEBUG_RESET = 0x00000004, /* reset processing */
- ZYD_DEBUG_INIT = 0x00000008, /* device init */
- ZYD_DEBUG_TX_PROC = 0x00000010, /* tx ISR proc */
- ZYD_DEBUG_RX_PROC = 0x00000020, /* rx ISR proc */
- ZYD_DEBUG_STATE = 0x00000040, /* 802.11 state transitions */
- ZYD_DEBUG_STAT = 0x00000080, /* statistic */
- ZYD_DEBUG_FW = 0x00000100, /* firmware */
- ZYD_DEBUG_ANY = 0xffffffff
-};
-#define DPRINTF(sc, m, fmt, ...) do { \
- if (sc->sc_debug & (m)) \
- printf(fmt, __VA_ARGS__); \
-} while (0)
-#else
-#define DPRINTF(sc, m, fmt, ...) do { \
- (void) sc; \
-} while (0)
-#endif
-
-static const struct zyd_phy_pair zyd_def_phy[] = ZYD_DEF_PHY;
-static const struct zyd_phy_pair zyd_def_phyB[] = ZYD_DEF_PHYB;
-
-/* various supported device vendors/products */
-#define ZYD_ZD1211_DEV(v, p) \
- { { USB_VENDOR_##v, USB_PRODUCT_##v##_##p }, ZYD_ZD1211 }
-#define ZYD_ZD1211B_DEV(v, p) \
- { { USB_VENDOR_##v, USB_PRODUCT_##v##_##p }, ZYD_ZD1211B }
-static const struct zyd_type {
- struct usb_devno dev;
- uint8_t rev;
-#define ZYD_ZD1211 0
-#define ZYD_ZD1211B 1
-} zyd_devs[] = {
- ZYD_ZD1211_DEV(3COM2, 3CRUSB10075),
- ZYD_ZD1211_DEV(ABOCOM, WL54),
- ZYD_ZD1211_DEV(ASUS, WL159G),
- ZYD_ZD1211_DEV(CYBERTAN, TG54USB),
- ZYD_ZD1211_DEV(DRAYTEK, VIGOR550),
- ZYD_ZD1211_DEV(PLANEX2, GWUS54GD),
- ZYD_ZD1211_DEV(PLANEX2, GWUS54GZL),
- ZYD_ZD1211_DEV(PLANEX3, GWUS54GZ),
- ZYD_ZD1211_DEV(PLANEX3, GWUS54MINI),
- ZYD_ZD1211_DEV(SAGEM, XG760A),
- ZYD_ZD1211_DEV(SENAO, NUB8301),
- ZYD_ZD1211_DEV(SITECOMEU, WL113),
- ZYD_ZD1211_DEV(SWEEX, ZD1211),
- ZYD_ZD1211_DEV(TEKRAM, QUICKWLAN),
- ZYD_ZD1211_DEV(TEKRAM, ZD1211_1),
- ZYD_ZD1211_DEV(TEKRAM, ZD1211_2),
- ZYD_ZD1211_DEV(TWINMOS, G240),
- ZYD_ZD1211_DEV(UMEDIA, ALL0298V2),
- ZYD_ZD1211_DEV(UMEDIA, TEW429UB_A),
- ZYD_ZD1211_DEV(UMEDIA, TEW429UB),
- ZYD_ZD1211_DEV(WISTRONNEWEB, UR055G),
- ZYD_ZD1211_DEV(ZCOM, ZD1211),
- ZYD_ZD1211_DEV(ZYDAS, ZD1211),
- ZYD_ZD1211_DEV(ZYXEL, AG225H),
- ZYD_ZD1211_DEV(ZYXEL, ZYAIRG220),
- ZYD_ZD1211_DEV(ZYXEL, G200V2),
- ZYD_ZD1211_DEV(ZYXEL, G202),
-
- ZYD_ZD1211B_DEV(ACCTON, SMCWUSBG),
- ZYD_ZD1211B_DEV(ACCTON, ZD1211B),
- ZYD_ZD1211B_DEV(ASUS, A9T_WIFI),
- ZYD_ZD1211B_DEV(BELKIN, F5D7050_V4000),
- ZYD_ZD1211B_DEV(BELKIN, ZD1211B),
- ZYD_ZD1211B_DEV(CISCOLINKSYS, WUSBF54G),
- ZYD_ZD1211B_DEV(FIBERLINE, WL430U),
- ZYD_ZD1211B_DEV(MELCO, KG54L),
- ZYD_ZD1211B_DEV(PHILIPS, SNU5600),
- ZYD_ZD1211B_DEV(PLANEX2, GW_US54GXS),
- ZYD_ZD1211B_DEV(SAGEM, XG76NA),
- ZYD_ZD1211B_DEV(SITECOMEU, ZD1211B),
- ZYD_ZD1211B_DEV(UMEDIA, TEW429UBC1),
-#if 0 /* Shall we needs? */
- ZYD_ZD1211B_DEV(UNKNOWN1, ZD1211B_1),
- ZYD_ZD1211B_DEV(UNKNOWN1, ZD1211B_2),
- ZYD_ZD1211B_DEV(UNKNOWN2, ZD1211B),
- ZYD_ZD1211B_DEV(UNKNOWN3, ZD1211B),
-#endif
- ZYD_ZD1211B_DEV(USR, USR5423),
- ZYD_ZD1211B_DEV(VTECH, ZD1211B),
- ZYD_ZD1211B_DEV(ZCOM, ZD1211B),
- ZYD_ZD1211B_DEV(ZYDAS, ZD1211B),
- ZYD_ZD1211B_DEV(ZYXEL, M202),
- ZYD_ZD1211B_DEV(ZYXEL, G220V2),
-};
-#define zyd_lookup(v, p) \
- ((const struct zyd_type *)usb_lookup(zyd_devs, v, p))
-#define zyd_read16_m(sc, val, data) do { \
- error = zyd_read16(sc, val, data); \
- if (error != 0) \
- goto fail; \
-} while (0)
-#define zyd_write16_m(sc, val, data) do { \
- error = zyd_write16(sc, val, data); \
- if (error != 0) \
- goto fail; \
-} while (0)
-#define zyd_read32_m(sc, val, data) do { \
- error = zyd_read32(sc, val, data); \
- if (error != 0) \
- goto fail; \
-} while (0)
-#define zyd_write32_m(sc, val, data) do { \
- error = zyd_write32(sc, val, data); \
- if (error != 0) \
- goto fail; \
-} while (0)
-
-static device_probe_t zyd_match;
-static device_attach_t zyd_attach;
-static device_detach_t zyd_detach;
-
-static struct ieee80211vap *zyd_vap_create(struct ieee80211com *,
- const char name[IFNAMSIZ], int unit, int opmode,
- int flags, const uint8_t bssid[IEEE80211_ADDR_LEN],
- const uint8_t mac[IEEE80211_ADDR_LEN]);
-static void zyd_vap_delete(struct ieee80211vap *);
-static int zyd_open_pipes(struct zyd_softc *);
-static void zyd_close_pipes(struct zyd_softc *);
-static int zyd_alloc_tx_list(struct zyd_softc *);
-static void zyd_free_tx_list(struct zyd_softc *);
-static int zyd_alloc_rx_list(struct zyd_softc *);
-static void zyd_free_rx_list(struct zyd_softc *);
-static struct ieee80211_node *zyd_node_alloc(struct ieee80211vap *,
- const uint8_t mac[IEEE80211_ADDR_LEN]);
-static void zyd_task(void *);
-static int zyd_newstate(struct ieee80211vap *, enum ieee80211_state, int);
-static int zyd_cmd(struct zyd_softc *, uint16_t, const void *, int,
- void *, int, u_int);
-static int zyd_read16(struct zyd_softc *, uint16_t, uint16_t *);
-static int zyd_read32(struct zyd_softc *, uint16_t, uint32_t *);
-static int zyd_write16(struct zyd_softc *, uint16_t, uint16_t);
-static int zyd_write32(struct zyd_softc *, uint16_t, uint32_t);
-static int zyd_rfwrite(struct zyd_softc *, uint32_t);
-static int zyd_lock_phy(struct zyd_softc *);
-static int zyd_unlock_phy(struct zyd_softc *);
-static int zyd_rf_attach(struct zyd_softc *, uint8_t);
-static const char *zyd_rf_name(uint8_t);
-static int zyd_hw_init(struct zyd_softc *);
-static int zyd_read_pod(struct zyd_softc *);
-static int zyd_read_eeprom(struct zyd_softc *);
-static int zyd_get_macaddr(struct zyd_softc *);
-static int zyd_set_macaddr(struct zyd_softc *, const uint8_t *);
-static int zyd_set_bssid(struct zyd_softc *, const uint8_t *);
-static int zyd_switch_radio(struct zyd_softc *, int);
-static int zyd_set_led(struct zyd_softc *, int, int);
-static void zyd_set_multi(void *);
-static void zyd_update_mcast(struct ifnet *);
-static int zyd_set_rxfilter(struct zyd_softc *);
-static void zyd_set_chan(struct zyd_softc *, struct ieee80211_channel *);
-static int zyd_set_beacon_interval(struct zyd_softc *, int);
-static void zyd_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
-static void zyd_rx_data(struct zyd_softc *, const uint8_t *, uint16_t);
-static void zyd_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
-static void zyd_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
-static int zyd_tx_mgt(struct zyd_softc *, struct mbuf *,
- struct ieee80211_node *);
-static int zyd_tx_data(struct zyd_softc *, struct mbuf *,
- struct ieee80211_node *);
-static void zyd_start(struct ifnet *);
-static int zyd_raw_xmit(struct ieee80211_node *, struct mbuf *,
- const struct ieee80211_bpf_params *);
-static void zyd_watchdog(void *);
-static int zyd_ioctl(struct ifnet *, u_long, caddr_t);
-static void zyd_init_locked(struct zyd_softc *);
-static void zyd_init(void *);
-static void zyd_stop(struct zyd_softc *, int);
-static int zyd_loadfirmware(struct zyd_softc *);
-static void zyd_newassoc(struct ieee80211_node *, int);
-static void zyd_scantask(void *);
-static void zyd_scan_start(struct ieee80211com *);
-static void zyd_scan_end(struct ieee80211com *);
-static void zyd_set_channel(struct ieee80211com *);
-static void zyd_wakeup(struct zyd_softc *);
-static int zyd_rfmd_init(struct zyd_rf *);
-static int zyd_rfmd_switch_radio(struct zyd_rf *, int);
-static int zyd_rfmd_set_channel(struct zyd_rf *, uint8_t);
-static int zyd_al2230_init(struct zyd_rf *);
-static int zyd_al2230_switch_radio(struct zyd_rf *, int);
-static int zyd_al2230_set_channel(struct zyd_rf *, uint8_t);
-static int zyd_al2230_set_channel_b(struct zyd_rf *, uint8_t);
-static int zyd_al2230_init_b(struct zyd_rf *);
-static int zyd_al7230B_init(struct zyd_rf *);
-static int zyd_al7230B_switch_radio(struct zyd_rf *, int);
-static int zyd_al7230B_set_channel(struct zyd_rf *, uint8_t);
-static int zyd_al2210_init(struct zyd_rf *);
-static int zyd_al2210_switch_radio(struct zyd_rf *, int);
-static int zyd_al2210_set_channel(struct zyd_rf *, uint8_t);
-static int zyd_gct_init(struct zyd_rf *);
-static int zyd_gct_switch_radio(struct zyd_rf *, int);
-static int zyd_gct_set_channel(struct zyd_rf *, uint8_t);
-static int zyd_maxim_init(struct zyd_rf *);
-static int zyd_maxim_switch_radio(struct zyd_rf *, int);
-static int zyd_maxim_set_channel(struct zyd_rf *, uint8_t);
-static int zyd_maxim2_init(struct zyd_rf *);
-static int zyd_maxim2_switch_radio(struct zyd_rf *, int);
-static int zyd_maxim2_set_channel(struct zyd_rf *, uint8_t);
-
-static int
-zyd_match(device_t dev)
-{
- struct usb_attach_arg *uaa = device_get_ivars(dev);
-
- if (!uaa->iface)
- return (UMATCH_NONE);
-
- return (zyd_lookup(uaa->vendor, uaa->product) != NULL) ?
- (UMATCH_VENDOR_PRODUCT) : (UMATCH_NONE);
-}
-
-static int
-zyd_attach(device_t dev)
-{
- int error = ENXIO;
- struct ieee80211com *ic;
- struct ifnet *ifp;
- struct usb_attach_arg *uaa = device_get_ivars(dev);
- struct zyd_softc *sc = device_get_softc(dev);
- usb_device_descriptor_t* ddesc;
- uint8_t bands;
-
- sc->sc_dev = dev;
- sc->sc_udev = uaa->device;
- sc->sc_macrev = zyd_lookup(uaa->vendor, uaa->product)->rev;
-#ifdef ZYD_DEBUG
- sc->sc_debug = zyd_debug;
-#endif
-
- ddesc = usbd_get_device_descriptor(sc->sc_udev);
- if (UGETW(ddesc->bcdDevice) < 0x4330) {
- device_printf(dev, "device version mismatch: 0x%x "
- "(only >= 43.30 supported)\n",
- UGETW(ddesc->bcdDevice));
- return (ENXIO);
- }
-
- if ((error = zyd_get_macaddr(sc)) != 0) {
- device_printf(sc->sc_dev, "could not read EEPROM\n");
- return (ENXIO);
- }
-
- mtx_init(&sc->sc_txmtx, device_get_nameunit(sc->sc_dev),
- MTX_NETWORK_LOCK, MTX_DEF);
- usb_init_task(&sc->sc_mcasttask, zyd_set_multi, sc);
- usb_init_task(&sc->sc_scantask, zyd_scantask, sc);
- usb_init_task(&sc->sc_task, zyd_task, sc);
- callout_init(&sc->sc_watchdog_ch, 0);
- STAILQ_INIT(&sc->sc_rqh);
-
- ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
- if (ifp == NULL) {
- device_printf(dev, "can not if_alloc()\n");
- error = ENXIO;
- goto fail0;
- }
- ifp->if_softc = sc;
- if_initname(ifp, "zyd", device_get_unit(sc->sc_dev));
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
- IFF_NEEDSGIANT; /* USB stack is still under Giant lock */
- ifp->if_init = zyd_init;
- ifp->if_ioctl = zyd_ioctl;
- ifp->if_start = zyd_start;
- IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
- IFQ_SET_READY(&ifp->if_snd);
-
- ic = ifp->if_l2com;
- ic->ic_ifp = ifp;
- ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
- ic->ic_opmode = IEEE80211_M_STA;
- IEEE80211_ADDR_COPY(ic->ic_myaddr, sc->sc_bssid);
-
- /* set device capabilities */
- ic->ic_caps =
- IEEE80211_C_STA /* station mode */
- | IEEE80211_C_MONITOR /* monitor mode */
- | IEEE80211_C_SHPREAMBLE /* short preamble supported */
- | IEEE80211_C_SHSLOT /* short slot time supported */
- | IEEE80211_C_BGSCAN /* capable of bg scanning */
- | IEEE80211_C_WPA /* 802.11i */
- ;
-
- bands = 0;
- setbit(&bands, IEEE80211_MODE_11B);
- setbit(&bands, IEEE80211_MODE_11G);
- ieee80211_init_channels(ic, NULL, &bands);
-
- ieee80211_ifattach(ic);
- ic->ic_newassoc = zyd_newassoc;
- ic->ic_raw_xmit = zyd_raw_xmit;
- ic->ic_node_alloc = zyd_node_alloc;
- ic->ic_scan_start = zyd_scan_start;
- ic->ic_scan_end = zyd_scan_end;
- ic->ic_set_channel = zyd_set_channel;
-
- ic->ic_vap_create = zyd_vap_create;
- ic->ic_vap_delete = zyd_vap_delete;
- ic->ic_update_mcast = zyd_update_mcast;
-
- bpfattach(ifp, DLT_IEEE802_11_RADIO,
- sizeof(struct ieee80211_frame) + sizeof(sc->sc_txtap));
- sc->sc_rxtap_len = sizeof(sc->sc_rxtap);
- sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
- sc->sc_rxtap.wr_ihdr.it_present = htole32(ZYD_RX_RADIOTAP_PRESENT);
- sc->sc_txtap_len = sizeof(sc->sc_txtap);
- sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
- sc->sc_txtap.wt_ihdr.it_present = htole32(ZYD_TX_RADIOTAP_PRESENT);
-
- if (bootverbose)
- ieee80211_announce(ic);
-
- usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev);
-
- return (0);
-
-fail0: mtx_destroy(&sc->sc_txmtx);
- return (error);
-}
-
-static int
-zyd_detach(device_t dev)
-{
- struct zyd_softc *sc = device_get_softc(dev);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
-
- if (!device_is_attached(dev))
- return (0);
-
- /* set a flag to indicate we're detaching. */
- sc->sc_flags |= ZYD_FLAG_DETACHING;
-
- zyd_stop(sc, 1);
- bpfdetach(ifp);
- ieee80211_ifdetach(ic);
-
- zyd_wakeup(sc);
- zyd_close_pipes(sc);
-
- if_free(ifp);
- mtx_destroy(&sc->sc_txmtx);
-
- usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev);
-
- return (0);
-}
-
-static struct ieee80211vap *
-zyd_vap_create(struct ieee80211com *ic,
- const char name[IFNAMSIZ], int unit, int opmode, int flags,
- const uint8_t bssid[IEEE80211_ADDR_LEN],
- const uint8_t mac[IEEE80211_ADDR_LEN])
-{
- struct zyd_vap *zvp;
- struct ieee80211vap *vap;
-
- if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */
- return (NULL);
- zvp = (struct zyd_vap *) malloc(sizeof(struct zyd_vap),
- M_80211_VAP, M_NOWAIT | M_ZERO);
- if (zvp == NULL)
- return (NULL);
- vap = &zvp->vap;
- /* enable s/w bmiss handling for sta mode */
- ieee80211_vap_setup(ic, vap, name, unit, opmode,
- flags | IEEE80211_CLONE_NOBEACONS, bssid, mac);
-
- /* override state transition machine */
- zvp->newstate = vap->iv_newstate;
- vap->iv_newstate = zyd_newstate;
-
- ieee80211_amrr_init(&zvp->amrr, vap,
- IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
- IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD,
- 1000 /* 1 sec */);
-
- /* complete setup */
- ieee80211_vap_attach(vap, ieee80211_media_change,
- ieee80211_media_status);
- ic->ic_opmode = opmode;
- return (vap);
-}
-
-static void
-zyd_vap_delete(struct ieee80211vap *vap)
-{
- struct zyd_vap *zvp = ZYD_VAP(vap);
-
- ieee80211_amrr_cleanup(&zvp->amrr);
- ieee80211_vap_detach(vap);
- free(zvp, M_80211_VAP);
-}
-
-static int
-zyd_open_pipes(struct zyd_softc *sc)
-{
- usb_endpoint_descriptor_t *edesc;
- int isize;
- usbd_status error;
-
- /* interrupt in */
- edesc = usbd_get_endpoint_descriptor(sc->sc_iface, 0x83);
- if (edesc == NULL)
- return (EINVAL);
-
- isize = UGETW(edesc->wMaxPacketSize);
- if (isize == 0) /* should not happen */
- return (EINVAL);
-
- sc->sc_ibuf = malloc(isize, M_USBDEV, M_NOWAIT);
- if (sc->sc_ibuf == NULL)
- return (ENOMEM);
-
- error = usbd_open_pipe_intr(sc->sc_iface, 0x83, USBD_SHORT_XFER_OK,
- &sc->sc_ep[ZYD_ENDPT_IIN], sc, sc->sc_ibuf, isize, zyd_intr,
- USBD_DEFAULT_INTERVAL);
- if (error != 0) {
- device_printf(sc->sc_dev, "open rx intr pipe failed: %s\n",
- usbd_errstr(error));
- goto fail;
- }
-
- /* interrupt out (not necessarily an interrupt pipe) */
- error = usbd_open_pipe(sc->sc_iface, 0x04, USBD_EXCLUSIVE_USE,
- &sc->sc_ep[ZYD_ENDPT_IOUT]);
- if (error != 0) {
- device_printf(sc->sc_dev, "open tx intr pipe failed: %s\n",
- usbd_errstr(error));
- goto fail;
- }
-
- /* bulk in */
- error = usbd_open_pipe(sc->sc_iface, 0x82, USBD_EXCLUSIVE_USE,
- &sc->sc_ep[ZYD_ENDPT_BIN]);
- if (error != 0) {
- device_printf(sc->sc_dev, "open rx pipe failed: %s\n",
- usbd_errstr(error));
- goto fail;
- }
-
- /* bulk out */
- error = usbd_open_pipe(sc->sc_iface, 0x01, USBD_EXCLUSIVE_USE,
- &sc->sc_ep[ZYD_ENDPT_BOUT]);
- if (error != 0) {
- device_printf(sc->sc_dev, "open tx pipe failed: %s\n",
- usbd_errstr(error));
- goto fail;
- }
-
- return (0);
-
-fail: zyd_close_pipes(sc);
- return (ENXIO);
-}
-
-static void
-zyd_close_pipes(struct zyd_softc *sc)
-{
- int i;
-
- for (i = 0; i < ZYD_ENDPT_CNT; i++) {
- if (sc->sc_ep[i] != NULL) {
- usbd_abort_pipe(sc->sc_ep[i]);
- usbd_close_pipe(sc->sc_ep[i]);
- sc->sc_ep[i] = NULL;
- }
- }
- if (sc->sc_ibuf != NULL) {
- free(sc->sc_ibuf, M_USBDEV);
- sc->sc_ibuf = NULL;
- }
-}
-
-static int
-zyd_alloc_tx_list(struct zyd_softc *sc)
-{
- int i, error;
-
- sc->sc_txqueued = 0;
-
- for (i = 0; i < ZYD_TX_LIST_CNT; i++) {
- struct zyd_tx_data *data = &sc->sc_txdata[i];
-
- data->sc = sc; /* backpointer for callbacks */
-
- data->xfer = usbd_alloc_xfer(sc->sc_udev);
- if (data->xfer == NULL) {
- device_printf(sc->sc_dev,
- "could not allocate tx xfer\n");
- error = ENOMEM;
- goto fail;
- }
- data->buf = usbd_alloc_buffer(data->xfer, ZYD_MAX_TXBUFSZ);
- if (data->buf == NULL) {
- device_printf(sc->sc_dev,
- "could not allocate tx buffer\n");
- error = ENOMEM;
- goto fail;
- }
-
- /* clear Tx descriptor */
- bzero(data->buf, sizeof(struct zyd_tx_desc));
- }
- return (0);
-
-fail: zyd_free_tx_list(sc);
- return (error);
-}
-
-static void
-zyd_free_tx_list(struct zyd_softc *sc)
-{
- int i;
-
- for (i = 0; i < ZYD_TX_LIST_CNT; i++) {
- struct zyd_tx_data *data = &sc->sc_txdata[i];
-
- if (data->xfer != NULL) {
- usbd_free_xfer(data->xfer);
- data->xfer = NULL;
- }
- if (data->ni != NULL) {
- ieee80211_free_node(data->ni);
- data->ni = NULL;
- }
- }
-}
-
-static int
-zyd_alloc_rx_list(struct zyd_softc *sc)
-{
- int i, error;
-
- for (i = 0; i < ZYD_RX_LIST_CNT; i++) {
- struct zyd_rx_data *data = &sc->sc_rxdata[i];
-
- data->sc = sc; /* backpointer for callbacks */
-
- data->xfer = usbd_alloc_xfer(sc->sc_udev);
- if (data->xfer == NULL) {
- device_printf(sc->sc_dev,
- "could not allocate rx xfer\n");
- error = ENOMEM;
- goto fail;
- }
- data->buf = usbd_alloc_buffer(data->xfer, ZYX_MAX_RXBUFSZ);
- if (data->buf == NULL) {
- device_printf(sc->sc_dev,
- "could not allocate rx buffer\n");
- error = ENOMEM;
- goto fail;
- }
- }
- return (0);
-
-fail: zyd_free_rx_list(sc);
- return (error);
-}
-
-static void
-zyd_free_rx_list(struct zyd_softc *sc)
-{
- int i;
-
- for (i = 0; i < ZYD_RX_LIST_CNT; i++) {
- struct zyd_rx_data *data = &sc->sc_rxdata[i];
-
- if (data->xfer != NULL) {
- usbd_free_xfer(data->xfer);
- data->xfer = NULL;
- }
- }
-}
-
-/* ARGUSED */
-static struct ieee80211_node *
-zyd_node_alloc(struct ieee80211vap *vap __unused,
- const uint8_t mac[IEEE80211_ADDR_LEN] __unused)
-{
- struct zyd_node *zn;
-
- zn = malloc(sizeof(struct zyd_node), M_80211_NODE, M_NOWAIT | M_ZERO);
- return (zn != NULL) ? (&zn->ni) : (NULL);
-}
-
-static void
-zyd_task(void *arg)
-{
- int error;
- struct zyd_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
- struct ieee80211_node *ni = vap->iv_bss;
- struct zyd_vap *zvp = ZYD_VAP(vap);
-
- switch (sc->sc_state) {
- case IEEE80211_S_AUTH:
- zyd_set_chan(sc, ic->ic_curchan);
- break;
- case IEEE80211_S_RUN:
- if (vap->iv_opmode == IEEE80211_M_MONITOR)
- break;
-
- /* turn link LED on */
- error = zyd_set_led(sc, ZYD_LED1, 1);
- if (error != 0)
- goto fail;
-
- /* make data LED blink upon Tx */
- zyd_write32_m(sc, sc->sc_fwbase + ZYD_FW_LINK_STATUS, 1);
-
- IEEE80211_ADDR_COPY(sc->sc_bssid, ni->ni_bssid);
- zyd_set_bssid(sc, sc->sc_bssid);
- break;
- default:
- break;
- }
-
-fail:
- IEEE80211_LOCK(ic);
- zvp->newstate(vap, sc->sc_state, sc->sc_arg);
- if (vap->iv_newstate_cb != NULL)
- vap->iv_newstate_cb(vap, sc->sc_state, sc->sc_arg);
- IEEE80211_UNLOCK(ic);
-}
-
-static int
-zyd_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
-{
- struct zyd_vap *zvp = ZYD_VAP(vap);
- struct ieee80211com *ic = vap->iv_ic;
- struct zyd_softc *sc = ic->ic_ifp->if_softc;
-
- DPRINTF(sc, ZYD_DEBUG_STATE, "%s: %s -> %s\n", __func__,
- ieee80211_state_name[vap->iv_state],
- ieee80211_state_name[nstate]);
-
- usb_rem_task(sc->sc_udev, &sc->sc_scantask);
- usb_rem_task(sc->sc_udev, &sc->sc_task);
- callout_stop(&sc->sc_watchdog_ch);
-
- /* do it in a process context */
- sc->sc_state = nstate;
- sc->sc_arg = arg;
-
- if (nstate == IEEE80211_S_INIT) {
- zvp->newstate(vap, nstate, arg);
- return (0);
- } else {
- usb_add_task(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER);
- return (EINPROGRESS);
- }
-}
-
-static int
-zyd_cmd(struct zyd_softc *sc, uint16_t code, const void *idata, int ilen,
- void *odata, int olen, u_int flags)
-{
- usbd_xfer_handle xfer;
- struct zyd_cmd cmd;
- struct zyd_rq rq;
- uint16_t xferflags;
- usbd_status error;
-
- if (sc->sc_flags & ZYD_FLAG_DETACHING)
- return (ENXIO);
-
- if ((xfer = usbd_alloc_xfer(sc->sc_udev)) == NULL)
- return (ENOMEM);
-
- cmd.code = htole16(code);
- bcopy(idata, cmd.data, ilen);
-
- xferflags = USBD_FORCE_SHORT_XFER;
- if (!(flags & ZYD_CMD_FLAG_READ))
- xferflags |= USBD_SYNCHRONOUS;
- else {
- rq.idata = idata;
- rq.odata = odata;
- rq.len = olen / sizeof(struct zyd_pair);
- STAILQ_INSERT_TAIL(&sc->sc_rqh, &rq, rq);
- }
-
- usbd_setup_xfer(xfer, sc->sc_ep[ZYD_ENDPT_IOUT], 0, &cmd,
- sizeof(uint16_t) + ilen, xferflags, ZYD_INTR_TIMEOUT, NULL);
- error = usbd_transfer(xfer);
- if (error != USBD_IN_PROGRESS && error != 0) {
- device_printf(sc->sc_dev, "could not send command (error=%s)\n",
- usbd_errstr(error));
- (void)usbd_free_xfer(xfer);
- return (EIO);
- }
- if (!(flags & ZYD_CMD_FLAG_READ)) {
- (void)usbd_free_xfer(xfer);
- return (0); /* write: don't wait for reply */
- }
- /* wait at most one second for command reply */
- error = tsleep(odata, PCATCH, "zydcmd", hz);
- if (error == EWOULDBLOCK)
- device_printf(sc->sc_dev, "zyd_read sleep timeout\n");
- STAILQ_REMOVE(&sc->sc_rqh, &rq, zyd_rq, rq);
-
- (void)usbd_free_xfer(xfer);
- return (error);
-}
-
-static int
-zyd_read16(struct zyd_softc *sc, uint16_t reg, uint16_t *val)
-{
- struct zyd_pair tmp;
- int error;
-
- reg = htole16(reg);
- error = zyd_cmd(sc, ZYD_CMD_IORD, &reg, sizeof(reg), &tmp, sizeof(tmp),
- ZYD_CMD_FLAG_READ);
- if (error == 0)
- *val = le16toh(tmp.val);
- return (error);
-}
-
-static int
-zyd_read32(struct zyd_softc *sc, uint16_t reg, uint32_t *val)
-{
- struct zyd_pair tmp[2];
- uint16_t regs[2];
- int error;
-
- regs[0] = htole16(ZYD_REG32_HI(reg));
- regs[1] = htole16(ZYD_REG32_LO(reg));
- error = zyd_cmd(sc, ZYD_CMD_IORD, regs, sizeof(regs), tmp, sizeof(tmp),
- ZYD_CMD_FLAG_READ);
- if (error == 0)
- *val = le16toh(tmp[0].val) << 16 | le16toh(tmp[1].val);
- return (error);
-}
-
-static int
-zyd_write16(struct zyd_softc *sc, uint16_t reg, uint16_t val)
-{
- struct zyd_pair pair;
-
- pair.reg = htole16(reg);
- pair.val = htole16(val);
-
- return zyd_cmd(sc, ZYD_CMD_IOWR, &pair, sizeof(pair), NULL, 0, 0);
-}
-
-static int
-zyd_write32(struct zyd_softc *sc, uint16_t reg, uint32_t val)
-{
- struct zyd_pair pair[2];
-
- pair[0].reg = htole16(ZYD_REG32_HI(reg));
- pair[0].val = htole16(val >> 16);
- pair[1].reg = htole16(ZYD_REG32_LO(reg));
- pair[1].val = htole16(val & 0xffff);
-
- return zyd_cmd(sc, ZYD_CMD_IOWR, pair, sizeof(pair), NULL, 0, 0);
-}
-
-static int
-zyd_rfwrite(struct zyd_softc *sc, uint32_t val)
-{
- struct zyd_rf *rf = &sc->sc_rf;
- struct zyd_rfwrite_cmd req;
- uint16_t cr203;
- int error, i;
-
- zyd_read16_m(sc, ZYD_CR203, &cr203);
- cr203 &= ~(ZYD_RF_IF_LE | ZYD_RF_CLK | ZYD_RF_DATA);
-
- req.code = htole16(2);
- req.width = htole16(rf->width);
- for (i = 0; i < rf->width; i++) {
- req.bit[i] = htole16(cr203);
- if (val & (1 << (rf->width - 1 - i)))
- req.bit[i] |= htole16(ZYD_RF_DATA);
- }
- error = zyd_cmd(sc, ZYD_CMD_RFCFG, &req, 4 + 2 * rf->width, NULL, 0, 0);
-fail:
- return (error);
-}
-
-static int
-zyd_rfwrite_cr(struct zyd_softc *sc, uint32_t val)
-{
- int error;
-
- zyd_write16_m(sc, ZYD_CR244, (val >> 16) & 0xff);
- zyd_write16_m(sc, ZYD_CR243, (val >> 8) & 0xff);
- zyd_write16_m(sc, ZYD_CR242, (val >> 0) & 0xff);
-fail:
- return (error);
-}
-
-static int
-zyd_lock_phy(struct zyd_softc *sc)
-{
- int error;
- uint32_t tmp;
-
- zyd_read32_m(sc, ZYD_MAC_MISC, &tmp);
- tmp &= ~ZYD_UNLOCK_PHY_REGS;
- zyd_write32_m(sc, ZYD_MAC_MISC, tmp);
-fail:
- return (error);
-}
-
-static int
-zyd_unlock_phy(struct zyd_softc *sc)
-{
- int error;
- uint32_t tmp;
-
- zyd_read32_m(sc, ZYD_MAC_MISC, &tmp);
- tmp |= ZYD_UNLOCK_PHY_REGS;
- zyd_write32_m(sc, ZYD_MAC_MISC, tmp);
-fail:
- return (error);
-}
-
-/*
- * RFMD RF methods.
- */
-static int
-zyd_rfmd_init(struct zyd_rf *rf)
-{
-#define N(a) (sizeof(a) / sizeof((a)[0]))
- struct zyd_softc *sc = rf->rf_sc;
- static const struct zyd_phy_pair phyini[] = ZYD_RFMD_PHY;
- static const uint32_t rfini[] = ZYD_RFMD_RF;
- int i, error;
-
- /* init RF-dependent PHY registers */
- for (i = 0; i < N(phyini); i++) {
- zyd_write16_m(sc, phyini[i].reg, phyini[i].val);
- }
-
- /* init RFMD radio */
- for (i = 0; i < N(rfini); i++) {
- if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
- return (error);
- }
-fail:
- return (error);
-#undef N
-}
-
-static int
-zyd_rfmd_switch_radio(struct zyd_rf *rf, int on)
-{
- int error;
- struct zyd_softc *sc = rf->rf_sc;
-
- zyd_write16_m(sc, ZYD_CR10, on ? 0x89 : 0x15);
- zyd_write16_m(sc, ZYD_CR11, on ? 0x00 : 0x81);
-fail:
- return (error);
-}
-
-static int
-zyd_rfmd_set_channel(struct zyd_rf *rf, uint8_t chan)
-{
- int error;
- struct zyd_softc *sc = rf->rf_sc;
- static const struct {
- uint32_t r1, r2;
- } rfprog[] = ZYD_RFMD_CHANTABLE;
-
- error = zyd_rfwrite(sc, rfprog[chan - 1].r1);
- if (error != 0)
- goto fail;
- error = zyd_rfwrite(sc, rfprog[chan - 1].r2);
- if (error != 0)
- goto fail;
-
-fail:
- return (error);
-}
-
-/*
- * AL2230 RF methods.
- */
-static int
-zyd_al2230_init(struct zyd_rf *rf)
-{
-#define N(a) (sizeof(a) / sizeof((a)[0]))
- struct zyd_softc *sc = rf->rf_sc;
- static const struct zyd_phy_pair phyini[] = ZYD_AL2230_PHY;
- static const struct zyd_phy_pair phy2230s[] = ZYD_AL2230S_PHY_INIT;
- static const struct zyd_phy_pair phypll[] = {
- { ZYD_CR251, 0x2f }, { ZYD_CR251, 0x3f },
- { ZYD_CR138, 0x28 }, { ZYD_CR203, 0x06 }
- };
- static const uint32_t rfini1[] = ZYD_AL2230_RF_PART1;
- static const uint32_t rfini2[] = ZYD_AL2230_RF_PART2;
- static const uint32_t rfini3[] = ZYD_AL2230_RF_PART3;
- int i, error;
-
- /* init RF-dependent PHY registers */
- for (i = 0; i < N(phyini); i++)
- zyd_write16_m(sc, phyini[i].reg, phyini[i].val);
-
- if (sc->sc_rfrev == ZYD_RF_AL2230S || sc->sc_al2230s != 0) {
- for (i = 0; i < N(phy2230s); i++)
- zyd_write16_m(sc, phy2230s[i].reg, phy2230s[i].val);
- }
-
- /* init AL2230 radio */
- for (i = 0; i < N(rfini1); i++) {
- error = zyd_rfwrite(sc, rfini1[i]);
- if (error != 0)
- goto fail;
- }
-
- if (sc->sc_rfrev == ZYD_RF_AL2230S || sc->sc_al2230s != 0)
- error = zyd_rfwrite(sc, 0x000824);
- else
- error = zyd_rfwrite(sc, 0x0005a4);
- if (error != 0)
- goto fail;
-
- for (i = 0; i < N(rfini2); i++) {
- error = zyd_rfwrite(sc, rfini2[i]);
- if (error != 0)
- goto fail;
- }
-
- for (i = 0; i < N(phypll); i++)
- zyd_write16_m(sc, phypll[i].reg, phypll[i].val);
-
- for (i = 0; i < N(rfini3); i++) {
- error = zyd_rfwrite(sc, rfini3[i]);
- if (error != 0)
- goto fail;
- }
-fail:
- return (error);
-#undef N
-}
-
-static int
-zyd_al2230_fini(struct zyd_rf *rf)
-{
-#define N(a) (sizeof(a) / sizeof((a)[0]))
- int error, i;
- struct zyd_softc *sc = rf->rf_sc;
- static const struct zyd_phy_pair phy[] = ZYD_AL2230_PHY_FINI_PART1;
-
- for (i = 0; i < N(phy); i++)
- zyd_write16_m(sc, phy[i].reg, phy[i].val);
-
- if (sc->sc_newphy != 0)
- zyd_write16_m(sc, ZYD_CR9, 0xe1);
-
- zyd_write16_m(sc, ZYD_CR203, 0x6);
-fail:
- return (error);
-#undef N
-}
-
-static int
-zyd_al2230_init_b(struct zyd_rf *rf)
-{
-#define N(a) (sizeof(a) / sizeof((a)[0]))
- struct zyd_softc *sc = rf->rf_sc;
- static const struct zyd_phy_pair phy1[] = ZYD_AL2230_PHY_PART1;
- static const struct zyd_phy_pair phy2[] = ZYD_AL2230_PHY_PART2;
- static const struct zyd_phy_pair phy3[] = ZYD_AL2230_PHY_PART3;
- static const struct zyd_phy_pair phy2230s[] = ZYD_AL2230S_PHY_INIT;
- static const struct zyd_phy_pair phyini[] = ZYD_AL2230_PHY_B;
- static const uint32_t rfini_part1[] = ZYD_AL2230_RF_B_PART1;
- static const uint32_t rfini_part2[] = ZYD_AL2230_RF_B_PART2;
- static const uint32_t rfini_part3[] = ZYD_AL2230_RF_B_PART3;
- static const uint32_t zyd_al2230_chtable[][3] = ZYD_AL2230_CHANTABLE;
- int i, error;
-
- for (i = 0; i < N(phy1); i++)
- zyd_write16_m(sc, phy1[i].reg, phy1[i].val);
-
- /* init RF-dependent PHY registers */
- for (i = 0; i < N(phyini); i++)
- zyd_write16_m(sc, phyini[i].reg, phyini[i].val);
-
- if (sc->sc_rfrev == ZYD_RF_AL2230S || sc->sc_al2230s != 0) {
- for (i = 0; i < N(phy2230s); i++)
- zyd_write16_m(sc, phy2230s[i].reg, phy2230s[i].val);
- }
-
- for (i = 0; i < 3; i++) {
- error = zyd_rfwrite_cr(sc, zyd_al2230_chtable[0][i]);
- if (error != 0)
- return (error);
- }
-
- for (i = 0; i < N(rfini_part1); i++) {
- error = zyd_rfwrite_cr(sc, rfini_part1[i]);
- if (error != 0)
- return (error);
- }
-
- if (sc->sc_rfrev == ZYD_RF_AL2230S || sc->sc_al2230s != 0)
- error = zyd_rfwrite(sc, 0x241000);
- else
- error = zyd_rfwrite(sc, 0x25a000);
- if (error != 0)
- goto fail;
-
- for (i = 0; i < N(rfini_part2); i++) {
- error = zyd_rfwrite_cr(sc, rfini_part2[i]);
- if (error != 0)
- return (error);
- }
-
- for (i = 0; i < N(phy2); i++)
- zyd_write16_m(sc, phy2[i].reg, phy2[i].val);
-
- for (i = 0; i < N(rfini_part3); i++) {
- error = zyd_rfwrite_cr(sc, rfini_part3[i]);
- if (error != 0)
- return (error);
- }
-
- for (i = 0; i < N(phy3); i++)
- zyd_write16_m(sc, phy3[i].reg, phy3[i].val);
-
- error = zyd_al2230_fini(rf);
-fail:
- return (error);
-#undef N
-}
-
-static int
-zyd_al2230_switch_radio(struct zyd_rf *rf, int on)
-{
- struct zyd_softc *sc = rf->rf_sc;
- int error, on251 = (sc->sc_macrev == ZYD_ZD1211) ? 0x3f : 0x7f;
-
- zyd_write16_m(sc, ZYD_CR11, on ? 0x00 : 0x04);
- zyd_write16_m(sc, ZYD_CR251, on ? on251 : 0x2f);
-fail:
- return (error);
-}
-
-static int
-zyd_al2230_set_channel(struct zyd_rf *rf, uint8_t chan)
-{
-#define N(a) (sizeof(a) / sizeof((a)[0]))
- int error, i;
- struct zyd_softc *sc = rf->rf_sc;
- static const struct zyd_phy_pair phy1[] = {
- { ZYD_CR138, 0x28 }, { ZYD_CR203, 0x06 },
- };
- static const struct {
- uint32_t r1, r2, r3;
- } rfprog[] = ZYD_AL2230_CHANTABLE;
-
- error = zyd_rfwrite(sc, rfprog[chan - 1].r1);
- if (error != 0)
- goto fail;
- error = zyd_rfwrite(sc, rfprog[chan - 1].r2);
- if (error != 0)
- goto fail;
- error = zyd_rfwrite(sc, rfprog[chan - 1].r3);
- if (error != 0)
- goto fail;
-
- for (i = 0; i < N(phy1); i++)
- zyd_write16_m(sc, phy1[i].reg, phy1[i].val);
-fail:
- return (error);
-#undef N
-}
-
-static int
-zyd_al2230_set_channel_b(struct zyd_rf *rf, uint8_t chan)
-{
-#define N(a) (sizeof(a) / sizeof((a)[0]))
- int error, i;
- struct zyd_softc *sc = rf->rf_sc;
- static const struct zyd_phy_pair phy1[] = ZYD_AL2230_PHY_PART1;
- static const struct {
- uint32_t r1, r2, r3;
- } rfprog[] = ZYD_AL2230_CHANTABLE_B;
-
- for (i = 0; i < N(phy1); i++)
- zyd_write16_m(sc, phy1[i].reg, phy1[i].val);
-
- error = zyd_rfwrite_cr(sc, rfprog[chan - 1].r1);
- if (error != 0)
- goto fail;
- error = zyd_rfwrite_cr(sc, rfprog[chan - 1].r2);
- if (error != 0)
- goto fail;
- error = zyd_rfwrite_cr(sc, rfprog[chan - 1].r3);
- if (error != 0)
- goto fail;
- error = zyd_al2230_fini(rf);
-fail:
- return (error);
-#undef N
-}
-
-#define ZYD_AL2230_PHY_BANDEDGE6 \
-{ \
- { ZYD_CR128, 0x14 }, { ZYD_CR129, 0x12 }, { ZYD_CR130, 0x10 }, \
- { ZYD_CR47, 0x1e } \
-}
-
-static int
-zyd_al2230_bandedge6(struct zyd_rf *rf, struct ieee80211_channel *c)
-{
-#define N(a) (sizeof(a) / sizeof((a)[0]))
- int error = 0, i;
- struct zyd_softc *sc = rf->rf_sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct zyd_phy_pair r[] = ZYD_AL2230_PHY_BANDEDGE6;
- u_int chan = ieee80211_chan2ieee(ic, c);
-
- if (chan == 1 || chan == 11)
- r[0].val = 0x12;
-
- for (i = 0; i < N(r); i++)
- zyd_write16_m(sc, r[i].reg, r[i].val);
-fail:
- return (error);
-#undef N
-}
-
-/*
- * AL7230B RF methods.
- */
-static int
-zyd_al7230B_init(struct zyd_rf *rf)
-{
-#define N(a) (sizeof(a) / sizeof((a)[0]))
- struct zyd_softc *sc = rf->rf_sc;
- static const struct zyd_phy_pair phyini_1[] = ZYD_AL7230B_PHY_1;
- static const struct zyd_phy_pair phyini_2[] = ZYD_AL7230B_PHY_2;
- static const struct zyd_phy_pair phyini_3[] = ZYD_AL7230B_PHY_3;
- static const uint32_t rfini_1[] = ZYD_AL7230B_RF_1;
- static const uint32_t rfini_2[] = ZYD_AL7230B_RF_2;
- int i, error;
-
- /* for AL7230B, PHY and RF need to be initialized in "phases" */
-
- /* init RF-dependent PHY registers, part one */
- for (i = 0; i < N(phyini_1); i++)
- zyd_write16_m(sc, phyini_1[i].reg, phyini_1[i].val);
-
- /* init AL7230B radio, part one */
- for (i = 0; i < N(rfini_1); i++) {
- if ((error = zyd_rfwrite(sc, rfini_1[i])) != 0)
- return (error);
- }
- /* init RF-dependent PHY registers, part two */
- for (i = 0; i < N(phyini_2); i++)
- zyd_write16_m(sc, phyini_2[i].reg, phyini_2[i].val);
-
- /* init AL7230B radio, part two */
- for (i = 0; i < N(rfini_2); i++) {
- if ((error = zyd_rfwrite(sc, rfini_2[i])) != 0)
- return (error);
- }
- /* init RF-dependent PHY registers, part three */
- for (i = 0; i < N(phyini_3); i++)
- zyd_write16_m(sc, phyini_3[i].reg, phyini_3[i].val);
-fail:
- return (error);
-#undef N
-}
-
-static int
-zyd_al7230B_switch_radio(struct zyd_rf *rf, int on)
-{
- int error;
- struct zyd_softc *sc = rf->rf_sc;
-
- zyd_write16_m(sc, ZYD_CR11, on ? 0x00 : 0x04);
- zyd_write16_m(sc, ZYD_CR251, on ? 0x3f : 0x2f);
-fail:
- return (error);
-}
-
-static int
-zyd_al7230B_set_channel(struct zyd_rf *rf, uint8_t chan)
-{
-#define N(a) (sizeof(a) / sizeof((a)[0]))
- struct zyd_softc *sc = rf->rf_sc;
- static const struct {
- uint32_t r1, r2;
- } rfprog[] = ZYD_AL7230B_CHANTABLE;
- static const uint32_t rfsc[] = ZYD_AL7230B_RF_SETCHANNEL;
- int i, error;
-
- zyd_write16_m(sc, ZYD_CR240, 0x57);
- zyd_write16_m(sc, ZYD_CR251, 0x2f);
-
- for (i = 0; i < N(rfsc); i++) {
- if ((error = zyd_rfwrite(sc, rfsc[i])) != 0)
- return (error);
- }
-
- zyd_write16_m(sc, ZYD_CR128, 0x14);
- zyd_write16_m(sc, ZYD_CR129, 0x12);
- zyd_write16_m(sc, ZYD_CR130, 0x10);
- zyd_write16_m(sc, ZYD_CR38, 0x38);
- zyd_write16_m(sc, ZYD_CR136, 0xdf);
-
- error = zyd_rfwrite(sc, rfprog[chan - 1].r1);
- if (error != 0)
- goto fail;
- error = zyd_rfwrite(sc, rfprog[chan - 1].r2);
- if (error != 0)
- goto fail;
- error = zyd_rfwrite(sc, 0x3c9000);
- if (error != 0)
- goto fail;
-
- zyd_write16_m(sc, ZYD_CR251, 0x3f);
- zyd_write16_m(sc, ZYD_CR203, 0x06);
- zyd_write16_m(sc, ZYD_CR240, 0x08);
-fail:
- return (error);
-#undef N
-}
-
-/*
- * AL2210 RF methods.
- */
-static int
-zyd_al2210_init(struct zyd_rf *rf)
-{
-#define N(a) (sizeof(a) / sizeof((a)[0]))
- struct zyd_softc *sc = rf->rf_sc;
- static const struct zyd_phy_pair phyini[] = ZYD_AL2210_PHY;
- static const uint32_t rfini[] = ZYD_AL2210_RF;
- uint32_t tmp;
- int i, error;
-
- zyd_write32_m(sc, ZYD_CR18, 2);
-
- /* init RF-dependent PHY registers */
- for (i = 0; i < N(phyini); i++)
- zyd_write16_m(sc, phyini[i].reg, phyini[i].val);
-
- /* init AL2210 radio */
- for (i = 0; i < N(rfini); i++) {
- if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
- return (error);
- }
- zyd_write16_m(sc, ZYD_CR47, 0x1e);
- zyd_read32_m(sc, ZYD_CR_RADIO_PD, &tmp);
- zyd_write32_m(sc, ZYD_CR_RADIO_PD, tmp & ~1);
- zyd_write32_m(sc, ZYD_CR_RADIO_PD, tmp | 1);
- zyd_write32_m(sc, ZYD_CR_RFCFG, 0x05);
- zyd_write32_m(sc, ZYD_CR_RFCFG, 0x00);
- zyd_write16_m(sc, ZYD_CR47, 0x1e);
- zyd_write32_m(sc, ZYD_CR18, 3);
-fail:
- return (error);
-#undef N
-}
-
-static int
-zyd_al2210_switch_radio(struct zyd_rf *rf, int on)
-{
- /* vendor driver does nothing for this RF chip */
-
- return (0);
-}
-
-static int
-zyd_al2210_set_channel(struct zyd_rf *rf, uint8_t chan)
-{
- int error;
- struct zyd_softc *sc = rf->rf_sc;
- static const uint32_t rfprog[] = ZYD_AL2210_CHANTABLE;
- uint32_t tmp;
-
- zyd_write32_m(sc, ZYD_CR18, 2);
- zyd_write16_m(sc, ZYD_CR47, 0x1e);
- zyd_read32_m(sc, ZYD_CR_RADIO_PD, &tmp);
- zyd_write32_m(sc, ZYD_CR_RADIO_PD, tmp & ~1);
- zyd_write32_m(sc, ZYD_CR_RADIO_PD, tmp | 1);
- zyd_write32_m(sc, ZYD_CR_RFCFG, 0x05);
- zyd_write32_m(sc, ZYD_CR_RFCFG, 0x00);
- zyd_write16_m(sc, ZYD_CR47, 0x1e);
-
- /* actually set the channel */
- error = zyd_rfwrite(sc, rfprog[chan - 1]);
- if (error != 0)
- goto fail;
-
- zyd_write32_m(sc, ZYD_CR18, 3);
-fail:
- return (error);
-}
-
-/*
- * GCT RF methods.
- */
-static int
-zyd_gct_init(struct zyd_rf *rf)
-{
-#define N(a) (sizeof(a) / sizeof((a)[0]))
- struct zyd_softc *sc = rf->rf_sc;
- static const struct zyd_phy_pair phyini[] = ZYD_GCT_PHY;
- static const uint32_t rfini[] = ZYD_GCT_RF;
- int i, error;
-
- /* init RF-dependent PHY registers */
- for (i = 0; i < N(phyini); i++)
- zyd_write16_m(sc, phyini[i].reg, phyini[i].val);
-
- /* init cgt radio */
- for (i = 0; i < N(rfini); i++) {
- if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
- return (error);
- }
-fail:
- return (error);
-#undef N
-}
-
-static int
-zyd_gct_switch_radio(struct zyd_rf *rf, int on)
-{
- /* vendor driver does nothing for this RF chip */
-
- return (0);
-}
-
-static int
-zyd_gct_set_channel(struct zyd_rf *rf, uint8_t chan)
-{
- int error;
- struct zyd_softc *sc = rf->rf_sc;
- static const uint32_t rfprog[] = ZYD_GCT_CHANTABLE;
-
- error = zyd_rfwrite(sc, 0x1c0000);
- if (error != 0)
- goto fail;
- error = zyd_rfwrite(sc, rfprog[chan - 1]);
- if (error != 0)
- goto fail;
- error = zyd_rfwrite(sc, 0x1c0008);
-fail:
- return (error);
-}
-
-/*
- * Maxim RF methods.
- */
-static int
-zyd_maxim_init(struct zyd_rf *rf)
-{
-#define N(a) (sizeof(a) / sizeof((a)[0]))
- struct zyd_softc *sc = rf->rf_sc;
- static const struct zyd_phy_pair phyini[] = ZYD_MAXIM_PHY;
- static const uint32_t rfini[] = ZYD_MAXIM_RF;
- uint16_t tmp;
- int i, error;
-
- /* init RF-dependent PHY registers */
- for (i = 0; i < N(phyini); i++)
- zyd_write16_m(sc, phyini[i].reg, phyini[i].val);
-
- zyd_read16_m(sc, ZYD_CR203, &tmp);
- zyd_write16_m(sc, ZYD_CR203, tmp & ~(1 << 4));
-
- /* init maxim radio */
- for (i = 0; i < N(rfini); i++) {
- if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
- return (error);
- }
- zyd_read16_m(sc, ZYD_CR203, &tmp);
- zyd_write16_m(sc, ZYD_CR203, tmp | (1 << 4));
-fail:
- return (error);
-#undef N
-}
-
-static int
-zyd_maxim_switch_radio(struct zyd_rf *rf, int on)
-{
-
- /* vendor driver does nothing for this RF chip */
- return (0);
-}
-
-static int
-zyd_maxim_set_channel(struct zyd_rf *rf, uint8_t chan)
-{
-#define N(a) (sizeof(a) / sizeof((a)[0]))
- struct zyd_softc *sc = rf->rf_sc;
- static const struct zyd_phy_pair phyini[] = ZYD_MAXIM_PHY;
- static const uint32_t rfini[] = ZYD_MAXIM_RF;
- static const struct {
- uint32_t r1, r2;
- } rfprog[] = ZYD_MAXIM_CHANTABLE;
- uint16_t tmp;
- int i, error;
-
- /*
- * Do the same as we do when initializing it, except for the channel
- * values coming from the two channel tables.
- */
-
- /* init RF-dependent PHY registers */
- for (i = 0; i < N(phyini); i++)
- zyd_write16_m(sc, phyini[i].reg, phyini[i].val);
-
- zyd_read16_m(sc, ZYD_CR203, &tmp);
- zyd_write16_m(sc, ZYD_CR203, tmp & ~(1 << 4));
-
- /* first two values taken from the chantables */
- error = zyd_rfwrite(sc, rfprog[chan - 1].r1);
- if (error != 0)
- goto fail;
- error = zyd_rfwrite(sc, rfprog[chan - 1].r2);
- if (error != 0)
- goto fail;
-
- /* init maxim radio - skipping the two first values */
- for (i = 2; i < N(rfini); i++) {
- if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
- return (error);
- }
- zyd_read16_m(sc, ZYD_CR203, &tmp);
- zyd_write16_m(sc, ZYD_CR203, tmp | (1 << 4));
-fail:
- return (error);
-#undef N
-}
-
-/*
- * Maxim2 RF methods.
- */
-static int
-zyd_maxim2_init(struct zyd_rf *rf)
-{
-#define N(a) (sizeof(a) / sizeof((a)[0]))
- struct zyd_softc *sc = rf->rf_sc;
- static const struct zyd_phy_pair phyini[] = ZYD_MAXIM2_PHY;
- static const uint32_t rfini[] = ZYD_MAXIM2_RF;
- uint16_t tmp;
- int i, error;
-
- /* init RF-dependent PHY registers */
- for (i = 0; i < N(phyini); i++)
- zyd_write16_m(sc, phyini[i].reg, phyini[i].val);
-
- zyd_read16_m(sc, ZYD_CR203, &tmp);
- zyd_write16_m(sc, ZYD_CR203, tmp & ~(1 << 4));
-
- /* init maxim2 radio */
- for (i = 0; i < N(rfini); i++) {
- if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
- return (error);
- }
- zyd_read16_m(sc, ZYD_CR203, &tmp);
- zyd_write16_m(sc, ZYD_CR203, tmp | (1 << 4));
-fail:
- return (error);
-#undef N
-}
-
-static int
-zyd_maxim2_switch_radio(struct zyd_rf *rf, int on)
-{
-
- /* vendor driver does nothing for this RF chip */
- return (0);
-}
-
-static int
-zyd_maxim2_set_channel(struct zyd_rf *rf, uint8_t chan)
-{
-#define N(a) (sizeof(a) / sizeof((a)[0]))
- struct zyd_softc *sc = rf->rf_sc;
- static const struct zyd_phy_pair phyini[] = ZYD_MAXIM2_PHY;
- static const uint32_t rfini[] = ZYD_MAXIM2_RF;
- static const struct {
- uint32_t r1, r2;
- } rfprog[] = ZYD_MAXIM2_CHANTABLE;
- uint16_t tmp;
- int i, error;
-
- /*
- * Do the same as we do when initializing it, except for the channel
- * values coming from the two channel tables.
- */
-
- /* init RF-dependent PHY registers */
- for (i = 0; i < N(phyini); i++)
- zyd_write16_m(sc, phyini[i].reg, phyini[i].val);
-
- zyd_read16_m(sc, ZYD_CR203, &tmp);
- zyd_write16_m(sc, ZYD_CR203, tmp & ~(1 << 4));
-
- /* first two values taken from the chantables */
- error = zyd_rfwrite(sc, rfprog[chan - 1].r1);
- if (error != 0)
- goto fail;
- error = zyd_rfwrite(sc, rfprog[chan - 1].r2);
- if (error != 0)
- goto fail;
-
- /* init maxim2 radio - skipping the two first values */
- for (i = 2; i < N(rfini); i++) {
- if ((error = zyd_rfwrite(sc, rfini[i])) != 0)
- return (error);
- }
- zyd_read16_m(sc, ZYD_CR203, &tmp);
- zyd_write16_m(sc, ZYD_CR203, tmp | (1 << 4));
-fail:
- return (error);
-#undef N
-}
-
-static int
-zyd_rf_attach(struct zyd_softc *sc, uint8_t type)
-{
- struct zyd_rf *rf = &sc->sc_rf;
-
- rf->rf_sc = sc;
-
- switch (type) {
- case ZYD_RF_RFMD:
- rf->init = zyd_rfmd_init;
- rf->switch_radio = zyd_rfmd_switch_radio;
- rf->set_channel = zyd_rfmd_set_channel;
- rf->width = 24; /* 24-bit RF values */
- break;
- case ZYD_RF_AL2230:
- case ZYD_RF_AL2230S:
- if (sc->sc_macrev == ZYD_ZD1211B) {
- rf->init = zyd_al2230_init_b;
- rf->set_channel = zyd_al2230_set_channel_b;
- } else {
- rf->init = zyd_al2230_init;
- rf->set_channel = zyd_al2230_set_channel;
- }
- rf->switch_radio = zyd_al2230_switch_radio;
- rf->bandedge6 = zyd_al2230_bandedge6;
- rf->width = 24; /* 24-bit RF values */
- break;
- case ZYD_RF_AL7230B:
- rf->init = zyd_al7230B_init;
- rf->switch_radio = zyd_al7230B_switch_radio;
- rf->set_channel = zyd_al7230B_set_channel;
- rf->width = 24; /* 24-bit RF values */
- break;
- case ZYD_RF_AL2210:
- rf->init = zyd_al2210_init;
- rf->switch_radio = zyd_al2210_switch_radio;
- rf->set_channel = zyd_al2210_set_channel;
- rf->width = 24; /* 24-bit RF values */
- break;
- case ZYD_RF_GCT:
- rf->init = zyd_gct_init;
- rf->switch_radio = zyd_gct_switch_radio;
- rf->set_channel = zyd_gct_set_channel;
- rf->width = 21; /* 21-bit RF values */
- break;
- case ZYD_RF_MAXIM_NEW:
- rf->init = zyd_maxim_init;
- rf->switch_radio = zyd_maxim_switch_radio;
- rf->set_channel = zyd_maxim_set_channel;
- rf->width = 18; /* 18-bit RF values */
- break;
- case ZYD_RF_MAXIM_NEW2:
- rf->init = zyd_maxim2_init;
- rf->switch_radio = zyd_maxim2_switch_radio;
- rf->set_channel = zyd_maxim2_set_channel;
- rf->width = 18; /* 18-bit RF values */
- break;
- default:
- device_printf(sc->sc_dev,
- "sorry, radio \"%s\" is not supported yet\n",
- zyd_rf_name(type));
- return (EINVAL);
- }
- return (0);
-}
-
-static const char *
-zyd_rf_name(uint8_t type)
-{
- static const char * const zyd_rfs[] = {
- "unknown", "unknown", "UW2451", "UCHIP", "AL2230",
- "AL7230B", "THETA", "AL2210", "MAXIM_NEW", "GCT",
- "AL2230S", "RALINK", "INTERSIL", "RFMD", "MAXIM_NEW2",
- "PHILIPS"
- };
-
- return zyd_rfs[(type > 15) ? 0 : type];
-}
-
-static int
-zyd_hw_init(struct zyd_softc *sc)
-{
- int error;
- const struct zyd_phy_pair *phyp;
- struct zyd_rf *rf = &sc->sc_rf;
- uint16_t val;
-
- /* specify that the plug and play is finished */
- zyd_write32_m(sc, ZYD_MAC_AFTER_PNP, 1);
- zyd_read16_m(sc, ZYD_FIRMWARE_BASE_ADDR, &sc->sc_fwbase);
- DPRINTF(sc, ZYD_DEBUG_FW, "firmware base address=0x%04x\n",
- sc->sc_fwbase);
-
- /* retrieve firmware revision number */
- zyd_read16_m(sc, sc->sc_fwbase + ZYD_FW_FIRMWARE_REV, &sc->sc_fwrev);
- zyd_write32_m(sc, ZYD_CR_GPI_EN, 0);
- zyd_write32_m(sc, ZYD_MAC_CONT_WIN_LIMIT, 0x7f043f);
- /* set mandatory rates - XXX assumes 802.11b/g */
- zyd_write32_m(sc, ZYD_MAC_MAN_RATE, 0x150f);
-
- /* disable interrupts */
- zyd_write32_m(sc, ZYD_CR_INTERRUPT, 0);
-
- if ((error = zyd_read_pod(sc)) != 0) {
- device_printf(sc->sc_dev, "could not read EEPROM\n");
- goto fail;
- }
-
- /* PHY init (resetting) */
- error = zyd_lock_phy(sc);
- if (error != 0)
- goto fail;
- phyp = (sc->sc_macrev == ZYD_ZD1211B) ? zyd_def_phyB : zyd_def_phy;
- for (; phyp->reg != 0; phyp++)
- zyd_write16_m(sc, phyp->reg, phyp->val);
- if (sc->sc_macrev == ZYD_ZD1211 && sc->sc_fix_cr157 != 0) {
- zyd_read16_m(sc, ZYD_EEPROM_PHY_REG, &val);
- zyd_write32_m(sc, ZYD_CR157, val >> 8);
- }
- error = zyd_unlock_phy(sc);
- if (error != 0)
- goto fail;
-
- /* HMAC init */
- zyd_write32_m(sc, ZYD_MAC_ACK_EXT, 0x00000020);
- zyd_write32_m(sc, ZYD_CR_ADDA_MBIAS_WT, 0x30000808);
- zyd_write32_m(sc, ZYD_MAC_SNIFFER, 0x00000000);
- zyd_write32_m(sc, ZYD_MAC_RXFILTER, 0x00000000);
- zyd_write32_m(sc, ZYD_MAC_GHTBL, 0x00000000);
- zyd_write32_m(sc, ZYD_MAC_GHTBH, 0x80000000);
- zyd_write32_m(sc, ZYD_MAC_MISC, 0x000000a4);
- zyd_write32_m(sc, ZYD_CR_ADDA_PWR_DWN, 0x0000007f);
- zyd_write32_m(sc, ZYD_MAC_BCNCFG, 0x00f00401);
- zyd_write32_m(sc, ZYD_MAC_PHY_DELAY2, 0x00000000);
- zyd_write32_m(sc, ZYD_MAC_ACK_EXT, 0x00000080);
- zyd_write32_m(sc, ZYD_CR_ADDA_PWR_DWN, 0x00000000);
- zyd_write32_m(sc, ZYD_MAC_SIFS_ACK_TIME, 0x00000100);
- zyd_write32_m(sc, ZYD_CR_RX_PE_DELAY, 0x00000070);
- zyd_write32_m(sc, ZYD_CR_PS_CTRL, 0x10000000);
- zyd_write32_m(sc, ZYD_MAC_RTSCTSRATE, 0x02030203);
- zyd_write32_m(sc, ZYD_MAC_AFTER_PNP, 1);
- zyd_write32_m(sc, ZYD_MAC_BACKOFF_PROTECT, 0x00000114);
- zyd_write32_m(sc, ZYD_MAC_DIFS_EIFS_SIFS, 0x0a47c032);
- zyd_write32_m(sc, ZYD_MAC_CAM_MODE, 0x3);
-
- if (sc->sc_macrev == ZYD_ZD1211) {
- zyd_write32_m(sc, ZYD_MAC_RETRY, 0x00000002);
- zyd_write32_m(sc, ZYD_MAC_RX_THRESHOLD, 0x000c0640);
- } else {
- zyd_write32_m(sc, ZYD_MACB_MAX_RETRY, 0x02020202);
- zyd_write32_m(sc, ZYD_MACB_TXPWR_CTL4, 0x007f003f);
- zyd_write32_m(sc, ZYD_MACB_TXPWR_CTL3, 0x007f003f);
- zyd_write32_m(sc, ZYD_MACB_TXPWR_CTL2, 0x003f001f);
- zyd_write32_m(sc, ZYD_MACB_TXPWR_CTL1, 0x001f000f);
- zyd_write32_m(sc, ZYD_MACB_AIFS_CTL1, 0x00280028);
- zyd_write32_m(sc, ZYD_MACB_AIFS_CTL2, 0x008C003C);
- zyd_write32_m(sc, ZYD_MACB_TXOP, 0x01800824);
- zyd_write32_m(sc, ZYD_MAC_RX_THRESHOLD, 0x000c0eff);
- }
-
- /* init beacon interval to 100ms */
- if ((error = zyd_set_beacon_interval(sc, 100)) != 0)
- goto fail;
-
- if ((error = zyd_rf_attach(sc, sc->sc_rfrev)) != 0) {
- device_printf(sc->sc_dev, "could not attach RF, rev 0x%x\n",
- sc->sc_rfrev);
- goto fail;
- }
-
- /* RF chip init */
- error = zyd_lock_phy(sc);
- if (error != 0)
- goto fail;
- error = (*rf->init)(rf);
- if (error != 0) {
- device_printf(sc->sc_dev,
- "radio initialization failed, error %d\n", error);
- goto fail;
- }
- error = zyd_unlock_phy(sc);
- if (error != 0)
- goto fail;
-
- if ((error = zyd_read_eeprom(sc)) != 0) {
- device_printf(sc->sc_dev, "could not read EEPROM\n");
- goto fail;
- }
-
-fail: return (error);
-}
-
-static int
-zyd_read_pod(struct zyd_softc *sc)
-{
- int error;
- uint32_t tmp;
-
- zyd_read32_m(sc, ZYD_EEPROM_POD, &tmp);
- sc->sc_rfrev = tmp & 0x0f;
- sc->sc_ledtype = (tmp >> 4) & 0x01;
- sc->sc_al2230s = (tmp >> 7) & 0x01;
- sc->sc_cckgain = (tmp >> 8) & 0x01;
- sc->sc_fix_cr157 = (tmp >> 13) & 0x01;
- sc->sc_parev = (tmp >> 16) & 0x0f;
- sc->sc_bandedge6 = (tmp >> 21) & 0x01;
- sc->sc_newphy = (tmp >> 31) & 0x01;
- sc->sc_txled = ((tmp & (1 << 24)) && (tmp & (1 << 29))) ? 0 : 1;
-fail:
- return (error);
-}
-
-static int
-zyd_read_eeprom(struct zyd_softc *sc)
-{
- uint16_t val;
- int error, i;
-
- /* read Tx power calibration tables */
- for (i = 0; i < 7; i++) {
- zyd_read16_m(sc, ZYD_EEPROM_PWR_CAL + i, &val);
- sc->sc_pwrcal[i * 2] = val >> 8;
- sc->sc_pwrcal[i * 2 + 1] = val & 0xff;
- zyd_read16_m(sc, ZYD_EEPROM_PWR_INT + i, &val);
- sc->sc_pwrint[i * 2] = val >> 8;
- sc->sc_pwrint[i * 2 + 1] = val & 0xff;
- zyd_read16_m(sc, ZYD_EEPROM_36M_CAL + i, &val);
- sc->sc_ofdm36_cal[i * 2] = val >> 8;
- sc->sc_ofdm36_cal[i * 2 + 1] = val & 0xff;
- zyd_read16_m(sc, ZYD_EEPROM_48M_CAL + i, &val);
- sc->sc_ofdm48_cal[i * 2] = val >> 8;
- sc->sc_ofdm48_cal[i * 2 + 1] = val & 0xff;
- zyd_read16_m(sc, ZYD_EEPROM_54M_CAL + i, &val);
- sc->sc_ofdm54_cal[i * 2] = val >> 8;
- sc->sc_ofdm54_cal[i * 2 + 1] = val & 0xff;
- }
-fail:
- return (error);
-}
-
-static int
-zyd_get_macaddr(struct zyd_softc *sc)
-{
- usb_device_request_t req;
- usbd_status error;
-
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = ZYD_READFWDATAREQ;
- USETW(req.wValue, ZYD_EEPROM_MAC_ADDR_P1);
- USETW(req.wIndex, 0);
- USETW(req.wLength, IEEE80211_ADDR_LEN);
-
- error = usbd_do_request(sc->sc_udev, &req, sc->sc_bssid);
- if (error != 0) {
- device_printf(sc->sc_dev, "could not read EEPROM: %s\n",
- usbd_errstr(error));
- }
-
- return (error);
-}
-
-static int
-zyd_set_macaddr(struct zyd_softc *sc, const uint8_t *addr)
-{
- int error;
- uint32_t tmp;
-
- tmp = addr[3] << 24 | addr[2] << 16 | addr[1] << 8 | addr[0];
- zyd_write32_m(sc, ZYD_MAC_MACADRL, tmp);
- tmp = addr[5] << 8 | addr[4];
- zyd_write32_m(sc, ZYD_MAC_MACADRH, tmp);
-fail:
- return (error);
-}
-
-static int
-zyd_set_bssid(struct zyd_softc *sc, const uint8_t *addr)
-{
- int error;
- uint32_t tmp;
-
- tmp = addr[3] << 24 | addr[2] << 16 | addr[1] << 8 | addr[0];
- zyd_write32_m(sc, ZYD_MAC_BSSADRL, tmp);
- tmp = addr[5] << 8 | addr[4];
- zyd_write32_m(sc, ZYD_MAC_BSSADRH, tmp);
-fail:
- return (error);
-}
-
-static int
-zyd_switch_radio(struct zyd_softc *sc, int on)
-{
- struct zyd_rf *rf = &sc->sc_rf;
- int error;
-
- error = zyd_lock_phy(sc);
- if (error != 0)
- goto fail;
- error = (*rf->switch_radio)(rf, on);
- if (error != 0)
- goto fail;
- error = zyd_unlock_phy(sc);
-fail:
- return (error);
-}
-
-static int
-zyd_set_led(struct zyd_softc *sc, int which, int on)
-{
- int error;
- uint32_t tmp;
-
- zyd_read32_m(sc, ZYD_MAC_TX_PE_CONTROL, &tmp);
- tmp &= ~which;
- if (on)
- tmp |= which;
- zyd_write32_m(sc, ZYD_MAC_TX_PE_CONTROL, tmp);
-fail:
- return (error);
-}
-
-static void
-zyd_set_multi(void *arg)
-{
- int error;
- struct zyd_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ifmultiaddr *ifma;
- uint32_t low, high;
- uint8_t v;
-
- if (!(ifp->if_flags & IFF_UP))
- return;
-
- low = 0x00000000;
- high = 0x80000000;
-
- if (ic->ic_opmode == IEEE80211_M_MONITOR ||
- (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC))) {
- low = 0xffffffff;
- high = 0xffffffff;
- } else {
- IF_ADDR_LOCK(ifp);
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
- if (ifma->ifma_addr->sa_family != AF_LINK)
- continue;
- v = ((uint8_t *)LLADDR((struct sockaddr_dl *)
- ifma->ifma_addr))[5] >> 2;
- if (v < 32)
- low |= 1 << v;
- else
- high |= 1 << (v - 32);
- }
- IF_ADDR_UNLOCK(ifp);
- }
-
- /* reprogram multicast global hash table */
- zyd_write32_m(sc, ZYD_MAC_GHTBL, low);
- zyd_write32_m(sc, ZYD_MAC_GHTBH, high);
-fail:
- if (error != 0)
- device_printf(sc->sc_dev,
- "could not set multicast hash table\n");
-}
-
-static void
-zyd_update_mcast(struct ifnet *ifp)
-{
- struct zyd_softc *sc = ifp->if_softc;
-
- if (!(sc->sc_flags & ZYD_FLAG_INITDONE))
- return;
-
- usb_add_task(sc->sc_udev, &sc->sc_mcasttask, USB_TASKQ_DRIVER);
-}
-
-static int
-zyd_set_rxfilter(struct zyd_softc *sc)
-{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- uint32_t rxfilter;
-
- switch (ic->ic_opmode) {
- case IEEE80211_M_STA:
- rxfilter = ZYD_FILTER_BSS;
- break;
- case IEEE80211_M_IBSS:
- case IEEE80211_M_HOSTAP:
- rxfilter = ZYD_FILTER_HOSTAP;
- break;
- case IEEE80211_M_MONITOR:
- rxfilter = ZYD_FILTER_MONITOR;
- break;
- default:
- /* should not get there */
- return (EINVAL);
- }
- return zyd_write32(sc, ZYD_MAC_RXFILTER, rxfilter);
-}
-
-static void
-zyd_set_chan(struct zyd_softc *sc, struct ieee80211_channel *c)
-{
- int error;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct zyd_rf *rf = &sc->sc_rf;
- uint32_t tmp;
- u_int chan;
-
- chan = ieee80211_chan2ieee(ic, c);
- if (chan == 0 || chan == IEEE80211_CHAN_ANY) {
- /* XXX should NEVER happen */
- device_printf(sc->sc_dev,
- "%s: invalid channel %x\n", __func__, chan);
- return;
- }
-
- error = zyd_lock_phy(sc);
- if (error != 0)
- goto fail;
-
- error = (*rf->set_channel)(rf, chan);
- if (error != 0)
- goto fail;
-
- /* update Tx power */
- zyd_write16_m(sc, ZYD_CR31, sc->sc_pwrint[chan - 1]);
-
- if (sc->sc_macrev == ZYD_ZD1211B) {
- zyd_write16_m(sc, ZYD_CR67, sc->sc_ofdm36_cal[chan - 1]);
- zyd_write16_m(sc, ZYD_CR66, sc->sc_ofdm48_cal[chan - 1]);
- zyd_write16_m(sc, ZYD_CR65, sc->sc_ofdm54_cal[chan - 1]);
- zyd_write16_m(sc, ZYD_CR68, sc->sc_pwrcal[chan - 1]);
- zyd_write16_m(sc, ZYD_CR69, 0x28);
- zyd_write16_m(sc, ZYD_CR69, 0x2a);
- }
- if (sc->sc_cckgain) {
- /* set CCK baseband gain from EEPROM */
- if (zyd_read32(sc, ZYD_EEPROM_PHY_REG, &tmp) == 0)
- zyd_write16_m(sc, ZYD_CR47, tmp & 0xff);
- }
- if (sc->sc_bandedge6 && rf->bandedge6 != NULL) {
- error = (*rf->bandedge6)(rf, c);
- if (error != 0)
- goto fail;
- }
- zyd_write32_m(sc, ZYD_CR_CONFIG_PHILIPS, 0);
-
- error = zyd_unlock_phy(sc);
- if (error != 0)
- goto fail;
-
- sc->sc_rxtap.wr_chan_freq = sc->sc_txtap.wt_chan_freq =
- htole16(c->ic_freq);
- sc->sc_rxtap.wr_chan_flags = sc->sc_txtap.wt_chan_flags =
- htole16(c->ic_flags);
-fail:
- return;
-}
-
-static int
-zyd_set_beacon_interval(struct zyd_softc *sc, int bintval)
-{
- int error;
- uint32_t val;
-
- zyd_read32_m(sc, ZYD_CR_ATIM_WND_PERIOD, &val);
- sc->sc_atim_wnd = val;
- zyd_read32_m(sc, ZYD_CR_PRE_TBTT, &val);
- sc->sc_pre_tbtt = val;
- sc->sc_bcn_int = bintval;
-
- if (sc->sc_bcn_int <= 5)
- sc->sc_bcn_int = 5;
- if (sc->sc_pre_tbtt < 4 || sc->sc_pre_tbtt >= sc->sc_bcn_int)
- sc->sc_pre_tbtt = sc->sc_bcn_int - 1;
- if (sc->sc_atim_wnd >= sc->sc_pre_tbtt)
- sc->sc_atim_wnd = sc->sc_pre_tbtt - 1;
-
- zyd_write32_m(sc, ZYD_CR_ATIM_WND_PERIOD, sc->sc_atim_wnd);
- zyd_write32_m(sc, ZYD_CR_PRE_TBTT, sc->sc_pre_tbtt);
- zyd_write32_m(sc, ZYD_CR_BCN_INTERVAL, sc->sc_bcn_int);
-fail:
- return (error);
-}
-
-static void
-zyd_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- struct zyd_softc *sc = (struct zyd_softc *)priv;
- struct zyd_cmd *cmd;
- uint32_t datalen;
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
- return;
-
- if (status == USBD_STALLED) {
- usbd_clear_endpoint_stall_async(
- sc->sc_ep[ZYD_ENDPT_IIN]);
- }
- return;
- }
-
- cmd = (struct zyd_cmd *)sc->sc_ibuf;
-
- if (le16toh(cmd->code) == ZYD_NOTIF_RETRYSTATUS) {
- struct zyd_notif_retry *retry =
- (struct zyd_notif_retry *)cmd->data;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
- struct ieee80211_node *ni;
-
- DPRINTF(sc, ZYD_DEBUG_TX_PROC,
- "retry intr: rate=0x%x addr=%s count=%d (0x%x)\n",
- le16toh(retry->rate), ether_sprintf(retry->macaddr),
- le16toh(retry->count) & 0xff, le16toh(retry->count));
-
- /*
- * Find the node to which the packet was sent and update its
- * retry statistics. In BSS mode, this node is the AP we're
- * associated to so no lookup is actually needed.
- */
- ni = ieee80211_find_txnode(vap, retry->macaddr);
- if (ni != NULL) {
- ieee80211_amrr_tx_complete(&ZYD_NODE(ni)->amn,
- IEEE80211_AMRR_FAILURE, 1);
- ieee80211_free_node(ni);
- }
- if (le16toh(retry->count) & 0x100)
- ifp->if_oerrors++; /* too many retries */
- } else if (le16toh(cmd->code) == ZYD_NOTIF_IORD) {
- struct zyd_rq *rqp;
-
- if (le16toh(*(uint16_t *)cmd->data) == ZYD_CR_INTERRUPT)
- return; /* HMAC interrupt */
-
- usbd_get_xfer_status(xfer, NULL, NULL, &datalen, NULL);
- datalen -= sizeof(cmd->code);
- datalen -= 2; /* XXX: padding? */
-
- STAILQ_FOREACH(rqp, &sc->sc_rqh, rq) {
- int i;
-
- if (sizeof(struct zyd_pair) * rqp->len != datalen)
- continue;
- for (i = 0; i < rqp->len; i++) {
- if (*(((const uint16_t *)rqp->idata) + i) !=
- (((struct zyd_pair *)cmd->data) + i)->reg)
- break;
- }
- if (i != rqp->len)
- continue;
-
- /* copy answer into caller-supplied buffer */
- bcopy(cmd->data, rqp->odata,
- sizeof(struct zyd_pair) * rqp->len);
- wakeup(rqp->odata); /* wakeup caller */
-
- return;
- }
- return; /* unexpected IORD notification */
- } else {
- device_printf(sc->sc_dev, "unknown notification %x\n",
- le16toh(cmd->code));
- }
-}
-
-static void
-zyd_rx_data(struct zyd_softc *sc, const uint8_t *buf, uint16_t len)
-{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211_node *ni;
- const struct zyd_plcphdr *plcp;
- const struct zyd_rx_stat *stat;
- struct mbuf *m;
- int rlen, rssi, nf;
-
- if (len < ZYD_MIN_FRAGSZ) {
- DPRINTF(sc, ZYD_DEBUG_RECV, "%s: frame too short (length=%d)\n",
- device_get_nameunit(sc->sc_dev), len);
- ifp->if_ierrors++;
- return;
- }
-
- plcp = (const struct zyd_plcphdr *)buf;
- stat = (const struct zyd_rx_stat *)
- (buf + len - sizeof(struct zyd_rx_stat));
-
- if (stat->flags & ZYD_RX_ERROR) {
- DPRINTF(sc, ZYD_DEBUG_RECV,
- "%s: RX status indicated error (%x)\n",
- device_get_nameunit(sc->sc_dev), stat->flags);
- ifp->if_ierrors++;
- return;
- }
-
- /* compute actual frame length */
- rlen = len - sizeof(struct zyd_plcphdr) -
- sizeof(struct zyd_rx_stat) - IEEE80211_CRC_LEN;
-
- /* allocate a mbuf to store the frame */
- if (rlen > MHLEN)
- m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
- else
- m = m_gethdr(M_DONTWAIT, MT_DATA);
- if (m == NULL) {
- DPRINTF(sc, ZYD_DEBUG_RECV, "%s: could not allocate rx mbuf\n",
- device_get_nameunit(sc->sc_dev));
- ifp->if_ierrors++;
- return;
- }
- m->m_pkthdr.rcvif = ifp;
- m->m_pkthdr.len = m->m_len = rlen;
- bcopy((const uint8_t *)(plcp + 1), mtod(m, uint8_t *), rlen);
-
- if (bpf_peers_present(ifp->if_bpf)) {
- struct zyd_rx_radiotap_header *tap = &sc->sc_rxtap;
-
- tap->wr_flags = 0;
- if (stat->flags & (ZYD_RX_BADCRC16 | ZYD_RX_BADCRC32))
- tap->wr_flags |= IEEE80211_RADIOTAP_F_BADFCS;
- /* XXX toss, no way to express errors */
- if (stat->flags & ZYD_RX_DECRYPTERR)
- tap->wr_flags |= IEEE80211_RADIOTAP_F_BADFCS;
- tap->wr_rate = ieee80211_plcp2rate(plcp->signal,
- (stat->flags & ZYD_RX_OFDM) ?
- IEEE80211_T_OFDM : IEEE80211_T_CCK);
- tap->wr_antsignal = stat->rssi + -95;
- tap->wr_antnoise = -95; /* XXX */
-
- bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m);
- }
-
- rssi = stat->rssi > 63 ? 127 : 2 * stat->rssi;
- nf = -95; /* XXX */
-
- ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *));
- if (ni != NULL) {
- (void)ieee80211_input(ni, m, rssi, nf, 0);
- ieee80211_free_node(ni);
- } else
- (void)ieee80211_input_all(ic, m, rssi, nf, 0);
-}
-
-static void
-zyd_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- struct zyd_rx_data *data = priv;
- struct zyd_softc *sc = data->sc;
- struct ifnet *ifp = sc->sc_ifp;
- const struct zyd_rx_desc *desc;
- int len;
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
- return;
-
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall(sc->sc_ep[ZYD_ENDPT_BIN]);
-
- goto skip;
- }
- usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL);
-
- if (len < ZYD_MIN_RXBUFSZ) {
- DPRINTF(sc, ZYD_DEBUG_RECV, "%s: xfer too short (length=%d)\n",
- device_get_nameunit(sc->sc_dev), len);
- ifp->if_ierrors++; /* XXX not really errors */
- goto skip;
- }
-
- desc = (const struct zyd_rx_desc *)
- (data->buf + len - sizeof(struct zyd_rx_desc));
-
- if (UGETW(desc->tag) == ZYD_TAG_MULTIFRAME) {
- const uint8_t *p = data->buf, *end = p + len;
- int i;
-
- DPRINTF(sc, ZYD_DEBUG_RECV,
- "%s: received multi-frame transfer\n", __func__);
-
- for (i = 0; i < ZYD_MAX_RXFRAMECNT; i++) {
- const uint16_t len16 = UGETW(desc->len[i]);
-
- if (len16 == 0 || p + len16 > end)
- break;
-
- zyd_rx_data(sc, p, len16);
- /* next frame is aligned on a 32-bit boundary */
- p += (len16 + 3) & ~3;
- }
- } else {
- DPRINTF(sc, ZYD_DEBUG_RECV,
- "%s: received single-frame transfer\n", __func__);
-
- zyd_rx_data(sc, data->buf, len);
- }
-
-skip: /* setup a new transfer */
- usbd_setup_xfer(xfer, sc->sc_ep[ZYD_ENDPT_BIN], data, NULL,
- ZYX_MAX_RXBUFSZ, USBD_NO_COPY | USBD_SHORT_XFER_OK,
- USBD_NO_TIMEOUT, zyd_rxeof);
- (void)usbd_transfer(xfer);
-}
-
-static uint8_t
-zyd_plcp_signal(int rate)
-{
- switch (rate) {
- /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
- case 12:
- return (0xb);
- case 18:
- return (0xf);
- case 24:
- return (0xa);
- case 36:
- return (0xe);
- case 48:
- return (0x9);
- case 72:
- return (0xd);
- case 96:
- return (0x8);
- case 108:
- return (0xc);
- /* CCK rates (NB: not IEEE std, device-specific) */
- case 2:
- return (0x0);
- case 4:
- return (0x1);
- case 11:
- return (0x2);
- case 22:
- return (0x3);
- }
- return (0xff); /* XXX unsupported/unknown rate */
-}
-
-static int
-zyd_tx_mgt(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
-{
- struct ieee80211vap *vap = ni->ni_vap;
- struct ieee80211com *ic = ni->ni_ic;
- struct ifnet *ifp = sc->sc_ifp;
- struct zyd_tx_desc *desc;
- struct zyd_tx_data *data;
- struct ieee80211_frame *wh;
- struct ieee80211_key *k;
- int data_idx, rate, totlen, xferlen;
- uint16_t pktlen;
- usbd_status error;
-
- data_idx = sc->sc_txidx;
- sc->sc_txidx = (sc->sc_txidx + 1) % ZYD_TX_LIST_CNT;
-
- data = &sc->sc_txdata[data_idx];
- desc = (struct zyd_tx_desc *)data->buf;
-
- rate = IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? 12 : 2;
-
- wh = mtod(m0, struct ieee80211_frame *);
-
- if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
- k = ieee80211_crypto_encap(ni, m0);
- if (k == NULL) {
- m_freem(m0);
- return (ENOBUFS);
- }
- }
-
- data->ni = ni;
- data->m = m0;
-
- wh = mtod(m0, struct ieee80211_frame *);
-
- xferlen = sizeof(struct zyd_tx_desc) + m0->m_pkthdr.len;
- totlen = m0->m_pkthdr.len + IEEE80211_CRC_LEN;
-
- /* fill Tx descriptor */
- desc->len = htole16(totlen);
-
- desc->flags = ZYD_TX_FLAG_BACKOFF;
- if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
- /* multicast frames are not sent at OFDM rates in 802.11b/g */
- if (totlen > vap->iv_rtsthreshold) {
- desc->flags |= ZYD_TX_FLAG_RTS;
- } else if (ZYD_RATE_IS_OFDM(rate) &&
- (ic->ic_flags & IEEE80211_F_USEPROT)) {
- if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
- desc->flags |= ZYD_TX_FLAG_CTS_TO_SELF;
- else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
- desc->flags |= ZYD_TX_FLAG_RTS;
- }
- } else
- desc->flags |= ZYD_TX_FLAG_MULTICAST;
-
- if ((wh->i_fc[0] &
- (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
- (IEEE80211_FC0_TYPE_CTL | IEEE80211_FC0_SUBTYPE_PS_POLL))
- desc->flags |= ZYD_TX_FLAG_TYPE(ZYD_TX_TYPE_PS_POLL);
-
- desc->phy = zyd_plcp_signal(rate);
- if (ZYD_RATE_IS_OFDM(rate)) {
- desc->phy |= ZYD_TX_PHY_OFDM;
- if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
- desc->phy |= ZYD_TX_PHY_5GHZ;
- } else if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
- desc->phy |= ZYD_TX_PHY_SHPREAMBLE;
-
- /* actual transmit length (XXX why +10?) */
- pktlen = sizeof(struct zyd_tx_desc) + 10;
- if (sc->sc_macrev == ZYD_ZD1211)
- pktlen += totlen;
- desc->pktlen = htole16(pktlen);
-
- desc->plcp_length = (16 * totlen + rate - 1) / rate;
- desc->plcp_service = 0;
- if (rate == 22) {
- const int remainder = (16 * totlen) % 22;
- if (remainder != 0 && remainder < 7)
- desc->plcp_service |= ZYD_PLCP_LENGEXT;
- }
-
- if (bpf_peers_present(ifp->if_bpf)) {
- struct zyd_tx_radiotap_header *tap = &sc->sc_txtap;
-
- tap->wt_flags = 0;
- tap->wt_rate = rate;
-
- bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0);
- }
-
- m_copydata(m0, 0, m0->m_pkthdr.len,
- data->buf + sizeof(struct zyd_tx_desc));
-
- DPRINTF(sc, ZYD_DEBUG_XMIT,
- "%s: sending mgt frame len=%zu rate=%u xferlen=%u\n",
- device_get_nameunit(sc->sc_dev), (size_t)m0->m_pkthdr.len,
- rate, xferlen);
-
- usbd_setup_xfer(data->xfer, sc->sc_ep[ZYD_ENDPT_BOUT], data,
- data->buf, xferlen, USBD_FORCE_SHORT_XFER | USBD_NO_COPY,
- ZYD_TX_TIMEOUT, zyd_txeof);
- error = usbd_transfer(data->xfer);
- if (error != USBD_IN_PROGRESS && error != 0) {
- ifp->if_oerrors++;
- return (EIO);
- }
- sc->sc_txqueued++;
-
- return (0);
-}
-
-static void
-zyd_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- struct zyd_tx_data *data = priv;
- struct zyd_softc *sc = data->sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211_node *ni;
- struct mbuf *m;
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
- return;
-
- device_printf(sc->sc_dev, "could not transmit buffer: %s\n",
- usbd_errstr(status));
-
- if (status == USBD_STALLED) {
- usbd_clear_endpoint_stall_async(
- sc->sc_ep[ZYD_ENDPT_BOUT]);
- }
- ifp->if_oerrors++;
- return;
- }
-
- ni = data->ni;
- /* update rate control statistics */
- ieee80211_amrr_tx_complete(&ZYD_NODE(ni)->amn,
- IEEE80211_AMRR_SUCCESS, 0);
-
- /*
- * Do any tx complete callback. Note this must
- * be done before releasing the node reference.
- */
- m = data->m;
- if (m != NULL && m->m_flags & M_TXCB) {
- ieee80211_process_callback(ni, m, 0); /* XXX status? */
- m_freem(m);
- data->m = NULL;
- }
-
- ieee80211_free_node(ni);
- data->ni = NULL;
-
- ZYD_TX_LOCK(sc);
- sc->sc_txqueued--;
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- ZYD_TX_UNLOCK(sc);
-
- ifp->if_opackets++;
- sc->sc_txtimer = 0;
- zyd_start(ifp);
-}
-
-static int
-zyd_tx_data(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
-{
- struct ieee80211vap *vap = ni->ni_vap;
- struct ieee80211com *ic = ni->ni_ic;
- struct ifnet *ifp = sc->sc_ifp;
- struct zyd_tx_desc *desc;
- struct zyd_tx_data *data;
- struct ieee80211_frame *wh;
- const struct ieee80211_txparam *tp;
- struct ieee80211_key *k;
- int data_idx, rate, totlen, xferlen;
- uint16_t pktlen;
- usbd_status error;
-
- data_idx = sc->sc_txidx;
- sc->sc_txidx = (sc->sc_txidx + 1) % ZYD_TX_LIST_CNT;
-
- wh = mtod(m0, struct ieee80211_frame *);
- data = &sc->sc_txdata[data_idx];
- desc = (struct zyd_tx_desc *)data->buf;
-
- desc->flags = ZYD_TX_FLAG_BACKOFF;
- tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)];
- if (IEEE80211_IS_MULTICAST(wh->i_addr1)) {
- rate = tp->mcastrate;
- desc->flags |= ZYD_TX_FLAG_MULTICAST;
- } else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) {
- rate = tp->ucastrate;
- } else {
- (void) ieee80211_amrr_choose(ni, &ZYD_NODE(ni)->amn);
- rate = ni->ni_txrate;
- }
-
- if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
- k = ieee80211_crypto_encap(ni, m0);
- if (k == NULL) {
- m_freem(m0);
- return (ENOBUFS);
- }
- /* packet header may have moved, reset our local pointer */
- wh = mtod(m0, struct ieee80211_frame *);
- }
-
- data->ni = ni;
- data->m = NULL;
-
- xferlen = sizeof(struct zyd_tx_desc) + m0->m_pkthdr.len;
- totlen = m0->m_pkthdr.len + IEEE80211_CRC_LEN;
-
- /* fill Tx descriptor */
- desc->len = htole16(totlen);
-
- if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
- /* multicast frames are not sent at OFDM rates in 802.11b/g */
- if (totlen > vap->iv_rtsthreshold) {
- desc->flags |= ZYD_TX_FLAG_RTS;
- } else if (ZYD_RATE_IS_OFDM(rate) &&
- (ic->ic_flags & IEEE80211_F_USEPROT)) {
- if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
- desc->flags |= ZYD_TX_FLAG_CTS_TO_SELF;
- else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
- desc->flags |= ZYD_TX_FLAG_RTS;
- }
- }
-
- if ((wh->i_fc[0] &
- (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
- (IEEE80211_FC0_TYPE_CTL | IEEE80211_FC0_SUBTYPE_PS_POLL))
- desc->flags |= ZYD_TX_FLAG_TYPE(ZYD_TX_TYPE_PS_POLL);
-
- desc->phy = zyd_plcp_signal(rate);
- if (ZYD_RATE_IS_OFDM(rate)) {
- desc->phy |= ZYD_TX_PHY_OFDM;
- if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
- desc->phy |= ZYD_TX_PHY_5GHZ;
- } else if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
- desc->phy |= ZYD_TX_PHY_SHPREAMBLE;
-
- /* actual transmit length (XXX why +10?) */
- pktlen = sizeof(struct zyd_tx_desc) + 10;
- if (sc->sc_macrev == ZYD_ZD1211)
- pktlen += totlen;
- desc->pktlen = htole16(pktlen);
-
- desc->plcp_length = (16 * totlen + rate - 1) / rate;
- desc->plcp_service = 0;
- if (rate == 22) {
- const int remainder = (16 * totlen) % 22;
- if (remainder != 0 && remainder < 7)
- desc->plcp_service |= ZYD_PLCP_LENGEXT;
- }
-
- if (bpf_peers_present(ifp->if_bpf)) {
- struct zyd_tx_radiotap_header *tap = &sc->sc_txtap;
-
- tap->wt_flags = 0;
- tap->wt_rate = rate;
- tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
- tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
-
- bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0);
- }
-
- m_copydata(m0, 0, m0->m_pkthdr.len,
- data->buf + sizeof(struct zyd_tx_desc));
-
- DPRINTF(sc, ZYD_DEBUG_XMIT,
- "%s: sending data frame len=%zu rate=%u xferlen=%u\n",
- device_get_nameunit(sc->sc_dev), (size_t)m0->m_pkthdr.len,
- rate, xferlen);
-
- m_freem(m0); /* mbuf no longer needed */
-
- usbd_setup_xfer(data->xfer, sc->sc_ep[ZYD_ENDPT_BOUT], data,
- data->buf, xferlen, USBD_FORCE_SHORT_XFER | USBD_NO_COPY,
- ZYD_TX_TIMEOUT, zyd_txeof);
- error = usbd_transfer(data->xfer);
- if (error != USBD_IN_PROGRESS && error != 0) {
- ifp->if_oerrors++;
- return (EIO);
- }
- sc->sc_txqueued++;
-
- return (0);
-}
-
-static void
-zyd_start(struct ifnet *ifp)
-{
- struct zyd_softc *sc = ifp->if_softc;
- struct ieee80211_node *ni;
- struct mbuf *m;
-
- ZYD_TX_LOCK(sc);
- for (;;) {
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL)
- break;
- if (sc->sc_txqueued >= ZYD_TX_LIST_CNT) {
- IFQ_DRV_PREPEND(&ifp->if_snd, m);
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- break;
- }
- ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
- m = ieee80211_encap(ni, m);
- if (m == NULL) {
- ieee80211_free_node(ni);
- ifp->if_oerrors++;
- continue;
- }
- if (zyd_tx_data(sc, m, ni) != 0) {
- ieee80211_free_node(ni);
- ifp->if_oerrors++;
- break;
- }
-
- sc->sc_txtimer = 5;
- }
- ZYD_TX_UNLOCK(sc);
-}
-
-static int
-zyd_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
- const struct ieee80211_bpf_params *params)
-{
- struct ieee80211com *ic = ni->ni_ic;
- struct ifnet *ifp = ic->ic_ifp;
- struct zyd_softc *sc = ifp->if_softc;
-
- /* prevent management frames from being sent if we're not ready */
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
- m_freem(m);
- ieee80211_free_node(ni);
- return (ENETDOWN);
- }
- ZYD_TX_LOCK(sc);
- if (sc->sc_txqueued >= ZYD_TX_LIST_CNT) {
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- m_freem(m);
- ieee80211_free_node(ni);
- return (ENOBUFS); /* XXX */
- }
-
- /*
- * Legacy path; interpret frame contents to decide
- * precisely how to send the frame.
- * XXX raw path
- */
- if (zyd_tx_mgt(sc, m, ni) != 0) {
- ZYD_TX_UNLOCK(sc);
- ifp->if_oerrors++;
- ieee80211_free_node(ni);
- return (EIO);
- }
-
- ZYD_TX_UNLOCK(sc);
- ifp->if_opackets++;
- sc->sc_txtimer = 5;
- return (0);
-}
-
-static void
-zyd_watchdog(void *arg)
-{
- struct zyd_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
-
- if (sc->sc_txtimer > 0) {
- if (--sc->sc_txtimer == 0) {
- device_printf(sc->sc_dev, "device timeout\n");
- /* zyd_init(ifp); XXX needs a process context ? */
- ifp->if_oerrors++;
- return;
- }
- callout_reset(&sc->sc_watchdog_ch, hz, zyd_watchdog, sc);
- }
-}
-
-static int
-zyd_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
-{
- struct zyd_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ifreq *ifr = (struct ifreq *) data;
- int error = 0, startall = 0;
-
- switch (cmd) {
- case SIOCSIFFLAGS:
- ZYD_LOCK(sc);
- if (ifp->if_flags & IFF_UP) {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
- if ((ifp->if_flags ^ sc->sc_if_flags) &
- (IFF_ALLMULTI | IFF_PROMISC))
- zyd_set_multi(sc);
- } else {
- zyd_init_locked(sc);
- startall = 1;
- }
- } else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- zyd_stop(sc, 1);
- }
- sc->sc_if_flags = ifp->if_flags;
- ZYD_UNLOCK(sc);
- if (startall)
- ieee80211_start_all(ic);
- break;
- case SIOCGIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
- break;
- case SIOCGIFADDR:
- error = ether_ioctl(ifp, cmd, data);
- break;
- default:
- error = EINVAL;
- break;
- }
- return (error);
-}
-
-static void
-zyd_init_locked(struct zyd_softc *sc)
-{
- int error, i;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- uint32_t val;
-
- if (!(sc->sc_flags & ZYD_FLAG_INITONCE)) {
- error = zyd_loadfirmware(sc);
- if (error != 0) {
- device_printf(sc->sc_dev,
- "could not load firmware (error=%d)\n", error);
- goto fail;
- }
-
- error = usbd_set_config_no(sc->sc_udev, ZYD_CONFIG_NO, 1);
- if (error != 0) {
- device_printf(sc->sc_dev, "setting config no failed\n");
- goto fail;
- }
- error = usbd_device2interface_handle(sc->sc_udev,
- ZYD_IFACE_INDEX, &sc->sc_iface);
- if (error != 0) {
- device_printf(sc->sc_dev,
- "getting interface handle failed\n");
- goto fail;
- }
-
- if ((error = zyd_open_pipes(sc)) != 0) {
- device_printf(sc->sc_dev, "could not open pipes\n");
- goto fail;
- }
- if ((error = zyd_hw_init(sc)) != 0) {
- device_printf(sc->sc_dev,
- "hardware initialization failed\n");
- goto fail;
- }
-
- device_printf(sc->sc_dev,
- "HMAC ZD1211%s, FW %02x.%02x, RF %s S%x, PA%x LED %x "
- "BE%x NP%x Gain%x F%x\n",
- (sc->sc_macrev == ZYD_ZD1211) ? "": "B",
- sc->sc_fwrev >> 8, sc->sc_fwrev & 0xff,
- zyd_rf_name(sc->sc_rfrev), sc->sc_al2230s, sc->sc_parev,
- sc->sc_ledtype, sc->sc_bandedge6, sc->sc_newphy,
- sc->sc_cckgain, sc->sc_fix_cr157);
-
- /* read regulatory domain (currently unused) */
- zyd_read32_m(sc, ZYD_EEPROM_SUBID, &val);
- sc->sc_regdomain = val >> 16;
- DPRINTF(sc, ZYD_DEBUG_INIT, "regulatory domain %x\n",
- sc->sc_regdomain);
-
- /* we'll do software WEP decryption for now */
- DPRINTF(sc, ZYD_DEBUG_INIT, "%s: setting encryption type\n",
- __func__);
- zyd_write32_m(sc, ZYD_MAC_ENCRYPTION_TYPE, ZYD_ENC_SNIFFER);
-
- sc->sc_flags |= ZYD_FLAG_INITONCE;
- }
-
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- zyd_stop(sc, 0);
-
- /* reset softc variables. */
- sc->sc_txidx = 0;
-
- IEEE80211_ADDR_COPY(ic->ic_myaddr, IF_LLADDR(ifp));
- DPRINTF(sc, ZYD_DEBUG_INIT, "setting MAC address to %s\n",
- ether_sprintf(ic->ic_myaddr));
- error = zyd_set_macaddr(sc, ic->ic_myaddr);
- if (error != 0)
- return;
-
- /* set basic rates */
- if (ic->ic_curmode == IEEE80211_MODE_11B)
- zyd_write32_m(sc, ZYD_MAC_BAS_RATE, 0x0003);
- else if (ic->ic_curmode == IEEE80211_MODE_11A)
- zyd_write32_m(sc, ZYD_MAC_BAS_RATE, 0x1500);
- else /* assumes 802.11b/g */
- zyd_write32_m(sc, ZYD_MAC_BAS_RATE, 0xff0f);
-
- /* promiscuous mode */
- zyd_write32_m(sc, ZYD_MAC_SNIFFER, 0);
- /* multicast setup */
- zyd_set_multi(sc);
- /* set RX filter */
- error = zyd_set_rxfilter(sc);
- if (error != 0)
- goto fail;
-
- /* switch radio transmitter ON */
- error = zyd_switch_radio(sc, 1);
- if (error != 0)
- goto fail;
- /* set default BSS channel */
- zyd_set_chan(sc, ic->ic_curchan);
-
- /*
- * Allocate Tx and Rx xfer queues.
- */
- if ((error = zyd_alloc_tx_list(sc)) != 0) {
- device_printf(sc->sc_dev, "could not allocate Tx list\n");
- goto fail;
- }
- if ((error = zyd_alloc_rx_list(sc)) != 0) {
- device_printf(sc->sc_dev, "could not allocate Rx list\n");
- goto fail;
- }
-
- /*
- * Start up the receive pipe.
- */
- for (i = 0; i < ZYD_RX_LIST_CNT; i++) {
- struct zyd_rx_data *data = &sc->sc_rxdata[i];
-
- usbd_setup_xfer(data->xfer, sc->sc_ep[ZYD_ENDPT_BIN], data,
- NULL, ZYX_MAX_RXBUFSZ, USBD_NO_COPY | USBD_SHORT_XFER_OK,
- USBD_NO_TIMEOUT, zyd_rxeof);
- error = usbd_transfer(data->xfer);
- if (error != USBD_IN_PROGRESS && error != 0) {
- device_printf(sc->sc_dev,
- "could not queue Rx transfer\n");
- goto fail;
- }
- }
-
- /* enable interrupts */
- zyd_write32_m(sc, ZYD_CR_INTERRUPT, ZYD_HWINT_MASK);
-
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
- sc->sc_flags |= ZYD_FLAG_INITDONE;
-
- callout_reset(&sc->sc_watchdog_ch, hz, zyd_watchdog, sc);
- return;
-
-fail: zyd_stop(sc, 1);
- return;
-}
-
-static void
-zyd_init(void *priv)
-{
- struct zyd_softc *sc = priv;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
-
- ZYD_LOCK(sc);
- zyd_init_locked(sc);
- ZYD_UNLOCK(sc);
-
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- ieee80211_start_all(ic); /* start all vap's */
-}
-
-static void
-zyd_stop(struct zyd_softc *sc, int disable)
-{
- int error;
- struct ifnet *ifp = sc->sc_ifp;
-
- sc->sc_txtimer = 0;
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
-
- /* switch radio transmitter OFF */
- error = zyd_switch_radio(sc, 0);
- if (error != 0)
- goto fail;
- /* disable Rx */
- zyd_write32_m(sc, ZYD_MAC_RXFILTER, 0);
- /* disable interrupts */
- zyd_write32_m(sc, ZYD_CR_INTERRUPT, 0);
-
- usb_rem_task(sc->sc_udev, &sc->sc_scantask);
- usb_rem_task(sc->sc_udev, &sc->sc_task);
- callout_stop(&sc->sc_watchdog_ch);
-
- usbd_abort_pipe(sc->sc_ep[ZYD_ENDPT_BIN]);
- usbd_abort_pipe(sc->sc_ep[ZYD_ENDPT_BOUT]);
-
- zyd_free_rx_list(sc);
- zyd_free_tx_list(sc);
-fail:
- return;
-}
-
-static int
-zyd_loadfirmware(struct zyd_softc *sc)
-{
- usb_device_request_t req;
- size_t size;
- u_char *fw;
- uint8_t stat;
- uint16_t addr;
-
- if (sc->sc_flags & ZYD_FLAG_FWLOADED)
- return (0);
-
- if (sc->sc_macrev == ZYD_ZD1211) {
- fw = (u_char *)zd1211_firmware;
- size = sizeof(zd1211_firmware);
- } else {
- fw = (u_char *)zd1211b_firmware;
- size = sizeof(zd1211b_firmware);
- }
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = ZYD_DOWNLOADREQ;
- USETW(req.wIndex, 0);
-
- addr = ZYD_FIRMWARE_START_ADDR;
- while (size > 0) {
- /*
- * When the transfer size is 4096 bytes, it is not
- * likely to be able to transfer it.
- * The cause is port or machine or chip?
- */
- const int mlen = min(size, 64);
-
- DPRINTF(sc, ZYD_DEBUG_FW,
- "loading firmware block: len=%d, addr=0x%x\n", mlen, addr);
-
- USETW(req.wValue, addr);
- USETW(req.wLength, mlen);
- if (usbd_do_request(sc->sc_udev, &req, fw) != 0)
- return (EIO);
-
- addr += mlen / 2;
- fw += mlen;
- size -= mlen;
- }
-
- /* check whether the upload succeeded */
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = ZYD_DOWNLOADSTS;
- USETW(req.wValue, 0);
- USETW(req.wIndex, 0);
- USETW(req.wLength, sizeof(stat));
- if (usbd_do_request(sc->sc_udev, &req, &stat) != 0)
- return (EIO);
-
- sc->sc_flags |= ZYD_FLAG_FWLOADED;
-
- return (stat & 0x80) ? (EIO) : (0);
-}
-
-static void
-zyd_newassoc(struct ieee80211_node *ni, int isnew)
-{
- struct ieee80211vap *vap = ni->ni_vap;
-
- ieee80211_amrr_node_init(&ZYD_VAP(vap)->amrr, &ZYD_NODE(ni)->amn, ni);
-}
-
-static void
-zyd_scan_start(struct ieee80211com *ic)
-{
- struct zyd_softc *sc = ic->ic_ifp->if_softc;
-
- usb_rem_task(sc->sc_udev, &sc->sc_scantask);
-
- /* do it in a process context */
- sc->sc_scan_action = ZYD_SCAN_START;
- usb_add_task(sc->sc_udev, &sc->sc_scantask, USB_TASKQ_DRIVER);
-}
-
-static void
-zyd_scan_end(struct ieee80211com *ic)
-{
- struct zyd_softc *sc = ic->ic_ifp->if_softc;
-
- usb_rem_task(sc->sc_udev, &sc->sc_scantask);
-
- /* do it in a process context */
- sc->sc_scan_action = ZYD_SCAN_END;
- usb_add_task(sc->sc_udev, &sc->sc_scantask, USB_TASKQ_DRIVER);
-}
-
-static void
-zyd_set_channel(struct ieee80211com *ic)
-{
- struct zyd_softc *sc = ic->ic_ifp->if_softc;
-
- usb_rem_task(sc->sc_udev, &sc->sc_scantask);
- /* do it in a process context */
- sc->sc_scan_action = ZYD_SET_CHANNEL;
- usb_add_task(sc->sc_udev, &sc->sc_scantask, USB_TASKQ_DRIVER);
-}
-
-static void
-zyd_scantask(void *arg)
-{
- struct zyd_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
-
- ZYD_LOCK(sc);
-
- switch (sc->sc_scan_action) {
- case ZYD_SCAN_START:
- /* want broadcast address while scanning */
- zyd_set_bssid(sc, ifp->if_broadcastaddr);
- break;
- case ZYD_SCAN_END:
- /* restore previous bssid */
- zyd_set_bssid(sc, sc->sc_bssid);
- break;
- case ZYD_SET_CHANNEL:
- zyd_set_chan(sc, ic->ic_curchan);
- break;
- default:
- device_printf(sc->sc_dev, "unknown scan action %d\n",
- sc->sc_scan_action);
- break;
- }
-
- ZYD_UNLOCK(sc);
-}
-
-static void
-zyd_wakeup(struct zyd_softc *sc)
-{
- struct zyd_rq *rqp;
-
- STAILQ_FOREACH(rqp, &sc->sc_rqh, rq)
- wakeup(rqp->odata); /* wakeup sleeping caller */
-}
-
-static device_method_t zyd_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, zyd_match),
- DEVMETHOD(device_attach, zyd_attach),
- DEVMETHOD(device_detach, zyd_detach),
-
- { 0, 0 }
-};
-
-static driver_t zyd_driver = {
- "zyd",
- zyd_methods,
- sizeof(struct zyd_softc)
-};
-
-static devclass_t zyd_devclass;
-
-DRIVER_MODULE(zyd, uhub, zyd_driver, zyd_devclass, usbd_driver_load, 0);
-MODULE_DEPEND(zyd, wlan, 1, 1, 1);
-MODULE_DEPEND(zyd, wlan_amrr, 1, 1, 1);
-MODULE_DEPEND(zyd, usb, 1, 1, 1);
diff --git a/sys/dev/usb/if_zydfw.h b/sys/dev/usb/if_zydfw.h
deleted file mode 100644
index 46f5c2a..0000000
--- a/sys/dev/usb/if_zydfw.h
+++ /dev/null
@@ -1,1144 +0,0 @@
-/*
- * Copyright (C) 2001, 2002, 2003,2004 ZyDAS Technology Corporation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted provided
- * that the following conditions are met:
- * 1. Redistribution of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistribution 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. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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$ */
-
-uint8_t zd1211_firmware[] = {
- 0x08, 0x91, 0xFF, 0xED, 0x09, 0x93, 0x1E, 0xEE,
- 0xD1, 0x94, 0x11, 0xEE, 0x88, 0xD4, 0xD1, 0x96,
- 0xD1, 0x98, 0x5C, 0x99, 0x5C, 0x99, 0x4C, 0x99,
- 0x04, 0x9D, 0xD1, 0x98, 0xD1, 0x9A, 0x03, 0xEE,
- 0xF4, 0x94, 0xD3, 0xD4, 0x41, 0x2A, 0x40, 0x4A,
- 0x45, 0xBE, 0x88, 0x92, 0x41, 0x24, 0x40, 0x44,
- 0x53, 0xBE, 0x40, 0xF0, 0x93, 0xEE, 0x41, 0xEE,
- 0x98, 0x9A, 0xD4, 0xF7, 0x02, 0x00, 0x1F, 0xEC,
- 0x00, 0x00, 0xB2, 0xF8, 0x4D, 0x00, 0xA1, 0xEC,
- 0x00, 0x00, 0xA6, 0xF7, 0x21, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0xD8,
- 0xA0, 0x90, 0x98, 0x9A, 0x98, 0x9A, 0xA0, 0xD8,
- 0x40, 0xF0, 0xB4, 0xF0, 0xA0, 0x90, 0x98, 0x9A,
- 0xA0, 0xD8, 0x40, 0xF0, 0x64, 0xEF, 0xA0, 0x90,
- 0x98, 0x9A, 0xA0, 0xD8, 0x40, 0xF0, 0xF6, 0xF0,
- 0xA0, 0x90, 0x98, 0x9A, 0xA0, 0xD8, 0x40, 0xF0,
- 0xF7, 0xF6, 0xA0, 0x90, 0x98, 0x9A, 0xA0, 0xD8,
- 0x40, 0xF0, 0xF8, 0xF5, 0xA0, 0x90, 0x98, 0x9A,
- 0xA0, 0xD8, 0x40, 0xF0, 0xF1, 0xF0, 0xA0, 0x90,
- 0x98, 0x9A, 0x98, 0x9A, 0xA0, 0xD8, 0x40, 0xF0,
- 0x97, 0xF7, 0xA0, 0x90, 0x98, 0x9A, 0x88, 0xDA,
- 0x08, 0x0B, 0x01, 0x00, 0x0D, 0x03, 0x03, 0x00,
- 0x09, 0x05, 0x01, 0x00, 0xC2, 0x94, 0x42, 0x02,
- 0xC1, 0x92, 0x03, 0x96, 0x1B, 0xD7, 0x2A, 0x86,
- 0x1A, 0xD5, 0x2B, 0x86, 0x09, 0xA3, 0x00, 0x80,
- 0x19, 0xD3, 0x2C, 0x86, 0x00, 0xEE, 0x0A, 0x65,
- 0xC0, 0x7A, 0x02, 0x97, 0xC3, 0x92, 0x09, 0xB3,
- 0xFE, 0xFF, 0xC2, 0xD2, 0x88, 0x98, 0x90, 0x9A,
- 0x88, 0xDA, 0x42, 0x20, 0x08, 0x0B, 0x01, 0x00,
- 0x0D, 0x03, 0x05, 0x00, 0x05, 0x94, 0xC5, 0xD4,
- 0x09, 0x05, 0x01, 0x00, 0xC2, 0x94, 0x01, 0xD4,
- 0x42, 0x02, 0xC1, 0x96, 0x0A, 0x65, 0xC0, 0x7A,
- 0x02, 0x99, 0xC4, 0x92, 0x41, 0xA2, 0xC4, 0xD2,
- 0xC5, 0x98, 0x1C, 0xD9, 0x2A, 0x86, 0x01, 0x98,
- 0x1C, 0xD9, 0x2B, 0x86, 0x1B, 0xD7, 0x2C, 0x86,
- 0x00, 0xEE, 0x09, 0xB3, 0xFE, 0xFF, 0xC2, 0xD2,
- 0x42, 0x00, 0x88, 0x98, 0x90, 0x9A, 0x88, 0xDA,
- 0x41, 0x20, 0x08, 0x0B, 0x01, 0x00, 0x40, 0xF0,
- 0xE5, 0xEE, 0x11, 0x93, 0xD8, 0xF7, 0x41, 0x42,
- 0x02, 0x5E, 0x0F, 0x9F, 0xAE, 0xEE, 0x40, 0xF1,
- 0x40, 0x92, 0x19, 0xD3, 0xD8, 0xF7, 0xC5, 0x92,
- 0x41, 0x92, 0x19, 0xD3, 0x00, 0x83, 0x40, 0x92,
- 0x19, 0xD3, 0x00, 0x83, 0x0F, 0x9F, 0x95, 0xF8,
- 0x0F, 0x9F, 0x99, 0xEE, 0x42, 0x42, 0x02, 0x5E,
- 0x0F, 0x9F, 0x99, 0xEE, 0x40, 0x92, 0x19, 0xD3,
- 0xD8, 0xF7, 0x09, 0x93, 0xC7, 0xF7, 0x19, 0xD3,
- 0x91, 0xEC, 0x40, 0xF0, 0x5F, 0xF2, 0x09, 0x63,
- 0x00, 0x80, 0x19, 0xD3, 0xF2, 0xBD, 0x0F, 0x9F,
- 0x99, 0xEE, 0x41, 0x00, 0x88, 0x98, 0x90, 0x9A,
- 0x88, 0xDA, 0x08, 0x0B, 0x01, 0x00, 0x40, 0x92,
- 0x19, 0xD3, 0x12, 0x95, 0x19, 0xD3, 0x10, 0x95,
- 0x19, 0xD3, 0x02, 0x80, 0x19, 0xD3, 0x03, 0x82,
- 0x09, 0x93, 0xC7, 0xF7, 0x19, 0xD3, 0x91, 0xEC,
- 0x40, 0xF0, 0x5F, 0xF2, 0x40, 0xF0, 0xDE, 0xF3,
- 0x11, 0x93, 0x04, 0xEC, 0x42, 0x42, 0x02, 0x5E,
- 0x0F, 0x9F, 0xE3, 0xEE, 0x40, 0x92, 0x19, 0xD3,
- 0x04, 0xEC, 0x40, 0xF0, 0x38, 0xF2, 0x88, 0x98,
- 0x90, 0x9A, 0x88, 0xDA, 0x08, 0x0B, 0x01, 0x00,
- 0x11, 0x93, 0x44, 0x96, 0x09, 0xB3, 0xFF, 0xFD,
- 0x19, 0xD3, 0x44, 0x96, 0x40, 0xF0, 0x90, 0xF7,
- 0x6E, 0x92, 0x19, 0xD3, 0x05, 0x84, 0x40, 0xF0,
- 0xC4, 0xEE, 0x4B, 0x62, 0x0A, 0x95, 0x2E, 0xEE,
- 0xD1, 0xD4, 0x0B, 0x97, 0x2B, 0xEE, 0xD1, 0xD6,
- 0x0A, 0x95, 0x00, 0xEE, 0xD1, 0xD4, 0x0B, 0x97,
- 0x2F, 0xEE, 0xD1, 0xD6, 0x0A, 0x95, 0x34, 0xEE,
- 0xD1, 0xD4, 0x0B, 0x97, 0x39, 0xEE, 0xD1, 0xD6,
- 0x0A, 0x95, 0x3E, 0xEE, 0xD1, 0xD4, 0x0B, 0x97,
- 0x43, 0xEE, 0xD1, 0xD6, 0x0A, 0x95, 0x48, 0xEE,
- 0xD1, 0xD4, 0x0B, 0x97, 0x4D, 0xEE, 0xD1, 0xD6,
- 0x0A, 0x95, 0x4E, 0xEE, 0xC1, 0xD4, 0x0A, 0x65,
- 0x00, 0x44, 0x02, 0x97, 0xC3, 0x92, 0x44, 0xA2,
- 0xC2, 0xD2, 0x43, 0xF1, 0x09, 0x93, 0x01, 0x3F,
- 0x19, 0xD3, 0xC0, 0x85, 0x11, 0x93, 0x44, 0x96,
- 0x09, 0xB3, 0xFF, 0xFC, 0x19, 0xD3, 0x44, 0x96,
- 0x88, 0x98, 0x90, 0x9A, 0x88, 0xDA, 0x08, 0x0B,
- 0x01, 0x00, 0x0D, 0x03, 0x03, 0x00, 0x03, 0x96,
- 0x41, 0x02, 0x03, 0x99, 0xC4, 0x94, 0x42, 0x04,
- 0xC1, 0x04, 0xC2, 0x94, 0xC3, 0xD4, 0x88, 0x98,
- 0x90, 0x9A, 0x88, 0xDA, 0x08, 0x0B, 0x01, 0x00,
- 0x40, 0x92, 0x19, 0xD3, 0x94, 0xEC, 0x13, 0x97,
- 0x95, 0xEC, 0x1B, 0xD7, 0x02, 0x80, 0x11, 0x93,
- 0x99, 0xEC, 0x19, 0xD3, 0x7C, 0x96, 0x0B, 0x97,
- 0xA0, 0x00, 0x1B, 0xD7, 0x6E, 0xEC, 0x0A, 0x65,
- 0x0E, 0x42, 0x02, 0x97, 0xC3, 0x92, 0x09, 0xB3,
- 0xFF, 0xBF, 0x11, 0xA3, 0x9A, 0xEC, 0xC2, 0xD2,
- 0x0A, 0x65, 0xEB, 0x43, 0x02, 0x97, 0xC3, 0x92,
- 0x09, 0xA3, 0xC0, 0x00, 0xC2, 0xD2, 0x0A, 0x65,
- 0xE9, 0x43, 0x02, 0x97, 0xC3, 0x92, 0x09, 0xB3,
- 0xBF, 0xFF, 0xC2, 0xD2, 0x88, 0x98, 0x90, 0x9A,
- 0x88, 0xDA, 0x47, 0x20, 0x08, 0x0B, 0x01, 0x00,
- 0x14, 0x99, 0x03, 0x80, 0x0C, 0xB3, 0x00, 0x10,
- 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F, 0x97, 0xF0,
- 0x11, 0x93, 0x9F, 0xEC, 0x41, 0x02, 0x19, 0xD3,
- 0x9F, 0xEC, 0x11, 0x93, 0xD6, 0xF7, 0x40, 0x42,
- 0x02, 0x4E, 0x0F, 0x9F, 0x84, 0xEF, 0x0A, 0x65,
- 0xFE, 0x7F, 0x02, 0x97, 0xC3, 0x92, 0x09, 0xA3,
- 0x00, 0x04, 0xC2, 0xD2, 0x0F, 0x9F, 0xB1, 0xF0,
- 0x11, 0x93, 0x94, 0xEC, 0x02, 0xD2, 0x40, 0x42,
- 0x02, 0x5E, 0x0F, 0x9F, 0xD0, 0xEF, 0x41, 0x92,
- 0x19, 0xD3, 0x94, 0xEC, 0x19, 0xD3, 0x9F, 0xEC,
- 0x12, 0x95, 0x02, 0x80, 0x1A, 0xD5, 0x95, 0xEC,
- 0x13, 0x97, 0x7C, 0x96, 0x1B, 0xD7, 0x99, 0xEC,
- 0x0A, 0x65, 0x0E, 0x42, 0x02, 0x97, 0xC3, 0x92,
- 0x09, 0xB3, 0x00, 0x40, 0x19, 0xD3, 0x9A, 0xEC,
- 0x09, 0x63, 0x00, 0x40, 0xC2, 0xD2, 0x02, 0x94,
- 0x1A, 0xD5, 0x7C, 0x96, 0x0C, 0xB3, 0x00, 0x08,
- 0x40, 0x42, 0x02, 0x5E, 0x0F, 0x9F, 0xB0, 0xEF,
- 0x0C, 0xB3, 0xFF, 0x07, 0x0F, 0x9F, 0xB4, 0xEF,
- 0x11, 0x93, 0x06, 0x80, 0x09, 0xB3, 0xFF, 0x07,
- 0x09, 0x03, 0x00, 0xA0, 0x19, 0xD3, 0x97, 0xEC,
- 0x40, 0x98, 0x0B, 0x97, 0x9C, 0xEC, 0x04, 0x95,
- 0x03, 0x05, 0x14, 0x03, 0x97, 0xEC, 0x46, 0x02,
- 0xC1, 0x92, 0xC2, 0xD2, 0x41, 0x08, 0x42, 0x48,
- 0x02, 0x9E, 0x0F, 0x9F, 0xBB, 0xEF, 0x11, 0x93,
- 0x97, 0xEC, 0xC1, 0x92, 0xC5, 0xD2, 0x5F, 0xB2,
- 0x19, 0xD3, 0x9B, 0xEC, 0x0F, 0x9F, 0xD3, 0xEF,
- 0x13, 0x97, 0x98, 0xEC, 0xC5, 0xD6, 0x11, 0x93,
- 0x03, 0x80, 0x09, 0xB3, 0x00, 0x08, 0x40, 0x42,
- 0x02, 0x4E, 0x0F, 0x9F, 0xE9, 0xEF, 0x11, 0x93,
- 0xDC, 0xF7, 0x41, 0x02, 0x19, 0xD3, 0xDC, 0xF7,
- 0x11, 0x93, 0xDB, 0xF7, 0x09, 0xA3, 0x00, 0x10,
- 0x19, 0xD3, 0xDB, 0xF7, 0x40, 0x98, 0x1C, 0xD9,
- 0x9B, 0xEC, 0x12, 0x95, 0x9B, 0xEC, 0x40, 0x44,
- 0x02, 0x4E, 0x0F, 0x9F, 0x86, 0xF0, 0x0A, 0xB3,
- 0x08, 0x00, 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F,
- 0x07, 0xF0, 0x0A, 0xB3, 0x07, 0x00, 0x09, 0x05,
- 0xA9, 0xEC, 0xC2, 0x94, 0x01, 0xD4, 0x09, 0x03,
- 0xA1, 0xEC, 0xC1, 0x92, 0x19, 0xD3, 0x9B, 0xEC,
- 0xC5, 0x94, 0x0A, 0xB5, 0x00, 0xFF, 0x01, 0xA5,
- 0xC5, 0xD4, 0x0F, 0x9F, 0x13, 0xF0, 0x0A, 0x05,
- 0xFF, 0xFF, 0x0A, 0x03, 0xB1, 0xEC, 0xC1, 0x92,
- 0x01, 0xD2, 0x1A, 0xD5, 0x9B, 0xEC, 0xC5, 0x96,
- 0x0B, 0x07, 0xFF, 0xFF, 0xC5, 0xD6, 0x11, 0x93,
- 0x97, 0xEC, 0xC5, 0x98, 0xC1, 0xD8, 0x11, 0x93,
- 0x97, 0xEC, 0x09, 0x05, 0x0B, 0x00, 0x03, 0xD4,
- 0xC2, 0x96, 0x06, 0xD6, 0x7B, 0x95, 0x7A, 0x95,
- 0x4C, 0x02, 0xC1, 0x92, 0x59, 0x93, 0x59, 0x93,
- 0x01, 0xA5, 0x01, 0x98, 0x0C, 0xF5, 0x7B, 0x93,
- 0x09, 0x09, 0x01, 0x00, 0x06, 0x92, 0x09, 0xB3,
- 0xFF, 0x00, 0x04, 0xD2, 0x5C, 0x93, 0x59, 0x93,
- 0x04, 0x94, 0x01, 0xA5, 0x03, 0x96, 0xC3, 0xD4,
- 0x11, 0x93, 0x97, 0xEC, 0x4C, 0x02, 0x05, 0xD2,
- 0xC1, 0x92, 0x09, 0xB3, 0x00, 0xFF, 0x7C, 0x95,
- 0x7A, 0x95, 0x02, 0xA3, 0x05, 0x98, 0xC4, 0xD2,
- 0x12, 0x95, 0x97, 0xEC, 0x45, 0x04, 0x02, 0x97,
- 0xC3, 0x92, 0x09, 0xA3, 0x00, 0x01, 0xC2, 0xD2,
- 0x12, 0x95, 0x9B, 0xEC, 0x0A, 0xB3, 0x08, 0x00,
- 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F, 0x5B, 0xF0,
- 0x12, 0x95, 0x97, 0xEC, 0x4A, 0x04, 0x02, 0x99,
- 0xC4, 0x92, 0x01, 0x98, 0x0C, 0xF3, 0x7B, 0x93,
- 0x41, 0x02, 0x0F, 0x9F, 0x7C, 0xF0, 0x43, 0x44,
- 0x02, 0x8E, 0x0F, 0x9F, 0x7D, 0xF0, 0x11, 0x93,
- 0x97, 0xEC, 0x42, 0x02, 0x0A, 0x05, 0xFF, 0xFF,
- 0xC1, 0xD4, 0x11, 0x93, 0x97, 0xEC, 0x4A, 0x02,
- 0x12, 0x95, 0x60, 0x96, 0xC1, 0xD4, 0x12, 0x95,
- 0x97, 0xEC, 0x4B, 0x04, 0x02, 0x97, 0xC3, 0x92,
- 0x09, 0xB3, 0x1F, 0xFF, 0xC2, 0xD2, 0x12, 0x95,
- 0x97, 0xEC, 0x4B, 0x04, 0x11, 0x93, 0x62, 0x96,
- 0x41, 0x93, 0x59, 0x93, 0x02, 0x99, 0xC4, 0xA2,
- 0xC2, 0xD2, 0xC5, 0x92, 0x19, 0xD3, 0x98, 0xEC,
- 0x0A, 0x95, 0x0C, 0x02, 0x1A, 0xD5, 0x02, 0x80,
- 0x0F, 0x9F, 0xB1, 0xF0, 0x09, 0x63, 0xFE, 0x7F,
- 0x01, 0x97, 0xC3, 0x94, 0x0A, 0xA5, 0x00, 0x04,
- 0xC1, 0xD4, 0x11, 0x93, 0x9F, 0xEC, 0x09, 0xA3,
- 0x00, 0x01, 0x19, 0xD3, 0x9F, 0xEC, 0x40, 0xF0,
- 0x39, 0xEF, 0x0F, 0x9F, 0xB1, 0xF0, 0x11, 0x93,
- 0x94, 0xEC, 0x41, 0x42, 0x02, 0x5E, 0x0F, 0x9F,
- 0xA6, 0xF0, 0x40, 0xF0, 0x39, 0xEF, 0x11, 0x93,
- 0x95, 0xEC, 0x44, 0xB2, 0x40, 0x42, 0x02, 0x4E,
- 0x0F, 0x9F, 0xB1, 0xF0, 0x48, 0x98, 0x1C, 0xD9,
- 0x02, 0x80, 0x11, 0x93, 0x91, 0xEC, 0x41, 0x22,
- 0x0A, 0x95, 0xB1, 0xF0, 0x88, 0xD4, 0x88, 0xDC,
- 0x91, 0x9A, 0x47, 0x00, 0x88, 0x98, 0x90, 0x9A,
- 0x88, 0xDA, 0x08, 0x0B, 0x01, 0x00, 0x11, 0x93,
- 0x04, 0x82, 0x48, 0xB2, 0x40, 0x42, 0x02, 0x4E,
- 0x0F, 0x9F, 0xC8, 0xF0, 0x0A, 0x65, 0xFD, 0x7D,
- 0x02, 0x97, 0xC3, 0x92, 0x09, 0xB3, 0xFF, 0xFE,
- 0xC2, 0xD2, 0x41, 0x92, 0x19, 0xD3, 0xBF, 0xEC,
- 0x11, 0x93, 0x04, 0x82, 0x43, 0xB2, 0x12, 0x95,
- 0x03, 0x82, 0x02, 0xB3, 0x40, 0x42, 0x02, 0x4E,
- 0x0F, 0x9F, 0xEF, 0xF0, 0x0A, 0xB3, 0x00, 0xFF,
- 0x48, 0xA2, 0x19, 0xD3, 0x03, 0x82, 0x40, 0xF0,
- 0xEB, 0xF3, 0x11, 0x93, 0xBF, 0xEC, 0x41, 0x42,
- 0x02, 0x5E, 0x0F, 0x9F, 0xEF, 0xF0, 0x11, 0x93,
- 0x07, 0x82, 0x11, 0x43, 0x03, 0xEC, 0x02, 0x0E,
- 0x0F, 0x9F, 0xEF, 0xF0, 0x11, 0x93, 0x03, 0x82,
- 0x09, 0xA3, 0x00, 0x01, 0x19, 0xD3, 0x03, 0x82,
- 0x40, 0x96, 0x1B, 0xD7, 0xBF, 0xEC, 0x88, 0x98,
- 0x90, 0x9A, 0x88, 0xDA, 0x08, 0x0B, 0x01, 0x00,
- 0x88, 0x98, 0x90, 0x9A, 0x88, 0xDA, 0x08, 0x0B,
- 0x01, 0x00, 0x11, 0x93, 0x20, 0xBC, 0xC8, 0xD2,
- 0x40, 0xF0, 0x48, 0xF1, 0x41, 0x00, 0x88, 0x98,
- 0x90, 0x9A, 0x88, 0xDA, 0x42, 0x20, 0x08, 0x0B,
- 0x01, 0x00, 0x0D, 0x03, 0x05, 0x00, 0x05, 0x94,
- 0x41, 0x02, 0xC1, 0x92, 0x01, 0x97, 0xC3, 0x96,
- 0xC2, 0xD6, 0x0A, 0x45, 0x00, 0x95, 0x02, 0x5E,
- 0x0F, 0x9F, 0x45, 0xF1, 0xC1, 0x92, 0x41, 0xB2,
- 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F, 0x45, 0xF1,
- 0x11, 0x93, 0xC0, 0xEC, 0x40, 0x42, 0x02, 0x5E,
- 0x0F, 0x9F, 0x45, 0xF1, 0x41, 0x98, 0x1C, 0xD9,
- 0xC0, 0xEC, 0x12, 0x95, 0x02, 0x80, 0x01, 0xD4,
- 0x40, 0xF0, 0x56, 0xF2, 0x0B, 0x67, 0xFD, 0x7D,
- 0x03, 0x99, 0xC4, 0x92, 0x0C, 0x99, 0x96, 0x03,
- 0x1C, 0xD9, 0x06, 0x82, 0x41, 0x98, 0x1C, 0xD9,
- 0x02, 0x82, 0x42, 0x98, 0x1C, 0xD9, 0x05, 0x82,
- 0x0C, 0x69, 0x80, 0x7F, 0x1C, 0xD9, 0x00, 0xB0,
- 0x09, 0xA3, 0x00, 0x01, 0xC3, 0xD2, 0x01, 0x94,
- 0x0A, 0xB3, 0x04, 0x00, 0x40, 0x42, 0x02, 0x4E,
- 0x0F, 0x9F, 0x43, 0xF1, 0x42, 0xA4, 0x1A, 0xD5,
- 0x02, 0x80, 0x42, 0x00, 0x88, 0x98, 0x90, 0x9A,
- 0x88, 0xDA, 0x42, 0x20, 0x08, 0x0B, 0x01, 0x00,
- 0x05, 0x92, 0xC5, 0xD2, 0x60, 0xB2, 0x40, 0x42,
- 0x02, 0x4E, 0x0F, 0x9F, 0x55, 0xF1, 0x40, 0xF0,
- 0x35, 0xF7, 0xC5, 0x94, 0x0A, 0xB3, 0x10, 0x00,
- 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F, 0x5E, 0xF1,
- 0x40, 0xF0, 0x23, 0xF6, 0xC5, 0x96, 0x0B, 0xB3,
- 0x40, 0x00, 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F,
- 0x67, 0xF1, 0x40, 0xF0, 0x5D, 0xF5, 0xC5, 0x94,
- 0x0A, 0xB3, 0x01, 0x00, 0x40, 0x42, 0x02, 0x4E,
- 0x0F, 0x9F, 0xC8, 0xF1, 0x13, 0x97, 0x21, 0xBC,
- 0x01, 0xD6, 0x0B, 0xB3, 0x02, 0x00, 0x40, 0x42,
- 0x02, 0x4E, 0x0F, 0x9F, 0x79, 0xF1, 0x40, 0xF0,
- 0x62, 0xFB, 0x01, 0x94, 0x0A, 0xB3, 0x04, 0x00,
- 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F, 0x82, 0xF1,
- 0x40, 0xF0, 0x6C, 0xFB, 0x01, 0x96, 0x0B, 0xB3,
- 0x01, 0x00, 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F,
- 0xA2, 0xF1, 0x40, 0xF0, 0xB0, 0xFA, 0x41, 0x92,
- 0x19, 0xD3, 0xD5, 0xF7, 0x11, 0x93, 0x03, 0xEC,
- 0x09, 0x43, 0x40, 0x00, 0x02, 0x5E, 0x0F, 0x9F,
- 0x98, 0xF1, 0x40, 0x94, 0x1A, 0xD5, 0xD5, 0xF7,
- 0x11, 0x93, 0x00, 0xEC, 0x40, 0x42, 0x02, 0x4E,
- 0x0F, 0x9F, 0xAB, 0xF1, 0x40, 0xF0, 0x38, 0xF2,
- 0x0F, 0x9F, 0xAB, 0xF1, 0x01, 0x96, 0x0B, 0xB3,
- 0x08, 0x00, 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F,
- 0xAB, 0xF1, 0x40, 0xF0, 0x7C, 0xFB, 0x01, 0x94,
- 0x0A, 0xB3, 0x10, 0x00, 0x40, 0x42, 0x02, 0x4E,
- 0x0F, 0x9F, 0xB4, 0xF1, 0x40, 0xF0, 0x87, 0xFB,
- 0x11, 0x93, 0x10, 0xEC, 0x42, 0x42, 0x02, 0x5E,
- 0x0F, 0x9F, 0xBF, 0xF1, 0x44, 0x96, 0x1B, 0xD7,
- 0x0B, 0xBC, 0x0F, 0x9F, 0xC5, 0xF1, 0x41, 0x42,
- 0x02, 0x5E, 0x0F, 0x9F, 0xC5, 0xF1, 0x19, 0xD3,
- 0x0B, 0xBC, 0x40, 0x92, 0x19, 0xD3, 0x10, 0xEC,
- 0xC5, 0x94, 0x0A, 0xB3, 0x80, 0x00, 0x40, 0x42,
- 0x02, 0x4E, 0x0F, 0x9F, 0x12, 0xF2, 0x13, 0x97,
- 0x28, 0xBC, 0x01, 0xD6, 0x0B, 0xB3, 0x40, 0x00,
- 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F, 0xDA, 0xF1,
- 0x40, 0xF0, 0x18, 0xF7, 0x01, 0x94, 0x0A, 0xB3,
- 0x02, 0x00, 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F,
- 0xED, 0xF1, 0x40, 0xF0, 0xC4, 0xEE, 0x40, 0xF0,
- 0x8F, 0xFB, 0x40, 0xF0, 0x1B, 0xF2, 0x40, 0x96,
- 0x1B, 0xD7, 0x00, 0xEC, 0x41, 0x92, 0x19, 0xD3,
- 0xD8, 0xF7, 0x01, 0x94, 0x0A, 0xB3, 0x04, 0x00,
- 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F, 0x09, 0xF2,
- 0x40, 0xF0, 0x9E, 0xFB, 0x09, 0x63, 0x00, 0x44,
- 0x01, 0x97, 0xC3, 0x94, 0x48, 0xA4, 0xC1, 0xD4,
- 0x00, 0xEE, 0x40, 0x92, 0x19, 0xD3, 0x12, 0x95,
- 0x19, 0xD3, 0x10, 0x95, 0x19, 0xD3, 0x02, 0x80,
- 0x19, 0xD3, 0x03, 0x82, 0x41, 0x92, 0x19, 0xD3,
- 0xD8, 0xF7, 0x01, 0x94, 0x0A, 0xB3, 0x08, 0x00,
- 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F, 0x12, 0xF2,
- 0x40, 0xF0, 0xAE, 0xFB, 0x0A, 0x65, 0x00, 0x44,
- 0x02, 0x97, 0xC3, 0x92, 0x44, 0xA2, 0xC2, 0xD2,
- 0x42, 0x00, 0x88, 0x98, 0x90, 0x9A, 0x88, 0xDA,
- 0x08, 0x0B, 0x01, 0x00, 0x09, 0x63, 0x00, 0x40,
- 0x19, 0xD3, 0xF2, 0xBD, 0x0A, 0x65, 0xEA, 0x43,
- 0x02, 0x97, 0xC3, 0x92, 0x44, 0xA2, 0xC2, 0xD2,
- 0x0A, 0x65, 0xE9, 0x43, 0x02, 0x97, 0xC3, 0x92,
- 0x09, 0xA3, 0x40, 0x00, 0xC2, 0xD2, 0x0A, 0x65,
- 0xEB, 0x43, 0x02, 0x97, 0xC3, 0x92, 0x09, 0xA3,
- 0xC0, 0x00, 0xC2, 0xD2, 0x88, 0x98, 0x90, 0x9A,
- 0x88, 0xDA, 0x08, 0x0B, 0x01, 0x00, 0x09, 0x63,
- 0x00, 0x80, 0x19, 0xD3, 0xF2, 0xBD, 0x0A, 0x65,
- 0xE8, 0x43, 0x02, 0x97, 0xC3, 0x92, 0x09, 0xA3,
- 0xC0, 0x00, 0xC2, 0xD2, 0x0A, 0x65, 0xEB, 0x43,
- 0x02, 0x97, 0xC3, 0x92, 0x09, 0xB3, 0xBF, 0xFF,
- 0xC2, 0xD2, 0x0A, 0x65, 0xEA, 0x43, 0x02, 0x97,
- 0xC3, 0x92, 0x09, 0xB3, 0xFB, 0xFF, 0xC2, 0xD2,
- 0x88, 0x98, 0x90, 0x9A, 0x88, 0xDA, 0x08, 0x0B,
- 0x01, 0x00, 0x09, 0x93, 0x00, 0x01, 0x19, 0xD3,
- 0x02, 0x80, 0x88, 0x98, 0x90, 0x9A, 0x88, 0xDA,
- 0x08, 0x0B, 0x01, 0x00, 0x09, 0x93, 0x00, 0x09,
- 0x19, 0xD3, 0x02, 0x80, 0x40, 0xF0, 0x56, 0xF2,
- 0x40, 0x92, 0x19, 0xD3, 0x94, 0xEC, 0xC8, 0xD2,
- 0x09, 0x93, 0x91, 0xEC, 0xC8, 0xD2, 0x40, 0xF0,
- 0x2A, 0xEF, 0x42, 0x00, 0x88, 0x98, 0x90, 0x9A,
- 0x88, 0xDA, 0x08, 0x0B, 0x01, 0x00, 0x40, 0xF0,
- 0x3B, 0xF5, 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F,
- 0x85, 0xF2, 0x0A, 0x65, 0xFE, 0x7F, 0x02, 0x97,
- 0xC3, 0x92, 0x44, 0xA2, 0xC2, 0xD2, 0x0F, 0x9F,
- 0x92, 0xF2, 0x40, 0xF0, 0x94, 0xF2, 0x40, 0x42,
- 0x02, 0x5E, 0x0F, 0x9F, 0x92, 0xF2, 0xC8, 0xD2,
- 0x09, 0x93, 0x91, 0xEC, 0xC8, 0xD2, 0x40, 0xF0,
- 0x2A, 0xEF, 0x42, 0x00, 0x88, 0x98, 0x90, 0x9A,
- 0x88, 0xDA, 0x08, 0x0B, 0x01, 0x00, 0x11, 0x93,
- 0xF1, 0xBD, 0x19, 0xD3, 0xB6, 0xEC, 0x11, 0x93,
- 0xB4, 0xEC, 0x40, 0x42, 0x02, 0x5E, 0x0F, 0x9F,
- 0xAC, 0xF2, 0x09, 0x63, 0x00, 0x80, 0x01, 0x97,
- 0xC3, 0x94, 0x0A, 0x07, 0x07, 0x00, 0xC1, 0xD6,
- 0x0A, 0x05, 0x00, 0xA0, 0x1A, 0xD5, 0x96, 0xEC,
- 0x11, 0x93, 0xB6, 0xEC, 0x19, 0xD3, 0x01, 0x80,
- 0x0A, 0x65, 0xFE, 0x7F, 0x02, 0x97, 0xC3, 0x92,
- 0x41, 0xA2, 0xC2, 0xD2, 0x40, 0x92, 0x88, 0x98,
- 0x90, 0x9A, 0x88, 0xDA, 0x41, 0x20, 0x08, 0x0B,
- 0x01, 0x00, 0x13, 0x97, 0xB4, 0xEC, 0x40, 0x46,
- 0x02, 0x5E, 0x0F, 0x9F, 0x2C, 0xF3, 0x12, 0x95,
- 0x96, 0xEC, 0x0A, 0x03, 0x07, 0x00, 0xC1, 0x92,
- 0xC2, 0xD2, 0x11, 0x93, 0x96, 0xEC, 0x09, 0x05,
- 0x01, 0x00, 0x48, 0x02, 0xC1, 0x92, 0xC2, 0xD2,
- 0x11, 0x93, 0x96, 0xEC, 0x4E, 0x02, 0xC1, 0x94,
- 0xC5, 0xD6, 0xC5, 0x92, 0x11, 0x07, 0x96, 0xEC,
- 0x0B, 0x03, 0x0F, 0x00, 0xC1, 0x98, 0x46, 0x06,
- 0x7A, 0x93, 0x79, 0x93, 0x5C, 0x95, 0x5A, 0x95,
- 0x02, 0xA3, 0xC3, 0xD2, 0x04, 0x95, 0xC5, 0x96,
- 0x41, 0x06, 0xC5, 0xD6, 0x42, 0x46, 0x02, 0x9E,
- 0x0F, 0x9F, 0xD5, 0xF2, 0x11, 0x93, 0x96, 0xEC,
- 0x09, 0x05, 0x05, 0x00, 0x41, 0x02, 0xC1, 0x92,
- 0xC2, 0xD2, 0x11, 0x93, 0x96, 0xEC, 0xC1, 0x92,
- 0x09, 0xB5, 0x1F, 0x00, 0x43, 0x44, 0x02, 0x8E,
- 0x0F, 0x9F, 0x02, 0xF3, 0x40, 0x44, 0x02, 0x4E,
- 0x0F, 0x9F, 0x03, 0xF3, 0x0A, 0x05, 0xFF, 0xFF,
- 0x0F, 0x9F, 0x03, 0xF3, 0x43, 0x94, 0x11, 0x93,
- 0x96, 0xEC, 0x42, 0x02, 0xC1, 0xD4, 0x11, 0x93,
- 0x96, 0xEC, 0x49, 0x02, 0xC1, 0x92, 0x19, 0xD3,
- 0xB4, 0xEC, 0x09, 0x05, 0xF2, 0xFF, 0x1A, 0xD5,
- 0x92, 0xEC, 0x09, 0x43, 0xD0, 0x07, 0x02, 0x9E,
- 0x0F, 0x9F, 0x2C, 0xF3, 0x11, 0x93, 0xDC, 0xF7,
- 0x41, 0x02, 0x19, 0xD3, 0xDC, 0xF7, 0x11, 0x93,
- 0xDB, 0xF7, 0x09, 0xA3, 0x40, 0x00, 0x19, 0xD3,
- 0xDB, 0xF7, 0x09, 0x63, 0x00, 0x80, 0x01, 0x95,
- 0xC2, 0x94, 0x1A, 0xD5, 0xB5, 0xEC, 0x40, 0x96,
- 0x1B, 0xD7, 0xB4, 0xEC, 0x0F, 0x9F, 0x92, 0xF3,
- 0x11, 0x93, 0x92, 0xEC, 0x12, 0x95, 0xB6, 0xEC,
- 0x02, 0x43, 0x02, 0x8E, 0x0F, 0x9F, 0x7A, 0xF3,
- 0x02, 0x0E, 0x0F, 0x9F, 0x4D, 0xF3, 0x11, 0x93,
- 0xDC, 0xF7, 0x41, 0x02, 0x19, 0xD3, 0xDC, 0xF7,
- 0x11, 0x93, 0xDB, 0xF7, 0x09, 0xA3, 0x80, 0x00,
- 0x19, 0xD3, 0xDB, 0xF7, 0x09, 0x63, 0x00, 0x80,
- 0x01, 0x95, 0xC2, 0x94, 0x1A, 0xD5, 0xB5, 0xEC,
- 0x40, 0x96, 0x1B, 0xD7, 0xB4, 0xEC, 0x0F, 0x9F,
- 0x92, 0xF3, 0x11, 0x93, 0x03, 0x80, 0x09, 0xB3,
- 0x00, 0x40, 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F,
- 0x5F, 0xF3, 0x11, 0x93, 0xC0, 0xEC, 0x40, 0x42,
- 0x02, 0x5E, 0x0F, 0x9F, 0x5F, 0xF3, 0x40, 0xF0,
- 0xA6, 0xF3, 0x0F, 0x9F, 0x94, 0xF3, 0x41, 0x92,
- 0xC8, 0xD2, 0x0A, 0x95, 0x91, 0xEC, 0xC8, 0xD4,
- 0x40, 0xF0, 0x2A, 0xEF, 0x42, 0x00, 0x11, 0x93,
- 0xC0, 0xEC, 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F,
- 0x72, 0xF3, 0x42, 0x96, 0x1B, 0xD7, 0xC0, 0xEC,
- 0x0F, 0x9F, 0x94, 0xF3, 0x0A, 0x65, 0xFE, 0x7F,
- 0x02, 0x97, 0xC3, 0x92, 0x42, 0xA2, 0xC2, 0xD2,
- 0x0F, 0x9F, 0x94, 0xF3, 0x12, 0x45, 0x03, 0xEC,
- 0x02, 0x4E, 0x0F, 0x9F, 0x8C, 0xF3, 0x11, 0x93,
- 0xDC, 0xF7, 0x41, 0x02, 0x19, 0xD3, 0xDC, 0xF7,
- 0x11, 0x93, 0xDB, 0xF7, 0x09, 0xA3, 0x00, 0x08,
- 0x19, 0xD3, 0xDB, 0xF7, 0x1A, 0xD5, 0x92, 0xEC,
- 0x11, 0x93, 0x92, 0xEC, 0x19, 0x25, 0x92, 0xEC,
- 0x09, 0x63, 0x00, 0x80, 0x19, 0xD3, 0xF2, 0xBD,
- 0x41, 0x00, 0x88, 0x98, 0x90, 0x9A, 0x88, 0xDA,
- 0x08, 0x0B, 0x01, 0x00, 0x40, 0xF0, 0xA6, 0xF3,
- 0x40, 0x92, 0xC8, 0xD2, 0x09, 0x93, 0x91, 0xEC,
- 0xC8, 0xD2, 0x40, 0xF0, 0x2A, 0xEF, 0x42, 0x00,
- 0x88, 0x98, 0x90, 0x9A, 0x88, 0xDA, 0x08, 0x0B,
- 0x01, 0x00, 0x11, 0x93, 0xD7, 0xF7, 0x40, 0x42,
- 0x02, 0x4E, 0x0F, 0x9F, 0xB6, 0xF3, 0x0A, 0x65,
- 0xBC, 0x69, 0x02, 0x97, 0xC3, 0x92, 0x09, 0x83,
- 0x00, 0x02, 0xC2, 0xD2, 0x11, 0x93, 0x03, 0x80,
- 0x09, 0xB3, 0x00, 0x40, 0x40, 0x42, 0x02, 0x5E,
- 0x0F, 0x9F, 0xC9, 0xF3, 0x11, 0x93, 0xDC, 0xF7,
- 0x41, 0x02, 0x19, 0xD3, 0xDC, 0xF7, 0x11, 0x93,
- 0xDB, 0xF7, 0x09, 0xA3, 0x00, 0x20, 0x19, 0xD3,
- 0xDB, 0xF7, 0x11, 0x93, 0xB5, 0xEC, 0x19, 0xD3,
- 0x04, 0x80, 0x12, 0x95, 0xB4, 0xEC, 0x1A, 0xD5,
- 0x05, 0x80, 0x09, 0x63, 0x00, 0x80, 0x01, 0x97,
- 0xC3, 0x96, 0x1B, 0xD7, 0xB5, 0xEC, 0x40, 0x94,
- 0x1A, 0xD5, 0xB4, 0xEC, 0x19, 0xD3, 0xF2, 0xBD,
- 0x88, 0x98, 0x90, 0x9A, 0x88, 0xDA, 0x08, 0x0B,
- 0x01, 0x00, 0x09, 0x93, 0x96, 0x03, 0x19, 0xD3,
- 0x06, 0x82, 0x09, 0x93, 0x00, 0x01, 0x19, 0xD3,
- 0x03, 0x82, 0x88, 0x98, 0x90, 0x9A, 0x88, 0xDA,
- 0x47, 0x20, 0x08, 0x0B, 0x01, 0x00, 0x11, 0x93,
- 0x01, 0x82, 0xC5, 0xD2, 0x40, 0x94, 0x01, 0xD4,
- 0x13, 0x97, 0xB8, 0xEC, 0x02, 0xD6, 0x03, 0x95,
- 0x0C, 0x99, 0xBB, 0xEC, 0x04, 0x05, 0x13, 0x97,
- 0x03, 0xEC, 0x01, 0x27, 0x02, 0x99, 0xC4, 0x92,
- 0x03, 0x03, 0xC2, 0xD2, 0x14, 0x99, 0xBA, 0xEC,
- 0x03, 0x09, 0x1C, 0xD9, 0xBA, 0xEC, 0x12, 0x95,
- 0x04, 0x82, 0x0A, 0xB3, 0x02, 0x00, 0x40, 0x42,
- 0x02, 0x4E, 0x0F, 0x9F, 0x29, 0xF5, 0x01, 0x92,
- 0x03, 0xD2, 0x0A, 0xA3, 0x02, 0x00, 0x19, 0xD3,
- 0x04, 0x82, 0x02, 0x96, 0x0B, 0x05, 0x01, 0x00,
- 0x1A, 0xD5, 0xB8, 0xEC, 0xC5, 0x92, 0x43, 0x42,
- 0x02, 0x9E, 0x0F, 0x9F, 0x37, 0xF4, 0x42, 0x44,
- 0x02, 0x8E, 0x0F, 0x9F, 0x37, 0xF4, 0x11, 0x93,
- 0xBF, 0xEC, 0x40, 0x42, 0x02, 0x5E, 0x0F, 0x9F,
- 0x37, 0xF4, 0x0C, 0x49, 0xD3, 0x08, 0x02, 0x8E,
- 0x0F, 0x9F, 0x37, 0xF4, 0x11, 0x63, 0x07, 0x82,
- 0x11, 0xA3, 0x07, 0x82, 0x71, 0x93, 0x79, 0x93,
- 0x79, 0x93, 0x79, 0x93, 0x03, 0xD2, 0xC5, 0x94,
- 0x0A, 0xB5, 0xFC, 0xFF, 0x04, 0xD4, 0x03, 0x96,
- 0x40, 0x46, 0x02, 0x5E, 0x0F, 0x9F, 0x46, 0xF4,
- 0x11, 0x93, 0xB8, 0xEC, 0x41, 0x42, 0x02, 0x8E,
- 0x0F, 0x9F, 0x4D, 0xF4, 0xC5, 0x98, 0x0C, 0x03,
- 0xFF, 0xFF, 0x42, 0x42, 0x02, 0x8E, 0x0F, 0x9F,
- 0x74, 0xF4, 0x0A, 0x95, 0xBB, 0xEC, 0x42, 0x92,
- 0x19, 0xD3, 0xB9, 0xEC, 0xC5, 0x96, 0x43, 0x46,
- 0x02, 0x9E, 0x0F, 0x9F, 0x66, 0xF4, 0x0B, 0x07,
- 0xFC, 0xFF, 0xC5, 0xD6, 0xD2, 0x98, 0x1C, 0xD9,
- 0xC8, 0xBC, 0xD2, 0x96, 0x1B, 0xD7, 0xCA, 0xBC,
- 0x09, 0x03, 0xFF, 0xFF, 0x40, 0x42, 0x02, 0x5E,
- 0x0F, 0x9F, 0x52, 0xF4, 0x19, 0xD3, 0xB9, 0xEC,
- 0x40, 0x42, 0x02, 0x5E, 0x0F, 0x9F, 0x72, 0xF4,
- 0x0A, 0x05, 0xFE, 0xFF, 0xCA, 0xD2, 0xC2, 0xD2,
- 0x0F, 0x9F, 0x74, 0xF4, 0x1A, 0xD5, 0x93, 0xEC,
- 0x03, 0x98, 0x40, 0x48, 0x02, 0x5E, 0x0F, 0x9F,
- 0xA1, 0xF4, 0x11, 0x93, 0xB8, 0xEC, 0x41, 0x42,
- 0x02, 0x9E, 0x0F, 0x9F, 0x84, 0xF4, 0x04, 0x94,
- 0x48, 0x44, 0x02, 0x4E, 0x0F, 0x9F, 0x8F, 0xF4,
- 0x41, 0x42, 0x02, 0x5E, 0x0F, 0x9F, 0xA1, 0xF4,
- 0x11, 0x93, 0x04, 0x82, 0x41, 0xB2, 0x40, 0x42,
- 0x02, 0x4E, 0x0F, 0x9F, 0xA1, 0xF4, 0x41, 0x96,
- 0x01, 0xD6, 0x0A, 0x65, 0xBD, 0x43, 0x02, 0x99,
- 0xC4, 0x92, 0x09, 0xA3, 0x80, 0x00, 0xC2, 0xD2,
- 0x0A, 0x65, 0xE8, 0x43, 0x02, 0x97, 0xC3, 0x92,
- 0x09, 0xB3, 0xBF, 0xFF, 0xC2, 0xD2, 0x0F, 0x9F,
- 0xFA, 0xF4, 0xC5, 0x98, 0x43, 0x48, 0x02, 0x9E,
- 0x0F, 0x9F, 0xFA, 0xF4, 0x4F, 0x96, 0x0C, 0xB3,
- 0x01, 0x00, 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F,
- 0xAE, 0xF4, 0x47, 0x96, 0x11, 0x93, 0xB7, 0xEC,
- 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F, 0xD6, 0xF4,
- 0x11, 0x93, 0xB8, 0xEC, 0x41, 0x42, 0x02, 0x5E,
- 0x0F, 0x9F, 0xD6, 0xF4, 0x12, 0x95, 0x00, 0x82,
- 0x0A, 0x05, 0xFF, 0xAF, 0x05, 0xD4, 0xC8, 0xD6,
- 0xC8, 0xD2, 0x40, 0xF0, 0x7B, 0xF7, 0x42, 0x00,
- 0x05, 0x96, 0xC3, 0x94, 0x01, 0xB5, 0x40, 0x44,
- 0x02, 0x4E, 0x0F, 0x9F, 0xD6, 0xF4, 0x06, 0x98,
- 0x50, 0x98, 0x1C, 0xD9, 0xA2, 0xBC, 0x40, 0x98,
- 0x1C, 0xD9, 0xA2, 0xBC, 0x40, 0x92, 0x03, 0xD2,
- 0x0F, 0x9F, 0xFF, 0xF4, 0x03, 0x94, 0x40, 0x44,
- 0x02, 0x5E, 0x0F, 0x9F, 0xE3, 0xF4, 0x0A, 0x65,
- 0x5E, 0x43, 0x02, 0x97, 0xC3, 0x92, 0x48, 0xA2,
- 0xC2, 0xD2, 0x0F, 0x9F, 0xFF, 0xF4, 0x11, 0x93,
- 0xB8, 0xEC, 0x0C, 0x99, 0xBB, 0xEC, 0x04, 0x03,
- 0x04, 0x96, 0x13, 0x25, 0x03, 0xEC, 0xC1, 0xD4,
- 0x11, 0x93, 0xBA, 0xEC, 0x19, 0x05, 0xBA, 0xEC,
- 0x1B, 0xD7, 0x01, 0x82, 0x0A, 0x65, 0xFD, 0x7D,
- 0x02, 0x99, 0xC4, 0x92, 0x43, 0xA2, 0xC2, 0xD2,
- 0x41, 0x92, 0x01, 0xD2, 0x03, 0x94, 0x40, 0x44,
- 0x02, 0x5E, 0x0F, 0x9F, 0x13, 0xF5, 0x11, 0x93,
- 0xB9, 0xEC, 0x40, 0x42, 0x02, 0x5E, 0x0F, 0x9F,
- 0x0B, 0xF5, 0x19, 0xD3, 0xB8, 0xEC, 0x19, 0xD3,
- 0xBA, 0xEC, 0x19, 0xD3, 0xBB, 0xEC, 0x03, 0x96,
- 0x40, 0x46, 0x02, 0x5E, 0x0F, 0x9F, 0x13, 0xF5,
- 0x41, 0x98, 0x1C, 0xD9, 0xB7, 0xEC, 0x11, 0x93,
- 0xBF, 0xEC, 0x41, 0x42, 0x02, 0x5E, 0x0F, 0x9F,
- 0x24, 0xF5, 0x11, 0x93, 0x00, 0x82, 0x19, 0xD3,
- 0x02, 0x82, 0x0A, 0x65, 0xFD, 0x7D, 0x02, 0x97,
- 0xC3, 0x92, 0x09, 0xA3, 0x00, 0x01, 0xC2, 0xD2,
- 0x40, 0x98, 0x1C, 0xD9, 0xBF, 0xEC, 0x0F, 0x9F,
- 0x2C, 0xF5, 0x01, 0x92, 0x19, 0xD3, 0xB7, 0xEC,
- 0x01, 0x94, 0x40, 0x44, 0x02, 0x5E, 0x0F, 0x9F,
- 0x38, 0xF5, 0x0A, 0x65, 0xEA, 0x43, 0x02, 0x97,
- 0xC3, 0x92, 0x09, 0xB3, 0xFB, 0xFF, 0xC2, 0xD2,
- 0x47, 0x00, 0x88, 0x98, 0x90, 0x9A, 0x88, 0xDA,
- 0x08, 0x0B, 0x01, 0x00, 0x12, 0x95, 0x03, 0x80,
- 0x0A, 0xB3, 0x00, 0x40, 0x40, 0x42, 0x02, 0x4E,
- 0x0F, 0x9F, 0x57, 0xF5, 0x0A, 0xB7, 0x00, 0x08,
- 0x40, 0x46, 0x02, 0x5E, 0x0F, 0x9F, 0x5A, 0xF5,
- 0x11, 0x93, 0x03, 0xEC, 0x41, 0x02, 0x09, 0xB3,
- 0xFE, 0xFF, 0x12, 0x95, 0x07, 0x80, 0x01, 0x45,
- 0x02, 0x8E, 0x0F, 0x9F, 0x5A, 0xF5, 0x41, 0x92,
- 0x0F, 0x9F, 0x5B, 0xF5, 0x40, 0x92, 0x88, 0x98,
- 0x90, 0x9A, 0x88, 0xDA, 0x41, 0x20, 0x08, 0x0B,
- 0x01, 0x00, 0x0A, 0x65, 0xE9, 0x43, 0x02, 0x97,
- 0xC3, 0x92, 0x09, 0xA3, 0x40, 0x00, 0xC2, 0xD2,
- 0x13, 0x97, 0x6E, 0xEC, 0x0B, 0x47, 0xA0, 0x00,
- 0x02, 0x5E, 0x0F, 0x9F, 0x86, 0xF5, 0x09, 0x63,
- 0x08, 0x43, 0x0A, 0x65, 0xFF, 0x5F, 0x01, 0x99,
- 0xC4, 0xD4, 0x0A, 0x95, 0x9B, 0xEC, 0xD2, 0x96,
- 0x1B, 0xD7, 0xFA, 0xBC, 0xD2, 0x96, 0xC4, 0xD6,
- 0xD2, 0x98, 0x1C, 0xD9, 0xFA, 0xBC, 0xD2, 0x96,
- 0xC1, 0xD6, 0xC2, 0x94, 0x1A, 0xD5, 0xFA, 0xBC,
- 0x0F, 0x9F, 0xC4, 0xF5, 0x0C, 0x69, 0xFF, 0x6F,
- 0x1C, 0xD9, 0xF8, 0xBC, 0x0B, 0x47, 0x10, 0x95,
- 0x02, 0x5E, 0x0F, 0x9F, 0x9E, 0xF5, 0x0A, 0x95,
- 0x6F, 0xEC, 0x09, 0x63, 0x06, 0x43, 0x01, 0x99,
- 0xC4, 0xD6, 0xD2, 0x96, 0x1B, 0xD7, 0xF8, 0xBC,
- 0x0C, 0x69, 0xEE, 0x6A, 0xC1, 0xD8, 0xC2, 0x94,
- 0x1A, 0xD5, 0xF8, 0xBC, 0x40, 0x92, 0xC5, 0xD2,
- 0x11, 0x43, 0xC1, 0xEC, 0x02, 0x0E, 0x0F, 0x9F,
- 0xC1, 0xF5, 0xC5, 0x94, 0x0A, 0x03, 0x71, 0xEC,
- 0xC1, 0x94, 0x1A, 0xD5, 0xFA, 0xBC, 0x11, 0x93,
- 0xC0, 0xEC, 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F,
- 0xB3, 0xF5, 0x0A, 0x95, 0x6F, 0xEC, 0xC8, 0xD4,
- 0x40, 0xF0, 0x9C, 0xF7, 0x19, 0xD3, 0xF8, 0xBC,
- 0x41, 0x00, 0xC5, 0x96, 0x41, 0x06, 0xC5, 0xD6,
- 0x13, 0x47, 0xC1, 0xEC, 0x02, 0x1E, 0x0F, 0x9F,
- 0xA5, 0xF5, 0x40, 0x98, 0x1C, 0xD9, 0xFA, 0xBC,
- 0x40, 0x92, 0x19, 0xD3, 0x6E, 0xEC, 0x19, 0xD3,
- 0xC1, 0xEC, 0x0A, 0x65, 0x52, 0x43, 0x02, 0x97,
- 0xC3, 0x92, 0x48, 0xA2, 0xC2, 0xD2, 0x0A, 0x65,
- 0xEB, 0x43, 0x02, 0x99, 0xC4, 0x92, 0x09, 0xB3,
- 0xBF, 0xFF, 0xC2, 0xD2, 0x41, 0x00, 0x88, 0x98,
- 0x90, 0x9A, 0x88, 0xDA, 0x43, 0x20, 0x08, 0x0B,
- 0x01, 0x00, 0x06, 0x92, 0x01, 0xD2, 0x0A, 0x65,
- 0xF0, 0x6A, 0x0B, 0x97, 0x6F, 0xEC, 0x02, 0x99,
- 0xC4, 0x98, 0xD3, 0xD8, 0x02, 0xD6, 0x0A, 0x03,
- 0x02, 0x00, 0x01, 0x97, 0xC3, 0x98, 0x02, 0x96,
- 0xC3, 0xD8, 0x01, 0x96, 0xC1, 0xD6, 0x1A, 0xD5,
- 0x6E, 0xEC, 0xC5, 0x98, 0x14, 0x99, 0x6F, 0xEC,
- 0xC2, 0xD8, 0x43, 0x00, 0x88, 0x98, 0x90, 0x9A,
- 0x88, 0xDA, 0x08, 0x0B, 0x01, 0x00, 0x40, 0x92,
- 0xC8, 0xD2, 0x40, 0xF0, 0xD9, 0xF5, 0x41, 0x00,
- 0x11, 0x93, 0xC0, 0xEC, 0x40, 0x42, 0x02, 0x4E,
- 0x0F, 0x9F, 0x13, 0xF6, 0x42, 0x42, 0x02, 0x5E,
- 0x0F, 0x9F, 0x10, 0xF6, 0x0A, 0x65, 0xFE, 0x7F,
- 0x02, 0x97, 0xC3, 0x92, 0x42, 0xA2, 0xC2, 0xD2,
- 0x40, 0x92, 0x19, 0xD3, 0xC0, 0xEC, 0x0A, 0x65,
- 0xEB, 0x43, 0x02, 0x97, 0xC3, 0x92, 0x09, 0xA3,
- 0xC0, 0x00, 0xC2, 0xD2, 0x0A, 0x65, 0xE9, 0x43,
- 0x02, 0x97, 0xC3, 0x92, 0x09, 0xB3, 0xBF, 0xFF,
- 0xC2, 0xD2, 0x88, 0x98, 0x90, 0x9A, 0x88, 0xDA,
- 0x63, 0x20, 0x08, 0x0B, 0x01, 0x00, 0x11, 0x93,
- 0xAF, 0xBC, 0x47, 0xB2, 0x59, 0x95, 0x5A, 0x95,
- 0x12, 0xA5, 0xBF, 0xBC, 0x0A, 0xB3, 0x01, 0x00,
- 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F, 0x35, 0xF6,
- 0x41, 0x04, 0x05, 0x93, 0x40, 0x96, 0x20, 0xD6,
- 0x62, 0x97, 0x0F, 0x9F, 0x44, 0xF6, 0x14, 0x99,
- 0xFC, 0xBC, 0xD1, 0xD8, 0x14, 0x99, 0xFE, 0xBC,
- 0xD1, 0xD8, 0x20, 0x98, 0x42, 0x08, 0x20, 0xD8,
- 0x20, 0x98, 0x03, 0x49, 0x02, 0x1E, 0x0F, 0x9F,
- 0x3B, 0xF6, 0xC5, 0x92, 0x62, 0x42, 0x02, 0x4E,
- 0x0F, 0x9F, 0x5D, 0xF6, 0x02, 0x8E, 0x0F, 0x9F,
- 0x57, 0xF6, 0x61, 0x42, 0x02, 0x4E, 0x0F, 0x9F,
- 0x81, 0xF6, 0x0F, 0x9F, 0xAE, 0xF6, 0x63, 0x42,
- 0x02, 0x4E, 0x0F, 0x9F, 0xA4, 0xF6, 0x0F, 0x9F,
- 0xAE, 0xF6, 0x0D, 0x03, 0x01, 0x00, 0x0C, 0x99,
- 0x71, 0xEC, 0x0B, 0x05, 0xFF, 0xFF, 0x40, 0x96,
- 0x0F, 0x9F, 0x6A, 0xF6, 0xD1, 0x96, 0xD4, 0xD6,
- 0x20, 0x96, 0x41, 0x06, 0x20, 0xD6, 0x02, 0x47,
- 0x02, 0x1E, 0x0F, 0x9F, 0x66, 0xF6, 0x1A, 0xD5,
- 0xC1, 0xEC, 0x0A, 0x65, 0xEB, 0x43, 0x02, 0x99,
- 0xC4, 0x92, 0x09, 0xA3, 0xC0, 0x00, 0xC2, 0xD2,
- 0x0A, 0x65, 0xE9, 0x43, 0x02, 0x97, 0xC3, 0x92,
- 0x09, 0xB3, 0xBF, 0xFF, 0xC2, 0xD2, 0x0F, 0x9F,
- 0xAE, 0xF6, 0x0A, 0x03, 0xFE, 0xFF, 0x61, 0x95,
- 0x40, 0x98, 0x20, 0xD8, 0x02, 0x49, 0x02, 0x0E,
- 0x0F, 0x9F, 0xAE, 0xF6, 0x0D, 0x03, 0x01, 0x00,
- 0x21, 0xD2, 0x20, 0x92, 0x05, 0x03, 0x42, 0x02,
- 0xC8, 0xD2, 0x21, 0x96, 0xC3, 0x92, 0x42, 0x06,
- 0x21, 0xD6, 0xC8, 0xD2, 0x22, 0xD4, 0x40, 0xF0,
- 0x01, 0xF1, 0x42, 0x00, 0x20, 0x98, 0x42, 0x08,
- 0x20, 0xD8, 0x22, 0x94, 0x02, 0x49, 0x02, 0x1E,
- 0x0F, 0x9F, 0x8D, 0xF6, 0x0F, 0x9F, 0xAE, 0xF6,
- 0x0D, 0x03, 0x03, 0x00, 0xC8, 0xD2, 0x02, 0x92,
- 0xC8, 0xD2, 0x01, 0x96, 0xC8, 0xD6, 0x40, 0xF0,
- 0xB1, 0xF6, 0x43, 0x00, 0x63, 0x00, 0x88, 0x98,
- 0x90, 0x9A, 0x88, 0xDA, 0x45, 0x20, 0x08, 0x0B,
- 0x01, 0x00, 0x0D, 0x03, 0x08, 0x00, 0x08, 0x94,
- 0xC5, 0xD4, 0x09, 0x05, 0x01, 0x00, 0xC2, 0x94,
- 0x03, 0xD4, 0x42, 0x02, 0xC1, 0x92, 0x01, 0xD2,
- 0x02, 0x97, 0xC5, 0x94, 0x0A, 0x83, 0xFF, 0xFF,
- 0x11, 0xB3, 0x2C, 0x93, 0x09, 0xB3, 0xFB, 0xFF,
- 0x19, 0xD3, 0x2C, 0x93, 0x03, 0x92, 0x40, 0x42,
- 0x02, 0x4E, 0x0F, 0x9F, 0xE4, 0xF6, 0x01, 0x94,
- 0xD2, 0x92, 0x19, 0xD3, 0x2C, 0x93, 0x01, 0xD4,
- 0x02, 0x94, 0x12, 0x95, 0x2C, 0x93, 0x44, 0xA4,
- 0x1A, 0xD5, 0x2C, 0x93, 0x0A, 0xB5, 0xFB, 0xFF,
- 0x1A, 0xD5, 0x2C, 0x93, 0x0B, 0x07, 0xFF, 0xFF,
- 0x40, 0x46, 0x02, 0x5E, 0x0F, 0x9F, 0xCF, 0xF6,
- 0x09, 0x63, 0xD4, 0x6C, 0x01, 0x95, 0xC2, 0x96,
- 0xC5, 0x94, 0x02, 0xA7, 0xC1, 0xD6, 0x03, 0x92,
- 0x54, 0x42, 0x02, 0x5E, 0x0F, 0x9F, 0xF4, 0xF6,
- 0x0A, 0x83, 0xFF, 0xFF, 0x1B, 0xB3, 0x2C, 0x93,
- 0x45, 0x00, 0x88, 0x98, 0x90, 0x9A, 0x88, 0xDA,
- 0x08, 0x0B, 0x01, 0x00, 0x09, 0x63, 0x00, 0x40,
- 0x19, 0xD3, 0xF2, 0xBD, 0x40, 0xF0, 0x3B, 0xF5,
- 0x40, 0x42, 0x02, 0x5E, 0x0F, 0x9F, 0x08, 0xF7,
- 0x40, 0xF0, 0x94, 0xF2, 0x0F, 0x9F, 0x16, 0xF7,
- 0x40, 0x96, 0xC8, 0xD6, 0x09, 0x93, 0x91, 0xEC,
- 0xC8, 0xD2, 0x40, 0xF0, 0x2A, 0xEF, 0x0A, 0x65,
- 0xFE, 0x7F, 0x02, 0x97, 0xC3, 0x92, 0x44, 0xA2,
- 0xC2, 0xD2, 0x42, 0x00, 0x88, 0x98, 0x90, 0x9A,
- 0x88, 0xDA, 0x08, 0x0B, 0x01, 0x00, 0x0A, 0x65,
- 0xE8, 0x43, 0x02, 0x97, 0xC3, 0x92, 0x09, 0xA3,
- 0x40, 0x00, 0xC2, 0xD2, 0x0A, 0x65, 0xEA, 0x43,
- 0x02, 0x97, 0xC3, 0x92, 0x09, 0xB3, 0xFB, 0xFF,
- 0xC2, 0xD2, 0x40, 0x92, 0x19, 0xD3, 0x2D, 0xBC,
- 0x0A, 0x65, 0xD8, 0x43, 0x02, 0x97, 0xC3, 0x92,
- 0x09, 0xB3, 0xBF, 0xFF, 0xC2, 0xD2, 0x88, 0x98,
- 0x90, 0x9A, 0x88, 0xDA, 0x08, 0x0B, 0x01, 0x00,
- 0x09, 0x63, 0xEA, 0x43, 0x01, 0x97, 0xC3, 0x94,
- 0x44, 0xA4, 0xC1, 0xD4, 0x11, 0x93, 0xB9, 0xEC,
- 0x40, 0x42, 0x02, 0x4E, 0x0F, 0x9F, 0x6F, 0xF7,
- 0x12, 0x95, 0x93, 0xEC, 0x0B, 0x67, 0x36, 0x43,
- 0xD2, 0x98, 0x1C, 0xD9, 0xC8, 0xBC, 0xD2, 0x98,
- 0x03, 0x93, 0xC1, 0xD8, 0x11, 0x93, 0xB9, 0xEC,
- 0x09, 0x03, 0xFF, 0xFF, 0x19, 0xD3, 0xB9, 0xEC,
- 0x40, 0x42, 0x02, 0x5E, 0x0F, 0x9F, 0x48, 0xF7,
- 0x19, 0xD3, 0xB8, 0xEC, 0x19, 0xD3, 0xBA, 0xEC,
- 0x0A, 0x05, 0xFE, 0xFF, 0xCA, 0xD2, 0xCA, 0xD2,
- 0xC2, 0xD2, 0x0A, 0x65, 0x5E, 0x43, 0x02, 0x97,
- 0xC3, 0x92, 0x48, 0xA2, 0xC2, 0xD2, 0x0A, 0x65,
- 0xEA, 0x43, 0x02, 0x99, 0xC4, 0x92, 0x09, 0xB3,
- 0xFB, 0xFF, 0x0F, 0x9F, 0x78, 0xF7, 0x11, 0x93,
- 0x03, 0xEC, 0x19, 0xD3, 0x01, 0x82, 0x0A, 0x65,
- 0xFD, 0x7D, 0x02, 0x97, 0xC3, 0x92, 0x43, 0xA2,
- 0xC2, 0xD2, 0x88, 0x98, 0x90, 0x9A, 0x88, 0xDA,
- 0x08, 0x0B, 0x01, 0x00, 0x03, 0x92, 0x04, 0x96,
- 0x0D, 0x5E, 0x50, 0x46, 0x02, 0x0E, 0x40, 0x92,
- 0x09, 0xEE, 0x44, 0x46, 0x04, 0x0E, 0x59, 0x93,
- 0x44, 0x26, 0x04, 0x5E, 0x46, 0xEE, 0x41, 0x93,
- 0x41, 0x26, 0x43, 0x4E, 0x88, 0x98, 0x90, 0x9A,
- 0x88, 0xDA, 0x08, 0x0B, 0x01, 0x00, 0x40, 0xF0,
- 0xB1, 0xFE, 0x88, 0x98, 0x90, 0x9A, 0x88, 0xDA,
- 0x08, 0x0B, 0x01, 0x00, 0x88, 0x98, 0x90, 0x9A,
- 0x88, 0xDA, 0x08, 0x0B, 0x01, 0x00, 0x03, 0x94,
- 0x1A, 0xD5, 0xA3, 0xF7, 0x11, 0x93, 0x00, 0x90,
- 0x88, 0x98, 0x90, 0x9A, 0x1D, 0x00, 0x1A, 0x00,
- 0x03, 0x00, 0x03, 0x00, 0x18, 0x00, 0x19, 0x00,
- 0x1A, 0x00, 0x1B, 0x00, 0x16, 0x00, 0x21, 0x00,
- 0x12, 0x00, 0x09, 0x00, 0x13, 0x00, 0x19, 0x00,
- 0x19, 0x00, 0x19, 0x00, 0x21, 0x00, 0x2D, 0x00,
- 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x69,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x5F, 0xF2, 0xCD, 0xF7, 0x00, 0x00, 0x74, 0xF2,
- 0xCD, 0xF7, 0x00, 0x00, 0xB9, 0xF2, 0xCA, 0xF7,
- 0xD1, 0xF7, 0x00, 0x00, 0x97, 0xF3, 0xCD, 0xF7,
- 0x05, 0x46, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-/*
- * current zd1211b firmware version.
- */
-#define ZD1211B_FIRMWARE_VER 4705
-
-uint8_t zd1211b_firmware[] = {
- 0x08, 0x91, 0xff, 0xed, 0x09, 0x93, 0x1e, 0xee, 0xd1, 0x94, 0x11,
- 0xee, 0x88, 0xd4, 0xd1, 0x96, 0xd1, 0x98, 0x5c, 0x99, 0x5c, 0x99,
- 0x4c, 0x99, 0x04, 0x9d, 0xd1, 0x98, 0xd1, 0x9a, 0x03, 0xee, 0xf4,
- 0x94, 0xd3, 0xd4, 0x41, 0x2a, 0x40, 0x4a, 0x45, 0xbe, 0x88, 0x92,
- 0x41, 0x24, 0x40, 0x44, 0x53, 0xbe, 0x40, 0xf0, 0x4e, 0xee, 0x41,
- 0xee, 0x98, 0x9a, 0x72, 0xf7, 0x02, 0x00, 0x1f, 0xec, 0x00, 0x00,
- 0xb2, 0xf8, 0x4d, 0x00, 0xa1, 0xec, 0x00, 0x00, 0x43, 0xf7, 0x22,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xd8,
- 0xa0, 0x90, 0x98, 0x9a, 0x98, 0x9a, 0xa0, 0xd8, 0x40, 0xf0, 0x5a,
- 0xf0, 0xa0, 0x90, 0x98, 0x9a, 0xa0, 0xd8, 0x40, 0xf0, 0x0a, 0xef,
- 0xa0, 0x90, 0x98, 0x9a, 0xa0, 0xd8, 0x40, 0xf0, 0x97, 0xf0, 0xa0,
- 0x90, 0x98, 0x9a, 0xa0, 0xd8, 0x40, 0xf0, 0x94, 0xf6, 0xa0, 0x90,
- 0x98, 0x9a, 0xa0, 0xd8, 0x40, 0xf0, 0x95, 0xf5, 0xa0, 0x90, 0x98,
- 0x9a, 0x98, 0x9a, 0xa0, 0xd8, 0x40, 0xf0, 0x34, 0xf7, 0xa0, 0x90,
- 0x98, 0x9a, 0x88, 0xda, 0x41, 0x20, 0x08, 0x0b, 0x01, 0x00, 0x40,
- 0xf0, 0x8e, 0xee, 0x40, 0x96, 0x0a, 0x65, 0x00, 0x7d, 0x11, 0x93,
- 0x76, 0xf7, 0x41, 0x42, 0x02, 0x5e, 0x0f, 0x9f, 0x57, 0xee, 0x40,
- 0xf1, 0x1b, 0xd7, 0x76, 0xf7, 0xc5, 0x92, 0x02, 0x99, 0x41, 0x92,
- 0xc4, 0xd2, 0x40, 0x92, 0xc4, 0xd2, 0x0f, 0x9f, 0x95, 0xf8, 0x0f,
- 0x9f, 0x57, 0xee, 0x41, 0x00, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda,
- 0x08, 0x0b, 0x01, 0x00, 0x40, 0x92, 0x19, 0xd3, 0x12, 0x95, 0x19,
- 0xd3, 0x10, 0x95, 0x19, 0xd3, 0x02, 0x80, 0x19, 0xd3, 0x03, 0x82,
- 0x09, 0x93, 0x65, 0xf7, 0x19, 0xd3, 0x91, 0xec, 0x40, 0xf0, 0x07,
- 0xf2, 0x40, 0xf0, 0x75, 0xf3, 0x11, 0x93, 0x04, 0xec, 0x42, 0x42,
- 0x02, 0x5e, 0x0f, 0x9f, 0x8c, 0xee, 0x40, 0x92, 0x19, 0xd3, 0x04,
- 0xec, 0x40, 0xf0, 0xe0, 0xf1, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda,
- 0x08, 0x0b, 0x01, 0x00, 0x11, 0x93, 0x44, 0x96, 0x09, 0xb3, 0xff,
- 0xfd, 0x19, 0xd3, 0x44, 0x96, 0x40, 0xf0, 0x2d, 0xf7, 0x40, 0xf0,
- 0x6d, 0xee, 0x4b, 0x62, 0x0a, 0x95, 0x2e, 0xee, 0xd1, 0xd4, 0x0b,
- 0x97, 0x2b, 0xee, 0xd1, 0xd6, 0x0a, 0x95, 0x00, 0xee, 0xd1, 0xd4,
- 0x0b, 0x97, 0x2f, 0xee, 0xd1, 0xd6, 0x0a, 0x95, 0x34, 0xee, 0xd1,
- 0xd4, 0x0b, 0x97, 0x39, 0xee, 0xd1, 0xd6, 0x0a, 0x95, 0x3e, 0xee,
- 0xd1, 0xd4, 0x0b, 0x97, 0x43, 0xee, 0xd1, 0xd6, 0x0a, 0x95, 0x2e,
- 0xee, 0xd1, 0xd4, 0x0b, 0x97, 0x48, 0xee, 0xd1, 0xd6, 0x0a, 0x95,
- 0x49, 0xee, 0xc1, 0xd4, 0x0a, 0x65, 0x00, 0x44, 0x02, 0x97, 0xc3,
- 0x92, 0x44, 0xa2, 0xc2, 0xd2, 0x43, 0xf1, 0x09, 0x93, 0x01, 0x3f,
- 0x19, 0xd3, 0xc0, 0x85, 0x11, 0x93, 0x44, 0x96, 0x09, 0xb3, 0xff,
- 0xfc, 0x19, 0xd3, 0x44, 0x96, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda,
- 0x08, 0x0b, 0x01, 0x00, 0x0d, 0x03, 0x03, 0x00, 0x03, 0x96, 0x41,
- 0x02, 0x03, 0x99, 0xc4, 0x94, 0x42, 0x04, 0xc1, 0x04, 0xc2, 0x94,
- 0xc3, 0xd4, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01,
- 0x00, 0x40, 0x92, 0x19, 0xd3, 0x94, 0xec, 0x13, 0x97, 0x95, 0xec,
- 0x1b, 0xd7, 0x02, 0x80, 0x11, 0x93, 0x99, 0xec, 0x19, 0xd3, 0x7c,
- 0x96, 0x0b, 0x97, 0xa0, 0x00, 0x1b, 0xd7, 0x6e, 0xec, 0x0a, 0x65,
- 0x0e, 0x42, 0x02, 0x97, 0xc3, 0x92, 0x09, 0xb3, 0xff, 0xbf, 0x11,
- 0xa3, 0x9a, 0xec, 0xc2, 0xd2, 0x0a, 0x65, 0xeb, 0x43, 0x02, 0x97,
- 0xc3, 0x92, 0x09, 0xa3, 0xc0, 0x00, 0xc2, 0xd2, 0x0a, 0x65, 0xe9,
- 0x43, 0x02, 0x97, 0xc3, 0x92, 0x09, 0xb3, 0xbf, 0xff, 0xc2, 0xd2,
- 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, 0x47, 0x20, 0x08, 0x0b, 0x01,
- 0x00, 0x14, 0x99, 0x03, 0x80, 0x0c, 0xb3, 0x00, 0x10, 0x40, 0x42,
- 0x02, 0x4e, 0x0f, 0x9f, 0x3d, 0xf0, 0x11, 0x93, 0x9f, 0xec, 0x41,
- 0x02, 0x19, 0xd3, 0x9f, 0xec, 0x11, 0x93, 0x74, 0xf7, 0x40, 0x42,
- 0x02, 0x4e, 0x0f, 0x9f, 0x2a, 0xef, 0x0a, 0x65, 0xfe, 0x7f, 0x02,
- 0x97, 0xc3, 0x92, 0x09, 0xa3, 0x00, 0x04, 0xc2, 0xd2, 0x0f, 0x9f,
- 0x57, 0xf0, 0x11, 0x93, 0x94, 0xec, 0x02, 0xd2, 0x40, 0x42, 0x02,
- 0x5e, 0x0f, 0x9f, 0x76, 0xef, 0x41, 0x92, 0x19, 0xd3, 0x94, 0xec,
- 0x19, 0xd3, 0x9f, 0xec, 0x12, 0x95, 0x02, 0x80, 0x1a, 0xd5, 0x95,
- 0xec, 0x13, 0x97, 0x7c, 0x96, 0x1b, 0xd7, 0x99, 0xec, 0x0a, 0x65,
- 0x0e, 0x42, 0x02, 0x97, 0xc3, 0x92, 0x09, 0xb3, 0x00, 0x40, 0x19,
- 0xd3, 0x9a, 0xec, 0x09, 0x63, 0x00, 0x40, 0xc2, 0xd2, 0x02, 0x94,
- 0x1a, 0xd5, 0x7c, 0x96, 0x0c, 0xb3, 0x00, 0x08, 0x40, 0x42, 0x02,
- 0x5e, 0x0f, 0x9f, 0x56, 0xef, 0x0c, 0xb3, 0xff, 0x07, 0x0f, 0x9f,
- 0x5a, 0xef, 0x11, 0x93, 0x06, 0x80, 0x09, 0xb3, 0xff, 0x07, 0x09,
- 0x03, 0x00, 0xa0, 0x19, 0xd3, 0x97, 0xec, 0x40, 0x98, 0x0b, 0x97,
- 0x9c, 0xec, 0x04, 0x95, 0x03, 0x05, 0x14, 0x03, 0x97, 0xec, 0x46,
- 0x02, 0xc1, 0x92, 0xc2, 0xd2, 0x41, 0x08, 0x42, 0x48, 0x02, 0x9e,
- 0x0f, 0x9f, 0x61, 0xef, 0x11, 0x93, 0x97, 0xec, 0xc1, 0x92, 0xc5,
- 0xd2, 0x5f, 0xb2, 0x19, 0xd3, 0x9b, 0xec, 0x0f, 0x9f, 0x79, 0xef,
- 0x13, 0x97, 0x98, 0xec, 0xc5, 0xd6, 0x11, 0x93, 0x03, 0x80, 0x09,
- 0xb3, 0x00, 0x08, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x8f, 0xef,
- 0x11, 0x93, 0x7a, 0xf7, 0x41, 0x02, 0x19, 0xd3, 0x7a, 0xf7, 0x11,
- 0x93, 0x79, 0xf7, 0x09, 0xa3, 0x00, 0x10, 0x19, 0xd3, 0x79, 0xf7,
- 0x40, 0x98, 0x1c, 0xd9, 0x9b, 0xec, 0x12, 0x95, 0x9b, 0xec, 0x40,
- 0x44, 0x02, 0x4e, 0x0f, 0x9f, 0x2c, 0xf0, 0x0a, 0xb3, 0x08, 0x00,
- 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0xad, 0xef, 0x0a, 0xb3, 0x07,
- 0x00, 0x09, 0x05, 0xa9, 0xec, 0xc2, 0x94, 0x01, 0xd4, 0x09, 0x03,
- 0xa1, 0xec, 0xc1, 0x92, 0x19, 0xd3, 0x9b, 0xec, 0xc5, 0x94, 0x0a,
- 0xb5, 0x00, 0xff, 0x01, 0xa5, 0xc5, 0xd4, 0x0f, 0x9f, 0xb9, 0xef,
- 0x0a, 0x05, 0xff, 0xff, 0x0a, 0x03, 0xb1, 0xec, 0xc1, 0x92, 0x01,
- 0xd2, 0x1a, 0xd5, 0x9b, 0xec, 0xc5, 0x96, 0x0b, 0x07, 0xff, 0xff,
- 0xc5, 0xd6, 0x11, 0x93, 0x97, 0xec, 0xc5, 0x98, 0xc1, 0xd8, 0x11,
- 0x93, 0x97, 0xec, 0x09, 0x05, 0x0b, 0x00, 0x03, 0xd4, 0xc2, 0x96,
- 0x06, 0xd6, 0x7b, 0x95, 0x7a, 0x95, 0x4c, 0x02, 0xc1, 0x92, 0x59,
- 0x93, 0x59, 0x93, 0x01, 0xa5, 0x01, 0x98, 0x0c, 0xf5, 0x7b, 0x93,
- 0x09, 0x09, 0x01, 0x00, 0x06, 0x92, 0x09, 0xb3, 0xff, 0x00, 0x04,
- 0xd2, 0x5c, 0x93, 0x59, 0x93, 0x04, 0x94, 0x01, 0xa5, 0x03, 0x96,
- 0xc3, 0xd4, 0x11, 0x93, 0x97, 0xec, 0x4c, 0x02, 0x05, 0xd2, 0xc1,
- 0x92, 0x09, 0xb3, 0x00, 0xff, 0x7c, 0x95, 0x7a, 0x95, 0x02, 0xa3,
- 0x05, 0x98, 0xc4, 0xd2, 0x12, 0x95, 0x97, 0xec, 0x45, 0x04, 0x02,
- 0x97, 0xc3, 0x92, 0x09, 0xa3, 0x00, 0x01, 0xc2, 0xd2, 0x12, 0x95,
- 0x9b, 0xec, 0x0a, 0xb3, 0x08, 0x00, 0x40, 0x42, 0x02, 0x4e, 0x0f,
- 0x9f, 0x01, 0xf0, 0x12, 0x95, 0x97, 0xec, 0x4a, 0x04, 0x02, 0x99,
- 0xc4, 0x92, 0x01, 0x98, 0x0c, 0xf3, 0x7b, 0x93, 0x41, 0x02, 0x0f,
- 0x9f, 0x22, 0xf0, 0x43, 0x44, 0x02, 0x8e, 0x0f, 0x9f, 0x23, 0xf0,
- 0x11, 0x93, 0x97, 0xec, 0x42, 0x02, 0x0a, 0x05, 0xff, 0xff, 0xc1,
- 0xd4, 0x11, 0x93, 0x97, 0xec, 0x4a, 0x02, 0x12, 0x95, 0x60, 0x96,
- 0xc1, 0xd4, 0x12, 0x95, 0x97, 0xec, 0x4b, 0x04, 0x02, 0x97, 0xc3,
- 0x92, 0x09, 0xb3, 0x1f, 0xff, 0xc2, 0xd2, 0x12, 0x95, 0x97, 0xec,
- 0x4b, 0x04, 0x11, 0x93, 0x62, 0x96, 0x41, 0x93, 0x59, 0x93, 0x02,
- 0x99, 0xc4, 0xa2, 0xc2, 0xd2, 0xc5, 0x92, 0x19, 0xd3, 0x98, 0xec,
- 0x0a, 0x95, 0x0c, 0x02, 0x1a, 0xd5, 0x02, 0x80, 0x0f, 0x9f, 0x57,
- 0xf0, 0x09, 0x63, 0xfe, 0x7f, 0x01, 0x97, 0xc3, 0x94, 0x0a, 0xa5,
- 0x00, 0x04, 0xc1, 0xd4, 0x11, 0x93, 0x9f, 0xec, 0x09, 0xa3, 0x00,
- 0x01, 0x19, 0xd3, 0x9f, 0xec, 0x40, 0xf0, 0xdf, 0xee, 0x0f, 0x9f,
- 0x57, 0xf0, 0x11, 0x93, 0x94, 0xec, 0x41, 0x42, 0x02, 0x5e, 0x0f,
- 0x9f, 0x4c, 0xf0, 0x40, 0xf0, 0xdf, 0xee, 0x11, 0x93, 0x95, 0xec,
- 0x44, 0xb2, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x57, 0xf0, 0x48,
- 0x98, 0x1c, 0xd9, 0x02, 0x80, 0x11, 0x93, 0x91, 0xec, 0x41, 0x22,
- 0x0a, 0x95, 0x57, 0xf0, 0x88, 0xd4, 0x88, 0xdc, 0x91, 0x9a, 0x47,
- 0x00, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01, 0x00,
- 0x11, 0x93, 0x04, 0x82, 0x48, 0xb2, 0x40, 0x42, 0x02, 0x4e, 0x0f,
- 0x9f, 0x6e, 0xf0, 0x0a, 0x65, 0xfd, 0x7d, 0x02, 0x97, 0xc3, 0x92,
- 0x09, 0xb3, 0xff, 0xfe, 0xc2, 0xd2, 0x41, 0x92, 0x19, 0xd3, 0xbf,
- 0xec, 0x11, 0x93, 0x04, 0x82, 0x43, 0xb2, 0x12, 0x95, 0x03, 0x82,
- 0x02, 0xb3, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x95, 0xf0, 0x0a,
- 0xb3, 0x00, 0xff, 0x48, 0xa2, 0x19, 0xd3, 0x03, 0x82, 0x40, 0xf0,
- 0x82, 0xf3, 0x11, 0x93, 0xbf, 0xec, 0x41, 0x42, 0x02, 0x5e, 0x0f,
- 0x9f, 0x95, 0xf0, 0x11, 0x93, 0x07, 0x82, 0x11, 0x43, 0x03, 0xec,
- 0x02, 0x0e, 0x0f, 0x9f, 0x95, 0xf0, 0x11, 0x93, 0x03, 0x82, 0x09,
- 0xa3, 0x00, 0x01, 0x19, 0xd3, 0x03, 0x82, 0x40, 0x96, 0x1b, 0xd7,
- 0xbf, 0xec, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01,
- 0x00, 0x11, 0x93, 0x20, 0xbc, 0xc8, 0xd2, 0x40, 0xf0, 0xe9, 0xf0,
- 0x41, 0x00, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, 0x42, 0x20, 0x08,
- 0x0b, 0x01, 0x00, 0x0d, 0x03, 0x05, 0x00, 0x05, 0x94, 0x41, 0x02,
- 0xc1, 0x92, 0x01, 0x97, 0xc3, 0x96, 0xc2, 0xd6, 0x0a, 0x45, 0x00,
- 0x95, 0x02, 0x5e, 0x0f, 0x9f, 0xe6, 0xf0, 0xc1, 0x92, 0x41, 0xb2,
- 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0xe6, 0xf0, 0x11, 0x93, 0xc0,
- 0xec, 0x40, 0x42, 0x02, 0x5e, 0x0f, 0x9f, 0xe6, 0xf0, 0x41, 0x98,
- 0x1c, 0xd9, 0xc0, 0xec, 0x12, 0x95, 0x02, 0x80, 0x01, 0xd4, 0x40,
- 0xf0, 0xfe, 0xf1, 0x0b, 0x67, 0xfd, 0x7d, 0x03, 0x99, 0xc4, 0x92,
- 0x0c, 0x99, 0x96, 0x03, 0x1c, 0xd9, 0x06, 0x82, 0x41, 0x98, 0x1c,
- 0xd9, 0x02, 0x82, 0x42, 0x98, 0x1c, 0xd9, 0x05, 0x82, 0x0c, 0x69,
- 0x80, 0x7f, 0x1c, 0xd9, 0x00, 0xb0, 0x09, 0xa3, 0x00, 0x01, 0xc3,
- 0xd2, 0x01, 0x94, 0x0a, 0xb3, 0x04, 0x00, 0x40, 0x42, 0x02, 0x4e,
- 0x0f, 0x9f, 0xe4, 0xf0, 0x42, 0xa4, 0x1a, 0xd5, 0x02, 0x80, 0x42,
- 0x00, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, 0x42, 0x20, 0x08, 0x0b,
- 0x01, 0x00, 0x05, 0x92, 0xc5, 0xd2, 0x60, 0xb2, 0x40, 0x42, 0x02,
- 0x4e, 0x0f, 0x9f, 0xf6, 0xf0, 0x40, 0xf0, 0xd2, 0xf6, 0xc5, 0x94,
- 0x0a, 0xb3, 0x10, 0x00, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0xff,
- 0xf0, 0x40, 0xf0, 0xc0, 0xf5, 0xc5, 0x96, 0x0b, 0xb3, 0x40, 0x00,
- 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x08, 0xf1, 0x40, 0xf0, 0xfa,
- 0xf4, 0xc5, 0x94, 0x0a, 0xb3, 0x01, 0x00, 0x40, 0x42, 0x02, 0x4e,
- 0x0f, 0x9f, 0x70, 0xf1, 0x13, 0x97, 0x21, 0xbc, 0x01, 0xd6, 0x0b,
- 0xb3, 0x02, 0x00, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x1a, 0xf1,
- 0x40, 0xf0, 0x62, 0xfb, 0x01, 0x94, 0x0a, 0xb3, 0x04, 0x00, 0x40,
- 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x23, 0xf1, 0x40, 0xf0, 0x6c, 0xfb,
- 0x01, 0x96, 0x0b, 0xb3, 0x01, 0x00, 0x40, 0x42, 0x02, 0x4e, 0x0f,
- 0x9f, 0x4c, 0xf1, 0x40, 0xf0, 0xb0, 0xfa, 0x41, 0x92, 0x19, 0xd3,
- 0x73, 0xf7, 0x11, 0x93, 0x03, 0xec, 0x09, 0x43, 0x40, 0x00, 0x02,
- 0x5e, 0x0f, 0x9f, 0x39, 0xf1, 0x40, 0x94, 0x1a, 0xd5, 0x73, 0xf7,
- 0x11, 0x93, 0x00, 0xec, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x55,
- 0xf1, 0x11, 0x93, 0xc1, 0xec, 0x40, 0x42, 0x02, 0x5e, 0x0f, 0x9f,
- 0x55, 0xf1, 0x40, 0xf0, 0xe0, 0xf1, 0x41, 0x96, 0x1b, 0xd7, 0xc1,
- 0xec, 0x0f, 0x9f, 0x55, 0xf1, 0x01, 0x94, 0x0a, 0xb3, 0x08, 0x00,
- 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x55, 0xf1, 0x40, 0xf0, 0x7c,
- 0xfb, 0x01, 0x96, 0x0b, 0xb3, 0x10, 0x00, 0x40, 0x42, 0x02, 0x4e,
- 0x0f, 0x9f, 0x5e, 0xf1, 0x40, 0xf0, 0x87, 0xfb, 0x11, 0x93, 0x10,
- 0xec, 0x42, 0x42, 0x02, 0x5e, 0x0f, 0x9f, 0x67, 0xf1, 0x44, 0x92,
- 0x0f, 0x9f, 0x6b, 0xf1, 0x41, 0x42, 0x02, 0x5e, 0x0f, 0x9f, 0x6d,
- 0xf1, 0x19, 0xd3, 0x0b, 0xbc, 0x40, 0x94, 0x1a, 0xd5, 0x10, 0xec,
- 0xc5, 0x96, 0x0b, 0xb3, 0x80, 0x00, 0x40, 0x42, 0x02, 0x4e, 0x0f,
- 0x9f, 0xba, 0xf1, 0x11, 0x93, 0x28, 0xbc, 0x01, 0xd2, 0x09, 0xb3,
- 0x40, 0x00, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x82, 0xf1, 0x40,
- 0xf0, 0xb5, 0xf6, 0x01, 0x94, 0x0a, 0xb3, 0x02, 0x00, 0x40, 0x42,
- 0x02, 0x4e, 0x0f, 0x9f, 0x95, 0xf1, 0x40, 0xf0, 0x6d, 0xee, 0x40,
- 0xf0, 0x8f, 0xfb, 0x40, 0xf0, 0xc3, 0xf1, 0x40, 0x96, 0x1b, 0xd7,
- 0x00, 0xec, 0x41, 0x92, 0x19, 0xd3, 0x76, 0xf7, 0x01, 0x94, 0x0a,
- 0xb3, 0x04, 0x00, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0xb1, 0xf1,
- 0x40, 0xf0, 0x9e, 0xfb, 0x09, 0x63, 0x00, 0x44, 0x01, 0x97, 0xc3,
- 0x94, 0x48, 0xa4, 0xc1, 0xd4, 0x00, 0xee, 0x40, 0x92, 0x19, 0xd3,
- 0x12, 0x95, 0x19, 0xd3, 0x10, 0x95, 0x19, 0xd3, 0x02, 0x80, 0x19,
- 0xd3, 0x03, 0x82, 0x41, 0x92, 0x19, 0xd3, 0x76, 0xf7, 0x01, 0x94,
- 0x0a, 0xb3, 0x08, 0x00, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0xba,
- 0xf1, 0x40, 0xf0, 0xae, 0xfb, 0x0a, 0x65, 0x00, 0x44, 0x02, 0x97,
- 0xc3, 0x92, 0x44, 0xa2, 0xc2, 0xd2, 0x42, 0x00, 0x88, 0x98, 0x90,
- 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01, 0x00, 0x09, 0x63, 0x00, 0x40,
- 0x19, 0xd3, 0xf2, 0xbd, 0x0a, 0x65, 0xea, 0x43, 0x02, 0x97, 0xc3,
- 0x92, 0x44, 0xa2, 0xc2, 0xd2, 0x0a, 0x65, 0xe9, 0x43, 0x02, 0x97,
- 0xc3, 0x92, 0x09, 0xa3, 0x40, 0x00, 0xc2, 0xd2, 0x0a, 0x65, 0xeb,
- 0x43, 0x02, 0x97, 0xc3, 0x92, 0x09, 0xa3, 0xc0, 0x00, 0xc2, 0xd2,
- 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01, 0x00, 0x09,
- 0x63, 0x00, 0x80, 0x19, 0xd3, 0xf2, 0xbd, 0x0a, 0x65, 0xe8, 0x43,
- 0x02, 0x97, 0xc3, 0x92, 0x09, 0xa3, 0xc0, 0x00, 0xc2, 0xd2, 0x0a,
- 0x65, 0xeb, 0x43, 0x02, 0x97, 0xc3, 0x92, 0x09, 0xb3, 0xbf, 0xff,
- 0xc2, 0xd2, 0x0a, 0x65, 0xea, 0x43, 0x02, 0x97, 0xc3, 0x92, 0x09,
- 0xb3, 0xfb, 0xff, 0xc2, 0xd2, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda,
- 0x08, 0x0b, 0x01, 0x00, 0x09, 0x93, 0x00, 0x01, 0x19, 0xd3, 0x02,
- 0x80, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01, 0x00,
- 0x09, 0x93, 0x00, 0x09, 0x19, 0xd3, 0x02, 0x80, 0x40, 0xf0, 0xfe,
- 0xf1, 0x40, 0x92, 0x19, 0xd3, 0x94, 0xec, 0xc8, 0xd2, 0x09, 0x93,
- 0x91, 0xec, 0xc8, 0xd2, 0x40, 0xf0, 0xd0, 0xee, 0x42, 0x00, 0x88,
- 0x98, 0x90, 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01, 0x00, 0x40, 0xf0,
- 0xd8, 0xf4, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x2d, 0xf2, 0x0a,
- 0x65, 0xfe, 0x7f, 0x02, 0x97, 0xc3, 0x92, 0x44, 0xa2, 0xc2, 0xd2,
- 0x0f, 0x9f, 0x3a, 0xf2, 0x40, 0xf0, 0x3c, 0xf2, 0x40, 0x42, 0x02,
- 0x5e, 0x0f, 0x9f, 0x3a, 0xf2, 0xc8, 0xd2, 0x09, 0x93, 0x91, 0xec,
- 0xc8, 0xd2, 0x40, 0xf0, 0xd0, 0xee, 0x42, 0x00, 0x88, 0x98, 0x90,
- 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01, 0x00, 0x11, 0x93, 0xf1, 0xbd,
- 0x19, 0xd3, 0xb6, 0xec, 0x11, 0x93, 0xb4, 0xec, 0x40, 0x42, 0x02,
- 0x5e, 0x0f, 0x9f, 0x54, 0xf2, 0x09, 0x63, 0x00, 0x80, 0x01, 0x97,
- 0xc3, 0x94, 0x0a, 0x07, 0x07, 0x00, 0xc1, 0xd6, 0x0a, 0x05, 0x00,
- 0xa0, 0x1a, 0xd5, 0x96, 0xec, 0x11, 0x93, 0xb6, 0xec, 0x19, 0xd3,
- 0x01, 0x80, 0x0a, 0x65, 0xfe, 0x7f, 0x02, 0x97, 0xc3, 0x92, 0x41,
- 0xa2, 0xc2, 0xd2, 0x40, 0x92, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda,
- 0x41, 0x20, 0x08, 0x0b, 0x01, 0x00, 0x13, 0x97, 0xb4, 0xec, 0x40,
- 0x46, 0x02, 0x5e, 0x0f, 0x9f, 0xc3, 0xf2, 0x12, 0x95, 0x96, 0xec,
- 0x0a, 0x03, 0x07, 0x00, 0xc1, 0x92, 0xc2, 0xd2, 0x11, 0x93, 0x96,
- 0xec, 0x09, 0x05, 0x01, 0x00, 0x48, 0x02, 0xc1, 0x92, 0xc2, 0xd2,
- 0x11, 0x93, 0x96, 0xec, 0x4e, 0x02, 0xc1, 0x94, 0xc5, 0xd6, 0xc5,
- 0x92, 0x11, 0x07, 0x96, 0xec, 0x0b, 0x03, 0x0f, 0x00, 0xc1, 0x98,
- 0x46, 0x06, 0x7a, 0x93, 0x79, 0x93, 0x5c, 0x95, 0x5a, 0x95, 0x02,
- 0xa3, 0xc3, 0xd2, 0x04, 0x95, 0xc5, 0x96, 0x41, 0x06, 0xc5, 0xd6,
- 0x42, 0x46, 0x02, 0x9e, 0x0f, 0x9f, 0x7d, 0xf2, 0x11, 0x93, 0x96,
- 0xec, 0x09, 0x05, 0x05, 0x00, 0x41, 0x02, 0xc1, 0x92, 0xc2, 0xd2,
- 0x11, 0x93, 0x96, 0xec, 0xc1, 0x92, 0x09, 0xb5, 0x1f, 0x00, 0x43,
- 0x44, 0x02, 0x8e, 0x0f, 0x9f, 0xaa, 0xf2, 0x40, 0x44, 0x02, 0x4e,
- 0x0f, 0x9f, 0xab, 0xf2, 0x0a, 0x05, 0xff, 0xff, 0x0f, 0x9f, 0xab,
- 0xf2, 0x43, 0x94, 0x11, 0x93, 0x96, 0xec, 0x42, 0x02, 0xc1, 0xd4,
- 0x13, 0x97, 0x96, 0xec, 0x03, 0x93, 0xd1, 0x94, 0x7a, 0x95, 0x7a,
- 0x95, 0xc1, 0x92, 0x59, 0x93, 0x59, 0x93, 0x01, 0x05, 0x49, 0x06,
- 0xc3, 0x92, 0x7f, 0xb2, 0x01, 0x05, 0x1a, 0xd5, 0xb4, 0xec, 0x0a,
- 0x05, 0xf2, 0xff, 0x1a, 0xd5, 0x92, 0xec, 0x11, 0x93, 0x92, 0xec,
- 0x12, 0x95, 0xb6, 0xec, 0x02, 0x43, 0x02, 0x8e, 0x0f, 0x9f, 0x11,
- 0xf3, 0x02, 0x0e, 0x0f, 0x9f, 0xe4, 0xf2, 0x11, 0x93, 0x7a, 0xf7,
- 0x41, 0x02, 0x19, 0xd3, 0x7a, 0xf7, 0x11, 0x93, 0x79, 0xf7, 0x09,
- 0xa3, 0x80, 0x00, 0x19, 0xd3, 0x79, 0xf7, 0x09, 0x63, 0x00, 0x80,
- 0x01, 0x95, 0xc2, 0x94, 0x1a, 0xd5, 0xb5, 0xec, 0x40, 0x96, 0x1b,
- 0xd7, 0xb4, 0xec, 0x0f, 0x9f, 0x29, 0xf3, 0x11, 0x93, 0x03, 0x80,
- 0x09, 0xb3, 0x00, 0x40, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0xf6,
- 0xf2, 0x11, 0x93, 0xc0, 0xec, 0x40, 0x42, 0x02, 0x5e, 0x0f, 0x9f,
- 0xf6, 0xf2, 0x40, 0xf0, 0x3d, 0xf3, 0x0f, 0x9f, 0x2b, 0xf3, 0x41,
- 0x92, 0xc8, 0xd2, 0x0a, 0x95, 0x91, 0xec, 0xc8, 0xd4, 0x40, 0xf0,
- 0xd0, 0xee, 0x42, 0x00, 0x11, 0x93, 0xc0, 0xec, 0x40, 0x42, 0x02,
- 0x4e, 0x0f, 0x9f, 0x09, 0xf3, 0x42, 0x96, 0x1b, 0xd7, 0xc0, 0xec,
- 0x0f, 0x9f, 0x2b, 0xf3, 0x0a, 0x65, 0xfe, 0x7f, 0x02, 0x97, 0xc3,
- 0x92, 0x42, 0xa2, 0xc2, 0xd2, 0x0f, 0x9f, 0x2b, 0xf3, 0x12, 0x45,
- 0x03, 0xec, 0x02, 0x4e, 0x0f, 0x9f, 0x23, 0xf3, 0x11, 0x93, 0x7a,
- 0xf7, 0x41, 0x02, 0x19, 0xd3, 0x7a, 0xf7, 0x11, 0x93, 0x79, 0xf7,
- 0x09, 0xa3, 0x00, 0x08, 0x19, 0xd3, 0x79, 0xf7, 0x1a, 0xd5, 0x92,
- 0xec, 0x11, 0x93, 0x92, 0xec, 0x19, 0x25, 0x92, 0xec, 0x09, 0x63,
- 0x00, 0x80, 0x19, 0xd3, 0xf2, 0xbd, 0x41, 0x00, 0x88, 0x98, 0x90,
- 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01, 0x00, 0x40, 0xf0, 0x3d, 0xf3,
- 0x40, 0x92, 0xc8, 0xd2, 0x09, 0x93, 0x91, 0xec, 0xc8, 0xd2, 0x40,
- 0xf0, 0xd0, 0xee, 0x42, 0x00, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda,
- 0x08, 0x0b, 0x01, 0x00, 0x11, 0x93, 0x75, 0xf7, 0x40, 0x42, 0x02,
- 0x4e, 0x0f, 0x9f, 0x4d, 0xf3, 0x0a, 0x65, 0xbc, 0x69, 0x02, 0x97,
- 0xc3, 0x92, 0x09, 0x83, 0x00, 0x02, 0xc2, 0xd2, 0x11, 0x93, 0x03,
- 0x80, 0x09, 0xb3, 0x00, 0x40, 0x40, 0x42, 0x02, 0x5e, 0x0f, 0x9f,
- 0x60, 0xf3, 0x11, 0x93, 0x7a, 0xf7, 0x41, 0x02, 0x19, 0xd3, 0x7a,
- 0xf7, 0x11, 0x93, 0x79, 0xf7, 0x09, 0xa3, 0x00, 0x20, 0x19, 0xd3,
- 0x79, 0xf7, 0x11, 0x93, 0xb5, 0xec, 0x19, 0xd3, 0x04, 0x80, 0x12,
- 0x95, 0xb4, 0xec, 0x1a, 0xd5, 0x05, 0x80, 0x09, 0x63, 0x00, 0x80,
- 0x01, 0x97, 0xc3, 0x96, 0x1b, 0xd7, 0xb5, 0xec, 0x40, 0x94, 0x1a,
- 0xd5, 0xb4, 0xec, 0x19, 0xd3, 0xf2, 0xbd, 0x88, 0x98, 0x90, 0x9a,
- 0x88, 0xda, 0x08, 0x0b, 0x01, 0x00, 0x09, 0x93, 0x96, 0x03, 0x19,
- 0xd3, 0x06, 0x82, 0x09, 0x93, 0x00, 0x01, 0x19, 0xd3, 0x03, 0x82,
- 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, 0x47, 0x20, 0x08, 0x0b, 0x01,
- 0x00, 0x11, 0x93, 0x01, 0x82, 0xc5, 0xd2, 0x40, 0x94, 0x01, 0xd4,
- 0x13, 0x97, 0xb8, 0xec, 0x02, 0xd6, 0x03, 0x95, 0x0c, 0x99, 0xbb,
- 0xec, 0x04, 0x05, 0x13, 0x97, 0x03, 0xec, 0x01, 0x27, 0x02, 0x99,
- 0xc4, 0x92, 0x03, 0x03, 0xc2, 0xd2, 0x14, 0x99, 0xba, 0xec, 0x03,
- 0x09, 0x1c, 0xd9, 0xba, 0xec, 0x12, 0x95, 0x04, 0x82, 0x0a, 0xb3,
- 0x02, 0x00, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0xc6, 0xf4, 0x01,
- 0x92, 0x03, 0xd2, 0x0a, 0xa3, 0x02, 0x00, 0x19, 0xd3, 0x04, 0x82,
- 0x02, 0x96, 0x0b, 0x05, 0x01, 0x00, 0x1a, 0xd5, 0xb8, 0xec, 0xc5,
- 0x92, 0x43, 0x42, 0x02, 0x9e, 0x0f, 0x9f, 0xce, 0xf3, 0x42, 0x44,
- 0x02, 0x8e, 0x0f, 0x9f, 0xce, 0xf3, 0x11, 0x93, 0xbf, 0xec, 0x40,
- 0x42, 0x02, 0x5e, 0x0f, 0x9f, 0xce, 0xf3, 0x0c, 0x49, 0xd3, 0x08,
- 0x02, 0x8e, 0x0f, 0x9f, 0xce, 0xf3, 0x11, 0x63, 0x07, 0x82, 0x11,
- 0xa3, 0x07, 0x82, 0x71, 0x93, 0x79, 0x93, 0x79, 0x93, 0x79, 0x93,
- 0x03, 0xd2, 0xc5, 0x94, 0x0a, 0xb5, 0xfc, 0xff, 0x04, 0xd4, 0x03,
- 0x96, 0x40, 0x46, 0x02, 0x5e, 0x0f, 0x9f, 0xdd, 0xf3, 0x11, 0x93,
- 0xb8, 0xec, 0x41, 0x42, 0x02, 0x8e, 0x0f, 0x9f, 0xe4, 0xf3, 0xc5,
- 0x98, 0x0c, 0x03, 0xff, 0xff, 0x42, 0x42, 0x02, 0x8e, 0x0f, 0x9f,
- 0x0b, 0xf4, 0x0a, 0x95, 0xbb, 0xec, 0x42, 0x92, 0x19, 0xd3, 0xb9,
- 0xec, 0xc5, 0x96, 0x43, 0x46, 0x02, 0x9e, 0x0f, 0x9f, 0xfd, 0xf3,
- 0x0b, 0x07, 0xfc, 0xff, 0xc5, 0xd6, 0xd2, 0x98, 0x1c, 0xd9, 0xc8,
- 0xbc, 0xd2, 0x96, 0x1b, 0xd7, 0xca, 0xbc, 0x09, 0x03, 0xff, 0xff,
- 0x40, 0x42, 0x02, 0x5e, 0x0f, 0x9f, 0xe9, 0xf3, 0x19, 0xd3, 0xb9,
- 0xec, 0x40, 0x42, 0x02, 0x5e, 0x0f, 0x9f, 0x09, 0xf4, 0x0a, 0x05,
- 0xfe, 0xff, 0xca, 0xd2, 0xc2, 0xd2, 0x0f, 0x9f, 0x0b, 0xf4, 0x1a,
- 0xd5, 0x93, 0xec, 0x03, 0x98, 0x40, 0x48, 0x02, 0x5e, 0x0f, 0x9f,
- 0x38, 0xf4, 0x11, 0x93, 0xb8, 0xec, 0x41, 0x42, 0x02, 0x9e, 0x0f,
- 0x9f, 0x1b, 0xf4, 0x04, 0x94, 0x48, 0x44, 0x02, 0x4e, 0x0f, 0x9f,
- 0x26, 0xf4, 0x41, 0x42, 0x02, 0x5e, 0x0f, 0x9f, 0x38, 0xf4, 0x11,
- 0x93, 0x04, 0x82, 0x41, 0xb2, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f,
- 0x38, 0xf4, 0x41, 0x96, 0x01, 0xd6, 0x0a, 0x65, 0xbd, 0x43, 0x02,
- 0x99, 0xc4, 0x92, 0x09, 0xa3, 0x80, 0x00, 0xc2, 0xd2, 0x0a, 0x65,
- 0xe8, 0x43, 0x02, 0x97, 0xc3, 0x92, 0x09, 0xb3, 0xbf, 0xff, 0xc2,
- 0xd2, 0x0f, 0x9f, 0x97, 0xf4, 0xc5, 0x98, 0x43, 0x48, 0x02, 0x9e,
- 0x0f, 0x9f, 0x97, 0xf4, 0x4f, 0x96, 0x0c, 0xb3, 0x01, 0x00, 0x40,
- 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x45, 0xf4, 0x47, 0x96, 0x11, 0x93,
- 0xb7, 0xec, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x73, 0xf4, 0x11,
- 0x93, 0xb8, 0xec, 0x41, 0x42, 0x02, 0x5e, 0x0f, 0x9f, 0x73, 0xf4,
- 0x12, 0x95, 0x00, 0x82, 0x0a, 0x05, 0xff, 0xaf, 0x05, 0xd4, 0xc8,
- 0xd6, 0xc8, 0xd2, 0x40, 0xf0, 0x18, 0xf7, 0x42, 0x00, 0x05, 0x96,
- 0xc3, 0x94, 0x01, 0xb5, 0x40, 0x44, 0x02, 0x5e, 0x0f, 0x9f, 0x68,
- 0xf4, 0x11, 0x93, 0xba, 0xec, 0x4d, 0x42, 0x02, 0x8e, 0x0f, 0x9f,
- 0x73, 0xf4, 0x06, 0x98, 0x50, 0x98, 0x1c, 0xd9, 0xa2, 0xbc, 0x40,
- 0x98, 0x1c, 0xd9, 0xa2, 0xbc, 0x40, 0x92, 0x03, 0xd2, 0x0f, 0x9f,
- 0x9c, 0xf4, 0x03, 0x94, 0x40, 0x44, 0x02, 0x5e, 0x0f, 0x9f, 0x80,
- 0xf4, 0x0a, 0x65, 0x5e, 0x43, 0x02, 0x97, 0xc3, 0x92, 0x48, 0xa2,
- 0xc2, 0xd2, 0x0f, 0x9f, 0x9c, 0xf4, 0x11, 0x93, 0xb8, 0xec, 0x0c,
- 0x99, 0xbb, 0xec, 0x04, 0x03, 0x04, 0x96, 0x13, 0x25, 0x03, 0xec,
- 0xc1, 0xd4, 0x11, 0x93, 0xba, 0xec, 0x19, 0x05, 0xba, 0xec, 0x1b,
- 0xd7, 0x01, 0x82, 0x0a, 0x65, 0xfd, 0x7d, 0x02, 0x99, 0xc4, 0x92,
- 0x43, 0xa2, 0xc2, 0xd2, 0x41, 0x92, 0x01, 0xd2, 0x03, 0x94, 0x40,
- 0x44, 0x02, 0x5e, 0x0f, 0x9f, 0xb0, 0xf4, 0x11, 0x93, 0xb9, 0xec,
- 0x40, 0x42, 0x02, 0x5e, 0x0f, 0x9f, 0xa8, 0xf4, 0x19, 0xd3, 0xb8,
- 0xec, 0x19, 0xd3, 0xba, 0xec, 0x19, 0xd3, 0xbb, 0xec, 0x03, 0x96,
- 0x40, 0x46, 0x02, 0x5e, 0x0f, 0x9f, 0xb0, 0xf4, 0x41, 0x98, 0x1c,
- 0xd9, 0xb7, 0xec, 0x11, 0x93, 0xbf, 0xec, 0x41, 0x42, 0x02, 0x5e,
- 0x0f, 0x9f, 0xc1, 0xf4, 0x11, 0x93, 0x00, 0x82, 0x19, 0xd3, 0x02,
- 0x82, 0x0a, 0x65, 0xfd, 0x7d, 0x02, 0x97, 0xc3, 0x92, 0x09, 0xa3,
- 0x00, 0x01, 0xc2, 0xd2, 0x40, 0x98, 0x1c, 0xd9, 0xbf, 0xec, 0x0f,
- 0x9f, 0xc9, 0xf4, 0x01, 0x92, 0x19, 0xd3, 0xb7, 0xec, 0x01, 0x94,
- 0x40, 0x44, 0x02, 0x5e, 0x0f, 0x9f, 0xd5, 0xf4, 0x0a, 0x65, 0xea,
- 0x43, 0x02, 0x97, 0xc3, 0x92, 0x09, 0xb3, 0xfb, 0xff, 0xc2, 0xd2,
- 0x47, 0x00, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01,
- 0x00, 0x12, 0x95, 0x03, 0x80, 0x0a, 0xb3, 0x00, 0x40, 0x40, 0x42,
- 0x02, 0x4e, 0x0f, 0x9f, 0xf4, 0xf4, 0x0a, 0xb7, 0x00, 0x08, 0x40,
- 0x46, 0x02, 0x5e, 0x0f, 0x9f, 0xf7, 0xf4, 0x11, 0x93, 0x03, 0xec,
- 0x41, 0x02, 0x09, 0xb3, 0xfe, 0xff, 0x12, 0x95, 0x07, 0x80, 0x01,
- 0x45, 0x02, 0x8e, 0x0f, 0x9f, 0xf7, 0xf4, 0x41, 0x92, 0x0f, 0x9f,
- 0xf8, 0xf4, 0x40, 0x92, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, 0x41,
- 0x20, 0x08, 0x0b, 0x01, 0x00, 0x0a, 0x65, 0xe9, 0x43, 0x02, 0x97,
- 0xc3, 0x92, 0x09, 0xa3, 0x40, 0x00, 0xc2, 0xd2, 0x13, 0x97, 0x6e,
- 0xec, 0x0b, 0x47, 0xa0, 0x00, 0x02, 0x5e, 0x0f, 0x9f, 0x23, 0xf5,
- 0x09, 0x63, 0x08, 0x43, 0x0a, 0x65, 0xff, 0x5f, 0x01, 0x99, 0xc4,
- 0xd4, 0x0a, 0x95, 0x9b, 0xec, 0xd2, 0x96, 0x1b, 0xd7, 0xfa, 0xbc,
- 0xd2, 0x96, 0xc4, 0xd6, 0xd2, 0x98, 0x1c, 0xd9, 0xfa, 0xbc, 0xd2,
- 0x96, 0xc1, 0xd6, 0xc2, 0x94, 0x1a, 0xd5, 0xfa, 0xbc, 0x0f, 0x9f,
- 0x61, 0xf5, 0x0c, 0x69, 0xff, 0x6f, 0x1c, 0xd9, 0xf8, 0xbc, 0x0b,
- 0x47, 0x10, 0x95, 0x02, 0x5e, 0x0f, 0x9f, 0x3b, 0xf5, 0x0a, 0x95,
- 0x6f, 0xec, 0x09, 0x63, 0x06, 0x43, 0x01, 0x99, 0xc4, 0xd6, 0xd2,
- 0x96, 0x1b, 0xd7, 0xf8, 0xbc, 0x0c, 0x69, 0xee, 0x6a, 0xc1, 0xd8,
- 0xc2, 0x94, 0x1a, 0xd5, 0xf8, 0xbc, 0x40, 0x92, 0xc5, 0xd2, 0x11,
- 0x43, 0xc2, 0xec, 0x02, 0x0e, 0x0f, 0x9f, 0x5e, 0xf5, 0xc5, 0x94,
- 0x0a, 0x03, 0x71, 0xec, 0xc1, 0x94, 0x1a, 0xd5, 0xfa, 0xbc, 0x11,
- 0x93, 0xc0, 0xec, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x50, 0xf5,
- 0x0a, 0x95, 0x6f, 0xec, 0xc8, 0xd4, 0x40, 0xf0, 0x39, 0xf7, 0x19,
- 0xd3, 0xf8, 0xbc, 0x41, 0x00, 0xc5, 0x96, 0x41, 0x06, 0xc5, 0xd6,
- 0x13, 0x47, 0xc2, 0xec, 0x02, 0x1e, 0x0f, 0x9f, 0x42, 0xf5, 0x40,
- 0x98, 0x1c, 0xd9, 0xfa, 0xbc, 0x40, 0x92, 0x19, 0xd3, 0x6e, 0xec,
- 0x19, 0xd3, 0xc2, 0xec, 0x0a, 0x65, 0x52, 0x43, 0x02, 0x97, 0xc3,
- 0x92, 0x48, 0xa2, 0xc2, 0xd2, 0x0a, 0x65, 0xeb, 0x43, 0x02, 0x99,
- 0xc4, 0x92, 0x09, 0xb3, 0xbf, 0xff, 0xc2, 0xd2, 0x41, 0x00, 0x88,
- 0x98, 0x90, 0x9a, 0x88, 0xda, 0x43, 0x20, 0x08, 0x0b, 0x01, 0x00,
- 0x06, 0x92, 0x01, 0xd2, 0x0a, 0x65, 0xf0, 0x6a, 0x0b, 0x97, 0x6f,
- 0xec, 0x02, 0x99, 0xc4, 0x98, 0xd3, 0xd8, 0x02, 0xd6, 0x0a, 0x03,
- 0x02, 0x00, 0x01, 0x97, 0xc3, 0x98, 0x02, 0x96, 0xc3, 0xd8, 0x01,
- 0x96, 0xc1, 0xd6, 0x1a, 0xd5, 0x6e, 0xec, 0xc5, 0x98, 0x14, 0x99,
- 0x6f, 0xec, 0xc2, 0xd8, 0x43, 0x00, 0x88, 0x98, 0x90, 0x9a, 0x88,
- 0xda, 0x08, 0x0b, 0x01, 0x00, 0x40, 0x92, 0xc8, 0xd2, 0x40, 0xf0,
- 0x76, 0xf5, 0x41, 0x00, 0x11, 0x93, 0xc0, 0xec, 0x40, 0x42, 0x02,
- 0x4e, 0x0f, 0x9f, 0xb0, 0xf5, 0x42, 0x42, 0x02, 0x5e, 0x0f, 0x9f,
- 0xad, 0xf5, 0x0a, 0x65, 0xfe, 0x7f, 0x02, 0x97, 0xc3, 0x92, 0x42,
- 0xa2, 0xc2, 0xd2, 0x40, 0x92, 0x19, 0xd3, 0xc0, 0xec, 0x0a, 0x65,
- 0xeb, 0x43, 0x02, 0x97, 0xc3, 0x92, 0x09, 0xa3, 0xc0, 0x00, 0xc2,
- 0xd2, 0x0a, 0x65, 0xe9, 0x43, 0x02, 0x97, 0xc3, 0x92, 0x09, 0xb3,
- 0xbf, 0xff, 0xc2, 0xd2, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, 0x63,
- 0x20, 0x08, 0x0b, 0x01, 0x00, 0x11, 0x93, 0xaf, 0xbc, 0x47, 0xb2,
- 0x59, 0x95, 0x5a, 0x95, 0x12, 0xa5, 0xbf, 0xbc, 0x0a, 0xb3, 0x01,
- 0x00, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0xd2, 0xf5, 0x41, 0x04,
- 0x05, 0x93, 0x40, 0x96, 0x20, 0xd6, 0x62, 0x97, 0x0f, 0x9f, 0xe1,
- 0xf5, 0x14, 0x99, 0xfc, 0xbc, 0xd1, 0xd8, 0x14, 0x99, 0xfe, 0xbc,
- 0xd1, 0xd8, 0x20, 0x98, 0x42, 0x08, 0x20, 0xd8, 0x20, 0x98, 0x03,
- 0x49, 0x02, 0x1e, 0x0f, 0x9f, 0xd8, 0xf5, 0xc5, 0x92, 0x62, 0x42,
- 0x02, 0x4e, 0x0f, 0x9f, 0xfa, 0xf5, 0x02, 0x8e, 0x0f, 0x9f, 0xf4,
- 0xf5, 0x61, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x1e, 0xf6, 0x0f, 0x9f,
- 0x4b, 0xf6, 0x63, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x41, 0xf6, 0x0f,
- 0x9f, 0x4b, 0xf6, 0x0d, 0x03, 0x01, 0x00, 0x0c, 0x99, 0x71, 0xec,
- 0x0b, 0x05, 0xff, 0xff, 0x40, 0x96, 0x0f, 0x9f, 0x07, 0xf6, 0xd1,
- 0x96, 0xd4, 0xd6, 0x20, 0x96, 0x41, 0x06, 0x20, 0xd6, 0x02, 0x47,
- 0x02, 0x1e, 0x0f, 0x9f, 0x03, 0xf6, 0x1a, 0xd5, 0xc2, 0xec, 0x0a,
- 0x65, 0xeb, 0x43, 0x02, 0x99, 0xc4, 0x92, 0x09, 0xa3, 0xc0, 0x00,
- 0xc2, 0xd2, 0x0a, 0x65, 0xe9, 0x43, 0x02, 0x97, 0xc3, 0x92, 0x09,
- 0xb3, 0xbf, 0xff, 0xc2, 0xd2, 0x0f, 0x9f, 0x4b, 0xf6, 0x0a, 0x03,
- 0xfe, 0xff, 0x61, 0x95, 0x40, 0x98, 0x20, 0xd8, 0x02, 0x49, 0x02,
- 0x0e, 0x0f, 0x9f, 0x4b, 0xf6, 0x0d, 0x03, 0x01, 0x00, 0x21, 0xd2,
- 0x20, 0x92, 0x05, 0x03, 0x42, 0x02, 0xc8, 0xd2, 0x21, 0x96, 0xc3,
- 0x92, 0x42, 0x06, 0x21, 0xd6, 0xc8, 0xd2, 0x22, 0xd4, 0x40, 0xf0,
- 0xa2, 0xf0, 0x42, 0x00, 0x20, 0x98, 0x42, 0x08, 0x20, 0xd8, 0x22,
- 0x94, 0x02, 0x49, 0x02, 0x1e, 0x0f, 0x9f, 0x2a, 0xf6, 0x0f, 0x9f,
- 0x4b, 0xf6, 0x0d, 0x03, 0x03, 0x00, 0xc8, 0xd2, 0x02, 0x92, 0xc8,
- 0xd2, 0x01, 0x96, 0xc8, 0xd6, 0x40, 0xf0, 0x4e, 0xf6, 0x43, 0x00,
- 0x63, 0x00, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, 0x45, 0x20, 0x08,
- 0x0b, 0x01, 0x00, 0x0d, 0x03, 0x08, 0x00, 0x08, 0x94, 0xc5, 0xd4,
- 0x09, 0x05, 0x01, 0x00, 0xc2, 0x94, 0x03, 0xd4, 0x42, 0x02, 0xc1,
- 0x92, 0x01, 0xd2, 0x02, 0x97, 0xc5, 0x94, 0x0a, 0x83, 0xff, 0xff,
- 0x11, 0xb3, 0x2c, 0x93, 0x09, 0xb3, 0xfb, 0xff, 0x19, 0xd3, 0x2c,
- 0x93, 0x03, 0x92, 0x40, 0x42, 0x02, 0x4e, 0x0f, 0x9f, 0x81, 0xf6,
- 0x01, 0x94, 0xd2, 0x92, 0x19, 0xd3, 0x2c, 0x93, 0x01, 0xd4, 0x02,
- 0x94, 0x12, 0x95, 0x2c, 0x93, 0x44, 0xa4, 0x1a, 0xd5, 0x2c, 0x93,
- 0x0a, 0xb5, 0xfb, 0xff, 0x1a, 0xd5, 0x2c, 0x93, 0x0b, 0x07, 0xff,
- 0xff, 0x40, 0x46, 0x02, 0x5e, 0x0f, 0x9f, 0x6c, 0xf6, 0x09, 0x63,
- 0xd4, 0x6c, 0x01, 0x95, 0xc2, 0x96, 0xc5, 0x94, 0x02, 0xa7, 0xc1,
- 0xd6, 0x03, 0x92, 0x54, 0x42, 0x02, 0x5e, 0x0f, 0x9f, 0x91, 0xf6,
- 0x0a, 0x83, 0xff, 0xff, 0x1b, 0xb3, 0x2c, 0x93, 0x45, 0x00, 0x88,
- 0x98, 0x90, 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01, 0x00, 0x09, 0x63,
- 0x00, 0x40, 0x19, 0xd3, 0xf2, 0xbd, 0x40, 0xf0, 0xd8, 0xf4, 0x40,
- 0x42, 0x02, 0x5e, 0x0f, 0x9f, 0xa5, 0xf6, 0x40, 0xf0, 0x3c, 0xf2,
- 0x0f, 0x9f, 0xb3, 0xf6, 0x40, 0x96, 0xc8, 0xd6, 0x09, 0x93, 0x91,
- 0xec, 0xc8, 0xd2, 0x40, 0xf0, 0xd0, 0xee, 0x0a, 0x65, 0xfe, 0x7f,
- 0x02, 0x97, 0xc3, 0x92, 0x44, 0xa2, 0xc2, 0xd2, 0x42, 0x00, 0x88,
- 0x98, 0x90, 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01, 0x00, 0x0a, 0x65,
- 0xe8, 0x43, 0x02, 0x97, 0xc3, 0x92, 0x09, 0xa3, 0x40, 0x00, 0xc2,
- 0xd2, 0x0a, 0x65, 0xea, 0x43, 0x02, 0x97, 0xc3, 0x92, 0x09, 0xb3,
- 0xfb, 0xff, 0xc2, 0xd2, 0x40, 0x92, 0x19, 0xd3, 0x2d, 0xbc, 0x0a,
- 0x65, 0xd8, 0x43, 0x02, 0x97, 0xc3, 0x92, 0x09, 0xb3, 0xbf, 0xff,
- 0xc2, 0xd2, 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01,
- 0x00, 0x09, 0x63, 0xea, 0x43, 0x01, 0x97, 0xc3, 0x94, 0x44, 0xa4,
- 0xc1, 0xd4, 0x11, 0x93, 0xb9, 0xec, 0x40, 0x42, 0x02, 0x4e, 0x0f,
- 0x9f, 0x0c, 0xf7, 0x12, 0x95, 0x93, 0xec, 0x0b, 0x67, 0x36, 0x43,
- 0xd2, 0x98, 0x1c, 0xd9, 0xc8, 0xbc, 0xd2, 0x98, 0x03, 0x93, 0xc1,
- 0xd8, 0x11, 0x93, 0xb9, 0xec, 0x09, 0x03, 0xff, 0xff, 0x19, 0xd3,
- 0xb9, 0xec, 0x40, 0x42, 0x02, 0x5e, 0x0f, 0x9f, 0xe5, 0xf6, 0x19,
- 0xd3, 0xb8, 0xec, 0x19, 0xd3, 0xba, 0xec, 0x0a, 0x05, 0xfe, 0xff,
- 0xca, 0xd2, 0xca, 0xd2, 0xc2, 0xd2, 0x0a, 0x65, 0x5e, 0x43, 0x02,
- 0x97, 0xc3, 0x92, 0x48, 0xa2, 0xc2, 0xd2, 0x0a, 0x65, 0xea, 0x43,
- 0x02, 0x99, 0xc4, 0x92, 0x09, 0xb3, 0xfb, 0xff, 0x0f, 0x9f, 0x15,
- 0xf7, 0x11, 0x93, 0x03, 0xec, 0x19, 0xd3, 0x01, 0x82, 0x0a, 0x65,
- 0xfd, 0x7d, 0x02, 0x97, 0xc3, 0x92, 0x43, 0xa2, 0xc2, 0xd2, 0x88,
- 0x98, 0x90, 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01, 0x00, 0x03, 0x92,
- 0x04, 0x96, 0x0d, 0x5e, 0x50, 0x46, 0x02, 0x0e, 0x40, 0x92, 0x09,
- 0xee, 0x44, 0x46, 0x04, 0x0e, 0x59, 0x93, 0x44, 0x26, 0x04, 0x5e,
- 0x46, 0xee, 0x41, 0x93, 0x41, 0x26, 0x43, 0x4e, 0x88, 0x98, 0x90,
- 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01, 0x00, 0x40, 0xf0, 0xb1, 0xfe,
- 0x88, 0x98, 0x90, 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01, 0x00, 0x88,
- 0x98, 0x90, 0x9a, 0x88, 0xda, 0x08, 0x0b, 0x01, 0x00, 0x03, 0x94,
- 0x1a, 0xd5, 0x40, 0xf7, 0x11, 0x93, 0x00, 0x90, 0x88, 0x98, 0x90,
- 0x9a, 0x1d, 0x00, 0x1a, 0x00, 0x03, 0x00, 0x03, 0x00, 0x18, 0x00,
- 0x19, 0x00, 0x1a, 0x00, 0x1b, 0x00, 0x16, 0x00, 0x21, 0x00, 0x12,
- 0x00, 0x09, 0x00, 0x13, 0x00, 0x19, 0x00, 0x19, 0x00, 0x19, 0x00,
- 0x21, 0x00, 0x2d, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x7e, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf2, 0x6b, 0xf7, 0x00, 0x00,
- 0x1c, 0xf2, 0x6b, 0xf7, 0x00, 0x00, 0x61, 0xf2, 0x68, 0xf7, 0x6f,
- 0xf7, 0x00, 0x00, 0x2e, 0xf3, 0x6b, 0xf7, 0x25, 0x47, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00
-};
diff --git a/sys/dev/usb/if_zydreg.h b/sys/dev/usb/if_zydreg.h
deleted file mode 100644
index feae22f..0000000
--- a/sys/dev/usb/if_zydreg.h
+++ /dev/null
@@ -1,1322 +0,0 @@
-/* $OpenBSD: if_zydreg.h,v 1.19 2006/11/30 19:28:07 damien Exp $ */
-/* $NetBSD: if_zydreg.h,v 1.2 2007/06/16 11:18:45 kiyohara Exp $ */
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 2006 by Damien Bergamini <damien.bergamini@free.fr>
- * Copyright (c) 2006 by Florian Stoehr <ich@florian-stoehr.de>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * ZyDAS ZD1211/ZD1211B USB WLAN driver.
- */
-
-#define ZYD_CR_GPI_EN 0x9418
-#define ZYD_CR_RADIO_PD 0x942c
-#define ZYD_CR_RF2948_PD 0x942c
-#define ZYD_CR_EN_PS_MANUAL_AGC 0x943c
-#define ZYD_CR_CONFIG_PHILIPS 0x9440
-#define ZYD_CR_I2C_WRITE 0x9444
-#define ZYD_CR_SA2400_SER_RP 0x9448
-#define ZYD_CR_RADIO_PE 0x9458
-#define ZYD_CR_RST_BUS_MASTER 0x945c
-#define ZYD_CR_RFCFG 0x9464
-#define ZYD_CR_HSTSCHG 0x946c
-#define ZYD_CR_PHY_ON 0x9474
-#define ZYD_CR_RX_DELAY 0x9478
-#define ZYD_CR_RX_PE_DELAY 0x947c
-#define ZYD_CR_GPIO_1 0x9490
-#define ZYD_CR_GPIO_2 0x9494
-#define ZYD_CR_EnZYD_CRyBufMux 0x94a8
-#define ZYD_CR_PS_CTRL 0x9500
-#define ZYD_CR_ADDA_PWR_DWN 0x9504
-#define ZYD_CR_ADDA_MBIAS_WT 0x9508
-#define ZYD_CR_INTERRUPT 0x9510
-#define ZYD_CR_MAC_PS_STATE 0x950c
-#define ZYD_CR_ATIM_WND_PERIOD 0x951c
-#define ZYD_CR_BCN_INTERVAL 0x9520
-#define ZYD_CR_PRE_TBTT 0x9524
-
-/*
- * MAC registers.
- */
-#define ZYD_MAC_MACADRL 0x9610 /* MAC address (low) */
-#define ZYD_MAC_MACADRH 0x9614 /* MAC address (high) */
-#define ZYD_MAC_BSSADRL 0x9618 /* BSS address (low) */
-#define ZYD_MAC_BSSADRH 0x961c /* BSS address (high) */
-#define ZYD_MAC_BCNCFG 0x9620 /* BCN configuration */
-#define ZYD_MAC_GHTBL 0x9624 /* Group hash table (low) */
-#define ZYD_MAC_GHTBH 0x9628 /* Group hash table (high) */
-#define ZYD_MAC_RX_TIMEOUT 0x962c /* Rx timeout value */
-#define ZYD_MAC_BAS_RATE 0x9630 /* Basic rate setting */
-#define ZYD_MAC_MAN_RATE 0x9634 /* Mandatory rate setting */
-#define ZYD_MAC_RTSCTSRATE 0x9638 /* RTS CTS rate */
-#define ZYD_MAC_BACKOFF_PROTECT 0x963c /* Backoff protection */
-#define ZYD_MAC_RX_THRESHOLD 0x9640 /* Rx threshold */
-#define ZYD_MAC_TX_PE_CONTROL 0x9644 /* Tx_PE control */
-#define ZYD_MAC_AFTER_PNP 0x9648 /* After PnP */
-#define ZYD_MAC_RX_PE_DELAY 0x964c /* Rx_pe delay */
-#define ZYD_MAC_RX_ADDR2_L 0x9650 /* RX address2 (low) */
-#define ZYD_MAC_RX_ADDR2_H 0x9654 /* RX address2 (high) */
-#define ZYD_MAC_SIFS_ACK_TIME 0x9658 /* Dynamic SIFS ack time */
-#define ZYD_MAC_PHY_DELAY 0x9660 /* PHY delay */
-#define ZYD_MAC_PHY_DELAY2 0x966c /* PHY delay */
-#define ZYD_MAC_BCNFIFO 0x9670 /* Beacon FIFO I/O port */
-#define ZYD_MAC_SNIFFER 0x9674 /* Sniffer on/off */
-#define ZYD_MAC_ENCRYPTION_TYPE 0x9678 /* Encryption type */
-#define ZYD_MAC_RETRY 0x967c /* Retry time */
-#define ZYD_MAC_MISC 0x9680 /* Misc */
-#define ZYD_MAC_STMACHINESTAT 0x9684 /* State machine status */
-#define ZYD_MAC_TX_UNDERRUN_CNT 0x9688 /* TX underrun counter */
-#define ZYD_MAC_RXFILTER 0x968c /* Send to host settings */
-#define ZYD_MAC_ACK_EXT 0x9690 /* Acknowledge extension */
-#define ZYD_MAC_BCNFIFOST 0x9694 /* BCN FIFO set and status */
-#define ZYD_MAC_DIFS_EIFS_SIFS 0x9698 /* DIFS, EIFS & SIFS settings */
-#define ZYD_MAC_RX_TIMEOUT_CNT 0x969c /* RX timeout count */
-#define ZYD_MAC_RX_TOTAL_FRAME 0x96a0 /* RX total frame count */
-#define ZYD_MAC_RX_CRC32_CNT 0x96a4 /* RX CRC32 frame count */
-#define ZYD_MAC_RX_CRC16_CNT 0x96a8 /* RX CRC16 frame count */
-#define ZYD_MAC_RX_UDEC 0x96ac /* RX unicast decr. error count */
-#define ZYD_MAC_RX_OVERRUN_CNT 0x96b0 /* RX FIFO overrun count */
-#define ZYD_MAC_RX_MDEC 0x96bc /* RX multicast decr. err. cnt. */
-#define ZYD_MAC_NAV_TCR 0x96c4 /* NAV timer count read */
-#define ZYD_MAC_BACKOFF_ST_RD 0x96c8 /* Backoff status read */
-#define ZYD_MAC_DM_RETRY_CNT_RD 0x96cc /* DM retry count read */
-#define ZYD_MAC_RX_ACR 0x96d0 /* RX arbitration count read */
-#define ZYD_MAC_TX_CCR 0x96d4 /* Tx complete count read */
-#define ZYD_MAC_TCB_ADDR 0x96e8 /* Current PCI process TCP addr */
-#define ZYD_MAC_RCB_ADDR 0x96ec /* Next RCB address */
-#define ZYD_MAC_CONT_WIN_LIMIT 0x96f0 /* Contention window limit */
-#define ZYD_MAC_TX_PKT 0x96f4 /* Tx total packet count read */
-#define ZYD_MAC_DL_CTRL 0x96f8 /* Download control */
-#define ZYD_MAC_CAM_MODE 0x9700 /* CAM: Continuous Access Mode */
-#define ZYD_MACB_TXPWR_CTL1 0x9b00
-#define ZYD_MACB_TXPWR_CTL2 0x9b04
-#define ZYD_MACB_TXPWR_CTL3 0x9b08
-#define ZYD_MACB_TXPWR_CTL4 0x9b0c
-#define ZYD_MACB_AIFS_CTL1 0x9b10
-#define ZYD_MACB_AIFS_CTL2 0x9b14
-#define ZYD_MACB_TXOP 0x9b20
-#define ZYD_MACB_MAX_RETRY 0x9b28
-
-/*
- * Miscellanous registers.
- */
-#define ZYD_FIRMWARE_START_ADDR 0xee00
-#define ZYD_FIRMWARE_BASE_ADDR 0xee1d /* Firmware base address */
-
-/*
- * EEPROM registers.
- */
-#define ZYD_EEPROM_START_HEAD 0xf800 /* EEPROM start */
-#define ZYD_EEPROM_SUBID 0xf817
-#define ZYD_EEPROM_POD 0xf819
-#define ZYD_EEPROM_MAC_ADDR_P1 0xf81b /* Part 1 of the MAC address */
-#define ZYD_EEPROM_MAC_ADDR_P2 0xf81d /* Part 2 of the MAC address */
-#define ZYD_EEPROM_PWR_CAL 0xf81f /* Calibration */
-#define ZYD_EEPROM_PWR_INT 0xf827 /* Calibration */
-#define ZYD_EEPROM_ALLOWEDCHAN 0xf82f /* Allowed CH mask, 1 bit each */
-#define ZYD_EEPROM_DEVICE_VER 0xf837 /* Device version */
-#define ZYD_EEPROM_PHY_REG 0xf83c /* PHY registers */
-#define ZYD_EEPROM_36M_CAL 0xf83f /* Calibration */
-#define ZYD_EEPROM_11A_INT 0xf847 /* Interpolation */
-#define ZYD_EEPROM_48M_CAL 0xf84f /* Calibration */
-#define ZYD_EEPROM_48M_INT 0xf857 /* Interpolation */
-#define ZYD_EEPROM_54M_CAL 0xf85f /* Calibration */
-#define ZYD_EEPROM_54M_INT 0xf867 /* Interpolation */
-
-/*
- * Firmware registers offsets (relative to fwbase).
- */
-#define ZYD_FW_FIRMWARE_REV 0x0000 /* Firmware version */
-#define ZYD_FW_USB_SPEED 0x0001 /* USB speed (!=0 if highspeed) */
-#define ZYD_FW_FIX_TX_RATE 0x0002 /* Fixed TX rate */
-#define ZYD_FW_LINK_STATUS 0x0003
-#define ZYD_FW_SOFT_RESET 0x0004
-#define ZYD_FW_FLASH_CHK 0x0005
-
-/* possible flags for register ZYD_FW_LINK_STATUS */
-#define ZYD_LED1 (1 << 8)
-#define ZYD_LED2 (1 << 9)
-
-/*
- * RF IDs.
- */
-#define ZYD_RF_UW2451 0x2 /* not supported yet */
-#define ZYD_RF_UCHIP 0x3 /* not supported yet */
-#define ZYD_RF_AL2230 0x4
-#define ZYD_RF_AL7230B 0x5
-#define ZYD_RF_THETA 0x6 /* not supported yet */
-#define ZYD_RF_AL2210 0x7
-#define ZYD_RF_MAXIM_NEW 0x8
-#define ZYD_RF_GCT 0x9
-#define ZYD_RF_AL2230S 0xa /* not supported yet */
-#define ZYD_RF_RALINK 0xb /* not supported yet */
-#define ZYD_RF_INTERSIL 0xc /* not supported yet */
-#define ZYD_RF_RFMD 0xd
-#define ZYD_RF_MAXIM_NEW2 0xe
-#define ZYD_RF_PHILIPS 0xf /* not supported yet */
-
-/*
- * PHY registers (8 bits, not documented).
- */
-#define ZYD_CR0 0x9000
-#define ZYD_CR1 0x9004
-#define ZYD_CR2 0x9008
-#define ZYD_CR3 0x900c
-#define ZYD_CR5 0x9010
-#define ZYD_CR6 0x9014
-#define ZYD_CR7 0x9018
-#define ZYD_CR8 0x901c
-#define ZYD_CR4 0x9020
-#define ZYD_CR9 0x9024
-#define ZYD_CR10 0x9028
-#define ZYD_CR11 0x902c
-#define ZYD_CR12 0x9030
-#define ZYD_CR13 0x9034
-#define ZYD_CR14 0x9038
-#define ZYD_CR15 0x903c
-#define ZYD_CR16 0x9040
-#define ZYD_CR17 0x9044
-#define ZYD_CR18 0x9048
-#define ZYD_CR19 0x904c
-#define ZYD_CR20 0x9050
-#define ZYD_CR21 0x9054
-#define ZYD_CR22 0x9058
-#define ZYD_CR23 0x905c
-#define ZYD_CR24 0x9060
-#define ZYD_CR25 0x9064
-#define ZYD_CR26 0x9068
-#define ZYD_CR27 0x906c
-#define ZYD_CR28 0x9070
-#define ZYD_CR29 0x9074
-#define ZYD_CR30 0x9078
-#define ZYD_CR31 0x907c
-#define ZYD_CR32 0x9080
-#define ZYD_CR33 0x9084
-#define ZYD_CR34 0x9088
-#define ZYD_CR35 0x908c
-#define ZYD_CR36 0x9090
-#define ZYD_CR37 0x9094
-#define ZYD_CR38 0x9098
-#define ZYD_CR39 0x909c
-#define ZYD_CR40 0x90a0
-#define ZYD_CR41 0x90a4
-#define ZYD_CR42 0x90a8
-#define ZYD_CR43 0x90ac
-#define ZYD_CR44 0x90b0
-#define ZYD_CR45 0x90b4
-#define ZYD_CR46 0x90b8
-#define ZYD_CR47 0x90bc
-#define ZYD_CR48 0x90c0
-#define ZYD_CR49 0x90c4
-#define ZYD_CR50 0x90c8
-#define ZYD_CR51 0x90cc
-#define ZYD_CR52 0x90d0
-#define ZYD_CR53 0x90d4
-#define ZYD_CR54 0x90d8
-#define ZYD_CR55 0x90dc
-#define ZYD_CR56 0x90e0
-#define ZYD_CR57 0x90e4
-#define ZYD_CR58 0x90e8
-#define ZYD_CR59 0x90ec
-#define ZYD_CR60 0x90f0
-#define ZYD_CR61 0x90f4
-#define ZYD_CR62 0x90f8
-#define ZYD_CR63 0x90fc
-#define ZYD_CR64 0x9100
-#define ZYD_CR65 0x9104
-#define ZYD_CR66 0x9108
-#define ZYD_CR67 0x910c
-#define ZYD_CR68 0x9110
-#define ZYD_CR69 0x9114
-#define ZYD_CR70 0x9118
-#define ZYD_CR71 0x911c
-#define ZYD_CR72 0x9120
-#define ZYD_CR73 0x9124
-#define ZYD_CR74 0x9128
-#define ZYD_CR75 0x912c
-#define ZYD_CR76 0x9130
-#define ZYD_CR77 0x9134
-#define ZYD_CR78 0x9138
-#define ZYD_CR79 0x913c
-#define ZYD_CR80 0x9140
-#define ZYD_CR81 0x9144
-#define ZYD_CR82 0x9148
-#define ZYD_CR83 0x914c
-#define ZYD_CR84 0x9150
-#define ZYD_CR85 0x9154
-#define ZYD_CR86 0x9158
-#define ZYD_CR87 0x915c
-#define ZYD_CR88 0x9160
-#define ZYD_CR89 0x9164
-#define ZYD_CR90 0x9168
-#define ZYD_CR91 0x916c
-#define ZYD_CR92 0x9170
-#define ZYD_CR93 0x9174
-#define ZYD_CR94 0x9178
-#define ZYD_CR95 0x917c
-#define ZYD_CR96 0x9180
-#define ZYD_CR97 0x9184
-#define ZYD_CR98 0x9188
-#define ZYD_CR99 0x918c
-#define ZYD_CR100 0x9190
-#define ZYD_CR101 0x9194
-#define ZYD_CR102 0x9198
-#define ZYD_CR103 0x919c
-#define ZYD_CR104 0x91a0
-#define ZYD_CR105 0x91a4
-#define ZYD_CR106 0x91a8
-#define ZYD_CR107 0x91ac
-#define ZYD_CR108 0x91b0
-#define ZYD_CR109 0x91b4
-#define ZYD_CR110 0x91b8
-#define ZYD_CR111 0x91bc
-#define ZYD_CR112 0x91c0
-#define ZYD_CR113 0x91c4
-#define ZYD_CR114 0x91c8
-#define ZYD_CR115 0x91cc
-#define ZYD_CR116 0x91d0
-#define ZYD_CR117 0x91d4
-#define ZYD_CR118 0x91d8
-#define ZYD_CR119 0x91dc
-#define ZYD_CR120 0x91e0
-#define ZYD_CR121 0x91e4
-#define ZYD_CR122 0x91e8
-#define ZYD_CR123 0x91ec
-#define ZYD_CR124 0x91f0
-#define ZYD_CR125 0x91f4
-#define ZYD_CR126 0x91f8
-#define ZYD_CR127 0x91fc
-#define ZYD_CR128 0x9200
-#define ZYD_CR129 0x9204
-#define ZYD_CR130 0x9208
-#define ZYD_CR131 0x920c
-#define ZYD_CR132 0x9210
-#define ZYD_CR133 0x9214
-#define ZYD_CR134 0x9218
-#define ZYD_CR135 0x921c
-#define ZYD_CR136 0x9220
-#define ZYD_CR137 0x9224
-#define ZYD_CR138 0x9228
-#define ZYD_CR139 0x922c
-#define ZYD_CR140 0x9230
-#define ZYD_CR141 0x9234
-#define ZYD_CR142 0x9238
-#define ZYD_CR143 0x923c
-#define ZYD_CR144 0x9240
-#define ZYD_CR145 0x9244
-#define ZYD_CR146 0x9248
-#define ZYD_CR147 0x924c
-#define ZYD_CR148 0x9250
-#define ZYD_CR149 0x9254
-#define ZYD_CR150 0x9258
-#define ZYD_CR151 0x925c
-#define ZYD_CR152 0x9260
-#define ZYD_CR153 0x9264
-#define ZYD_CR154 0x9268
-#define ZYD_CR155 0x926c
-#define ZYD_CR156 0x9270
-#define ZYD_CR157 0x9274
-#define ZYD_CR158 0x9278
-#define ZYD_CR159 0x927c
-#define ZYD_CR160 0x9280
-#define ZYD_CR161 0x9284
-#define ZYD_CR162 0x9288
-#define ZYD_CR163 0x928c
-#define ZYD_CR164 0x9290
-#define ZYD_CR165 0x9294
-#define ZYD_CR166 0x9298
-#define ZYD_CR167 0x929c
-#define ZYD_CR168 0x92a0
-#define ZYD_CR169 0x92a4
-#define ZYD_CR170 0x92a8
-#define ZYD_CR171 0x92ac
-#define ZYD_CR172 0x92b0
-#define ZYD_CR173 0x92b4
-#define ZYD_CR174 0x92b8
-#define ZYD_CR175 0x92bc
-#define ZYD_CR176 0x92c0
-#define ZYD_CR177 0x92c4
-#define ZYD_CR178 0x92c8
-#define ZYD_CR179 0x92cc
-#define ZYD_CR180 0x92d0
-#define ZYD_CR181 0x92d4
-#define ZYD_CR182 0x92d8
-#define ZYD_CR183 0x92dc
-#define ZYD_CR184 0x92e0
-#define ZYD_CR185 0x92e4
-#define ZYD_CR186 0x92e8
-#define ZYD_CR187 0x92ec
-#define ZYD_CR188 0x92f0
-#define ZYD_CR189 0x92f4
-#define ZYD_CR190 0x92f8
-#define ZYD_CR191 0x92fc
-#define ZYD_CR192 0x9300
-#define ZYD_CR193 0x9304
-#define ZYD_CR194 0x9308
-#define ZYD_CR195 0x930c
-#define ZYD_CR196 0x9310
-#define ZYD_CR197 0x9314
-#define ZYD_CR198 0x9318
-#define ZYD_CR199 0x931c
-#define ZYD_CR200 0x9320
-#define ZYD_CR201 0x9324
-#define ZYD_CR202 0x9328
-#define ZYD_CR203 0x932c
-#define ZYD_CR204 0x9330
-#define ZYD_CR205 0x9334
-#define ZYD_CR206 0x9338
-#define ZYD_CR207 0x933c
-#define ZYD_CR208 0x9340
-#define ZYD_CR209 0x9344
-#define ZYD_CR210 0x9348
-#define ZYD_CR211 0x934c
-#define ZYD_CR212 0x9350
-#define ZYD_CR213 0x9354
-#define ZYD_CR214 0x9358
-#define ZYD_CR215 0x935c
-#define ZYD_CR216 0x9360
-#define ZYD_CR217 0x9364
-#define ZYD_CR218 0x9368
-#define ZYD_CR219 0x936c
-#define ZYD_CR220 0x9370
-#define ZYD_CR221 0x9374
-#define ZYD_CR222 0x9378
-#define ZYD_CR223 0x937c
-#define ZYD_CR224 0x9380
-#define ZYD_CR225 0x9384
-#define ZYD_CR226 0x9388
-#define ZYD_CR227 0x938c
-#define ZYD_CR228 0x9390
-#define ZYD_CR229 0x9394
-#define ZYD_CR230 0x9398
-#define ZYD_CR231 0x939c
-#define ZYD_CR232 0x93a0
-#define ZYD_CR233 0x93a4
-#define ZYD_CR234 0x93a8
-#define ZYD_CR235 0x93ac
-#define ZYD_CR236 0x93b0
-#define ZYD_CR240 0x93c0
-#define ZYD_CR241 0x93c4
-#define ZYD_CR242 0x93c8
-#define ZYD_CR243 0x93cc
-#define ZYD_CR244 0x93d0
-#define ZYD_CR245 0x93d4
-#define ZYD_CR251 0x93ec
-#define ZYD_CR252 0x93f0
-#define ZYD_CR253 0x93f4
-#define ZYD_CR254 0x93f8
-#define ZYD_CR255 0x93fc
-
-/* copied nearly verbatim from the Linux driver rewrite */
-#define ZYD_DEF_PHY \
-{ \
- { ZYD_CR0, 0x0a }, { ZYD_CR1, 0x06 }, { ZYD_CR2, 0x26 }, \
- { ZYD_CR3, 0x38 }, { ZYD_CR4, 0x80 }, { ZYD_CR9, 0xa0 }, \
- { ZYD_CR10, 0x81 }, { ZYD_CR11, 0x00 }, { ZYD_CR12, 0x7f }, \
- { ZYD_CR13, 0x8c }, { ZYD_CR14, 0x80 }, { ZYD_CR15, 0x3d }, \
- { ZYD_CR16, 0x20 }, { ZYD_CR17, 0x1e }, { ZYD_CR18, 0x0a }, \
- { ZYD_CR19, 0x48 }, { ZYD_CR20, 0x0c }, { ZYD_CR21, 0x0c }, \
- { ZYD_CR22, 0x23 }, { ZYD_CR23, 0x90 }, { ZYD_CR24, 0x14 }, \
- { ZYD_CR25, 0x40 }, { ZYD_CR26, 0x10 }, { ZYD_CR27, 0x19 }, \
- { ZYD_CR28, 0x7f }, { ZYD_CR29, 0x80 }, { ZYD_CR30, 0x4b }, \
- { ZYD_CR31, 0x60 }, { ZYD_CR32, 0x43 }, { ZYD_CR33, 0x08 }, \
- { ZYD_CR34, 0x06 }, { ZYD_CR35, 0x0a }, { ZYD_CR36, 0x00 }, \
- { ZYD_CR37, 0x00 }, { ZYD_CR38, 0x38 }, { ZYD_CR39, 0x0c }, \
- { ZYD_CR40, 0x84 }, { ZYD_CR41, 0x2a }, { ZYD_CR42, 0x80 }, \
- { ZYD_CR43, 0x10 }, { ZYD_CR44, 0x12 }, { ZYD_CR46, 0xff }, \
- { ZYD_CR47, 0x1e }, { ZYD_CR48, 0x26 }, { ZYD_CR49, 0x5b }, \
- { ZYD_CR64, 0xd0 }, { ZYD_CR65, 0x04 }, { ZYD_CR66, 0x58 }, \
- { ZYD_CR67, 0xc9 }, { ZYD_CR68, 0x88 }, { ZYD_CR69, 0x41 }, \
- { ZYD_CR70, 0x23 }, { ZYD_CR71, 0x10 }, { ZYD_CR72, 0xff }, \
- { ZYD_CR73, 0x32 }, { ZYD_CR74, 0x30 }, { ZYD_CR75, 0x65 }, \
- { ZYD_CR76, 0x41 }, { ZYD_CR77, 0x1b }, { ZYD_CR78, 0x30 }, \
- { ZYD_CR79, 0x68 }, { ZYD_CR80, 0x64 }, { ZYD_CR81, 0x64 }, \
- { ZYD_CR82, 0x00 }, { ZYD_CR83, 0x00 }, { ZYD_CR84, 0x00 }, \
- { ZYD_CR85, 0x02 }, { ZYD_CR86, 0x00 }, { ZYD_CR87, 0x00 }, \
- { ZYD_CR88, 0xff }, { ZYD_CR89, 0xfc }, { ZYD_CR90, 0x00 }, \
- { ZYD_CR91, 0x00 }, { ZYD_CR92, 0x00 }, { ZYD_CR93, 0x08 }, \
- { ZYD_CR94, 0x00 }, { ZYD_CR95, 0x00 }, { ZYD_CR96, 0xff }, \
- { ZYD_CR97, 0xe7 }, { ZYD_CR98, 0x00 }, { ZYD_CR99, 0x00 }, \
- { ZYD_CR100, 0x00 }, { ZYD_CR101, 0xae }, { ZYD_CR102, 0x02 }, \
- { ZYD_CR103, 0x00 }, { ZYD_CR104, 0x03 }, { ZYD_CR105, 0x65 }, \
- { ZYD_CR106, 0x04 }, { ZYD_CR107, 0x00 }, { ZYD_CR108, 0x0a }, \
- { ZYD_CR109, 0xaa }, { ZYD_CR110, 0xaa }, { ZYD_CR111, 0x25 }, \
- { ZYD_CR112, 0x25 }, { ZYD_CR113, 0x00 }, { ZYD_CR119, 0x1e }, \
- { ZYD_CR125, 0x90 }, { ZYD_CR126, 0x00 }, { ZYD_CR127, 0x00 }, \
- { ZYD_CR5, 0x00 }, { ZYD_CR6, 0x00 }, { ZYD_CR7, 0x00 }, \
- { ZYD_CR8, 0x00 }, { ZYD_CR9, 0x20 }, { ZYD_CR12, 0xf0 }, \
- { ZYD_CR20, 0x0e }, { ZYD_CR21, 0x0e }, { ZYD_CR27, 0x10 }, \
- { ZYD_CR44, 0x33 }, { ZYD_CR47, 0x1E }, { ZYD_CR83, 0x24 }, \
- { ZYD_CR84, 0x04 }, { ZYD_CR85, 0x00 }, { ZYD_CR86, 0x0C }, \
- { ZYD_CR87, 0x12 }, { ZYD_CR88, 0x0C }, { ZYD_CR89, 0x00 }, \
- { ZYD_CR90, 0x10 }, { ZYD_CR91, 0x08 }, { ZYD_CR93, 0x00 }, \
- { ZYD_CR94, 0x01 }, { ZYD_CR95, 0x00 }, { ZYD_CR96, 0x50 }, \
- { ZYD_CR97, 0x37 }, { ZYD_CR98, 0x35 }, { ZYD_CR101, 0x13 }, \
- { ZYD_CR102, 0x27 }, { ZYD_CR103, 0x27 }, { ZYD_CR104, 0x18 }, \
- { ZYD_CR105, 0x12 }, { ZYD_CR109, 0x27 }, { ZYD_CR110, 0x27 }, \
- { ZYD_CR111, 0x27 }, { ZYD_CR112, 0x27 }, { ZYD_CR113, 0x27 }, \
- { ZYD_CR114, 0x27 }, { ZYD_CR115, 0x26 }, { ZYD_CR116, 0x24 }, \
- { ZYD_CR117, 0xfc }, { ZYD_CR118, 0xfa }, { ZYD_CR120, 0x4f }, \
- { ZYD_CR125, 0xaa }, { ZYD_CR127, 0x03 }, { ZYD_CR128, 0x14 }, \
- { ZYD_CR129, 0x12 }, { ZYD_CR130, 0x10 }, { ZYD_CR131, 0x0C }, \
- { ZYD_CR136, 0xdf }, { ZYD_CR137, 0x40 }, { ZYD_CR138, 0xa0 }, \
- { ZYD_CR139, 0xb0 }, { ZYD_CR140, 0x99 }, { ZYD_CR141, 0x82 }, \
- { ZYD_CR142, 0x54 }, { ZYD_CR143, 0x1c }, { ZYD_CR144, 0x6c }, \
- { ZYD_CR147, 0x07 }, { ZYD_CR148, 0x4c }, { ZYD_CR149, 0x50 }, \
- { ZYD_CR150, 0x0e }, { ZYD_CR151, 0x18 }, { ZYD_CR160, 0xfe }, \
- { ZYD_CR161, 0xee }, { ZYD_CR162, 0xaa }, { ZYD_CR163, 0xfa }, \
- { ZYD_CR164, 0xfa }, { ZYD_CR165, 0xea }, { ZYD_CR166, 0xbe }, \
- { ZYD_CR167, 0xbe }, { ZYD_CR168, 0x6a }, { ZYD_CR169, 0xba }, \
- { ZYD_CR170, 0xba }, { ZYD_CR171, 0xba }, { ZYD_CR204, 0x7d }, \
- { ZYD_CR203, 0x30 }, { 0, 0} \
-}
-
-#define ZYD_DEF_PHYB \
-{ \
- { ZYD_CR0, 0x14 }, { ZYD_CR1, 0x06 }, { ZYD_CR2, 0x26 }, \
- { ZYD_CR3, 0x38 }, { ZYD_CR4, 0x80 }, { ZYD_CR9, 0xe0 }, \
- { ZYD_CR10, 0x81 }, { ZYD_CR11, 0x00 }, { ZYD_CR12, 0xf0 }, \
- { ZYD_CR13, 0x8c }, { ZYD_CR14, 0x80 }, { ZYD_CR15, 0x3d }, \
- { ZYD_CR16, 0x20 }, { ZYD_CR17, 0x1e }, { ZYD_CR18, 0x0a }, \
- { ZYD_CR19, 0x48 }, { ZYD_CR20, 0x10 }, { ZYD_CR21, 0x0e }, \
- { ZYD_CR22, 0x23 }, { ZYD_CR23, 0x90 }, { ZYD_CR24, 0x14 }, \
- { ZYD_CR25, 0x40 }, { ZYD_CR26, 0x10 }, { ZYD_CR27, 0x10 }, \
- { ZYD_CR28, 0x7f }, { ZYD_CR29, 0x80 }, { ZYD_CR30, 0x4b }, \
- { ZYD_CR31, 0x60 }, { ZYD_CR32, 0x43 }, { ZYD_CR33, 0x08 }, \
- { ZYD_CR34, 0x06 }, { ZYD_CR35, 0x0a }, { ZYD_CR36, 0x00 }, \
- { ZYD_CR37, 0x00 }, { ZYD_CR38, 0x38 }, { ZYD_CR39, 0x0c }, \
- { ZYD_CR40, 0x84 }, { ZYD_CR41, 0x2a }, { ZYD_CR42, 0x80 }, \
- { ZYD_CR43, 0x10 }, { ZYD_CR44, 0x33 }, { ZYD_CR46, 0xff }, \
- { ZYD_CR47, 0x1E }, { ZYD_CR48, 0x26 }, { ZYD_CR49, 0x5b }, \
- { ZYD_CR64, 0xd0 }, { ZYD_CR65, 0x04 }, { ZYD_CR66, 0x58 }, \
- { ZYD_CR67, 0xc9 }, { ZYD_CR68, 0x88 }, { ZYD_CR69, 0x41 }, \
- { ZYD_CR70, 0x23 }, { ZYD_CR71, 0x10 }, { ZYD_CR72, 0xff }, \
- { ZYD_CR73, 0x32 }, { ZYD_CR74, 0x30 }, { ZYD_CR75, 0x65 }, \
- { ZYD_CR76, 0x41 }, { ZYD_CR77, 0x1b }, { ZYD_CR78, 0x30 }, \
- { ZYD_CR79, 0xf0 }, { ZYD_CR80, 0x64 }, { ZYD_CR81, 0x64 }, \
- { ZYD_CR82, 0x00 }, { ZYD_CR83, 0x24 }, { ZYD_CR84, 0x04 }, \
- { ZYD_CR85, 0x00 }, { ZYD_CR86, 0x0c }, { ZYD_CR87, 0x12 }, \
- { ZYD_CR88, 0x0c }, { ZYD_CR89, 0x00 }, { ZYD_CR90, 0x58 }, \
- { ZYD_CR91, 0x04 }, { ZYD_CR92, 0x00 }, { ZYD_CR93, 0x00 }, \
- { ZYD_CR94, 0x01 }, { ZYD_CR95, 0x20 }, { ZYD_CR96, 0x50 }, \
- { ZYD_CR97, 0x37 }, { ZYD_CR98, 0x35 }, { ZYD_CR99, 0x00 }, \
- { ZYD_CR100, 0x01 }, { ZYD_CR101, 0x13 }, { ZYD_CR102, 0x27 }, \
- { ZYD_CR103, 0x27 }, { ZYD_CR104, 0x18 }, { ZYD_CR105, 0x12 }, \
- { ZYD_CR106, 0x04 }, { ZYD_CR107, 0x00 }, { ZYD_CR108, 0x0a }, \
- { ZYD_CR109, 0x27 }, { ZYD_CR110, 0x27 }, { ZYD_CR111, 0x27 }, \
- { ZYD_CR112, 0x27 }, { ZYD_CR113, 0x27 }, { ZYD_CR114, 0x27 }, \
- { ZYD_CR115, 0x26 }, { ZYD_CR116, 0x24 }, { ZYD_CR117, 0xfc }, \
- { ZYD_CR118, 0xfa }, { ZYD_CR119, 0x1e }, { ZYD_CR125, 0x90 }, \
- { ZYD_CR126, 0x00 }, { ZYD_CR127, 0x00 }, { ZYD_CR128, 0x14 }, \
- { ZYD_CR129, 0x12 }, { ZYD_CR130, 0x10 }, { ZYD_CR131, 0x0c }, \
- { ZYD_CR136, 0xdf }, { ZYD_CR137, 0xa0 }, { ZYD_CR138, 0xa8 }, \
- { ZYD_CR139, 0xb4 }, { ZYD_CR140, 0x98 }, { ZYD_CR141, 0x82 }, \
- { ZYD_CR142, 0x53 }, { ZYD_CR143, 0x1c }, { ZYD_CR144, 0x6c }, \
- { ZYD_CR147, 0x07 }, { ZYD_CR148, 0x40 }, { ZYD_CR149, 0x40 }, \
- { ZYD_CR150, 0x14 }, { ZYD_CR151, 0x18 }, { ZYD_CR159, 0x70 }, \
- { ZYD_CR160, 0xfe }, { ZYD_CR161, 0xee }, { ZYD_CR162, 0xaa }, \
- { ZYD_CR163, 0xfa }, { ZYD_CR164, 0xfa }, { ZYD_CR165, 0xea }, \
- { ZYD_CR166, 0xbe }, { ZYD_CR167, 0xbe }, { ZYD_CR168, 0x6a }, \
- { ZYD_CR169, 0xba }, { ZYD_CR170, 0xba }, { ZYD_CR171, 0xba }, \
- { ZYD_CR204, 0x7d }, { ZYD_CR203, 0x30 }, \
- { 0, 0 } \
-}
-
-#define ZYD_RFMD_PHY \
-{ \
- { ZYD_CR2, 0x1e }, { ZYD_CR9, 0x20 }, { ZYD_CR10, 0x89 }, \
- { ZYD_CR11, 0x00 }, { ZYD_CR15, 0xd0 }, { ZYD_CR17, 0x68 }, \
- { ZYD_CR19, 0x4a }, { ZYD_CR20, 0x0c }, { ZYD_CR21, 0x0e }, \
- { ZYD_CR23, 0x48 }, { ZYD_CR24, 0x14 }, { ZYD_CR26, 0x90 }, \
- { ZYD_CR27, 0x30 }, { ZYD_CR29, 0x20 }, { ZYD_CR31, 0xb2 }, \
- { ZYD_CR32, 0x43 }, { ZYD_CR33, 0x28 }, { ZYD_CR38, 0x30 }, \
- { ZYD_CR34, 0x0f }, { ZYD_CR35, 0xf0 }, { ZYD_CR41, 0x2a }, \
- { ZYD_CR46, 0x7f }, { ZYD_CR47, 0x1e }, { ZYD_CR51, 0xc5 }, \
- { ZYD_CR52, 0xc5 }, { ZYD_CR53, 0xc5 }, { ZYD_CR79, 0x58 }, \
- { ZYD_CR80, 0x30 }, { ZYD_CR81, 0x30 }, { ZYD_CR82, 0x00 }, \
- { ZYD_CR83, 0x24 }, { ZYD_CR84, 0x04 }, { ZYD_CR85, 0x00 }, \
- { ZYD_CR86, 0x10 }, { ZYD_CR87, 0x2a }, { ZYD_CR88, 0x10 }, \
- { ZYD_CR89, 0x24 }, { ZYD_CR90, 0x18 }, { ZYD_CR91, 0x00 }, \
- { ZYD_CR92, 0x0a }, { ZYD_CR93, 0x00 }, { ZYD_CR94, 0x01 }, \
- { ZYD_CR95, 0x00 }, { ZYD_CR96, 0x40 }, { ZYD_CR97, 0x37 }, \
- { ZYD_CR98, 0x05 }, { ZYD_CR99, 0x28 }, { ZYD_CR100, 0x00 }, \
- { ZYD_CR101, 0x13 }, { ZYD_CR102, 0x27 }, { ZYD_CR103, 0x27 }, \
- { ZYD_CR104, 0x18 }, { ZYD_CR105, 0x12 }, { ZYD_CR106, 0x1a }, \
- { ZYD_CR107, 0x24 }, { ZYD_CR108, 0x0a }, { ZYD_CR109, 0x13 }, \
- { ZYD_CR110, 0x2f }, { ZYD_CR111, 0x27 }, { ZYD_CR112, 0x27 }, \
- { ZYD_CR113, 0x27 }, { ZYD_CR114, 0x27 }, { ZYD_CR115, 0x40 }, \
- { ZYD_CR116, 0x40 }, { ZYD_CR117, 0xf0 }, { ZYD_CR118, 0xf0 }, \
- { ZYD_CR119, 0x16 }, { ZYD_CR122, 0x00 }, { ZYD_CR127, 0x03 }, \
- { ZYD_CR131, 0x08 }, { ZYD_CR138, 0x28 }, { ZYD_CR148, 0x44 }, \
- { ZYD_CR150, 0x10 }, { ZYD_CR169, 0xbb }, { ZYD_CR170, 0xbb } \
-}
-
-#define ZYD_RFMD_RF \
-{ \
- 0x000007, 0x07dd43, 0x080959, 0x0e6666, 0x116a57, 0x17dd43, \
- 0x1819f9, 0x1e6666, 0x214554, 0x25e7fa, 0x27fffa, 0x294128, \
- 0x2c0000, 0x300000, 0x340000, 0x381e0f, 0x6c180f \
-}
-
-#define ZYD_RFMD_CHANTABLE \
-{ \
- { 0x181979, 0x1e6666 }, \
- { 0x181989, 0x1e6666 }, \
- { 0x181999, 0x1e6666 }, \
- { 0x1819a9, 0x1e6666 }, \
- { 0x1819b9, 0x1e6666 }, \
- { 0x1819c9, 0x1e6666 }, \
- { 0x1819d9, 0x1e6666 }, \
- { 0x1819e9, 0x1e6666 }, \
- { 0x1819f9, 0x1e6666 }, \
- { 0x181a09, 0x1e6666 }, \
- { 0x181a19, 0x1e6666 }, \
- { 0x181a29, 0x1e6666 }, \
- { 0x181a39, 0x1e6666 }, \
- { 0x181a60, 0x1c0000 } \
-}
-
-#define ZYD_AL2230_PHY \
-{ \
- { ZYD_CR15, 0x20 }, { ZYD_CR23, 0x40 }, { ZYD_CR24, 0x20 }, \
- { ZYD_CR26, 0x11 }, { ZYD_CR28, 0x3e }, { ZYD_CR29, 0x00 }, \
- { ZYD_CR44, 0x33 }, { ZYD_CR106, 0x2a }, { ZYD_CR107, 0x1a }, \
- { ZYD_CR109, 0x09 }, { ZYD_CR110, 0x27 }, { ZYD_CR111, 0x2b }, \
- { ZYD_CR112, 0x2b }, { ZYD_CR119, 0x0a }, { ZYD_CR10, 0x89 }, \
- { ZYD_CR17, 0x28 }, { ZYD_CR26, 0x93 }, { ZYD_CR34, 0x30 }, \
- { ZYD_CR35, 0x3e }, { ZYD_CR41, 0x24 }, { ZYD_CR44, 0x32 }, \
- { ZYD_CR46, 0x96 }, { ZYD_CR47, 0x1e }, { ZYD_CR79, 0x58 }, \
- { ZYD_CR80, 0x30 }, { ZYD_CR81, 0x30 }, { ZYD_CR87, 0x0a }, \
- { ZYD_CR89, 0x04 }, { ZYD_CR92, 0x0a }, { ZYD_CR99, 0x28 }, \
- { ZYD_CR100, 0x00 }, { ZYD_CR101, 0x13 }, { ZYD_CR102, 0x27 }, \
- { ZYD_CR106, 0x24 }, { ZYD_CR107, 0x2a }, { ZYD_CR109, 0x09 }, \
- { ZYD_CR110, 0x13 }, { ZYD_CR111, 0x1f }, { ZYD_CR112, 0x1f }, \
- { ZYD_CR113, 0x27 }, { ZYD_CR114, 0x27 }, { ZYD_CR115, 0x24 }, \
- { ZYD_CR116, 0x24 }, { ZYD_CR117, 0xf4 }, { ZYD_CR118, 0xfc }, \
- { ZYD_CR119, 0x10 }, { ZYD_CR120, 0x4f }, { ZYD_CR121, 0x77 }, \
- { ZYD_CR122, 0xe0 }, { ZYD_CR137, 0x88 }, { ZYD_CR252, 0xff }, \
- { ZYD_CR253, 0xff }, { ZYD_CR251, 0x2f }, { ZYD_CR251, 0x3f }, \
- { ZYD_CR138, 0x28 }, { ZYD_CR203, 0x06 } \
-}
-
-#define ZYD_AL2230_PHY_B \
-{ \
- { ZYD_CR10, 0x89 }, { ZYD_CR15, 0x20 }, { ZYD_CR17, 0x2B }, \
- { ZYD_CR23, 0x40 }, { ZYD_CR24, 0x20 }, { ZYD_CR26, 0x93 }, \
- { ZYD_CR28, 0x3e }, { ZYD_CR29, 0x00 }, { ZYD_CR33, 0x28 }, \
- { ZYD_CR34, 0x30 }, { ZYD_CR35, 0x3e }, { ZYD_CR41, 0x24 }, \
- { ZYD_CR44, 0x32 }, { ZYD_CR46, 0x99 }, { ZYD_CR47, 0x1e }, \
- { ZYD_CR48, 0x06 }, { ZYD_CR49, 0xf9 }, { ZYD_CR51, 0x01 }, \
- { ZYD_CR52, 0x80 }, { ZYD_CR53, 0x7e }, { ZYD_CR65, 0x00 }, \
- { ZYD_CR66, 0x00 }, { ZYD_CR67, 0x00 }, { ZYD_CR68, 0x00 }, \
- { ZYD_CR69, 0x28 }, { ZYD_CR79, 0x58 }, { ZYD_CR80, 0x30 }, \
- { ZYD_CR81, 0x30 }, { ZYD_CR87, 0x0a }, { ZYD_CR89, 0x04 }, \
- { ZYD_CR91, 0x00 }, { ZYD_CR92, 0x0a }, { ZYD_CR98, 0x8d }, \
- { ZYD_CR99, 0x00 }, { ZYD_CR101, 0x13 }, { ZYD_CR102, 0x27 }, \
- { ZYD_CR106, 0x24 }, { ZYD_CR107, 0x2a }, { ZYD_CR109, 0x13 }, \
- { ZYD_CR110, 0x1f }, { ZYD_CR111, 0x1f }, { ZYD_CR112, 0x1f }, \
- { ZYD_CR113, 0x27 }, { ZYD_CR114, 0x27 }, { ZYD_CR115, 0x26 }, \
- { ZYD_CR116, 0x24 }, { ZYD_CR117, 0xfa }, { ZYD_CR118, 0xfa }, \
- { ZYD_CR119, 0x10 }, { ZYD_CR120, 0x4f }, { ZYD_CR121, 0x6c }, \
- { ZYD_CR122, 0xfc }, { ZYD_CR123, 0x57 }, { ZYD_CR125, 0xad }, \
- { ZYD_CR126, 0x6c }, { ZYD_CR127, 0x03 }, { ZYD_CR137, 0x50 }, \
- { ZYD_CR138, 0xa8 }, { ZYD_CR144, 0xac }, { ZYD_CR150, 0x0d }, \
- { ZYD_CR252, 0x34 }, { ZYD_CR253, 0x34 } \
-}
-
-#define ZYD_AL2230_PHY_PART1 \
-{ \
- { ZYD_CR240, 0x57 }, { ZYD_CR9, 0xe0 } \
-}
-
-#define ZYD_AL2230_PHY_PART2 \
-{ \
- { ZYD_CR251, 0x2f }, { ZYD_CR251, 0x7f }, \
-}
-
-#define ZYD_AL2230_PHY_PART3 \
-{ \
- { ZYD_CR128, 0x14 }, { ZYD_CR129, 0x12 }, { ZYD_CR130, 0x10 }, \
-}
-
-#define ZYD_AL2230S_PHY_INIT \
-{ \
- { ZYD_CR47, 0x1e }, { ZYD_CR106, 0x22 }, { ZYD_CR107, 0x2a }, \
- { ZYD_CR109, 0x13 }, { ZYD_CR118, 0xf8 }, { ZYD_CR119, 0x12 }, \
- { ZYD_CR122, 0xe0 }, { ZYD_CR128, 0x10 }, { ZYD_CR129, 0x0e }, \
- { ZYD_CR130, 0x10 } \
-}
-
-#define ZYD_AL2230_PHY_FINI_PART1 \
-{ \
- { ZYD_CR80, 0x30 }, { ZYD_CR81, 0x30 }, { ZYD_CR79, 0x58 }, \
- { ZYD_CR12, 0xf0 }, { ZYD_CR77, 0x1b }, { ZYD_CR78, 0x58 }, \
- { ZYD_CR203, 0x06 }, { ZYD_CR240, 0x80 }, \
-}
-
-#define ZYD_AL2230_RF_PART1 \
-{ \
- 0x03f790, 0x033331, 0x00000d, 0x0b3331, 0x03b812, 0x00fff3 \
-}
-
-#define ZYD_AL2230_RF_PART2 \
-{ \
- 0x000da4, 0x0f4dc5, 0x0805b6, 0x011687, 0x000688, 0x0403b9, \
- 0x00dbba, 0x00099b, 0x0bdffc, 0x00000d, 0x00500f \
-}
-
-#define ZYD_AL2230_RF_PART3 \
-{ \
- 0x00d00f, 0x004c0f, 0x00540f, 0x00700f, 0x00500f \
-}
-
-#define ZYD_AL2230_RF_B \
-{ \
- 0x03f790, 0x033331, 0x00000d, 0x0b3331, 0x03b812, 0x00fff3, \
- 0x0005a4, 0x0f4dc5, 0x0805b6, 0x0146c7, 0x000688, 0x0403b9, \
- 0x00dbba, 0x00099b, 0x0bdffc, 0x00000d, 0x00580f \
-}
-
-#define ZYD_AL2230_RF_B_PART1 \
-{ \
- 0x8cccd0, 0x481dc0, 0xcfff00, 0x25a000 \
-}
-
-#define ZYD_AL2230_RF_B_PART2 \
-{ \
- 0x25a000, 0xa3b2f0, 0x6da010, 0xe36280, 0x116000, 0x9dc020, \
- 0x5ddb00, 0xd99000, 0x3ffbd0, 0xb00000, 0xf01a00 \
-}
-
-#define ZYD_AL2230_RF_B_PART3 \
-{ \
- 0xf01b00, 0xf01e00, 0xf01a00 \
-}
-
-#define ZYD_AL2230_CHANTABLE \
-{ \
- { 0x03f790, 0x033331, 0x00000d }, \
- { 0x03f790, 0x0b3331, 0x00000d }, \
- { 0x03e790, 0x033331, 0x00000d }, \
- { 0x03e790, 0x0b3331, 0x00000d }, \
- { 0x03f7a0, 0x033331, 0x00000d }, \
- { 0x03f7a0, 0x0b3331, 0x00000d }, \
- { 0x03e7a0, 0x033331, 0x00000d }, \
- { 0x03e7a0, 0x0b3331, 0x00000d }, \
- { 0x03f7b0, 0x033331, 0x00000d }, \
- { 0x03f7b0, 0x0b3331, 0x00000d }, \
- { 0x03e7b0, 0x033331, 0x00000d }, \
- { 0x03e7b0, 0x0b3331, 0x00000d }, \
- { 0x03f7c0, 0x033331, 0x00000d }, \
- { 0x03e7c0, 0x066661, 0x00000d } \
-}
-
-#define ZYD_AL2230_CHANTABLE_B \
-{ \
- { 0x09efc0, 0x8cccc0, 0xb00000 }, \
- { 0x09efc0, 0x8cccd0, 0xb00000 }, \
- { 0x09e7c0, 0x8cccc0, 0xb00000 }, \
- { 0x09e7c0, 0x8cccd0, 0xb00000 }, \
- { 0x05efc0, 0x8cccc0, 0xb00000 }, \
- { 0x05efc0, 0x8cccd0, 0xb00000 }, \
- { 0x05e7c0, 0x8cccc0, 0xb00000 }, \
- { 0x05e7c0, 0x8cccd0, 0xb00000 }, \
- { 0x0defc0, 0x8cccc0, 0xb00000 }, \
- { 0x0defc0, 0x8cccd0, 0xb00000 }, \
- { 0x0de7c0, 0x8cccc0, 0xb00000 }, \
- { 0x0de7c0, 0x8cccd0, 0xb00000 }, \
- { 0x03efc0, 0x8cccc0, 0xb00000 }, \
- { 0x03e7c0, 0x866660, 0xb00000 } \
-}
-
-#define ZYD_AL7230B_PHY_1 \
-{ \
- { ZYD_CR240, 0x57 }, { ZYD_CR15, 0x20 }, { ZYD_CR23, 0x40 }, \
- { ZYD_CR24, 0x20 }, { ZYD_CR26, 0x11 }, { ZYD_CR28, 0x3e }, \
- { ZYD_CR29, 0x00 }, { ZYD_CR44, 0x33 }, { ZYD_CR106, 0x22 }, \
- { ZYD_CR107, 0x1a }, { ZYD_CR109, 0x09 }, { ZYD_CR110, 0x27 }, \
- { ZYD_CR111, 0x2b }, { ZYD_CR112, 0x2b }, { ZYD_CR119, 0x0a }, \
- { ZYD_CR122, 0xfc }, { ZYD_CR10, 0x89 }, { ZYD_CR17, 0x28 }, \
- { ZYD_CR26, 0x93 }, { ZYD_CR34, 0x30 }, { ZYD_CR35, 0x3e }, \
- { ZYD_CR41, 0x24 }, { ZYD_CR44, 0x32 }, { ZYD_CR46, 0x96 }, \
- { ZYD_CR47, 0x1e }, { ZYD_CR79, 0x58 }, { ZYD_CR80, 0x30 }, \
- { ZYD_CR81, 0x30 }, { ZYD_CR87, 0x0a }, { ZYD_CR89, 0x04 }, \
- { ZYD_CR92, 0x0a }, { ZYD_CR99, 0x28 }, { ZYD_CR100, 0x02 }, \
- { ZYD_CR101, 0x13 }, { ZYD_CR102, 0x27 }, { ZYD_CR106, 0x22 }, \
- { ZYD_CR107, 0x3f }, { ZYD_CR109, 0x09 }, { ZYD_CR110, 0x1f }, \
- { ZYD_CR111, 0x1f }, { ZYD_CR112, 0x1f }, { ZYD_CR113, 0x27 }, \
- { ZYD_CR114, 0x27 }, { ZYD_CR115, 0x24 }, { ZYD_CR116, 0x3f }, \
- { ZYD_CR117, 0xfa }, { ZYD_CR118, 0xfc }, { ZYD_CR119, 0x10 }, \
- { ZYD_CR120, 0x4f }, { ZYD_CR121, 0x77 }, { ZYD_CR137, 0x88 }, \
- { ZYD_CR138, 0xa8 }, { ZYD_CR252, 0x34 }, { ZYD_CR253, 0x34 }, \
- { ZYD_CR251, 0x2f } \
-}
-
-#define ZYD_AL7230B_PHY_2 \
-{ \
- { ZYD_CR251, 0x3f }, { ZYD_CR128, 0x14 }, { ZYD_CR129, 0x12 }, \
- { ZYD_CR130, 0x10 }, { ZYD_CR38, 0x38 }, { ZYD_CR136, 0xdf } \
-}
-
-#define ZYD_AL7230B_PHY_3 \
-{ \
- { ZYD_CR203, 0x06 }, { ZYD_CR240, 0x80 } \
-}
-
-#define ZYD_AL7230B_RF_1 \
-{ \
- 0x09ec04, 0x8cccc8, 0x4ff821, 0xc5fbfc, 0x21ebfe, 0xafd401, \
- 0x6cf56a, 0xe04073, 0x193d76, 0x9dd844, 0x500007, 0xd8c010, \
- 0x3c9000, 0xbfffff, 0x700000, 0xf15d58 \
-}
-
-#define ZYD_AL7230B_RF_2 \
-{ \
- 0xf15d59, 0xf15d5c, 0xf15d58 \
-}
-
-#define ZYD_AL7230B_RF_SETCHANNEL \
-{ \
- 0x4ff821, 0xc5fbfc, 0x21ebfe, 0xafd401, 0x6cf56a, 0xe04073, \
- 0x193d76, 0x9dd844, 0x500007, 0xd8c010, 0x3c9000, 0xf15d58 \
-}
-
-#define ZYD_AL7230B_CHANTABLE \
-{ \
- { 0x09ec00, 0x8cccc8 }, \
- { 0x09ec00, 0x8cccd8 }, \
- { 0x09ec00, 0x8cccc0 }, \
- { 0x09ec00, 0x8cccd0 }, \
- { 0x05ec00, 0x8cccc8 }, \
- { 0x05ec00, 0x8cccd8 }, \
- { 0x05ec00, 0x8cccc0 }, \
- { 0x05ec00, 0x8cccd0 }, \
- { 0x0dec00, 0x8cccc8 }, \
- { 0x0dec00, 0x8cccd8 }, \
- { 0x0dec00, 0x8cccc0 }, \
- { 0x0dec00, 0x8cccd0 }, \
- { 0x03ec00, 0x8cccc8 }, \
- { 0x03ec00, 0x866660 } \
-}
-
-#define ZYD_AL2210_PHY \
-{ \
- { ZYD_CR9, 0xe0 }, { ZYD_CR10, 0x91 }, { ZYD_CR12, 0x90 }, \
- { ZYD_CR15, 0xd0 }, { ZYD_CR16, 0x40 }, { ZYD_CR17, 0x58 }, \
- { ZYD_CR18, 0x04 }, { ZYD_CR23, 0x66 }, { ZYD_CR24, 0x14 }, \
- { ZYD_CR26, 0x90 }, { ZYD_CR31, 0x80 }, { ZYD_CR34, 0x06 }, \
- { ZYD_CR35, 0x3e }, { ZYD_CR38, 0x38 }, { ZYD_CR46, 0x90 }, \
- { ZYD_CR47, 0x1e }, { ZYD_CR64, 0x64 }, { ZYD_CR79, 0xb5 }, \
- { ZYD_CR80, 0x38 }, { ZYD_CR81, 0x30 }, { ZYD_CR113, 0xc0 }, \
- { ZYD_CR127, 0x03 } \
-}
-
-#define ZYD_AL2210_RF \
-{ \
- 0x2396c0, 0x00fcb1, 0x358132, 0x0108b3, 0xc77804, 0x456415, \
- 0xff2226, 0x806667, 0x7860f8, 0xbb01c9, 0x00000a, 0x00000b \
-}
-
-#define ZYD_AL2210_CHANTABLE \
-{ \
- 0x0196c0, 0x019710, 0x019760, 0x0197b0, 0x019800, 0x019850, \
- 0x0198a0, 0x0198f0, 0x019940, 0x019990, 0x0199e0, 0x019a30, \
- 0x019a80, 0x019b40 \
-}
-
-#define ZYD_GCT_PHY \
-{ \
- { ZYD_CR47, 0x1e }, { ZYD_CR15, 0xdc }, { ZYD_CR113, 0xc0 }, \
- { ZYD_CR20, 0x0c }, { ZYD_CR17, 0x65 }, { ZYD_CR34, 0x04 }, \
- { ZYD_CR35, 0x35 }, { ZYD_CR24, 0x20 }, { ZYD_CR9, 0xe0 }, \
- { ZYD_CR127, 0x02 }, { ZYD_CR10, 0x91 }, { ZYD_CR23, 0x7f }, \
- { ZYD_CR27, 0x10 }, { ZYD_CR28, 0x7a }, { ZYD_CR79, 0xb5 }, \
- { ZYD_CR64, 0x80 }, { ZYD_CR33, 0x28 }, { ZYD_CR38, 0x30 } \
-}
-
-#define ZYD_GCT_RF \
-{ \
- 0x1f0000, 0x1f0000, 0x1f0200, 0x1f0600, 0x1f8600, 0x1f8600, \
- 0x002050, 0x1f8000, 0x1f8200, 0x1f8600, 0x1c0000, 0x10c458, \
- 0x088e92, 0x187b82, 0x0401b4, 0x140816, 0x0c7000, 0x1c0000, \
- 0x02ccae, 0x128023, 0x0a0000, 0x1a0000, 0x06e380, 0x16cb94, \
- 0x0e1740, 0x014980, 0x116240, 0x090000, 0x192304, 0x05112f, \
- 0x0d54a8, 0x0f8000, 0x1c0008, 0x1c0000, 0x1a0000, 0x1c0008, \
- 0x150000, 0x0c7000, 0x150800, 0x150000 \
-}
-
-#define ZYD_GCT_CHANTABLE \
-{ \
- 0x1a0000, 0x1a8000, 0x1a4000, 0x1ac000, 0x1a2000, 0x1aa000, \
- 0x1a6000, 0x1ae000, 0x1a1000, 0x1a9000, 0x1a5000, 0x1ad000, \
- 0x1a3000, 0x1ab000 \
-}
-
-#define ZYD_MAXIM_PHY \
-{ \
- { ZYD_CR23, 0x40 }, { ZYD_CR15, 0x20 }, { ZYD_CR28, 0x3e }, \
- { ZYD_CR29, 0x00 }, { ZYD_CR26, 0x11 }, { ZYD_CR44, 0x33 }, \
- { ZYD_CR106, 0x2a }, { ZYD_CR107, 0x1a }, { ZYD_CR109, 0x2b }, \
- { ZYD_CR110, 0x2b }, { ZYD_CR111, 0x2b }, { ZYD_CR112, 0x2b }, \
- { ZYD_CR10, 0x89 }, { ZYD_CR17, 0x20 }, { ZYD_CR26, 0x93 }, \
- { ZYD_CR34, 0x30 }, { ZYD_CR35, 0x40 }, { ZYD_CR41, 0x24 }, \
- { ZYD_CR44, 0x32 }, { ZYD_CR46, 0x90 }, { ZYD_CR89, 0x18 }, \
- { ZYD_CR92, 0x0a }, { ZYD_CR101, 0x13 }, { ZYD_CR102, 0x27 }, \
- { ZYD_CR106, 0x20 }, { ZYD_CR107, 0x24 }, { ZYD_CR109, 0x09 }, \
- { ZYD_CR110, 0x13 }, { ZYD_CR111, 0x13 }, { ZYD_CR112, 0x13 }, \
- { ZYD_CR113, 0x27 }, { ZYD_CR114, 0x27 }, { ZYD_CR115, 0x24 }, \
- { ZYD_CR116, 0x24 }, { ZYD_CR117, 0xf4 }, { ZYD_CR118, 0xfa }, \
- { ZYD_CR120, 0x4f }, { ZYD_CR121, 0x77 }, { ZYD_CR122, 0xfe }, \
- { ZYD_CR10, 0x89 }, { ZYD_CR17, 0x20 }, { ZYD_CR26, 0x93 }, \
- { ZYD_CR34, 0x30 }, { ZYD_CR35, 0x40 }, { ZYD_CR41, 0x24 }, \
- { ZYD_CR44, 0x32 }, { ZYD_CR46, 0x90 }, { ZYD_CR89, 0x18 }, \
- { ZYD_CR92, 0x0a }, { ZYD_CR101, 0x13 }, { ZYD_CR102, 0x27 }, \
- { ZYD_CR106, 0x20 }, { ZYD_CR107, 0x24 }, { ZYD_CR109, 0x13 }, \
- { ZYD_CR110, 0x27 }, { ZYD_CR111, 0x27 }, { ZYD_CR112, 0x13 }, \
- { ZYD_CR113, 0x27 }, { ZYD_CR114, 0x27 }, { ZYD_CR115, 0x24 }, \
- { ZYD_CR116, 0x24 }, { ZYD_CR117, 0xf4 }, { ZYD_CR118, 0x00 }, \
- { ZYD_CR120, 0x4f }, { ZYD_CR121, 0x06 }, { ZYD_CR122, 0xfe }, \
- { ZYD_CR150, 0x0d } \
-}
-
-#define ZYD_MAXIM_RF \
-{ \
- 0x00ccd4, 0x030a03, 0x000400, 0x000ca1, 0x010072, 0x018645, \
- 0x004006, 0x0000a7, 0x008258, 0x003fc9, 0x00040a, 0x00000b, \
- 0x00026c \
-}
-
-#define ZYD_MAXIM_CHANTABLE \
-{ \
- { 0x0ccd4, 0x30a03 }, \
- { 0x22224, 0x00a13 }, \
- { 0x37774, 0x10a13 }, \
- { 0x0ccd4, 0x30a13 }, \
- { 0x22224, 0x00a23 }, \
- { 0x37774, 0x10a23 }, \
- { 0x0ccd4, 0x30a23 }, \
- { 0x22224, 0x00a33 }, \
- { 0x37774, 0x10a33 }, \
- { 0x0ccd4, 0x30a33 }, \
- { 0x22224, 0x00a43 }, \
- { 0x37774, 0x10a43 }, \
- { 0x0ccd4, 0x30a43 }, \
- { 0x199a4, 0x20a53 } \
-}
-
-#define ZYD_MAXIM2_PHY \
-{ \
- { ZYD_CR23, 0x40 }, { ZYD_CR15, 0x20 }, { ZYD_CR28, 0x3e }, \
- { ZYD_CR29, 0x00 }, { ZYD_CR26, 0x11 }, { ZYD_CR44, 0x33 }, \
- { ZYD_CR106, 0x2a }, { ZYD_CR107, 0x1a }, { ZYD_CR109, 0x2b }, \
- { ZYD_CR110, 0x2b }, { ZYD_CR111, 0x2b }, { ZYD_CR112, 0x2b }, \
- { ZYD_CR10, 0x89 }, { ZYD_CR17, 0x20 }, { ZYD_CR26, 0x93 }, \
- { ZYD_CR34, 0x30 }, { ZYD_CR35, 0x40 }, { ZYD_CR41, 0x24 }, \
- { ZYD_CR44, 0x32 }, { ZYD_CR46, 0x90 }, { ZYD_CR89, 0x18 }, \
- { ZYD_CR92, 0x0a }, { ZYD_CR101, 0x13 }, { ZYD_CR102, 0x27 }, \
- { ZYD_CR106, 0x20 }, { ZYD_CR107, 0x24 }, { ZYD_CR109, 0x09 }, \
- { ZYD_CR110, 0x13 }, { ZYD_CR111, 0x13 }, { ZYD_CR112, 0x13 }, \
- { ZYD_CR113, 0x27 }, { ZYD_CR114, 0x27 }, { ZYD_CR115, 0x24 }, \
- { ZYD_CR116, 0x24 }, { ZYD_CR117, 0xf4 }, { ZYD_CR118, 0xfa }, \
- { ZYD_CR120, 0x4f }, { ZYD_CR121, 0x77 }, { ZYD_CR122, 0xfe }, \
- { ZYD_CR10, 0x89 }, { ZYD_CR17, 0x20 }, { ZYD_CR26, 0x93 }, \
- { ZYD_CR34, 0x30 }, { ZYD_CR35, 0x40 }, { ZYD_CR41, 0x24 }, \
- { ZYD_CR44, 0x32 }, { ZYD_CR46, 0x90 }, { ZYD_CR79, 0x58 }, \
- { ZYD_CR80, 0x30 }, { ZYD_CR81, 0x30 }, { ZYD_CR89, 0x18 }, \
- { ZYD_CR92, 0x0a }, { ZYD_CR101, 0x13 }, { ZYD_CR102, 0x27 }, \
- { ZYD_CR106, 0x20 }, { ZYD_CR107, 0x24 }, { ZYD_CR109, 0x09 }, \
- { ZYD_CR110, 0x13 }, { ZYD_CR111, 0x13 }, { ZYD_CR112, 0x13 }, \
- { ZYD_CR113, 0x27 }, { ZYD_CR114, 0x27 }, { ZYD_CR115, 0x24 }, \
- { ZYD_CR116, 0x24 }, { ZYD_CR117, 0xf4 }, { ZYD_CR118, 0x00 }, \
- { ZYD_CR120, 0x4f }, { ZYD_CR121, 0x06 }, { ZYD_CR122, 0xfe } \
-}
-
-#define ZYD_MAXIM2_RF \
-{ \
- 0x33334, 0x10a03, 0x00400, 0x00ca1, 0x10072, 0x18645, 0x04006, \
- 0x000a7, 0x08258, 0x03fc9, 0x0040a, 0x0000b, 0x0026c \
-}
-
-#define ZYD_MAXIM2_CHANTABLE_F \
-{ \
- 0x33334, 0x08884, 0x1ddd4, 0x33334, 0x08884, 0x1ddd4, 0x33334, \
- 0x08884, 0x1ddd4, 0x33334, 0x08884, 0x1ddd4, 0x33334, 0x26664 \
-}
-
-#define ZYD_MAXIM2_CHANTABLE \
-{ \
- { 0x33334, 0x10a03 }, \
- { 0x08884, 0x20a13 }, \
- { 0x1ddd4, 0x30a13 }, \
- { 0x33334, 0x10a13 }, \
- { 0x08884, 0x20a23 }, \
- { 0x1ddd4, 0x30a23 }, \
- { 0x33334, 0x10a23 }, \
- { 0x08884, 0x20a33 }, \
- { 0x1ddd4, 0x30a33 }, \
- { 0x33334, 0x10a33 }, \
- { 0x08884, 0x20a43 }, \
- { 0x1ddd4, 0x30a43 }, \
- { 0x33334, 0x10a43 }, \
- { 0x26664, 0x20a53 } \
-}
-
-/*
- * Control pipe requests.
- */
-#define ZYD_DOWNLOADREQ 0x30
-#define ZYD_DOWNLOADSTS 0x31
-#define ZYD_READFWDATAREQ 0x32
-
-/* possible values for register ZYD_CR_INTERRUPT */
-#define ZYD_HWINT_MASK 0x004f0000
-
-/* possible values for register ZYD_MAC_MISC */
-#define ZYD_UNLOCK_PHY_REGS 0x80
-
-/* possible values for register ZYD_MAC_ENCRYPTION_TYPE */
-#define ZYD_ENC_SNIFFER 8
-
-/* flags for register ZYD_MAC_RXFILTER */
-#define ZYD_FILTER_ASS_REQ (1 << 0)
-#define ZYD_FILTER_ASS_RSP (1 << 1)
-#define ZYD_FILTER_REASS_REQ (1 << 2)
-#define ZYD_FILTER_REASS_RSP (1 << 3)
-#define ZYD_FILTER_PRB_REQ (1 << 4)
-#define ZYD_FILTER_PRB_RSP (1 << 5)
-#define ZYD_FILTER_BCN (1 << 8)
-#define ZYD_FILTER_ATIM (1 << 9)
-#define ZYD_FILTER_DEASS (1 << 10)
-#define ZYD_FILTER_AUTH (1 << 11)
-#define ZYD_FILTER_DEAUTH (1 << 12)
-#define ZYD_FILTER_PS_POLL (1 << 26)
-#define ZYD_FILTER_RTS (1 << 27)
-#define ZYD_FILTER_CTS (1 << 28)
-#define ZYD_FILTER_ACK (1 << 29)
-#define ZYD_FILTER_CFE (1 << 30)
-#define ZYD_FILTER_CFE_A (1 << 31)
-
-/* helpers for register ZYD_MAC_RXFILTER */
-#define ZYD_FILTER_MONITOR 0xffffffff
-#define ZYD_FILTER_BSS \
- (ZYD_FILTER_ASS_REQ | ZYD_FILTER_ASS_RSP | \
- ZYD_FILTER_REASS_REQ | ZYD_FILTER_REASS_RSP | \
- ZYD_FILTER_PRB_REQ | ZYD_FILTER_PRB_RSP | \
- (0x3 << 6) | \
- ZYD_FILTER_BCN | ZYD_FILTER_ATIM | ZYD_FILTER_DEASS | \
- ZYD_FILTER_AUTH | ZYD_FILTER_DEAUTH | \
- (0x7 << 13) | \
- ZYD_FILTER_PS_POLL | ZYD_FILTER_ACK)
-#define ZYD_FILTER_HOSTAP \
- (ZYD_FILTER_ASS_REQ | ZYD_FILTER_REASS_REQ | \
- ZYD_FILTER_PRB_REQ | ZYD_FILTER_DEASS | ZYD_FILTER_AUTH | \
- ZYD_FILTER_DEAUTH | ZYD_FILTER_PS_POLL)
-
-struct zyd_tx_desc {
- uint8_t phy;
-#define ZYD_TX_PHY_SIGNAL(x) ((x) & 0xf)
-#define ZYD_TX_PHY_OFDM (1 << 4)
-#define ZYD_TX_PHY_SHPREAMBLE (1 << 5) /* CCK */
-#define ZYD_TX_PHY_5GHZ (1 << 5) /* OFDM */
- uint16_t len;
- uint8_t flags;
-#define ZYD_TX_FLAG_BACKOFF (1 << 0)
-#define ZYD_TX_FLAG_MULTICAST (1 << 1)
-#define ZYD_TX_FLAG_TYPE(x) (((x) & 0x3) << 2)
-#define ZYD_TX_TYPE_DATA 0
-#define ZYD_TX_TYPE_PS_POLL 1
-#define ZYD_TX_TYPE_MGMT 2
-#define ZYD_TX_TYPE_CTL 3
-#define ZYD_TX_FLAG_WAKEUP (1 << 4)
-#define ZYD_TX_FLAG_RTS (1 << 5)
-#define ZYD_TX_FLAG_ENCRYPT (1 << 6)
-#define ZYD_TX_FLAG_CTS_TO_SELF (1 << 7)
- uint16_t pktlen;
- uint16_t plcp_length;
- uint8_t plcp_service;
-#define ZYD_PLCP_LENGEXT 0x80
- uint16_t nextlen;
-} __packed;
-
-struct zyd_plcphdr {
- uint8_t signal;
- uint8_t reserved[2];
- uint16_t service; /* unaligned! */
-} __packed;
-
-struct zyd_rx_stat {
- uint8_t signal_cck;
- uint8_t rssi;
- uint8_t signal_ofdm;
- uint8_t cipher;
-#define ZYD_RX_CIPHER_WEP64 1
-#define ZYD_RX_CIPHER_TKIP 2
-#define ZYD_RX_CIPHER_AES 4
-#define ZYD_RX_CIPHER_WEP128 5
-#define ZYD_RX_CIPHER_WEP256 6
-#define ZYD_RX_CIPHER_WEP \
- (ZYD_RX_CIPHER_WEP64 | ZYD_RX_CIPHER_WEP128 | ZYD_RX_CIPHER_WEP256)
- uint8_t flags;
-#define ZYD_RX_OFDM (1 << 0)
-#define ZYD_RX_TIMEOUT (1 << 1)
-#define ZYD_RX_OVERRUN (1 << 2)
-#define ZYD_RX_DECRYPTERR (1 << 3)
-#define ZYD_RX_BADCRC32 (1 << 4)
-#define ZYD_RX_NOT2ME (1 << 5)
-#define ZYD_RX_BADCRC16 (1 << 6)
-#define ZYD_RX_ERROR (1 << 7)
-} __packed;
-
-/* this structure may be unaligned */
-struct zyd_rx_desc {
-#define ZYD_MAX_RXFRAMECNT 3
- uWord len[ZYD_MAX_RXFRAMECNT];
- uWord tag;
-#define ZYD_TAG_MULTIFRAME 0x697e
-} __packed;
-
-/* I2C bus alike */
-struct zyd_rfwrite_cmd {
- uint16_t code;
- uint16_t width;
- uint16_t bit[32];
-#define ZYD_RF_IF_LE (1 << 1)
-#define ZYD_RF_CLK (1 << 2)
-#define ZYD_RF_DATA (1 << 3)
-} __packed;
-
-struct zyd_cmd {
- uint16_t code;
-#define ZYD_CMD_IOWR 0x0021 /* write HMAC or PHY register */
-#define ZYD_CMD_IORD 0x0022 /* read HMAC or PHY register */
-#define ZYD_CMD_RFCFG 0x0023 /* write RF register */
-#define ZYD_NOTIF_IORD 0x9001 /* response for ZYD_CMD_IORD */
-#define ZYD_NOTIF_MACINTR 0x9001 /* interrupt notification */
-#define ZYD_NOTIF_RETRYSTATUS 0xa001 /* Tx retry notification */
- uint8_t data[64];
-} __packed;
-
-/* structure for command ZYD_CMD_IOWR */
-struct zyd_pair {
- uint16_t reg;
-/* helpers macros to read/write 32-bit registers */
-#define ZYD_REG32_LO(reg) (reg)
-#define ZYD_REG32_HI(reg) \
- ((reg) + ((((reg) & 0xf000) == 0x9000) ? 2 : 1))
- uint16_t val;
-} __packed;
-
-/* structure for notification ZYD_NOTIF_RETRYSTATUS */
-struct zyd_notif_retry {
- uint16_t rate;
- uint8_t macaddr[IEEE80211_ADDR_LEN];
- uint16_t count;
-} __packed;
-
-#define ZYD_CONFIG_NO 1
-#define ZYD_IFACE_INDEX 0
-
-#define ZYD_INTR_TIMEOUT 1000
-#define ZYD_TX_TIMEOUT 10000
-
-#define ZYD_MAX_TXBUFSZ \
- (sizeof(struct zyd_tx_desc) + MCLBYTES)
-#define ZYD_MIN_FRAGSZ \
- (sizeof(struct zyd_plcphdr) + IEEE80211_MIN_LEN + \
- sizeof(struct zyd_rx_stat))
-#define ZYD_MIN_RXBUFSZ ZYD_MIN_FRAGSZ
-#define ZYX_MAX_RXBUFSZ \
- ((sizeof (struct zyd_plcphdr) + IEEE80211_MAX_LEN + \
- sizeof (struct zyd_rx_stat)) * ZYD_MAX_RXFRAMECNT + \
- sizeof (struct zyd_rx_desc))
-
-#define ZYD_RX_LIST_CNT 1
-#define ZYD_TX_LIST_CNT 5
-#define ZYD_CMD_FLAG_READ (1 << 0)
-
-/* quickly determine if a given rate is CCK or OFDM */
-#define ZYD_RATE_IS_OFDM(rate) ((rate) >= 12 && (rate) != 22)
-
-struct zyd_phy_pair {
- uint16_t reg;
- uint8_t val;
-};
-
-struct zyd_mac_pair {
- uint16_t reg;
- uint32_t val;
-};
-
-struct zyd_tx_data {
- struct zyd_softc *sc;
- usbd_xfer_handle xfer;
- uint8_t *buf;
- struct ieee80211_node *ni;
- struct mbuf *m;
-};
-
-struct zyd_rx_data {
- struct zyd_softc *sc;
- usbd_xfer_handle xfer;
- const uint8_t *buf;
-};
-
-struct zyd_node {
- struct ieee80211_node ni; /* must be the first */
- struct ieee80211_amrr_node amn;
-};
-#define ZYD_NODE(ni) ((struct zyd_node *)(ni))
-
-struct zyd_rx_radiotap_header {
- struct ieee80211_radiotap_header wr_ihdr;
- uint8_t wr_flags;
- uint8_t wr_rate;
- uint16_t wr_chan_freq;
- uint16_t wr_chan_flags;
- int8_t wr_antsignal;
- int8_t wr_antnoise;
-} __packed;
-
-#define ZYD_RX_RADIOTAP_PRESENT \
- ((1 << IEEE80211_RADIOTAP_FLAGS) | \
- (1 << IEEE80211_RADIOTAP_RATE) | \
- (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \
- (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) | \
- (1 << IEEE80211_RADIOTAP_CHANNEL))
-
-struct zyd_tx_radiotap_header {
- struct ieee80211_radiotap_header wt_ihdr;
- uint8_t wt_flags;
- uint8_t wt_rate;
- uint16_t wt_chan_freq;
- uint16_t wt_chan_flags;
-} __packed;
-
-#define ZYD_TX_RADIOTAP_PRESENT \
- ((1 << IEEE80211_RADIOTAP_FLAGS) | \
- (1 << IEEE80211_RADIOTAP_RATE) | \
- (1 << IEEE80211_RADIOTAP_CHANNEL))
-
-struct zyd_softc; /* forward declaration */
-
-struct zyd_rf {
- /* RF methods */
- int (*init)(struct zyd_rf *);
- int (*switch_radio)(struct zyd_rf *, int);
- int (*set_channel)(struct zyd_rf *, uint8_t);
- int (*bandedge6)(struct zyd_rf *,
- struct ieee80211_channel *);
- /* RF attributes */
- struct zyd_softc *rf_sc; /* back-pointer */
- int width;
-};
-
-struct zyd_rq {
- const uint16_t *idata;
- struct zyd_pair *odata;
- int len;
- STAILQ_ENTRY(zyd_rq) rq;
-};
-
-struct zyd_vap {
- struct ieee80211vap vap;
- int (*newstate)(struct ieee80211vap *,
- enum ieee80211_state, int);
- struct callout amrr_ch;
- struct ieee80211_amrr amrr;
-};
-#define ZYD_VAP(vap) ((struct zyd_vap *)(vap))
-
-struct zyd_softc {
- device_t sc_dev;
- usbd_device_handle sc_udev;
- usbd_interface_handle sc_iface;
- struct ifnet *sc_ifp;
-
- enum ieee80211_state sc_state;
- int sc_arg;
- int sc_flags;
-#define ZYD_FLAG_FWLOADED (1 << 0)
-#define ZYD_FLAG_DETACHING (1 << 1)
-#define ZYD_FLAG_INITONCE (1 << 2)
-#define ZYD_FLAG_INITDONE (1 << 3)
- int sc_if_flags;
- uint32_t sc_debug;
-
- struct usb_task sc_mcasttask;
- struct usb_task sc_scantask;
- int sc_scan_action;
-#define ZYD_SCAN_START 0
-#define ZYD_SCAN_END 1
-#define ZYD_SET_CHANNEL 2
- struct usb_task sc_task;
- struct callout sc_watchdog_ch;
-
- struct zyd_rf sc_rf;
-
- STAILQ_HEAD(, zyd_rq) sc_rqh;
-
- uint8_t sc_bssid[IEEE80211_ADDR_LEN];
- uint16_t sc_fwbase;
- uint8_t sc_regdomain;
- uint8_t sc_macrev;
- uint16_t sc_fwrev;
- uint8_t sc_rfrev;
- uint8_t sc_parev;
- uint8_t sc_al2230s;
- uint8_t sc_bandedge6;
- uint8_t sc_newphy;
- uint8_t sc_cckgain;
- uint8_t sc_fix_cr157;
- uint8_t sc_ledtype;
- uint8_t sc_txled;
-
- uint32_t sc_atim_wnd;
- uint32_t sc_pre_tbtt;
- uint32_t sc_bcn_int;
-
- uint8_t sc_pwrcal[14];
- uint8_t sc_pwrint[14];
- uint8_t sc_ofdm36_cal[14];
- uint8_t sc_ofdm48_cal[14];
- uint8_t sc_ofdm54_cal[14];
-#define ZYD_ENDPT_BOUT 0
-#define ZYD_ENDPT_BIN 1
-#define ZYD_ENDPT_IIN 2
-#define ZYD_ENDPT_IOUT 3
-#define ZYD_ENDPT_CNT 4
- usbd_pipe_handle sc_ep[ZYD_ENDPT_CNT];
- uint8_t *sc_ibuf;
-
- struct mtx sc_txmtx;
- struct zyd_rx_data sc_rxdata[ZYD_RX_LIST_CNT];
- struct zyd_tx_data sc_txdata[ZYD_TX_LIST_CNT];
- int sc_txidx;
- int sc_txqueued;
- int sc_txtimer;
-
- struct zyd_rx_radiotap_header sc_rxtap;
- int sc_rxtap_len;
- struct zyd_tx_radiotap_header sc_txtap;
- int sc_txtap_len;
-};
-
-#define ZYD_LOCK(sc) do { ((sc) = (sc)); mtx_lock(&Giant); } while (0)
-#define ZYD_UNLOCK(sc) mtx_unlock(&Giant)
-#define ZYD_TX_LOCK(sc) mtx_lock(&(sc)->sc_txmtx)
-#define ZYD_TX_UNLOCK(sc) mtx_unlock(&(sc)->sc_txmtx)
-
diff --git a/sys/dev/usb/kue_fw.h b/sys/dev/usb/kue_fw.h
deleted file mode 100644
index 8934465..0000000
--- a/sys/dev/usb/kue_fw.h
+++ /dev/null
@@ -1,685 +0,0 @@
-/*-
- * Copyright (c) 1997, 1998, 1999, 2000
- * Bill Paul <wpaul@ee.columbia.edu>. 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$
- */
-
-/*
- * This file contains the firmware needed to make the KLSI chip work,
- * along with a few constants related to the QT Engine microcontroller
- * embedded in the KLSI part.
- *
- * Firmware is loaded using the vendor-specific 'send scan data'
- * command (0xFF). The basic operation is that we must load the
- * firmware, then issue some trigger commands to fix it up and start
- * it running. There are three transfers: load the binary code,
- * load the 'fixup' (data segment?), then issue a command to
- * start the code firmware running. The data itself is prefixed by
- * a 16-bit signature word, a 16-bit length value, a type byte
- * and an interrupt (command) byte. The code segment is of type
- * 0x02 (replacement interrupt vector data) and the fixup segment
- * is of type 0x03 (replacement interrupt fixup data). The interrupt
- * code is 0x64 (load new code). The length word is the total length
- * of the segment minus 7. I precomputed the values and stuck them
- * into the appropriate locations within the segments to save some
- * work in the driver.
- */
-
-/* QT controller data block types. */
-/* Write data into specific memory location. */
-#define KUE_QTBTYPE_WRITE_DATA 0x00
-/* Write data into interrupt vector location */
-#define KUE_QTBTYPE_WRITE_INTVEC 0x01
-/* Replace interrupt vector with this data */
-#define KUE_QTBTYPE_REPL_INTVEC 0x02
-/* Fixup interrupt vector code with this data */
-#define KUE_QTBTYPE_FIXUP_INTVEC 0x03
-/* Force jump to location */
-#define KUE_QTBTYPE_JUMP 0x04
-/* Force call to location */
-#define KUE_QTBTYPE_CALL 0x05
-/* Force interrupt call */
-#define KUE_QTBTYPE_CALLINTR 0x06
-/*
- * Cause data to be written using the specified QT engine
- * interrupt, from starting location in memory for a specified
- * number of bytes.
- */
-#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
-/* Cause data to be written to config locations. */
-/* Addresses assume 0xc000 offset. */
-#define KUE_QTBTYPE_WRITE_CONFIG 0x09
-
-#define KUE_QTINTR_LOAD_CODE 0x64
-#define KUE_QTINTR_TRIGGER_CODE 0x3B
-#define KUE_QTINTR_LOAD_CODE_HIGH 0x9C
-
-/* Firmware code segment */
-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. */
- /******************************************/
- 0xB6, 0xC3, 0xf7, 0x0e, 0x02, 0x64,
- 0x9f, 0xcf, 0xbc, 0x08, 0xe7, 0x57, 0x00, 0x00,
- 0x9a, 0x08, 0x97, 0xc1, 0xe7, 0x67, 0xff, 0x1f,
- 0x28, 0xc0, 0xe7, 0x87, 0x00, 0x04, 0x24, 0xc0,
- 0xe7, 0x67, 0xff, 0xf9, 0x22, 0xc0, 0x97, 0xcf,
- 0xe7, 0x09, 0xa2, 0xc0, 0x94, 0x08, 0xd7, 0x09,
- 0x00, 0xc0, 0xe7, 0x59, 0xba, 0x08, 0x94, 0x08,
- 0x03, 0xc1, 0xe7, 0x67, 0xff, 0xf7, 0x24, 0xc0,
- 0xe7, 0x05, 0x00, 0xc0, 0xa7, 0xcf, 0x92, 0x08,
- 0xe7, 0x57, 0x00, 0x00, 0x8e, 0x08, 0xa7, 0xa1,
- 0x8e, 0x08, 0x97, 0xcf, 0xe7, 0x57, 0x00, 0x00,
- 0xf2, 0x09, 0x0a, 0xc0, 0xe7, 0x57, 0x00, 0x00,
- 0xa4, 0xc0, 0xa7, 0xc0, 0x56, 0x08, 0x9f, 0xaf,
- 0x70, 0x09, 0xe7, 0x07, 0x00, 0x00, 0xf2, 0x09,
- 0xe7, 0x57, 0xff, 0xff, 0x90, 0x08, 0x9f, 0xa0,
- 0x40, 0x00, 0xe7, 0x59, 0x90, 0x08, 0x94, 0x08,
- 0x9f, 0xa0, 0x40, 0x00, 0xc8, 0x09, 0xa2, 0x08,
- 0x08, 0x62, 0x9f, 0xa1, 0x14, 0x0a, 0xe7, 0x57,
- 0x00, 0x00, 0x52, 0x08, 0xa7, 0xc0, 0x56, 0x08,
- 0x9f, 0xaf, 0x04, 0x00, 0xe7, 0x57, 0x00, 0x00,
- 0x8e, 0x08, 0xa7, 0xc1, 0x56, 0x08, 0xc0, 0x09,
- 0xa8, 0x08, 0x00, 0x60, 0x05, 0xc4, 0xc0, 0x59,
- 0x94, 0x08, 0x02, 0xc0, 0x9f, 0xaf, 0xee, 0x00,
- 0xe7, 0x59, 0xae, 0x08, 0x94, 0x08, 0x02, 0xc1,
- 0x9f, 0xaf, 0xf6, 0x00, 0x9f, 0xaf, 0x9e, 0x03,
- 0xef, 0x57, 0x00, 0x00, 0xf0, 0x09, 0x9f, 0xa1,
- 0xde, 0x01, 0xe7, 0x57, 0x00, 0x00, 0x78, 0x08,
- 0x9f, 0xa0, 0xe4, 0x03, 0x9f, 0xaf, 0x2c, 0x04,
- 0xa7, 0xcf, 0x56, 0x08, 0x48, 0x02, 0xe7, 0x09,
- 0x94, 0x08, 0xa8, 0x08, 0xc8, 0x37, 0x04, 0x00,
- 0x9f, 0xaf, 0x68, 0x04, 0x97, 0xcf, 0xe7, 0x57,
- 0x00, 0x00, 0xa6, 0x08, 0x97, 0xc0, 0xd7, 0x09,
- 0x00, 0xc0, 0xc1, 0xdf, 0xc8, 0x09, 0x9c, 0x08,
- 0x08, 0x62, 0x1d, 0xc0, 0x27, 0x04, 0x9c, 0x08,
- 0x10, 0x94, 0xf0, 0x07, 0xee, 0x09, 0x02, 0x00,
- 0xc1, 0x07, 0x01, 0x00, 0x70, 0x00, 0x04, 0x00,
- 0xf0, 0x07, 0x44, 0x01, 0x06, 0x00, 0x50, 0xaf,
- 0xe7, 0x09, 0x94, 0x08, 0xae, 0x08, 0xe7, 0x17,
- 0x14, 0x00, 0xae, 0x08, 0xe7, 0x67, 0xff, 0x07,
- 0xae, 0x08, 0xe7, 0x07, 0xff, 0xff, 0xa8, 0x08,
- 0xe7, 0x07, 0x00, 0x00, 0xa6, 0x08, 0xe7, 0x05,
- 0x00, 0xc0, 0x97, 0xcf, 0xd7, 0x09, 0x00, 0xc0,
- 0xc1, 0xdf, 0x48, 0x02, 0xd0, 0x09, 0x9c, 0x08,
- 0x27, 0x02, 0x9c, 0x08, 0xe7, 0x09, 0x20, 0xc0,
- 0xee, 0x09, 0xe7, 0xd0, 0xee, 0x09, 0xe7, 0x05,
- 0x00, 0xc0, 0x97, 0xcf, 0x48, 0x02, 0xc8, 0x37,
- 0x04, 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00, 0x60,
- 0x21, 0xc0, 0xc0, 0x37, 0x3e, 0x00, 0x23, 0xc9,
- 0xc0, 0x57, 0xb4, 0x05, 0x1b, 0xc8, 0xc0, 0x17,
- 0x3f, 0x00, 0xc0, 0x67, 0xc0, 0xff, 0x30, 0x00,
- 0x08, 0x00, 0xf0, 0x07, 0x00, 0x00, 0x04, 0x00,
- 0x00, 0x02, 0xc0, 0x17, 0x4c, 0x00, 0x30, 0x00,
- 0x06, 0x00, 0xf0, 0x07, 0xbe, 0x01, 0x0a, 0x00,
- 0x48, 0x02, 0xc1, 0x07, 0x02, 0x00, 0xd7, 0x09,
- 0x00, 0xc0, 0xc1, 0xdf, 0x51, 0xaf, 0xe7, 0x05,
- 0x00, 0xc0, 0x97, 0xcf, 0x9f, 0xaf, 0x68, 0x04,
- 0x9f, 0xaf, 0xe4, 0x03, 0x97, 0xcf, 0x9f, 0xaf,
- 0xe4, 0x03, 0xc9, 0x37, 0x04, 0x00, 0xc1, 0xdf,
- 0xc8, 0x09, 0x70, 0x08, 0x50, 0x02, 0x67, 0x02,
- 0x70, 0x08, 0xd1, 0x07, 0x00, 0x00, 0xc0, 0xdf,
- 0x9f, 0xaf, 0xde, 0x01, 0x97, 0xcf, 0xe7, 0x57,
- 0x00, 0x00, 0xaa, 0x08, 0x97, 0xc1, 0xe7, 0x57,
- 0x01, 0x00, 0x7a, 0x08, 0x97, 0xc0, 0xc8, 0x09,
- 0x6e, 0x08, 0x08, 0x62, 0x97, 0xc0, 0x00, 0x02,
- 0xc0, 0x17, 0x0e, 0x00, 0x27, 0x00, 0x34, 0x01,
- 0x27, 0x0c, 0x0c, 0x00, 0x36, 0x01, 0xef, 0x57,
- 0x00, 0x00, 0xf0, 0x09, 0x9f, 0xc0, 0xbe, 0x02,
- 0xe7, 0x57, 0x00, 0x00, 0xb0, 0x08, 0x97, 0xc1,
- 0xe7, 0x07, 0x09, 0x00, 0x12, 0xc0, 0xe7, 0x77,
- 0x00, 0x08, 0x20, 0xc0, 0x9f, 0xc1, 0xb6, 0x02,
- 0xe7, 0x57, 0x09, 0x00, 0x12, 0xc0, 0x77, 0xc9,
- 0xd7, 0x09, 0x00, 0xc0, 0xc1, 0xdf, 0xe7, 0x77,
- 0x00, 0x08, 0x20, 0xc0, 0x2f, 0xc1, 0xe7, 0x07,
- 0x00, 0x00, 0x42, 0xc0, 0xe7, 0x07, 0x05, 0x00,
- 0x90, 0xc0, 0xc8, 0x07, 0x0a, 0x00, 0xe7, 0x77,
- 0x04, 0x00, 0x20, 0xc0, 0x09, 0xc1, 0x08, 0xda,
- 0x7a, 0xc1, 0xe7, 0x07, 0x00, 0x01, 0x42, 0xc0,
- 0xe7, 0x07, 0x04, 0x00, 0x90, 0xc0, 0x1a, 0xcf,
- 0xe7, 0x07, 0x01, 0x00, 0x7a, 0x08, 0x00, 0xd8,
- 0x27, 0x50, 0x34, 0x01, 0x17, 0xc1, 0xe7, 0x77,
- 0x02, 0x00, 0x20, 0xc0, 0x79, 0xc1, 0x27, 0x50,
- 0x34, 0x01, 0x10, 0xc1, 0xe7, 0x77, 0x02, 0x00,
- 0x20, 0xc0, 0x79, 0xc0, 0x9f, 0xaf, 0xd8, 0x02,
- 0xe7, 0x05, 0x00, 0xc0, 0x00, 0x60, 0x9f, 0xc0,
- 0xde, 0x01, 0x97, 0xcf, 0xe7, 0x07, 0x01, 0x00,
- 0xb8, 0x08, 0x06, 0xcf, 0xe7, 0x07, 0x30, 0x0e,
- 0x02, 0x00, 0xe7, 0x07, 0x50, 0xc3, 0x12, 0xc0,
- 0xe7, 0x05, 0x00, 0xc0, 0x97, 0xcf, 0xe7, 0x07,
- 0x01, 0x00, 0xb8, 0x08, 0x97, 0xcf, 0xe7, 0x07,
- 0x50, 0xc3, 0x12, 0xc0, 0xe7, 0x07, 0x30, 0x0e,
- 0x02, 0x00, 0xe7, 0x07, 0x01, 0x00, 0x7a, 0x08,
- 0xe7, 0x07, 0x05, 0x00, 0x90, 0xc0, 0x97, 0xcf,
- 0xe7, 0x07, 0x00, 0x01, 0x42, 0xc0, 0xe7, 0x07,
- 0x04, 0x00, 0x90, 0xc0, 0xe7, 0x07, 0x00, 0x00,
- 0x7a, 0x08, 0xe7, 0x57, 0x0f, 0x00, 0xb2, 0x08,
- 0x13, 0xc1, 0x9f, 0xaf, 0x2e, 0x08, 0xca, 0x09,
- 0xac, 0x08, 0xf2, 0x17, 0x01, 0x00, 0x5c, 0x00,
- 0xf2, 0x27, 0x00, 0x00, 0x5e, 0x00, 0xe7, 0x07,
- 0x00, 0x00, 0xb2, 0x08, 0xe7, 0x07, 0x01, 0x00,
- 0xb4, 0x08, 0xc0, 0x07, 0xff, 0xff, 0x97, 0xcf,
- 0x9f, 0xaf, 0x4c, 0x03, 0xc0, 0x69, 0xb4, 0x08,
- 0x57, 0x00, 0x9f, 0xde, 0x33, 0x00, 0xc1, 0x05,
- 0x27, 0xd8, 0xb2, 0x08, 0x27, 0xd2, 0xb4, 0x08,
- 0xe7, 0x87, 0x01, 0x00, 0xb4, 0x08, 0xe7, 0x67,
- 0xff, 0x03, 0xb4, 0x08, 0x00, 0x60, 0x97, 0xc0,
- 0xe7, 0x07, 0x01, 0x00, 0xb0, 0x08, 0x27, 0x00,
- 0x12, 0xc0, 0x97, 0xcf, 0xc0, 0x09, 0xb6, 0x08,
- 0x00, 0xd2, 0x02, 0xc3, 0xc0, 0x97, 0x05, 0x80,
- 0x27, 0x00, 0xb6, 0x08, 0xc0, 0x99, 0x82, 0x08,
- 0xc0, 0x99, 0xa2, 0xc0, 0x97, 0xcf, 0xe7, 0x07,
- 0x00, 0x00, 0xb0, 0x08, 0xc0, 0xdf, 0x97, 0xcf,
- 0xc8, 0x09, 0x72, 0x08, 0x08, 0x62, 0x02, 0xc0,
- 0x10, 0x64, 0x07, 0xc1, 0xe7, 0x07, 0x00, 0x00,
- 0x64, 0x08, 0xe7, 0x07, 0xc8, 0x05, 0x24, 0x00,
- 0x97, 0xcf, 0x27, 0x04, 0x72, 0x08, 0xc8, 0x17,
- 0x0e, 0x00, 0x27, 0x02, 0x64, 0x08, 0xe7, 0x07,
- 0xd6, 0x05, 0x24, 0x00, 0x97, 0xcf, 0xd7, 0x09,
- 0x00, 0xc0, 0xc1, 0xdf, 0xe7, 0x57, 0x00, 0x00,
- 0x62, 0x08, 0x13, 0xc1, 0x9f, 0xaf, 0x70, 0x03,
- 0xe7, 0x57, 0x00, 0x00, 0x64, 0x08, 0x13, 0xc0,
- 0xe7, 0x09, 0x64, 0x08, 0x30, 0x01, 0xe7, 0x07,
- 0xf2, 0x05, 0x32, 0x01, 0xe7, 0x07, 0x10, 0x00,
- 0x96, 0xc0, 0xe7, 0x09, 0x64, 0x08, 0x62, 0x08,
- 0x04, 0xcf, 0xe7, 0x57, 0x00, 0x00, 0x64, 0x08,
- 0x02, 0xc1, 0x9f, 0xaf, 0x70, 0x03, 0xe7, 0x05,
- 0x00, 0xc0, 0x97, 0xcf, 0xd7, 0x09, 0x00, 0xc0,
- 0xc1, 0xdf, 0xc8, 0x09, 0x72, 0x08, 0x27, 0x02,
- 0x78, 0x08, 0x08, 0x62, 0x03, 0xc1, 0xe7, 0x05,
- 0x00, 0xc0, 0x97, 0xcf, 0x27, 0x04, 0x72, 0x08,
- 0xe7, 0x05, 0x00, 0xc0, 0xf0, 0x07, 0x40, 0x00,
- 0x08, 0x00, 0xf0, 0x07, 0x00, 0x00, 0x04, 0x00,
- 0x00, 0x02, 0xc0, 0x17, 0x0c, 0x00, 0x30, 0x00,
- 0x06, 0x00, 0xf0, 0x07, 0x64, 0x01, 0x0a, 0x00,
- 0xc8, 0x17, 0x04, 0x00, 0xc1, 0x07, 0x02, 0x00,
- 0x51, 0xaf, 0x97, 0xcf, 0xe7, 0x57, 0x00, 0x00,
- 0x6a, 0x08, 0x97, 0xc0, 0xc1, 0xdf, 0xc8, 0x09,
- 0x6a, 0x08, 0x27, 0x04, 0x6a, 0x08, 0x27, 0x52,
- 0x6c, 0x08, 0x03, 0xc1, 0xe7, 0x07, 0x6a, 0x08,
- 0x6c, 0x08, 0xc0, 0xdf, 0x17, 0x02, 0xc8, 0x17,
- 0x0e, 0x00, 0x9f, 0xaf, 0x16, 0x05, 0xc8, 0x05,
- 0x00, 0x60, 0x03, 0xc0, 0x9f, 0xaf, 0x80, 0x04,
- 0x97, 0xcf, 0x9f, 0xaf, 0x68, 0x04, 0x97, 0xcf,
- 0xd7, 0x09, 0x00, 0xc0, 0xc1, 0xdf, 0x08, 0x62,
- 0x1c, 0xc0, 0xd0, 0x09, 0x72, 0x08, 0x27, 0x02,
- 0x72, 0x08, 0xe7, 0x05, 0x00, 0xc0, 0x97, 0xcf,
- 0x97, 0x02, 0xca, 0x09, 0xac, 0x08, 0xf2, 0x17,
- 0x01, 0x00, 0x04, 0x00, 0xf2, 0x27, 0x00, 0x00,
- 0x06, 0x00, 0xca, 0x17, 0x2c, 0x00, 0xf8, 0x77,
- 0x01, 0x00, 0x0e, 0x00, 0x06, 0xc0, 0xca, 0xd9,
- 0xf8, 0x57, 0xff, 0x00, 0x0e, 0x00, 0x01, 0xc1,
- 0xca, 0xd9, 0x22, 0x1c, 0x0c, 0x00, 0xe2, 0x27,
- 0x00, 0x00, 0xe2, 0x17, 0x01, 0x00, 0xe2, 0x27,
- 0x00, 0x00, 0xca, 0x05, 0x00, 0x0c, 0x0c, 0x00,
- 0xc0, 0x17, 0x41, 0x00, 0xc0, 0x67, 0xc0, 0xff,
- 0x30, 0x00, 0x08, 0x00, 0x00, 0x02, 0xc0, 0x17,
- 0x0c, 0x00, 0x30, 0x00, 0x06, 0x00, 0xf0, 0x07,
- 0xdc, 0x00, 0x0a, 0x00, 0xf0, 0x07, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x0c, 0x08, 0x00, 0x40, 0xd1,
- 0x01, 0x00, 0xc0, 0x19, 0xa6, 0x08, 0xc0, 0x59,
- 0x98, 0x08, 0x04, 0xc9, 0x49, 0xaf, 0x9f, 0xaf,
- 0xee, 0x00, 0x4a, 0xaf, 0x67, 0x10, 0xa6, 0x08,
- 0xc8, 0x17, 0x04, 0x00, 0xc1, 0x07, 0x01, 0x00,
- 0xd7, 0x09, 0x00, 0xc0, 0xc1, 0xdf, 0x50, 0xaf,
- 0xe7, 0x05, 0x00, 0xc0, 0x97, 0xcf, 0xc0, 0x07,
- 0x01, 0x00, 0xc1, 0x09, 0x7c, 0x08, 0xc1, 0x77,
- 0x01, 0x00, 0x97, 0xc1, 0xd8, 0x77, 0x01, 0x00,
- 0x12, 0xc0, 0xc9, 0x07, 0x4c, 0x08, 0x9f, 0xaf,
- 0x64, 0x05, 0x04, 0xc1, 0xc1, 0x77, 0x08, 0x00,
- 0x13, 0xc0, 0x97, 0xcf, 0xc1, 0x77, 0x02, 0x00,
- 0x97, 0xc1, 0xc1, 0x77, 0x10, 0x00, 0x0c, 0xc0,
- 0x9f, 0xaf, 0x86, 0x05, 0x97, 0xcf, 0xc1, 0x77,
- 0x04, 0x00, 0x06, 0xc0, 0xc9, 0x07, 0x7e, 0x08,
- 0x9f, 0xaf, 0x64, 0x05, 0x97, 0xc0, 0x00, 0xcf,
- 0x00, 0x90, 0x97, 0xcf, 0x50, 0x54, 0x97, 0xc1,
- 0x70, 0x5c, 0x02, 0x00, 0x02, 0x00, 0x97, 0xc1,
- 0x70, 0x5c, 0x04, 0x00, 0x04, 0x00, 0x97, 0xcf,
- 0xc0, 0x00, 0x60, 0x00, 0x30, 0x00, 0x18, 0x00,
- 0x0c, 0x00, 0x06, 0x00, 0x00, 0x00, 0xcb, 0x09,
- 0x88, 0x08, 0xcc, 0x09, 0x8a, 0x08, 0x0b, 0x53,
- 0x11, 0xc0, 0xc9, 0x02, 0xca, 0x07, 0x78, 0x05,
- 0x9f, 0xaf, 0x64, 0x05, 0x97, 0xc0, 0x0a, 0xc8,
- 0x82, 0x08, 0x0a, 0xcf, 0x82, 0x08, 0x9f, 0xaf,
- 0x64, 0x05, 0x97, 0xc0, 0x05, 0xc2, 0x89, 0x30,
- 0x82, 0x60, 0x78, 0xc1, 0x00, 0x90, 0x97, 0xcf,
- 0x89, 0x10, 0x09, 0x53, 0x79, 0xc2, 0x89, 0x30,
- 0x82, 0x08, 0x7a, 0xcf, 0xc0, 0xdf, 0x97, 0xcf,
- 0xe7, 0x09, 0x96, 0xc0, 0x66, 0x08, 0xe7, 0x09,
- 0x98, 0xc0, 0x68, 0x08, 0x0f, 0xcf, 0xe7, 0x09,
- 0x96, 0xc0, 0x66, 0x08, 0xe7, 0x09, 0x98, 0xc0,
- 0x68, 0x08, 0xe7, 0x09, 0x64, 0x08, 0x30, 0x01,
- 0xe7, 0x07, 0xf2, 0x05, 0x32, 0x01, 0xe7, 0x07,
- 0x10, 0x00, 0x96, 0xc0, 0xd7, 0x09, 0x00, 0xc0,
- 0x17, 0x02, 0xc8, 0x09, 0x62, 0x08, 0xc8, 0x37,
- 0x0e, 0x00, 0xe7, 0x57, 0x04, 0x00, 0x68, 0x08,
- 0x3d, 0xc0, 0xe7, 0x87, 0x00, 0x08, 0x24, 0xc0,
- 0xe7, 0x09, 0x94, 0x08, 0xba, 0x08, 0xe7, 0x17,
- 0x64, 0x00, 0xba, 0x08, 0xe7, 0x67, 0xff, 0x07,
- 0xba, 0x08, 0xe7, 0x77, 0x2a, 0x00, 0x66, 0x08,
- 0x30, 0xc0, 0x97, 0x02, 0xca, 0x09, 0xac, 0x08,
- 0xe7, 0x77, 0x20, 0x00, 0x66, 0x08, 0x0e, 0xc0,
- 0xf2, 0x17, 0x01, 0x00, 0x10, 0x00, 0xf2, 0x27,
- 0x00, 0x00, 0x12, 0x00, 0xe7, 0x77, 0x0a, 0x00,
- 0x66, 0x08, 0xca, 0x05, 0x1e, 0xc0, 0x97, 0x02,
- 0xca, 0x09, 0xac, 0x08, 0xf2, 0x17, 0x01, 0x00,
- 0x0c, 0x00, 0xf2, 0x27, 0x00, 0x00, 0x0e, 0x00,
- 0xe7, 0x77, 0x02, 0x00, 0x66, 0x08, 0x07, 0xc0,
- 0xf2, 0x17, 0x01, 0x00, 0x44, 0x00, 0xf2, 0x27,
- 0x00, 0x00, 0x46, 0x00, 0x06, 0xcf, 0xf2, 0x17,
- 0x01, 0x00, 0x60, 0x00, 0xf2, 0x27, 0x00, 0x00,
- 0x62, 0x00, 0xca, 0x05, 0x9f, 0xaf, 0x68, 0x04,
- 0x0f, 0xcf, 0x57, 0x02, 0x09, 0x02, 0xf1, 0x09,
- 0x68, 0x08, 0x0c, 0x00, 0xf1, 0xda, 0x0c, 0x00,
- 0xc8, 0x09, 0x6c, 0x08, 0x50, 0x02, 0x67, 0x02,
- 0x6c, 0x08, 0xd1, 0x07, 0x00, 0x00, 0xc9, 0x05,
- 0xe7, 0x09, 0x64, 0x08, 0x62, 0x08, 0xe7, 0x57,
- 0x00, 0x00, 0x62, 0x08, 0x02, 0xc0, 0x9f, 0xaf,
- 0x70, 0x03, 0xc8, 0x05, 0xe7, 0x05, 0x00, 0xc0,
- 0xc0, 0xdf, 0x97, 0xcf, 0xd7, 0x09, 0x00, 0xc0,
- 0x17, 0x00, 0x17, 0x02, 0x97, 0x02, 0xc0, 0x09,
- 0x92, 0xc0, 0xe7, 0x87, 0x00, 0x08, 0x24, 0xc0,
- 0xe7, 0x09, 0x94, 0x08, 0xba, 0x08, 0xe7, 0x17,
- 0x64, 0x00, 0xba, 0x08, 0xe7, 0x67, 0xff, 0x07,
- 0xba, 0x08, 0xe7, 0x07, 0x04, 0x00, 0x90, 0xc0,
- 0xca, 0x09, 0xac, 0x08, 0xe7, 0x07, 0x00, 0x00,
- 0x7a, 0x08, 0xe7, 0x07, 0x66, 0x03, 0x02, 0x00,
- 0xc0, 0x77, 0x02, 0x00, 0x10, 0xc0, 0xef, 0x57,
- 0x00, 0x00, 0xf0, 0x09, 0x04, 0xc0, 0x9f, 0xaf,
- 0xd8, 0x02, 0x9f, 0xcf, 0x12, 0x08, 0xf2, 0x17,
- 0x01, 0x00, 0x50, 0x00, 0xf2, 0x27, 0x00, 0x00,
- 0x52, 0x00, 0x9f, 0xcf, 0x12, 0x08, 0xef, 0x57,
- 0x00, 0x00, 0xf0, 0x09, 0x08, 0xc0, 0xe7, 0x57,
- 0x00, 0x00, 0xb8, 0x08, 0xe7, 0x07, 0x00, 0x00,
- 0xb8, 0x08, 0x0a, 0xc0, 0x03, 0xcf, 0xc0, 0x77,
- 0x10, 0x00, 0x06, 0xc0, 0xf2, 0x17, 0x01, 0x00,
- 0x58, 0x00, 0xf2, 0x27, 0x00, 0x00, 0x5a, 0x00,
- 0xc0, 0x77, 0x80, 0x00, 0x06, 0xc0, 0xf2, 0x17,
- 0x01, 0x00, 0x70, 0x00, 0xf2, 0x27, 0x00, 0x00,
- 0x72, 0x00, 0xc0, 0x77, 0x08, 0x00, 0x1d, 0xc1,
- 0xf2, 0x17, 0x01, 0x00, 0x08, 0x00, 0xf2, 0x27,
- 0x00, 0x00, 0x0a, 0x00, 0xc0, 0x77, 0x00, 0x02,
- 0x06, 0xc0, 0xf2, 0x17, 0x01, 0x00, 0x64, 0x00,
- 0xf2, 0x27, 0x00, 0x00, 0x66, 0x00, 0xc0, 0x77,
- 0x40, 0x00, 0x06, 0xc0, 0xf2, 0x17, 0x01, 0x00,
- 0x5c, 0x00, 0xf2, 0x27, 0x00, 0x00, 0x5e, 0x00,
- 0xc0, 0x77, 0x01, 0x00, 0x01, 0xc0, 0x37, 0xcf,
- 0x36, 0xcf, 0xf2, 0x17, 0x01, 0x00, 0x00, 0x00,
- 0xf2, 0x27, 0x00, 0x00, 0x02, 0x00, 0xef, 0x57,
- 0x00, 0x00, 0xf0, 0x09, 0x18, 0xc0, 0xe7, 0x57,
- 0x01, 0x00, 0xb2, 0x08, 0x0e, 0xc2, 0x07, 0xc8,
- 0xf2, 0x17, 0x01, 0x00, 0x50, 0x00, 0xf2, 0x27,
- 0x00, 0x00, 0x52, 0x00, 0x06, 0xcf, 0xf2, 0x17,
- 0x01, 0x00, 0x54, 0x00, 0xf2, 0x27, 0x00, 0x00,
- 0x56, 0x00, 0xe7, 0x07, 0x00, 0x00, 0xb2, 0x08,
- 0xe7, 0x07, 0x01, 0x00, 0xb4, 0x08, 0xc8, 0x09,
- 0x34, 0x01, 0xca, 0x17, 0x14, 0x00, 0xd8, 0x77,
- 0x01, 0x00, 0x05, 0xc0, 0xca, 0xd9, 0xd8, 0x57,
- 0xff, 0x00, 0x01, 0xc0, 0xca, 0xd9, 0xe2, 0x19,
- 0x94, 0xc0, 0xe2, 0x27, 0x00, 0x00, 0xe2, 0x17,
- 0x01, 0x00, 0xe2, 0x27, 0x00, 0x00, 0x9f, 0xaf,
- 0x2e, 0x08, 0x9f, 0xaf, 0xde, 0x01, 0xe7, 0x57,
- 0x00, 0x00, 0xaa, 0x08, 0x9f, 0xa1, 0xf0, 0x0b,
- 0xca, 0x05, 0xc8, 0x05, 0xc0, 0x05, 0xe7, 0x05,
- 0x00, 0xc0, 0xc0, 0xdf, 0x97, 0xcf, 0xc8, 0x09,
- 0x6e, 0x08, 0x08, 0x62, 0x97, 0xc0, 0x27, 0x04,
- 0x6e, 0x08, 0x27, 0x52, 0x70, 0x08, 0x03, 0xc1,
- 0xe7, 0x07, 0x6e, 0x08, 0x70, 0x08, 0x9f, 0xaf,
- 0x68, 0x04, 0x97, 0xcf, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x33, 0xcc,
- 0x00, 0x00, 0x00, 0x00, 0xe7, 0x57, 0x00, 0x80,
- 0xb2, 0x00, 0x06, 0xc2, 0xe7, 0x07, 0x52, 0x0e,
- 0x12, 0x00, 0xe7, 0x07, 0x98, 0x0e, 0xb2, 0x00,
- 0xe7, 0x07, 0xa4, 0x09, 0xf2, 0x02, 0xc8, 0x09,
- 0xb4, 0x00, 0xf8, 0x07, 0x02, 0x00, 0x0d, 0x00,
- 0xd7, 0x09, 0x0e, 0xc0, 0xe7, 0x07, 0x00, 0x00,
- 0x0e, 0xc0, 0xc8, 0x09, 0xdc, 0x00, 0xf0, 0x07,
- 0xff, 0xff, 0x09, 0x00, 0xf0, 0x07, 0xfb, 0x13,
- 0x0b, 0x00, 0xe7, 0x09, 0xc0, 0x00, 0x58, 0x08,
- 0xe7, 0x09, 0xbe, 0x00, 0x54, 0x08, 0xe7, 0x09,
- 0x10, 0x00, 0x92, 0x08, 0xc8, 0x07, 0xb4, 0x09,
- 0x9f, 0xaf, 0x8c, 0x09, 0x9f, 0xaf, 0xe2, 0x0b,
- 0xc0, 0x07, 0x80, 0x01, 0x44, 0xaf, 0x27, 0x00,
- 0x88, 0x08, 0x27, 0x00, 0x8a, 0x08, 0x27, 0x00,
- 0x8c, 0x08, 0xc0, 0x07, 0x74, 0x00, 0x44, 0xaf,
- 0x27, 0x00, 0xac, 0x08, 0x08, 0x00, 0x00, 0x90,
- 0xc1, 0x07, 0x1d, 0x00, 0x20, 0x00, 0x20, 0x00,
- 0x01, 0xda, 0x7c, 0xc1, 0x9f, 0xaf, 0x8a, 0x0b,
- 0xc0, 0x07, 0x4c, 0x00, 0x48, 0xaf, 0x27, 0x00,
- 0x56, 0x08, 0x9f, 0xaf, 0x72, 0x0c, 0xe7, 0x07,
- 0x00, 0x80, 0x96, 0x08, 0xef, 0x57, 0x00, 0x00,
- 0xf0, 0x09, 0x03, 0xc0, 0xe7, 0x07, 0x01, 0x00,
- 0x1c, 0xc0, 0xe7, 0x05, 0x0e, 0xc0, 0x97, 0xcf,
- 0x49, 0xaf, 0xe7, 0x87, 0x43, 0x00, 0x0e, 0xc0,
- 0xe7, 0x07, 0xff, 0xff, 0x94, 0x08, 0x9f, 0xaf,
- 0x8a, 0x0c, 0xc0, 0x07, 0x01, 0x00, 0x60, 0xaf,
- 0x4a, 0xaf, 0x97, 0xcf, 0x00, 0x08, 0x09, 0x08,
- 0x11, 0x08, 0x00, 0xda, 0x7c, 0xc1, 0x97, 0xcf,
- 0x67, 0x04, 0xcc, 0x02, 0xc0, 0xdf, 0x51, 0x94,
- 0xb1, 0xaf, 0x06, 0x00, 0xc1, 0xdf, 0xc9, 0x09,
- 0xcc, 0x02, 0x49, 0x62, 0x75, 0xc1, 0xc0, 0xdf,
- 0xa7, 0xcf, 0xd6, 0x02, 0x0e, 0x00, 0x24, 0x00,
- 0xd6, 0x05, 0x22, 0x00, 0xc4, 0x06, 0xd0, 0x00,
- 0xf0, 0x0b, 0xaa, 0x00, 0x0e, 0x0a, 0xbe, 0x00,
- 0x2c, 0x0c, 0x10, 0x00, 0x20, 0x00, 0x04, 0x00,
- 0xc4, 0x05, 0x02, 0x00, 0x66, 0x03, 0x06, 0x00,
- 0x00, 0x00, 0x24, 0xc0, 0x04, 0x04, 0x28, 0xc0,
- 0xfe, 0xfb, 0x1e, 0xc0, 0x00, 0x04, 0x22, 0xc0,
- 0xff, 0xf0, 0xc0, 0x00, 0x60, 0x0b, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0xff, 0x34, 0x0a, 0x3e, 0x0a,
- 0x9e, 0x0a, 0xa8, 0x0a, 0xce, 0x0a, 0xd2, 0x0a,
- 0xd6, 0x0a, 0x00, 0x0b, 0x10, 0x0b, 0x1e, 0x0b,
- 0x20, 0x0b, 0x28, 0x0b, 0x28, 0x0b, 0x27, 0x02,
- 0xa2, 0x08, 0x97, 0xcf, 0xe7, 0x07, 0x00, 0x00,
- 0xa2, 0x08, 0x0a, 0x0e, 0x01, 0x00, 0xca, 0x57,
- 0x0e, 0x00, 0x9f, 0xc3, 0x2a, 0x0b, 0xca, 0x37,
- 0x00, 0x00, 0x9f, 0xc2, 0x2a, 0x0b, 0x0a, 0xd2,
- 0xb2, 0xcf, 0xf4, 0x09, 0xc8, 0x09, 0xde, 0x00,
- 0x07, 0x06, 0x9f, 0xcf, 0x3c, 0x0b, 0xf0, 0x57,
- 0x80, 0x01, 0x06, 0x00, 0x9f, 0xc8, 0x2a, 0x0b,
- 0x27, 0x0c, 0x02, 0x00, 0x86, 0x08, 0xc0, 0x09,
- 0x88, 0x08, 0x27, 0x00, 0x8a, 0x08, 0xe7, 0x07,
- 0x00, 0x00, 0x84, 0x08, 0x27, 0x00, 0x5c, 0x08,
- 0x00, 0x1c, 0x06, 0x00, 0x27, 0x00, 0x8c, 0x08,
- 0x41, 0x90, 0x67, 0x50, 0x86, 0x08, 0x0d, 0xc0,
- 0x67, 0x00, 0x5a, 0x08, 0x27, 0x0c, 0x06, 0x00,
- 0x5e, 0x08, 0xe7, 0x07, 0x8a, 0x0a, 0x60, 0x08,
- 0xc8, 0x07, 0x5a, 0x08, 0x41, 0x90, 0x51, 0xaf,
- 0x97, 0xcf, 0x9f, 0xaf, 0xac, 0x0e, 0xe7, 0x09,
- 0x8c, 0x08, 0x8a, 0x08, 0xe7, 0x09, 0x86, 0x08,
- 0x84, 0x08, 0x59, 0xaf, 0x97, 0xcf, 0x27, 0x0c,
- 0x02, 0x00, 0x7c, 0x08, 0x59, 0xaf, 0x97, 0xcf,
- 0x09, 0x0c, 0x02, 0x00, 0x09, 0xda, 0x49, 0xd2,
- 0xc9, 0x19, 0xac, 0x08, 0xc8, 0x07, 0x5a, 0x08,
- 0xe0, 0x07, 0x00, 0x00, 0x60, 0x02, 0xe0, 0x07,
- 0x04, 0x00, 0xd0, 0x07, 0x9a, 0x0a, 0x48, 0xdb,
- 0x41, 0x90, 0x50, 0xaf, 0x97, 0xcf, 0x59, 0xaf,
- 0x97, 0xcf, 0x59, 0xaf, 0x97, 0xcf, 0xf0, 0x57,
- 0x06, 0x00, 0x06, 0x00, 0x26, 0xc1, 0xe7, 0x07,
- 0x7e, 0x08, 0x5c, 0x08, 0x41, 0x90, 0x67, 0x00,
- 0x5a, 0x08, 0x27, 0x0c, 0x06, 0x00, 0x5e, 0x08,
- 0xe7, 0x07, 0x5c, 0x0b, 0x60, 0x08, 0xc8, 0x07,
- 0x5a, 0x08, 0x41, 0x90, 0x51, 0xaf, 0x97, 0xcf,
- 0x07, 0x0c, 0x06, 0x00, 0xc7, 0x57, 0x06, 0x00,
- 0x10, 0xc1, 0xc8, 0x07, 0x7e, 0x08, 0x16, 0xcf,
- 0x00, 0x0c, 0x02, 0x00, 0x00, 0xda, 0x40, 0xd1,
- 0x27, 0x00, 0x98, 0x08, 0x1f, 0xcf, 0x1e, 0xcf,
- 0x27, 0x0c, 0x02, 0x00, 0xa4, 0x08, 0x1a, 0xcf,
- 0x00, 0xcf, 0x27, 0x02, 0x20, 0x01, 0xe7, 0x07,
- 0x08, 0x00, 0x22, 0x01, 0xe7, 0x07, 0x13, 0x00,
- 0xb0, 0xc0, 0x97, 0xcf, 0x41, 0x90, 0x67, 0x00,
- 0x5a, 0x08, 0xe7, 0x01, 0x5e, 0x08, 0x27, 0x02,
- 0x5c, 0x08, 0xe7, 0x07, 0x5c, 0x0b, 0x60, 0x08,
- 0xc8, 0x07, 0x5a, 0x08, 0xc1, 0x07, 0x00, 0x80,
- 0x50, 0xaf, 0x97, 0xcf, 0x59, 0xaf, 0x97, 0xcf,
- 0x00, 0x60, 0x05, 0xc0, 0xe7, 0x07, 0x00, 0x00,
- 0x9a, 0x08, 0xa7, 0xcf, 0x58, 0x08, 0x9f, 0xaf,
- 0xe2, 0x0b, 0xe7, 0x07, 0x01, 0x00, 0x9a, 0x08,
- 0x49, 0xaf, 0xd7, 0x09, 0x00, 0xc0, 0x07, 0xaf,
- 0xe7, 0x05, 0x00, 0xc0, 0x4a, 0xaf, 0xa7, 0xcf,
- 0x58, 0x08, 0xc0, 0x07, 0x40, 0x00, 0x44, 0xaf,
- 0x27, 0x00, 0xa0, 0x08, 0x08, 0x00, 0xc0, 0x07,
- 0x20, 0x00, 0x20, 0x94, 0x00, 0xda, 0x7d, 0xc1,
- 0xc0, 0x07, 0xfe, 0x7f, 0x44, 0xaf, 0x40, 0x00,
- 0x41, 0x90, 0xc0, 0x37, 0x08, 0x00, 0xdf, 0xde,
- 0x50, 0x06, 0xc0, 0x57, 0x10, 0x00, 0x02, 0xc2,
- 0xc0, 0x07, 0x10, 0x00, 0x27, 0x00, 0x76, 0x08,
- 0x41, 0x90, 0x9f, 0xde, 0x40, 0x06, 0x44, 0xaf,
- 0x27, 0x00, 0x74, 0x08, 0xc0, 0x09, 0x76, 0x08,
- 0x41, 0x90, 0x00, 0xd2, 0x00, 0xd8, 0x9f, 0xde,
- 0x08, 0x00, 0x44, 0xaf, 0x27, 0x00, 0x9e, 0x08,
- 0x97, 0xcf, 0xe7, 0x87, 0x00, 0x84, 0x28, 0xc0,
- 0xe7, 0x67, 0xff, 0xf3, 0x24, 0xc0, 0x97, 0xcf,
- 0xe7, 0x87, 0x01, 0x00, 0xaa, 0x08, 0xe7, 0x57,
- 0x00, 0x00, 0x7a, 0x08, 0x97, 0xc1, 0x9f, 0xaf,
- 0xe2, 0x0b, 0xe7, 0x87, 0x00, 0x06, 0x22, 0xc0,
- 0xe7, 0x07, 0x00, 0x00, 0x90, 0xc0, 0xe7, 0x67,
- 0xfe, 0xff, 0x3e, 0xc0, 0xe7, 0x07, 0x2e, 0x00,
- 0x0a, 0xc0, 0xe7, 0x87, 0x01, 0x00, 0x3e, 0xc0,
- 0xe7, 0x07, 0xff, 0xff, 0x94, 0x08, 0x9f, 0xaf,
- 0xf0, 0x0c, 0x97, 0xcf, 0x17, 0x00, 0xa7, 0xaf,
- 0x54, 0x08, 0xc0, 0x05, 0x27, 0x00, 0x52, 0x08,
- 0xe7, 0x87, 0x01, 0x00, 0xaa, 0x08, 0x9f, 0xaf,
- 0xe2, 0x0b, 0xe7, 0x07, 0x0c, 0x00, 0x40, 0xc0,
- 0x9f, 0xaf, 0xf0, 0x0c, 0xe7, 0x07, 0x00, 0x00,
- 0x78, 0x08, 0x00, 0x90, 0xe7, 0x09, 0x88, 0x08,
- 0x8a, 0x08, 0x27, 0x00, 0x84, 0x08, 0x27, 0x00,
- 0x7c, 0x08, 0x9f, 0xaf, 0x8a, 0x0c, 0xe7, 0x07,
- 0x00, 0x00, 0xb2, 0x02, 0xe7, 0x07, 0x00, 0x00,
- 0xb4, 0x02, 0xc0, 0x07, 0x06, 0x00, 0xc8, 0x09,
- 0xde, 0x00, 0xc8, 0x17, 0x03, 0x00, 0xc9, 0x07,
- 0x7e, 0x08, 0x29, 0x0a, 0x00, 0xda, 0x7d, 0xc1,
- 0x97, 0xcf, 0xd7, 0x09, 0x00, 0xc0, 0xc1, 0xdf,
- 0x00, 0x90, 0x27, 0x00, 0x6a, 0x08, 0xe7, 0x07,
- 0x6a, 0x08, 0x6c, 0x08, 0x27, 0x00, 0x6e, 0x08,
- 0xe7, 0x07, 0x6e, 0x08, 0x70, 0x08, 0x27, 0x00,
- 0x78, 0x08, 0x27, 0x00, 0x62, 0x08, 0x27, 0x00,
- 0x64, 0x08, 0xc8, 0x09, 0x74, 0x08, 0xc1, 0x09,
- 0x76, 0x08, 0xc9, 0x07, 0x72, 0x08, 0x11, 0x02,
- 0x09, 0x02, 0xc8, 0x17, 0x40, 0x06, 0x01, 0xda,
- 0x7a, 0xc1, 0x51, 0x94, 0xc8, 0x09, 0x9e, 0x08,
- 0xc9, 0x07, 0x9c, 0x08, 0xc1, 0x09, 0x76, 0x08,
- 0x01, 0xd2, 0x01, 0xd8, 0x11, 0x02, 0x09, 0x02,
- 0xc8, 0x17, 0x08, 0x00, 0x01, 0xda, 0x7a, 0xc1,
- 0x51, 0x94, 0xe7, 0x05, 0x00, 0xc0, 0x97, 0xcf,
- 0xe7, 0x57, 0x00, 0x00, 0x52, 0x08, 0x97, 0xc0,
- 0x9f, 0xaf, 0x04, 0x00, 0xe7, 0x09, 0x94, 0x08,
- 0x90, 0x08, 0xe7, 0x57, 0xff, 0xff, 0x90, 0x08,
- 0x04, 0xc1, 0xe7, 0x07, 0xf0, 0x0c, 0x8e, 0x08,
- 0x97, 0xcf, 0xe7, 0x17, 0x32, 0x00, 0x90, 0x08,
- 0xe7, 0x67, 0xff, 0x07, 0x90, 0x08, 0xe7, 0x07,
- 0x26, 0x0d, 0x8e, 0x08, 0x97, 0xcf, 0xd7, 0x09,
- 0x00, 0xc0, 0xc1, 0xdf, 0xe7, 0x57, 0x00, 0x00,
- 0x96, 0x08, 0x23, 0xc0, 0xe7, 0x07, 0x00, 0x80,
- 0x80, 0xc0, 0xe7, 0x07, 0x04, 0x00, 0x90, 0xc0,
- 0xe7, 0x07, 0x00, 0x00, 0x80, 0xc0, 0xe7, 0x07,
- 0x00, 0x80, 0x80, 0xc0, 0xc0, 0x07, 0x00, 0x00,
- 0xc0, 0x07, 0x00, 0x00, 0xc0, 0x07, 0x00, 0x00,
- 0xe7, 0x07, 0x00, 0x00, 0x80, 0xc0, 0xe7, 0x07,
- 0x00, 0x80, 0x80, 0xc0, 0xe7, 0x07, 0x00, 0x80,
- 0x40, 0xc0, 0xc0, 0x07, 0x00, 0x00, 0xe7, 0x07,
- 0x00, 0x00, 0x40, 0xc0, 0xe7, 0x07, 0x00, 0x00,
- 0x80, 0xc0, 0xef, 0x57, 0x00, 0x00, 0xf1, 0x09,
- 0x9f, 0xa0, 0xc0, 0x0d, 0xe7, 0x07, 0x04, 0x00,
- 0x90, 0xc0, 0xe7, 0x07, 0x00, 0x02, 0x40, 0xc0,
- 0xe7, 0x07, 0x0c, 0x02, 0x40, 0xc0, 0xe7, 0x07,
- 0x00, 0x00, 0x96, 0x08, 0xe7, 0x07, 0x00, 0x00,
- 0x8e, 0x08, 0xe7, 0x07, 0x00, 0x00, 0xaa, 0x08,
- 0xd7, 0x09, 0x00, 0xc0, 0xc1, 0xdf, 0x9f, 0xaf,
- 0x9e, 0x03, 0xe7, 0x05, 0x00, 0xc0, 0x9f, 0xaf,
- 0xde, 0x01, 0xe7, 0x05, 0x00, 0xc0, 0x97, 0xcf,
- 0x9f, 0xaf, 0xde, 0x0d, 0xef, 0x77, 0x00, 0x00,
- 0xf1, 0x09, 0x97, 0xc1, 0x9f, 0xaf, 0xde, 0x0d,
- 0xef, 0x77, 0x00, 0x00, 0xf1, 0x09, 0x97, 0xc1,
- 0xef, 0x07, 0x01, 0x00, 0xf1, 0x09, 0xe7, 0x87,
- 0x00, 0x08, 0x1e, 0xc0, 0xe7, 0x87, 0x00, 0x08,
- 0x22, 0xc0, 0xe7, 0x67, 0xff, 0xf7, 0x22, 0xc0,
- 0xe7, 0x77, 0x00, 0x08, 0x20, 0xc0, 0x11, 0xc0,
- 0xe7, 0x67, 0xff, 0xf7, 0x1e, 0xc0, 0xe7, 0x87,
- 0x00, 0x08, 0x22, 0xc0, 0xe7, 0x67, 0xff, 0xf7,
- 0x22, 0xc0, 0xe7, 0x77, 0x00, 0x08, 0x20, 0xc0,
- 0x04, 0xc1, 0xe7, 0x87, 0x00, 0x08, 0x22, 0xc0,
- 0x97, 0xcf, 0xe7, 0x07, 0x01, 0x01, 0xf0, 0x09,
- 0xef, 0x57, 0x18, 0x00, 0xfe, 0xff, 0x97, 0xc2,
- 0xef, 0x07, 0x00, 0x00, 0xf0, 0x09, 0x97, 0xcf,
- 0xd7, 0x09, 0x00, 0xc0, 0x17, 0x00, 0x17, 0x02,
- 0x97, 0x02, 0xe7, 0x57, 0x00, 0x00, 0x7a, 0x08,
- 0x06, 0xc0, 0xc0, 0x09, 0x92, 0xc0, 0xc0, 0x77,
- 0x09, 0x02, 0x9f, 0xc1, 0xea, 0x06, 0x9f, 0xcf,
- 0x20, 0x08, 0xd7, 0x09, 0x0e, 0xc0, 0xe7, 0x07,
- 0x00, 0x00, 0x0e, 0xc0, 0x9f, 0xaf, 0x66, 0x0e,
- 0xe7, 0x05, 0x0e, 0xc0, 0x97, 0xcf, 0xd7, 0x09,
- 0x00, 0xc0, 0x17, 0x02, 0xc8, 0x09, 0xb0, 0xc0,
- 0xe7, 0x67, 0xfe, 0x7f, 0xb0, 0xc0, 0xc8, 0x77,
- 0x00, 0x20, 0x9f, 0xc1, 0x64, 0xeb, 0xe7, 0x57,
- 0x00, 0x00, 0xc8, 0x02, 0x9f, 0xc1, 0x80, 0xeb,
- 0xc8, 0x99, 0xca, 0x02, 0xc8, 0x67, 0x04, 0x00,
- 0x9f, 0xc1, 0x96, 0xeb, 0x9f, 0xcf, 0x4c, 0xeb,
- 0xe7, 0x07, 0x00, 0x00, 0xa6, 0xc0, 0xe7, 0x09,
- 0xb0, 0xc0, 0xc8, 0x02, 0xe7, 0x07, 0x03, 0x00,
- 0xb0, 0xc0, 0x97, 0xcf, 0xc0, 0x09, 0x86, 0x08,
- 0xc0, 0x37, 0x01, 0x00, 0x97, 0xc9, 0xc9, 0x09,
- 0x88, 0x08, 0x02, 0x00, 0x41, 0x90, 0x48, 0x02,
- 0xc9, 0x17, 0x06, 0x00, 0x9f, 0xaf, 0x64, 0x05,
- 0x9f, 0xa2, 0xd6, 0x0e, 0x02, 0xda, 0x77, 0xc1,
- 0x41, 0x60, 0x71, 0xc1, 0x97, 0xcf, 0x17, 0x02,
- 0x57, 0x02, 0x43, 0x04, 0x21, 0x04, 0xe0, 0x00,
- 0x43, 0x04, 0x21, 0x04, 0xe0, 0x00, 0x43, 0x04,
- 0x21, 0x04, 0xe0, 0x00, 0xc1, 0x07, 0x01, 0x00,
- 0xc9, 0x05, 0xc8, 0x05, 0x97, 0xcf,
- 0, 0
-};
-
-/* Firmware fixup (data?) segment */
-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. */
- /******************************************/
- 0xB6, 0xC3, 0xc9, 0x02, 0x03, 0x64,
- 0x02, 0x00, 0x08, 0x00, 0x24, 0x00, 0x2e, 0x00,
- 0x2c, 0x00, 0x3e, 0x00, 0x44, 0x00, 0x48, 0x00,
- 0x50, 0x00, 0x5c, 0x00, 0x60, 0x00, 0x66, 0x00,
- 0x6c, 0x00, 0x70, 0x00, 0x76, 0x00, 0x74, 0x00,
- 0x7a, 0x00, 0x7e, 0x00, 0x84, 0x00, 0x8a, 0x00,
- 0x8e, 0x00, 0x92, 0x00, 0x98, 0x00, 0x9c, 0x00,
- 0xa0, 0x00, 0xa8, 0x00, 0xae, 0x00, 0xb4, 0x00,
- 0xb2, 0x00, 0xba, 0x00, 0xbe, 0x00, 0xc4, 0x00,
- 0xc8, 0x00, 0xce, 0x00, 0xd2, 0x00, 0xd6, 0x00,
- 0xda, 0x00, 0xe2, 0x00, 0xe0, 0x00, 0xea, 0x00,
- 0xf2, 0x00, 0xfe, 0x00, 0x06, 0x01, 0x0c, 0x01,
- 0x1a, 0x01, 0x24, 0x01, 0x22, 0x01, 0x2a, 0x01,
- 0x30, 0x01, 0x36, 0x01, 0x3c, 0x01, 0x4e, 0x01,
- 0x52, 0x01, 0x58, 0x01, 0x5c, 0x01, 0x9c, 0x01,
- 0xb6, 0x01, 0xba, 0x01, 0xc0, 0x01, 0xca, 0x01,
- 0xd0, 0x01, 0xda, 0x01, 0xe2, 0x01, 0xea, 0x01,
- 0xf0, 0x01, 0x0a, 0x02, 0x0e, 0x02, 0x14, 0x02,
- 0x26, 0x02, 0x6c, 0x02, 0x8e, 0x02, 0x98, 0x02,
- 0xa0, 0x02, 0xa6, 0x02, 0xba, 0x02, 0xc6, 0x02,
- 0xce, 0x02, 0xe8, 0x02, 0xee, 0x02, 0xf4, 0x02,
- 0xf8, 0x02, 0x0a, 0x03, 0x10, 0x03, 0x1a, 0x03,
- 0x1e, 0x03, 0x2a, 0x03, 0x2e, 0x03, 0x34, 0x03,
- 0x3a, 0x03, 0x44, 0x03, 0x4e, 0x03, 0x5a, 0x03,
- 0x5e, 0x03, 0x6a, 0x03, 0x72, 0x03, 0x80, 0x03,
- 0x84, 0x03, 0x8c, 0x03, 0x94, 0x03, 0x98, 0x03,
- 0xa8, 0x03, 0xae, 0x03, 0xb4, 0x03, 0xba, 0x03,
- 0xce, 0x03, 0xcc, 0x03, 0xd6, 0x03, 0xdc, 0x03,
- 0xec, 0x03, 0xf0, 0x03, 0xfe, 0x03, 0x1c, 0x04,
- 0x30, 0x04, 0x38, 0x04, 0x3c, 0x04, 0x40, 0x04,
- 0x48, 0x04, 0x46, 0x04, 0x54, 0x04, 0x5e, 0x04,
- 0x64, 0x04, 0x74, 0x04, 0x78, 0x04, 0x84, 0x04,
- 0xd8, 0x04, 0xec, 0x04, 0xf0, 0x04, 0xf8, 0x04,
- 0xfe, 0x04, 0x1c, 0x05, 0x2c, 0x05, 0x30, 0x05,
- 0x4a, 0x05, 0x56, 0x05, 0x5a, 0x05, 0x88, 0x05,
- 0x8c, 0x05, 0x96, 0x05, 0x9a, 0x05, 0xa8, 0x05,
- 0xcc, 0x05, 0xd2, 0x05, 0xda, 0x05, 0xe0, 0x05,
- 0xe4, 0x05, 0xfc, 0x05, 0x06, 0x06, 0x14, 0x06,
- 0x12, 0x06, 0x1a, 0x06, 0x20, 0x06, 0x26, 0x06,
- 0x2e, 0x06, 0x34, 0x06, 0x48, 0x06, 0x52, 0x06,
- 0x64, 0x06, 0x86, 0x06, 0x90, 0x06, 0x9a, 0x06,
- 0xa0, 0x06, 0xac, 0x06, 0xaa, 0x06, 0xb2, 0x06,
- 0xb8, 0x06, 0xdc, 0x06, 0xda, 0x06, 0xe2, 0x06,
- 0xe8, 0x06, 0xf2, 0x06, 0xf8, 0x06, 0xfc, 0x06,
- 0x0a, 0x07, 0x10, 0x07, 0x14, 0x07, 0x24, 0x07,
- 0x2a, 0x07, 0x32, 0x07, 0x38, 0x07, 0xb2, 0x07,
- 0xba, 0x07, 0xde, 0x07, 0xe4, 0x07, 0x10, 0x08,
- 0x14, 0x08, 0x1a, 0x08, 0x1e, 0x08, 0x30, 0x08,
- 0x38, 0x08, 0x3c, 0x08, 0x44, 0x08, 0x42, 0x08,
- 0x48, 0x08, 0xc6, 0x08, 0xcc, 0x08, 0xd2, 0x08,
- 0xfe, 0x08, 0x04, 0x09, 0x0a, 0x09, 0x0e, 0x09,
- 0x12, 0x09, 0x16, 0x09, 0x20, 0x09, 0x24, 0x09,
- 0x28, 0x09, 0x32, 0x09, 0x46, 0x09, 0x4a, 0x09,
- 0x50, 0x09, 0x54, 0x09, 0x5a, 0x09, 0x60, 0x09,
- 0x7c, 0x09, 0x80, 0x09, 0xb8, 0x09, 0xbc, 0x09,
- 0xc0, 0x09, 0xc4, 0x09, 0xc8, 0x09, 0xcc, 0x09,
- 0xd0, 0x09, 0xd4, 0x09, 0xec, 0x09, 0xf4, 0x09,
- 0xf6, 0x09, 0xf8, 0x09, 0xfa, 0x09, 0xfc, 0x09,
- 0xfe, 0x09, 0x00, 0x0a, 0x02, 0x0a, 0x04, 0x0a,
- 0x06, 0x0a, 0x08, 0x0a, 0x0a, 0x0a, 0x0c, 0x0a,
- 0x10, 0x0a, 0x18, 0x0a, 0x24, 0x0a, 0x2c, 0x0a,
- 0x32, 0x0a, 0x3c, 0x0a, 0x46, 0x0a, 0x4c, 0x0a,
- 0x50, 0x0a, 0x54, 0x0a, 0x5a, 0x0a, 0x5e, 0x0a,
- 0x66, 0x0a, 0x6c, 0x0a, 0x72, 0x0a, 0x78, 0x0a,
- 0x7e, 0x0a, 0x7c, 0x0a, 0x82, 0x0a, 0x8c, 0x0a,
- 0x92, 0x0a, 0x90, 0x0a, 0x98, 0x0a, 0x96, 0x0a,
- 0xa2, 0x0a, 0xb2, 0x0a, 0xb6, 0x0a, 0xc4, 0x0a,
- 0xe2, 0x0a, 0xe0, 0x0a, 0xe8, 0x0a, 0xee, 0x0a,
- 0xf4, 0x0a, 0xf2, 0x0a, 0xf8, 0x0a, 0x0c, 0x0b,
- 0x1a, 0x0b, 0x24, 0x0b, 0x40, 0x0b, 0x44, 0x0b,
- 0x48, 0x0b, 0x4e, 0x0b, 0x4c, 0x0b, 0x52, 0x0b,
- 0x68, 0x0b, 0x6c, 0x0b, 0x70, 0x0b, 0x76, 0x0b,
- 0x88, 0x0b, 0x92, 0x0b, 0xbe, 0x0b, 0xca, 0x0b,
- 0xce, 0x0b, 0xde, 0x0b, 0xf4, 0x0b, 0xfa, 0x0b,
- 0x00, 0x0c, 0x24, 0x0c, 0x28, 0x0c, 0x30, 0x0c,
- 0x36, 0x0c, 0x3c, 0x0c, 0x40, 0x0c, 0x4a, 0x0c,
- 0x50, 0x0c, 0x58, 0x0c, 0x56, 0x0c, 0x5c, 0x0c,
- 0x60, 0x0c, 0x64, 0x0c, 0x80, 0x0c, 0x94, 0x0c,
- 0x9a, 0x0c, 0x98, 0x0c, 0x9e, 0x0c, 0xa4, 0x0c,
- 0xa2, 0x0c, 0xa8, 0x0c, 0xac, 0x0c, 0xb0, 0x0c,
- 0xb4, 0x0c, 0xb8, 0x0c, 0xbc, 0x0c, 0xce, 0x0c,
- 0xd2, 0x0c, 0xd6, 0x0c, 0xf4, 0x0c, 0xfa, 0x0c,
- 0x00, 0x0d, 0xfe, 0x0c, 0x06, 0x0d, 0x0e, 0x0d,
- 0x0c, 0x0d, 0x16, 0x0d, 0x1c, 0x0d, 0x22, 0x0d,
- 0x20, 0x0d, 0x30, 0x0d, 0x7e, 0x0d, 0x82, 0x0d,
- 0x9a, 0x0d, 0xa0, 0x0d, 0xa6, 0x0d, 0xb0, 0x0d,
- 0xb8, 0x0d, 0xc2, 0x0d, 0xc8, 0x0d, 0xce, 0x0d,
- 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
-};
-
-/* Fixup command. */
-#define KUE_TRIGCMD_OFFSET 5
-static unsigned char kue_trig_seg[] = {
-0xb6, 0xc3, 0x01, 0x00, 0x06, 0x64, 0x00, 0x00
-};
diff --git a/sys/dev/usb/ohci.c b/sys/dev/usb/ohci.c
deleted file mode 100644
index efa6e7e..0000000
--- a/sys/dev/usb/ohci.c
+++ /dev/null
@@ -1,3638 +0,0 @@
-/* $NetBSD: ohci.c,v 1.138 2003/02/08 03:32:50 ichiro Exp $ */
-
-/* Also, already ported:
- * $NetBSD: ohci.c,v 1.140 2003/05/13 04:42:00 gson Exp $
- * $NetBSD: ohci.c,v 1.141 2003/09/10 20:08:29 mycroft Exp $
- * $NetBSD: ohci.c,v 1.142 2003/10/11 03:04:26 toshii Exp $
- * $NetBSD: ohci.c,v 1.143 2003/10/18 04:50:35 simonb Exp $
- * $NetBSD: ohci.c,v 1.144 2003/11/23 19:18:06 augustss Exp $
- * $NetBSD: ohci.c,v 1.145 2003/11/23 19:20:25 augustss Exp $
- * $NetBSD: ohci.c,v 1.146 2003/12/29 08:17:10 toshii Exp $
- * $NetBSD: ohci.c,v 1.147 2004/06/22 07:20:35 mycroft Exp $
- * $NetBSD: ohci.c,v 1.148 2004/06/22 18:27:46 mycroft Exp $
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) 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.
- */
-
-/*
- * USB Open Host Controller driver.
- *
- * OHCI spec: http://www.compaq.com/productinfo/development/openhci.html
- * USB spec: http://www.usb.org/developers/docs/usbspec.zip
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/malloc.h>
-#include <sys/kernel.h>
-#include <sys/endian.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#if defined(DIAGNOSTIC) && defined(__i386__) && defined(__FreeBSD__)
-#include <machine/cpu.h>
-#endif
-#include <sys/proc.h>
-#include <sys/queue.h>
-#include <sys/sysctl.h>
-
-#include <machine/bus.h>
-#include <machine/endian.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdivar.h>
-#include <dev/usb/usb_mem.h>
-#include <dev/usb/usb_quirks.h>
-
-#include <dev/usb/ohcireg.h>
-#include <dev/usb/ohcivar.h>
-
-#define delay(d) DELAY(d)
-
-#ifdef USB_DEBUG
-#define DPRINTF(x) if (ohcidebug) printf x
-#define DPRINTFN(n,x) if (ohcidebug>(n)) printf x
-int ohcidebug = 0;
-SYSCTL_NODE(_hw_usb, OID_AUTO, ohci, CTLFLAG_RW, 0, "USB ohci");
-SYSCTL_INT(_hw_usb_ohci, OID_AUTO, debug, CTLFLAG_RW,
- &ohcidebug, 0, "ohci debug level");
-#define bitmask_snprintf(q,f,b,l) snprintf((b), (l), "%b", (q), (f))
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-struct ohci_pipe;
-
-static ohci_soft_ed_t *ohci_alloc_sed(ohci_softc_t *);
-static void ohci_free_sed(ohci_softc_t *, ohci_soft_ed_t *);
-
-static ohci_soft_td_t *ohci_alloc_std(ohci_softc_t *);
-static void ohci_free_std(ohci_softc_t *, ohci_soft_td_t *);
-
-static ohci_soft_itd_t *ohci_alloc_sitd(ohci_softc_t *);
-static void ohci_free_sitd(ohci_softc_t *,ohci_soft_itd_t *);
-
-#if 0
-static void ohci_free_std_chain(ohci_softc_t *, ohci_soft_td_t *,
- ohci_soft_td_t *);
-#endif
-static usbd_status ohci_alloc_std_chain(struct ohci_pipe *,
- ohci_softc_t *, int, int, usbd_xfer_handle,
- ohci_soft_td_t *, ohci_soft_td_t **);
-
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-static void ohci_shutdown(void *v);
-static void ohci_power(int, void *);
-#endif
-static usbd_status ohci_open(usbd_pipe_handle);
-static void ohci_poll(struct usbd_bus *);
-static void ohci_softintr(void *);
-static void ohci_waitintr(ohci_softc_t *, usbd_xfer_handle);
-static void ohci_add_done(ohci_softc_t *, ohci_physaddr_t);
-static void ohci_rhsc(ohci_softc_t *, usbd_xfer_handle);
-
-static usbd_status ohci_device_request(usbd_xfer_handle xfer);
-static void ohci_add_ed(ohci_soft_ed_t *, ohci_soft_ed_t *);
-static void ohci_rem_ed(ohci_soft_ed_t *, ohci_soft_ed_t *);
-static void ohci_hash_add_td(ohci_softc_t *, ohci_soft_td_t *);
-static void ohci_hash_rem_td(ohci_softc_t *, ohci_soft_td_t *);
-static ohci_soft_td_t *ohci_hash_find_td(ohci_softc_t *, ohci_physaddr_t);
-static void ohci_hash_add_itd(ohci_softc_t *, ohci_soft_itd_t *);
-static void ohci_hash_rem_itd(ohci_softc_t *, ohci_soft_itd_t *);
-static ohci_soft_itd_t *ohci_hash_find_itd(ohci_softc_t *, ohci_physaddr_t);
-
-static usbd_status ohci_setup_isoc(usbd_pipe_handle pipe);
-static void ohci_device_isoc_enter(usbd_xfer_handle);
-
-static usbd_status ohci_allocm(struct usbd_bus *, usb_dma_t *, u_int32_t);
-static void ohci_freem(struct usbd_bus *, usb_dma_t *);
-
-static usbd_xfer_handle ohci_allocx(struct usbd_bus *);
-static void ohci_freex(struct usbd_bus *, usbd_xfer_handle);
-
-static usbd_status ohci_root_ctrl_transfer(usbd_xfer_handle);
-static usbd_status ohci_root_ctrl_start(usbd_xfer_handle);
-static void ohci_root_ctrl_abort(usbd_xfer_handle);
-static void ohci_root_ctrl_close(usbd_pipe_handle);
-static void ohci_root_ctrl_done(usbd_xfer_handle);
-
-static usbd_status ohci_root_intr_transfer(usbd_xfer_handle);
-static usbd_status ohci_root_intr_start(usbd_xfer_handle);
-static void ohci_root_intr_abort(usbd_xfer_handle);
-static void ohci_root_intr_close(usbd_pipe_handle);
-static void ohci_root_intr_done(usbd_xfer_handle);
-
-static usbd_status ohci_device_ctrl_transfer(usbd_xfer_handle);
-static usbd_status ohci_device_ctrl_start(usbd_xfer_handle);
-static void ohci_device_ctrl_abort(usbd_xfer_handle);
-static void ohci_device_ctrl_close(usbd_pipe_handle);
-static void ohci_device_ctrl_done(usbd_xfer_handle);
-
-static usbd_status ohci_device_bulk_transfer(usbd_xfer_handle);
-static usbd_status ohci_device_bulk_start(usbd_xfer_handle);
-static void ohci_device_bulk_abort(usbd_xfer_handle);
-static void ohci_device_bulk_close(usbd_pipe_handle);
-static void ohci_device_bulk_done(usbd_xfer_handle);
-
-static usbd_status ohci_device_intr_transfer(usbd_xfer_handle);
-static usbd_status ohci_device_intr_start(usbd_xfer_handle);
-static void ohci_device_intr_abort(usbd_xfer_handle);
-static void ohci_device_intr_close(usbd_pipe_handle);
-static void ohci_device_intr_done(usbd_xfer_handle);
-
-static usbd_status ohci_device_isoc_transfer(usbd_xfer_handle);
-static usbd_status ohci_device_isoc_start(usbd_xfer_handle);
-static void ohci_device_isoc_abort(usbd_xfer_handle);
-static void ohci_device_isoc_close(usbd_pipe_handle);
-static void ohci_device_isoc_done(usbd_xfer_handle);
-
-static usbd_status ohci_device_setintr(ohci_softc_t *sc,
- struct ohci_pipe *pipe, int ival);
-static usbd_status ohci_device_intr_insert(ohci_softc_t *sc,
- usbd_xfer_handle xfer);
-
-static int ohci_str(usb_string_descriptor_t *, int, const char *);
-
-static void ohci_timeout(void *);
-static void ohci_timeout_task(void *);
-static void ohci_rhsc_able(ohci_softc_t *, int);
-static void ohci_rhsc_enable(void *);
-
-static void ohci_close_pipe(usbd_pipe_handle, ohci_soft_ed_t *);
-static void ohci_abort_xfer(usbd_xfer_handle, usbd_status);
-
-static void ohci_device_clear_toggle(usbd_pipe_handle pipe);
-static void ohci_noop(usbd_pipe_handle pipe);
-
-static usbd_status ohci_controller_init(ohci_softc_t *sc);
-
-#ifdef USB_DEBUG
-static void ohci_dumpregs(ohci_softc_t *);
-static void ohci_dump_tds(ohci_soft_td_t *);
-static void ohci_dump_td(ohci_soft_td_t *);
-static void ohci_dump_ed(ohci_soft_ed_t *);
-static void ohci_dump_itd(ohci_soft_itd_t *);
-static void ohci_dump_itds(ohci_soft_itd_t *);
-#endif
-
-#define OBARR(sc) bus_space_barrier((sc)->iot, (sc)->ioh, 0, (sc)->sc_size, \
- BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE)
-#define OWRITE1(sc, r, x) \
- do { OBARR(sc); bus_space_write_1((sc)->iot, (sc)->ioh, (r), (x)); } while (0)
-#define OWRITE2(sc, r, x) \
- do { OBARR(sc); bus_space_write_2((sc)->iot, (sc)->ioh, (r), (x)); } while (0)
-#define OWRITE4(sc, r, x) \
- do { OBARR(sc); bus_space_write_4((sc)->iot, (sc)->ioh, (r), (x)); } while (0)
-#define OREAD1(sc, r) (OBARR(sc), bus_space_read_1((sc)->iot, (sc)->ioh, (r)))
-#define OREAD2(sc, r) (OBARR(sc), bus_space_read_2((sc)->iot, (sc)->ioh, (r)))
-#define OREAD4(sc, r) (OBARR(sc), bus_space_read_4((sc)->iot, (sc)->ioh, (r)))
-
-/* Reverse the bits in a value 0 .. 31 */
-static u_int8_t revbits[OHCI_NO_INTRS] =
- { 0x00, 0x10, 0x08, 0x18, 0x04, 0x14, 0x0c, 0x1c,
- 0x02, 0x12, 0x0a, 0x1a, 0x06, 0x16, 0x0e, 0x1e,
- 0x01, 0x11, 0x09, 0x19, 0x05, 0x15, 0x0d, 0x1d,
- 0x03, 0x13, 0x0b, 0x1b, 0x07, 0x17, 0x0f, 0x1f };
-
-struct ohci_pipe {
- struct usbd_pipe pipe;
- ohci_soft_ed_t *sed;
- u_int32_t aborting;
- union {
- ohci_soft_td_t *td;
- ohci_soft_itd_t *itd;
- } tail;
- /* Info needed for different pipe kinds. */
- union {
- /* Control pipe */
- struct {
- usb_dma_t reqdma;
- u_int length;
- ohci_soft_td_t *setup, *data, *stat;
- } ctl;
- /* Interrupt pipe */
- struct {
- int nslots;
- int pos;
- } intr;
- /* Bulk pipe */
- struct {
- u_int length;
- int isread;
- } bulk;
- /* Iso pipe */
- struct iso {
- int next, inuse;
- } iso;
- } u;
-};
-
-#define OHCI_INTR_ENDPT 1
-
-static struct usbd_bus_methods ohci_bus_methods = {
- ohci_open,
- ohci_softintr,
- ohci_poll,
- ohci_allocm,
- ohci_freem,
- ohci_allocx,
- ohci_freex,
-};
-
-static struct usbd_pipe_methods ohci_root_ctrl_methods = {
- ohci_root_ctrl_transfer,
- ohci_root_ctrl_start,
- ohci_root_ctrl_abort,
- ohci_root_ctrl_close,
- ohci_noop,
- ohci_root_ctrl_done,
-};
-
-static struct usbd_pipe_methods ohci_root_intr_methods = {
- ohci_root_intr_transfer,
- ohci_root_intr_start,
- ohci_root_intr_abort,
- ohci_root_intr_close,
- ohci_noop,
- ohci_root_intr_done,
-};
-
-static struct usbd_pipe_methods ohci_device_ctrl_methods = {
- ohci_device_ctrl_transfer,
- ohci_device_ctrl_start,
- ohci_device_ctrl_abort,
- ohci_device_ctrl_close,
- ohci_noop,
- ohci_device_ctrl_done,
-};
-
-static struct usbd_pipe_methods ohci_device_intr_methods = {
- ohci_device_intr_transfer,
- ohci_device_intr_start,
- ohci_device_intr_abort,
- ohci_device_intr_close,
- ohci_device_clear_toggle,
- ohci_device_intr_done,
-};
-
-static struct usbd_pipe_methods ohci_device_bulk_methods = {
- ohci_device_bulk_transfer,
- ohci_device_bulk_start,
- ohci_device_bulk_abort,
- ohci_device_bulk_close,
- ohci_device_clear_toggle,
- ohci_device_bulk_done,
-};
-
-static struct usbd_pipe_methods ohci_device_isoc_methods = {
- ohci_device_isoc_transfer,
- ohci_device_isoc_start,
- ohci_device_isoc_abort,
- ohci_device_isoc_close,
- ohci_noop,
- ohci_device_isoc_done,
-};
-
-int
-ohci_detach(struct ohci_softc *sc, int flags)
-{
- int i, rv = 0;
-
- sc->sc_dying = 1;
- callout_stop(&sc->sc_tmo_rhsc);
-
-#if defined(__NetBSD__) || defined(__OpenBSD__)
- powerhook_disestablish(sc->sc_powerhook);
- shutdownhook_disestablish(sc->sc_shutdownhook);
-#endif
-
- OWRITE4(sc, OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTRS);
- OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET);
-
- usb_delay_ms(&sc->sc_bus, 300); /* XXX let stray task complete */
-
- for (i = 0; i < OHCI_NO_EDS; i++)
- ohci_free_sed(sc, sc->sc_eds[i]);
- ohci_free_sed(sc, sc->sc_isoc_head);
- ohci_free_sed(sc, sc->sc_bulk_head);
- ohci_free_sed(sc, sc->sc_ctrl_head);
- usb_freemem(&sc->sc_bus, &sc->sc_hccadma);
-
- return (rv);
-}
-
-ohci_soft_ed_t *
-ohci_alloc_sed(ohci_softc_t *sc)
-{
- ohci_soft_ed_t *sed;
- usbd_status err;
- int i, offs;
- usb_dma_t dma;
-
- 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);
- if (err)
- return (NULL);
- for(i = 0; i < OHCI_SED_CHUNK; i++) {
- offs = i * OHCI_SED_SIZE;
- sed = KERNADDR(&dma, offs);
- sed->physaddr = DMAADDR(&dma, offs);
- sed->next = sc->sc_freeeds;
- sc->sc_freeeds = sed;
- }
- }
- sed = sc->sc_freeeds;
- sc->sc_freeeds = sed->next;
- memset(&sed->ed, 0, sizeof(ohci_ed_t));
- sed->next = 0;
- return (sed);
-}
-
-void
-ohci_free_sed(ohci_softc_t *sc, ohci_soft_ed_t *sed)
-{
- sed->next = sc->sc_freeeds;
- sc->sc_freeeds = sed;
-}
-
-ohci_soft_td_t *
-ohci_alloc_std(ohci_softc_t *sc)
-{
- ohci_soft_td_t *std;
- usbd_status err;
- int i, offs;
- usb_dma_t dma;
- int s;
-
- 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);
- if (err)
- return (NULL);
- s = splusb();
- for(i = 0; i < OHCI_STD_CHUNK; i++) {
- offs = i * OHCI_STD_SIZE;
- std = KERNADDR(&dma, offs);
- std->physaddr = DMAADDR(&dma, offs);
- std->nexttd = sc->sc_freetds;
- sc->sc_freetds = std;
- }
- splx(s);
- }
-
- s = splusb();
- std = sc->sc_freetds;
- sc->sc_freetds = std->nexttd;
- memset(&std->td, 0, sizeof(ohci_td_t));
- std->nexttd = NULL;
- std->xfer = NULL;
- ohci_hash_add_td(sc, std);
- splx(s);
-
- return (std);
-}
-
-void
-ohci_free_std(ohci_softc_t *sc, ohci_soft_td_t *std)
-{
- int s;
-
- s = splusb();
- ohci_hash_rem_td(sc, std);
- std->nexttd = sc->sc_freetds;
- sc->sc_freetds = std;
- splx(s);
-}
-
-usbd_status
-ohci_alloc_std_chain(struct ohci_pipe *opipe, ohci_softc_t *sc,
- int alen, int rd, usbd_xfer_handle xfer,
- ohci_soft_td_t *sp, ohci_soft_td_t **ep)
-{
- ohci_soft_td_t *next, *cur, *end;
- ohci_physaddr_t dataphys, physend;
- u_int32_t tdflags;
- int offset = 0;
- int len, maxp, curlen, curlen2, seg, segoff;
- struct usb_dma_mapping *dma = &xfer->dmamap;
- u_int16_t flags = xfer->flags;
-
- DPRINTFN(alen < 4096,("ohci_alloc_std_chain: start len=%d\n", alen));
-
- len = alen;
- cur = sp;
- end = NULL;
-
- maxp = UGETW(opipe->pipe.endpoint->edesc->wMaxPacketSize);
- 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_SET_DI(6));
-
- seg = 0;
- segoff = 0;
- while (len > 0) {
- next = ohci_alloc_std(sc);
- if (next == NULL)
- goto nomem;
-
- /*
- * The OHCI hardware can handle at most one 4k crossing.
- * The OHCI spec says: If during the data transfer the buffer
- * address contained in the HC's working copy of
- * CurrentBufferPointer crosses a 4K boundary, the upper 20
- * bits of Buffer End are copied to the working value of
- * CurrentBufferPointer causing the next buffer address to
- * be the 0th byte in the same 4K page that contains the
- * last byte of the buffer (the 4K boundary crossing may
- * occur within a data packet transfer.)
- */
- KASSERT(seg < dma->nsegs, ("ohci_alloc_std_chain: overrun"));
- dataphys = dma->segs[seg].ds_addr + segoff;
- curlen = dma->segs[seg].ds_len - segoff;
- if (curlen > len)
- curlen = len;
- physend = dataphys + curlen - 1;
- if (OHCI_PAGE(dataphys) != OHCI_PAGE(physend)) {
- /* Truncate to two OHCI pages if there are more. */
- if (curlen > 2 * OHCI_PAGE_SIZE -
- OHCI_PAGE_OFFSET(dataphys))
- curlen = 2 * OHCI_PAGE_SIZE -
- OHCI_PAGE_OFFSET(dataphys);
- if (curlen < len)
- curlen -= curlen % maxp;
- physend = dataphys + curlen - 1;
- } else if (OHCI_PAGE_OFFSET(physend + 1) == 0 && curlen < len &&
- curlen + segoff == dma->segs[seg].ds_len) {
- /* We can possibly include another segment. */
- KASSERT(seg + 1 < dma->nsegs,
- ("ohci_alloc_std_chain: overrun2"));
- seg++;
-
- /* Determine how much of the second segment to use. */
- curlen2 = dma->segs[seg].ds_len;
- if (curlen + curlen2 > len)
- curlen2 = len - curlen;
- if (OHCI_PAGE(dma->segs[seg].ds_addr) !=
- OHCI_PAGE(dma->segs[seg].ds_addr + curlen2 - 1))
- curlen2 = OHCI_PAGE_SIZE -
- OHCI_PAGE_OFFSET(dma->segs[seg].ds_addr);
- if (curlen + curlen2 < len)
- curlen2 -= (curlen + curlen2) % maxp;
-
- if (curlen2 > 0) {
- /* We can include a second segment */
- segoff = curlen2;
- physend = dma->segs[seg].ds_addr + curlen2 - 1;
- curlen += curlen2;
- } else {
- /* Second segment not usable now. */
- seg--;
- segoff += curlen;
- }
- } else {
- /* Simple case where there is just one OHCI page. */
- segoff += curlen;
- }
- if (curlen == 0 && len != 0) {
- /*
- * A maxp length packet would need to be split.
- * This shouldn't be possible if PAGE_SIZE >= 4k
- * and the buffer is contiguous in virtual memory.
- */
- panic("ohci_alloc_std_chain: XXX need to copy");
- }
- if (segoff >= dma->segs[seg].ds_len) {
- KASSERT(segoff == dma->segs[seg].ds_len,
- ("ohci_alloc_std_chain: overlap"));
- seg++;
- segoff = 0;
- }
- DPRINTFN(4,("ohci_alloc_std_chain: dataphys=0x%08x "
- "len=%d curlen=%d\n",
- dataphys, len, curlen));
- len -= curlen;
-
- cur->td.td_flags = tdflags;
- cur->td.td_cbp = htole32(dataphys);
- cur->nexttd = next;
- cur->td.td_nexttd = htole32(next->physaddr);
- cur->td.td_be = htole32(physend);
- cur->len = curlen;
- cur->flags = OHCI_ADD_LEN;
- cur->xfer = xfer;
- DPRINTFN(10,("ohci_alloc_std_chain: cbp=0x%08x be=0x%08x\n",
- dataphys, dataphys + curlen - 1));
- if (len < 0)
- panic("Length went negative: %d curlen %d dma %p offset %08x", len, curlen, dma, (int)0);
-
- DPRINTFN(10,("ohci_alloc_std_chain: extend chain\n"));
- offset += curlen;
- end = cur;
- cur = next;
- }
- if (((flags & USBD_FORCE_SHORT_XFER) || alen == 0) &&
- alen % UGETW(opipe->pipe.endpoint->edesc->wMaxPacketSize) == 0) {
- /* Force a 0 length transfer at the end. */
- next = ohci_alloc_std(sc);
- if (next == NULL)
- goto nomem;
-
- cur->td.td_flags = tdflags;
- cur->td.td_cbp = 0; /* indicate 0 length packet */
- cur->nexttd = next;
- cur->td.td_nexttd = htole32(next->physaddr);
- cur->td.td_be = ~0;
- cur->len = 0;
- cur->flags = 0;
- cur->xfer = xfer;
- DPRINTFN(2,("ohci_alloc_std_chain: add 0 xfer\n"));
- end = cur;
- }
- *ep = end;
-
- return (USBD_NORMAL_COMPLETION);
-
- nomem:
- /* XXX free chain */
- return (USBD_NOMEM);
-}
-
-#if 0
-static void
-ohci_free_std_chain(ohci_softc_t *sc, ohci_soft_td_t *std,
- ohci_soft_td_t *stdend)
-{
- ohci_soft_td_t *p;
-
- for (; std != stdend; std = p) {
- p = std->nexttd;
- ohci_free_std(sc, std);
- }
-}
-#endif
-
-ohci_soft_itd_t *
-ohci_alloc_sitd(ohci_softc_t *sc)
-{
- ohci_soft_itd_t *sitd;
- usbd_status err;
- int i, s, offs;
- usb_dma_t dma;
-
- if (sc->sc_freeitds == NULL) {
- DPRINTFN(2, ("ohci_alloc_sitd: allocating chunk\n"));
- err = usb_allocmem(&sc->sc_bus, OHCI_SITD_SIZE * OHCI_SITD_CHUNK,
- OHCI_ITD_ALIGN, &dma);
- if (err)
- return (NULL);
- s = splusb();
- for(i = 0; i < OHCI_SITD_CHUNK; i++) {
- offs = i * OHCI_SITD_SIZE;
- sitd = KERNADDR(&dma, offs);
- sitd->physaddr = DMAADDR(&dma, offs);
- sitd->nextitd = sc->sc_freeitds;
- sc->sc_freeitds = sitd;
- }
- splx(s);
- }
-
- s = splusb();
- sitd = sc->sc_freeitds;
- sc->sc_freeitds = sitd->nextitd;
- memset(&sitd->itd, 0, sizeof(ohci_itd_t));
- sitd->nextitd = NULL;
- sitd->xfer = NULL;
- ohci_hash_add_itd(sc, sitd);
- splx(s);
-
-#ifdef DIAGNOSTIC
- sitd->isdone = 0;
-#endif
-
- return (sitd);
-}
-
-void
-ohci_free_sitd(ohci_softc_t *sc, ohci_soft_itd_t *sitd)
-{
- int s;
-
- DPRINTFN(10,("ohci_free_sitd: sitd=%p\n", sitd));
-
-#ifdef DIAGNOSTIC
- if (!sitd->isdone) {
- panic("ohci_free_sitd: sitd=%p not done", sitd);
- return;
- }
- /* Warn double free */
- sitd->isdone = 0;
-#endif
-
- s = splusb();
- ohci_hash_rem_itd(sc, sitd);
- sitd->nextitd = sc->sc_freeitds;
- sc->sc_freeitds = sitd;
- splx(s);
-}
-
-usbd_status
-ohci_init(ohci_softc_t *sc)
-{
- ohci_soft_ed_t *sed, *psed;
- usbd_status err;
- int i;
- u_int32_t rev;
-
- DPRINTF(("ohci_init: start\n"));
- printf("%s:", device_get_nameunit(sc->sc_bus.bdev));
- 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",
- device_get_nameunit(sc->sc_bus.bdev));
- sc->sc_bus.usbrev = USBREV_UNKNOWN;
- return (USBD_INVAL);
- }
- sc->sc_bus.usbrev = USBREV_1_0;
-
- for (i = 0; i < OHCI_HASH_SIZE; i++)
- LIST_INIT(&sc->sc_hash_tds[i]);
- for (i = 0; i < OHCI_HASH_SIZE; i++)
- LIST_INIT(&sc->sc_hash_itds[i]);
-
- STAILQ_INIT(&sc->sc_free_xfers);
-
- /* XXX determine alignment by R/W */
- /* Allocate the HCCA area. */
- err = usb_allocmem(&sc->sc_bus, OHCI_HCCA_SIZE,
- OHCI_HCCA_ALIGN, &sc->sc_hccadma);
- if (err)
- return (err);
- sc->sc_hcca = KERNADDR(&sc->sc_hccadma, 0);
- memset(sc->sc_hcca, 0, OHCI_HCCA_SIZE);
-
- sc->sc_eintrs = OHCI_NORMAL_INTRS;
-
- /* Allocate dummy ED that starts the control list. */
- sc->sc_ctrl_head = ohci_alloc_sed(sc);
- if (sc->sc_ctrl_head == NULL) {
- err = USBD_NOMEM;
- goto bad1;
- }
- 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);
- if (sc->sc_bulk_head == NULL) {
- err = USBD_NOMEM;
- goto bad2;
- }
- 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);
- if (sc->sc_isoc_head == NULL) {
- err = USBD_NOMEM;
- goto bad3;
- }
- 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++) {
- sed = ohci_alloc_sed(sc);
- if (sed == NULL) {
- while (--i >= 0)
- ohci_free_sed(sc, sc->sc_eds[i]);
- err = USBD_NOMEM;
- goto bad4;
- }
- /* All ED fields are set to 0. */
- sc->sc_eds[i] = sed;
- sed->ed.ed_flags |= htole32(OHCI_ED_SKIP);
- if (i != 0)
- psed = sc->sc_eds[(i-1) / 2];
- else
- psed= sc->sc_isoc_head;
- sed->next = psed;
- sed->ed.ed_nexted = htole32(psed->physaddr);
- }
- /*
- * Fill HCCA interrupt table. The bit reversal is to get
- * the tree set up properly to spread the interrupts.
- */
- for (i = 0; i < OHCI_NO_INTRS; i++)
- sc->sc_hcca->hcca_interrupt_table[revbits[i]] =
- htole32(sc->sc_eds[OHCI_NO_EDS-OHCI_NO_INTRS+i]->physaddr);
-
-#ifdef USB_DEBUG
- if (ohcidebug > 15) {
- for (i = 0; i < OHCI_NO_EDS; i++) {
- printf("ed#%d ", i);
- ohci_dump_ed(sc->sc_eds[i]);
- }
- printf("iso ");
- ohci_dump_ed(sc->sc_isoc_head);
- }
-#endif
-
- err = ohci_controller_init(sc);
- if (err != USBD_NORMAL_COMPLETION)
- goto bad5;
-
- /* Set up the bus struct. */
- 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
-
- callout_init(&sc->sc_tmo_rhsc, 0);
-
- return (USBD_NORMAL_COMPLETION);
-
- bad5:
- for (i = 0; i < OHCI_NO_EDS; i++)
- ohci_free_sed(sc, sc->sc_eds[i]);
- bad4:
- ohci_free_sed(sc, sc->sc_isoc_head);
- bad3:
- ohci_free_sed(sc, sc->sc_bulk_head);
- bad2:
- ohci_free_sed(sc, sc->sc_ctrl_head);
- bad1:
- usb_freemem(&sc->sc_bus, &sc->sc_hccadma);
- return (err);
-}
-
-static usbd_status
-ohci_controller_init(ohci_softc_t *sc)
-{
- int i;
- u_int32_t ctl, ival, hcr, fm, per, desca;
-
- /* Determine in what context we are running. */
- ctl = OREAD4(sc, OHCI_CONTROL);
- if (ctl & OHCI_IR) {
- /* SMM active, request change */
- DPRINTF(("ohci_init: SMM active, request owner change\n"));
- OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_OCR);
- for (i = 0; i < 100 && (ctl & OHCI_IR); i++) {
- usb_delay_ms(&sc->sc_bus, 1);
- ctl = OREAD4(sc, OHCI_CONTROL);
- }
- if (ctl & OHCI_IR) {
- printf("%s: SMM does not respond, resetting\n",
- device_get_nameunit(sc->sc_bus.bdev));
- OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET);
- goto reset;
- }
-#if 0
-/* Don't bother trying to reuse the BIOS init, we'll reset it anyway. */
- } else if ((ctl & OHCI_HCFS_MASK) != OHCI_HCFS_RESET) {
- /* BIOS started controller. */
- DPRINTF(("ohci_init: BIOS active\n"));
- if ((ctl & OHCI_HCFS_MASK) != OHCI_HCFS_OPERATIONAL) {
- OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_OPERATIONAL);
- usb_delay_ms(&sc->sc_bus, USB_RESUME_DELAY);
- }
-#endif
- } else {
- DPRINTF(("ohci_init: cold started\n"));
- reset:
- /* Controller was cold started. */
- usb_delay_ms(&sc->sc_bus, USB_BUS_RESET_DELAY);
- }
-
- /*
- * This reset should not be necessary according to the OHCI spec, but
- * without it some controllers do not start.
- */
- DPRINTF(("%s: resetting\n", device_get_nameunit(sc->sc_bus.bdev)));
- OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET);
- usb_delay_ms(&sc->sc_bus, USB_BUS_RESET_DELAY);
-
- /* We now own the host controller and the bus has been reset. */
- ival = OHCI_GET_IVAL(OREAD4(sc, OHCI_FM_INTERVAL));
-
- OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_HCR); /* Reset HC */
- /* Nominal time for a reset is 10 us. */
- for (i = 0; i < 10; i++) {
- delay(10);
- hcr = OREAD4(sc, OHCI_COMMAND_STATUS) & OHCI_HCR;
- if (!hcr)
- break;
- }
- if (hcr) {
- printf("%s: reset timeout\n", device_get_nameunit(sc->sc_bus.bdev));
- return (USBD_IOERROR);
- }
-#ifdef USB_DEBUG
- if (ohcidebug > 15)
- ohci_dumpregs(sc);
-#endif
-
- /* The controller is now in SUSPEND state, we have 2ms to finish. */
-
- /* Set up HC registers. */
- OWRITE4(sc, OHCI_HCCA, DMAADDR(&sc->sc_hccadma, 0));
- OWRITE4(sc, OHCI_CONTROL_HEAD_ED, sc->sc_ctrl_head->physaddr);
- OWRITE4(sc, OHCI_BULK_HEAD_ED, sc->sc_bulk_head->physaddr);
- /* disable all interrupts and then switch on all desired interrupts */
- OWRITE4(sc, OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTRS);
- OWRITE4(sc, OHCI_INTERRUPT_ENABLE, sc->sc_eintrs | OHCI_MIE);
- /* switch on desired functional features */
- ctl = OREAD4(sc, OHCI_CONTROL);
- ctl &= ~(OHCI_CBSR_MASK | OHCI_LES | OHCI_HCFS_MASK | OHCI_IR);
- ctl |= OHCI_PLE | OHCI_IE | OHCI_CLE | OHCI_BLE |
- OHCI_RATIO_1_4 | OHCI_HCFS_OPERATIONAL;
- /* And finally start it! */
- OWRITE4(sc, OHCI_CONTROL, ctl);
-
- /*
- * The controller is now OPERATIONAL. Set a some final
- * registers that should be set earlier, but that the
- * controller ignores when in the SUSPEND state.
- */
- fm = (OREAD4(sc, OHCI_FM_INTERVAL) & OHCI_FIT) ^ OHCI_FIT;
- fm |= OHCI_FSMPS(ival) | ival;
- OWRITE4(sc, OHCI_FM_INTERVAL, fm);
- per = OHCI_PERIODIC(ival); /* 90% periodic */
- OWRITE4(sc, OHCI_PERIODIC_START, per);
-
- /* Fiddle the No OverCurrent Protection bit to avoid chip bug. */
- desca = OREAD4(sc, OHCI_RH_DESCRIPTOR_A);
- OWRITE4(sc, OHCI_RH_DESCRIPTOR_A, desca | OHCI_NOCP);
- OWRITE4(sc, OHCI_RH_STATUS, OHCI_LPSC); /* Enable port power */
- usb_delay_ms(&sc->sc_bus, OHCI_ENABLE_POWER_DELAY);
- OWRITE4(sc, OHCI_RH_DESCRIPTOR_A, desca);
-
- /*
- * The AMD756 requires a delay before re-reading the register,
- * otherwise it will occasionally report 0 ports.
- */
- sc->sc_noport = 0;
- for (i = 0; i < 10 && sc->sc_noport == 0; i++) {
- usb_delay_ms(&sc->sc_bus, OHCI_READ_DESC_DELAY);
- sc->sc_noport = OHCI_GET_NDP(OREAD4(sc, OHCI_RH_DESCRIPTOR_A));
- }
-
-#ifdef USB_DEBUG
- if (ohcidebug > 5)
- ohci_dumpregs(sc);
-#endif
- return (USBD_NORMAL_COMPLETION);
-}
-
-usbd_status
-ohci_allocm(struct usbd_bus *bus, usb_dma_t *dma, u_int32_t size)
-{
- return (usb_allocmem(bus, size, 0, dma));
-}
-
-void
-ohci_freem(struct usbd_bus *bus, usb_dma_t *dma)
-{
- usb_freemem(bus, dma);
-}
-
-usbd_xfer_handle
-ohci_allocx(struct usbd_bus *bus)
-{
- struct ohci_softc *sc = (struct ohci_softc *)bus;
- usbd_xfer_handle xfer;
-
- xfer = STAILQ_FIRST(&sc->sc_free_xfers);
- if (xfer != NULL) {
- STAILQ_REMOVE_HEAD(&sc->sc_free_xfers, next);
-#ifdef DIAGNOSTIC
- if (xfer->busy_free != XFER_FREE) {
- printf("ohci_allocx: xfer=%p not free, 0x%08x\n", xfer,
- xfer->busy_free);
- }
-#endif
- } else {
- xfer = malloc(sizeof(struct ohci_xfer), M_USB, M_NOWAIT);
- }
- if (xfer != NULL) {
- memset(xfer, 0, sizeof (struct ohci_xfer));
- usb_init_task(&OXFER(xfer)->abort_task, ohci_timeout_task,
- xfer);
- OXFER(xfer)->ohci_xfer_flags = 0;
-#ifdef DIAGNOSTIC
- xfer->busy_free = XFER_BUSY;
-#endif
- }
- return (xfer);
-}
-
-void
-ohci_freex(struct usbd_bus *bus, usbd_xfer_handle xfer)
-{
- struct ohci_softc *sc = (struct ohci_softc *)bus;
-
-#ifdef DIAGNOSTIC
- if (xfer->busy_free != XFER_BUSY) {
- printf("ohci_freex: xfer=%p not busy, 0x%08x\n", xfer,
- xfer->busy_free);
- return;
- }
- xfer->busy_free = XFER_FREE;
-#endif
- STAILQ_INSERT_HEAD(&sc->sc_free_xfers, xfer, next);
-}
-
-/*
- * Shut down the controller when the system is going down.
- */
-void
-ohci_shutdown(void *v)
-{
- ohci_softc_t *sc = v;
-
- DPRINTF(("ohci_shutdown: stopping the HC\n"));
- OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET);
-}
-
-/*
- * Handle suspend/resume.
- *
- * We need to switch to polling mode here, because this routine is
- * called from an intterupt context. This is all right since we
- * are almost suspended anyway.
- */
-void
-ohci_power(int why, void *v)
-{
- ohci_softc_t *sc = v;
- u_int32_t ctl;
- int s;
-
-#ifdef USB_DEBUG
- DPRINTF(("ohci_power: sc=%p, why=%d\n", sc, why));
- ohci_dumpregs(sc);
-#endif
-
- s = splhardusb();
- if (why != PWR_RESUME) {
- sc->sc_bus.use_polling++;
- ctl = OREAD4(sc, OHCI_CONTROL) & ~OHCI_HCFS_MASK;
- if (sc->sc_control == 0) {
- /*
- * Preserve register values, in case that APM BIOS
- * does not recover them.
- */
- sc->sc_control = ctl;
- sc->sc_intre = OREAD4(sc, OHCI_INTERRUPT_ENABLE);
- }
- ctl |= OHCI_HCFS_SUSPEND;
- OWRITE4(sc, OHCI_CONTROL, ctl);
- usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT);
- sc->sc_bus.use_polling--;
- } else {
- sc->sc_bus.use_polling++;
-
- /* Some broken BIOSes never initialize Controller chip */
- ohci_controller_init(sc);
-
- if (sc->sc_intre)
- OWRITE4(sc, OHCI_INTERRUPT_ENABLE,
- sc->sc_intre & (OHCI_ALL_INTRS | OHCI_MIE));
- if (sc->sc_control)
- ctl = sc->sc_control;
- else
- ctl = OREAD4(sc, OHCI_CONTROL);
- ctl |= OHCI_HCFS_RESUME;
- OWRITE4(sc, OHCI_CONTROL, ctl);
- usb_delay_ms(&sc->sc_bus, USB_RESUME_DELAY);
- ctl = (ctl & ~OHCI_HCFS_MASK) | OHCI_HCFS_OPERATIONAL;
- OWRITE4(sc, OHCI_CONTROL, ctl);
- usb_delay_ms(&sc->sc_bus, USB_RESUME_RECOVERY);
- sc->sc_control = sc->sc_intre = 0;
- sc->sc_bus.use_polling--;
- }
- splx(s);
-}
-
-#ifdef USB_DEBUG
-void
-ohci_dumpregs(ohci_softc_t *sc)
-{
- DPRINTF(("ohci_dumpregs: rev=0x%08x control=0x%08x command=0x%08x\n",
- OREAD4(sc, OHCI_REVISION),
- OREAD4(sc, OHCI_CONTROL),
- OREAD4(sc, OHCI_COMMAND_STATUS)));
- DPRINTF((" intrstat=0x%08x intre=0x%08x intrd=0x%08x\n",
- OREAD4(sc, OHCI_INTERRUPT_STATUS),
- OREAD4(sc, OHCI_INTERRUPT_ENABLE),
- OREAD4(sc, OHCI_INTERRUPT_DISABLE)));
- DPRINTF((" hcca=0x%08x percur=0x%08x ctrlhd=0x%08x\n",
- OREAD4(sc, OHCI_HCCA),
- OREAD4(sc, OHCI_PERIOD_CURRENT_ED),
- OREAD4(sc, OHCI_CONTROL_HEAD_ED)));
- DPRINTF((" ctrlcur=0x%08x bulkhd=0x%08x bulkcur=0x%08x\n",
- OREAD4(sc, OHCI_CONTROL_CURRENT_ED),
- OREAD4(sc, OHCI_BULK_HEAD_ED),
- OREAD4(sc, OHCI_BULK_CURRENT_ED)));
- DPRINTF((" done=0x%08x fmival=0x%08x fmrem=0x%08x\n",
- OREAD4(sc, OHCI_DONE_HEAD),
- OREAD4(sc, OHCI_FM_INTERVAL),
- OREAD4(sc, OHCI_FM_REMAINING)));
- DPRINTF((" fmnum=0x%08x perst=0x%08x lsthrs=0x%08x\n",
- OREAD4(sc, OHCI_FM_NUMBER),
- OREAD4(sc, OHCI_PERIODIC_START),
- OREAD4(sc, OHCI_LS_THRESHOLD)));
- DPRINTF((" desca=0x%08x descb=0x%08x stat=0x%08x\n",
- OREAD4(sc, OHCI_RH_DESCRIPTOR_A),
- OREAD4(sc, OHCI_RH_DESCRIPTOR_B),
- OREAD4(sc, OHCI_RH_STATUS)));
- DPRINTF((" port1=0x%08x port2=0x%08x\n",
- 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",
- le32toh(sc->sc_hcca->hcca_frame_number),
- le32toh(sc->sc_hcca->hcca_done_head)));
-}
-#endif
-
-static int ohci_intr1(ohci_softc_t *);
-
-void
-ohci_intr(void *p)
-{
- ohci_softc_t *sc = p;
-
- if (sc == NULL || sc->sc_dying)
- return;
-
- /* If we get an interrupt while polling, then just ignore it. */
- if (sc->sc_bus.use_polling) {
-#ifdef DIAGNOSTIC
- printf("ohci_intr: ignored interrupt while polling\n");
-#endif
- return;
- }
-
- ohci_intr1(sc);
-}
-
-static int
-ohci_intr1(ohci_softc_t *sc)
-{
- u_int32_t intrs, eintrs;
- ohci_physaddr_t done;
-
- DPRINTFN(14,("ohci_intr1: enter\n"));
-
- /* In case the interrupt occurs before initialization has completed. */
- if (sc == NULL || sc->sc_hcca == NULL) {
-#ifdef DIAGNOSTIC
- printf("ohci_intr: sc->sc_hcca == NULL\n");
-#endif
- return (0);
- }
-
- intrs = 0;
- done = le32toh(sc->sc_hcca->hcca_done_head);
-
- /* The LSb of done is used to inform the HC Driver that an interrupt
- * condition exists for both the Done list and for another event
- * recorded in HcInterruptStatus. On an interrupt from the HC, the HC
- * Driver checks the HccaDoneHead Value. If this value is 0, then the
- * interrupt was caused by other than the HccaDoneHead update and the
- * HcInterruptStatus register needs to be accessed to determine that
- * exact interrupt cause. If HccaDoneHead is nonzero, then a Done list
- * update interrupt is indicated and if the LSb of done is nonzero,
- * then an additional interrupt event is indicated and
- * HcInterruptStatus should be checked to determine its cause.
- */
- if (done != 0) {
- if (done & ~OHCI_DONE_INTRS)
- intrs = OHCI_WDH;
- if (done & OHCI_DONE_INTRS) {
- intrs |= OREAD4(sc, OHCI_INTERRUPT_STATUS);
- done &= ~OHCI_DONE_INTRS;
- }
- sc->sc_hcca->hcca_done_head = 0;
- } else
- intrs = OREAD4(sc, OHCI_INTERRUPT_STATUS) & ~OHCI_WDH;
-
- if (intrs == 0) /* nothing to be done (PCI shared interrupt) */
- return (0);
-
- intrs &= ~OHCI_MIE;
- OWRITE4(sc, OHCI_INTERRUPT_STATUS, intrs); /* Acknowledge */
- eintrs = intrs & sc->sc_eintrs;
- if (!eintrs)
- return (0);
-
- sc->sc_bus.intr_context++;
- sc->sc_bus.no_intrs++;
- 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));
-
- if (eintrs & OHCI_SO) {
- sc->sc_overrun_cnt++;
- if (usbd_ratecheck(&sc->sc_overrun_ntc)) {
- printf("%s: %u scheduling overruns\n",
- device_get_nameunit(sc->sc_bus.bdev), sc->sc_overrun_cnt);
- sc->sc_overrun_cnt = 0;
- }
- /* XXX do what */
- eintrs &= ~OHCI_SO;
- }
- if (eintrs & OHCI_WDH) {
- ohci_add_done(sc, done &~ OHCI_DONE_INTRS);
- usb_schedsoftintr(&sc->sc_bus);
- eintrs &= ~OHCI_WDH;
- }
- if (eintrs & OHCI_RD) {
- printf("%s: resume detect\n", device_get_nameunit(sc->sc_bus.bdev));
- /* XXX process resume detect */
- }
- if (eintrs & OHCI_UE) {
- printf("%s: unrecoverable error, controller halted\n",
- device_get_nameunit(sc->sc_bus.bdev));
- OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET);
- /* XXX what else */
- }
- if (eintrs & OHCI_RHSC) {
- ohci_rhsc(sc, sc->sc_intrxfer);
- /*
- * Disable RHSC interrupt for now, because it will be
- * on until the port has been reset.
- */
- ohci_rhsc_able(sc, 0);
- /* Do not allow RHSC interrupts > 1 per second */
- callout_reset(&sc->sc_tmo_rhsc, hz, ohci_rhsc_enable, sc);
- eintrs &= ~OHCI_RHSC;
- }
-
- sc->sc_bus.intr_context--;
-
- if (eintrs != 0) {
- /* Block unprocessed interrupts. XXX */
- OWRITE4(sc, OHCI_INTERRUPT_DISABLE, eintrs);
- sc->sc_eintrs &= ~eintrs;
- printf("%s: blocking intrs 0x%x\n",
- device_get_nameunit(sc->sc_bus.bdev), eintrs);
- }
-
- return (1);
-}
-
-void
-ohci_rhsc_able(ohci_softc_t *sc, int on)
-{
- DPRINTFN(4, ("ohci_rhsc_able: on=%d\n", on));
- if (on) {
- sc->sc_eintrs |= OHCI_RHSC;
- OWRITE4(sc, OHCI_INTERRUPT_ENABLE, OHCI_RHSC);
- } else {
- sc->sc_eintrs &= ~OHCI_RHSC;
- OWRITE4(sc, OHCI_INTERRUPT_DISABLE, OHCI_RHSC);
- }
-}
-
-void
-ohci_rhsc_enable(void *v_sc)
-{
- ohci_softc_t *sc = v_sc;
- int s;
-
- s = splhardusb();
- ohci_rhsc_able(sc, 1);
- splx(s);
-}
-
-#ifdef USB_DEBUG
-char *ohci_cc_strs[] = {
- "NO_ERROR",
- "CRC",
- "BIT_STUFFING",
- "DATA_TOGGLE_MISMATCH",
- "STALL",
- "DEVICE_NOT_RESPONDING",
- "PID_CHECK_FAILURE",
- "UNEXPECTED_PID",
- "DATA_OVERRUN",
- "DATA_UNDERRUN",
- "BUFFER_OVERRUN",
- "BUFFER_UNDERRUN",
- "reserved",
- "reserved",
- "NOT_ACCESSED",
- "NOT_ACCESSED"
-};
-#endif
-
-void
-ohci_add_done(ohci_softc_t *sc, ohci_physaddr_t done)
-{
- ohci_soft_itd_t *sitd, *sidone, **ip;
- ohci_soft_td_t *std, *sdone, **p;
-
- /* Reverse the done list. */
- for (sdone = NULL, sidone = NULL; done != 0; ) {
- std = ohci_hash_find_td(sc, done);
- if (std != NULL) {
- std->dnext = sdone;
- done = le32toh(std->td.td_nexttd);
- sdone = std;
- DPRINTFN(10,("add TD %p\n", std));
- continue;
- }
- sitd = ohci_hash_find_itd(sc, done);
- if (sitd != NULL) {
- sitd->dnext = sidone;
- done = le32toh(sitd->itd.itd_nextitd);
- sidone = sitd;
- DPRINTFN(5,("add ITD %p\n", sitd));
- continue;
- }
- panic("ohci_add_done: addr 0x%08lx not found", (u_long)done);
- }
-
- /* sdone & sidone now hold the done lists. */
- /* Put them on the already processed lists. */
- for (p = &sc->sc_sdone; *p != NULL; p = &(*p)->dnext)
- ;
- *p = sdone;
- for (ip = &sc->sc_sidone; *ip != NULL; ip = &(*ip)->dnext)
- ;
- *ip = sidone;
-}
-
-void
-ohci_softintr(void *v)
-{
- ohci_softc_t *sc = v;
- ohci_soft_itd_t *sitd, *sidone, *sitdnext;
- ohci_soft_td_t *std, *sdone, *stdnext, *p, *n;
- usbd_xfer_handle xfer;
- struct ohci_pipe *opipe;
- int len, cc, s;
- int i, j, iframes;
-
- DPRINTFN(10,("ohci_softintr: enter\n"));
-
- sc->sc_bus.intr_context++;
-
- s = splhardusb();
- sdone = sc->sc_sdone;
- sc->sc_sdone = NULL;
- sidone = sc->sc_sidone;
- sc->sc_sidone = NULL;
- splx(s);
-
- DPRINTFN(10,("ohci_softintr: sdone=%p sidone=%p\n", sdone, sidone));
-
-#ifdef USB_DEBUG
- if (ohcidebug > 10) {
- DPRINTF(("ohci_process_done: TD done:\n"));
- ohci_dump_tds(sdone);
- }
-#endif
-
- for (std = sdone; std; std = stdnext) {
- xfer = std->xfer;
- stdnext = std->dnext;
- DPRINTFN(10, ("ohci_process_done: std=%p xfer=%p hcpriv=%p\n",
- std, xfer, (xfer ? xfer->hcpriv : NULL)));
- 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;
- }
- if (xfer->status == USBD_CANCELLED ||
- xfer->status == USBD_TIMEOUT) {
- DPRINTF(("ohci_process_done: cancel/timeout %p\n",
- xfer));
- /* Handled by abort routine. */
- continue;
- }
-
- len = std->len;
- if (std->td.td_cbp != 0)
- 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)
- xfer->actlen += len;
-
- cc = OHCI_TD_GET_CC(le32toh(std->td.td_flags));
- if (cc != OHCI_CC_NO_ERROR) {
- /*
- * Endpoint is halted. First unlink all the TDs
- * belonging to the failed transfer, and then restart
- * the endpoint.
- */
- opipe = (struct ohci_pipe *)xfer->pipe;
-
- 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))]));
- callout_stop(&xfer->timeout_handle);
- usb_rem_task(OXFER(xfer)->xfer.pipe->device,
- &OXFER(xfer)->abort_task);
-
- /* Remove all this xfer's TDs from the done queue. */
- for (p = std; p->dnext != NULL; p = p->dnext) {
- if (p->dnext->xfer != xfer)
- continue;
- p->dnext = p->dnext->dnext;
- }
- /* The next TD may have been removed. */
- stdnext = std->dnext;
-
- /* Remove all TDs belonging to this xfer. */
- for (p = xfer->hcpriv; p->xfer == xfer; p = n) {
- n = p->nexttd;
- ohci_free_std(sc, p);
- }
-
- /* clear halt */
- opipe->sed->ed.ed_headp = htole32(p->physaddr);
- OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF);
-
- if (cc == OHCI_CC_STALL)
- xfer->status = USBD_STALLED;
- else
- xfer->status = USBD_IOERROR;
- s = splusb();
- usb_transfer_complete(xfer);
- splx(s);
- continue;
- }
- /*
- * Skip intermediate TDs. They remain linked from
- * xfer->hcpriv and we free them when the transfer completes.
- */
- if ((std->flags & OHCI_CALL_DONE) == 0)
- continue;
-
- /* Normal transfer completion */
- callout_stop(&xfer->timeout_handle);
- usb_rem_task(OXFER(xfer)->xfer.pipe->device,
- &OXFER(xfer)->abort_task);
- for (p = xfer->hcpriv; p->xfer == xfer; p = n) {
- n = p->nexttd;
- ohci_free_std(sc, p);
- }
- xfer->status = USBD_NORMAL_COMPLETION;
- s = splusb();
- usb_transfer_complete(xfer);
- splx(s);
- }
-
-#ifdef USB_DEBUG
- if (ohcidebug > 10) {
- DPRINTF(("ohci_softintr: ITD done:\n"));
- ohci_dump_itds(sidone);
- }
-#endif
-
- for (sitd = sidone; sitd != NULL; sitd = sitdnext) {
- xfer = sitd->xfer;
- sitdnext = sitd->dnext;
- sitd->flags |= OHCI_ITD_INTFIN;
- DPRINTFN(1, ("ohci_process_done: sitd=%p xfer=%p hcpriv=%p\n",
- sitd, xfer, xfer ? xfer->hcpriv : 0));
- if (xfer == NULL)
- continue;
- if (xfer->status == USBD_CANCELLED ||
- xfer->status == USBD_TIMEOUT) {
- DPRINTF(("ohci_process_done: cancel/timeout %p\n",
- xfer));
- /* Handled by abort routine. */
- continue;
- }
- if (xfer->pipe)
- if (xfer->pipe->aborting)
- continue; /*Ignore.*/
-#ifdef DIAGNOSTIC
- if (sitd->isdone)
- printf("ohci_softintr: sitd=%p is done\n", sitd);
- sitd->isdone = 1;
-#endif
- opipe = (struct ohci_pipe *)xfer->pipe;
- if (opipe->aborting)
- continue;
-
- if (sitd->flags & OHCI_CALL_DONE) {
- ohci_soft_itd_t *next;
-
- opipe->u.iso.inuse -= xfer->nframes;
- xfer->status = USBD_NORMAL_COMPLETION;
- for (i = 0, sitd = xfer->hcpriv;;sitd = next) {
- next = sitd->nextitd;
- if (OHCI_ITD_GET_CC(sitd->itd.itd_flags) != OHCI_CC_NO_ERROR)
- xfer->status = USBD_IOERROR;
-
- if (xfer->status == USBD_NORMAL_COMPLETION) {
- iframes = OHCI_ITD_GET_FC(sitd->itd.itd_flags);
- for (j = 0; j < iframes; i++, j++) {
- len = le16toh(sitd->itd.itd_offset[j]);
- len =
- (OHCI_ITD_PSW_GET_CC(len) ==
- OHCI_CC_NOT_ACCESSED) ? 0 :
- OHCI_ITD_PSW_LENGTH(len);
- xfer->frlengths[i] = len;
- }
- }
- if (sitd->flags & OHCI_CALL_DONE)
- break;
- }
- for (sitd = xfer->hcpriv; sitd->xfer == xfer;
- sitd = next) {
- next = sitd->nextitd;
- ohci_free_sitd(sc, sitd);
- }
-
- s = splusb();
- usb_transfer_complete(xfer);
- splx(s);
- }
- }
-
-#ifdef USB_USE_SOFTINTR
- if (sc->sc_softwake) {
- sc->sc_softwake = 0;
- wakeup(&sc->sc_softwake);
- }
-#endif /* USB_USE_SOFTINTR */
-
- sc->sc_bus.intr_context--;
- DPRINTFN(10,("ohci_softintr: done:\n"));
-}
-
-void
-ohci_device_ctrl_done(usbd_xfer_handle xfer)
-{
- DPRINTFN(10,("ohci_device_ctrl_done: xfer=%p\n", xfer));
-
-#ifdef DIAGNOSTIC
- if (!(xfer->rqflags & URQ_REQUEST)) {
- panic("ohci_device_ctrl_done: not a request");
- }
-#endif
- xfer->hcpriv = NULL;
-}
-
-void
-ohci_device_intr_done(usbd_xfer_handle xfer)
-{
- struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
- ohci_softc_t *sc = (ohci_softc_t *)opipe->pipe.device->bus;
- usbd_status err;
-
- DPRINTFN(10,("ohci_device_intr_done: xfer=%p, actlen=%d\n",
- xfer, xfer->actlen));
-
- xfer->hcpriv = NULL;
- if (xfer->pipe->repeat) {
- err = ohci_device_intr_insert(sc, xfer);
- if (err) {
- xfer->status = err;
- return;
- }
- }
-}
-
-void
-ohci_device_bulk_done(usbd_xfer_handle xfer)
-{
- DPRINTFN(10,("ohci_device_bulk_done: xfer=%p, actlen=%d\n",
- xfer, xfer->actlen));
-
- xfer->hcpriv = NULL;
-}
-
-/*
- * XXX write back xfer data for architectures with a write-back
- * data cache; this is a hack because usb is mis-architected
- * in blindly mixing bus_dma w/ PIO.
- */
-static __inline void
-hacksync(usbd_xfer_handle xfer)
-{
- bus_dma_tag_t tag;
- struct usb_dma_mapping *dmap;
-
- if (xfer->length == 0)
- return;
- tag = xfer->pipe->device->bus->buffer_dmatag;
- dmap = &xfer->dmamap;
- bus_dmamap_sync(tag, dmap->map, BUS_DMASYNC_PREWRITE);
-}
-
-void
-ohci_rhsc(ohci_softc_t *sc, usbd_xfer_handle xfer)
-{
- usbd_pipe_handle pipe;
- u_char *p;
- int i, m;
- int hstatus;
-
- hstatus = OREAD4(sc, OHCI_RH_STATUS);
- DPRINTF(("ohci_rhsc: sc=%p xfer=%p hstatus=0x%08x\n",
- sc, xfer, hstatus));
-
- if (xfer == NULL) {
- /* Just ignore the change. */
- return;
- }
-
- pipe = xfer->pipe;
-
- p = xfer->buffer;
- m = min(sc->sc_noport, xfer->length * 8 - 1);
- memset(p, 0, xfer->length);
- for (i = 1; i <= m; i++) {
- /* Pick out CHANGE bits from the status reg. */
- if (OREAD4(sc, OHCI_RH_PORT_STATUS(i)) >> 16)
- p[i/8] |= 1 << (i%8);
- }
- DPRINTF(("ohci_rhsc: change=0x%02x\n", *p));
- xfer->actlen = xfer->length;
- xfer->status = USBD_NORMAL_COMPLETION;
-
- hacksync(xfer); /* XXX to compensate for usb_transfer_complete */
- usb_transfer_complete(xfer);
-}
-
-void
-ohci_root_intr_done(usbd_xfer_handle xfer)
-{
- xfer->hcpriv = NULL;
-}
-
-void
-ohci_root_ctrl_done(usbd_xfer_handle xfer)
-{
- xfer->hcpriv = NULL;
-}
-
-/*
- * Wait here until controller claims to have an interrupt.
- * Then call ohci_intr and return. Use timeout to avoid waiting
- * too long.
- */
-void
-ohci_waitintr(ohci_softc_t *sc, usbd_xfer_handle xfer)
-{
- int timo = xfer->timeout;
- int usecs;
- u_int32_t intrs;
-
- xfer->status = USBD_IN_PROGRESS;
- for (usecs = timo * 1000000 / hz; usecs > 0; usecs -= 1000) {
- usb_delay_ms(&sc->sc_bus, 1);
- if (sc->sc_dying)
- break;
- intrs = OREAD4(sc, OHCI_INTERRUPT_STATUS) & sc->sc_eintrs;
- DPRINTFN(15,("ohci_waitintr: 0x%04x\n", intrs));
-#ifdef USB_DEBUG
- if (ohcidebug > 15)
- ohci_dumpregs(sc);
-#endif
- if (intrs) {
- ohci_intr1(sc);
- if (xfer->status != USBD_IN_PROGRESS)
- return;
- }
- }
-
- /* Timeout */
- DPRINTF(("ohci_waitintr: timeout\n"));
- xfer->status = USBD_TIMEOUT;
- usb_transfer_complete(xfer);
- /* XXX should free TD */
-}
-
-void
-ohci_poll(struct usbd_bus *bus)
-{
- ohci_softc_t *sc = (ohci_softc_t *)bus;
-#ifdef USB_DEBUG
- static int last;
- int new;
- new = OREAD4(sc, OHCI_INTERRUPT_STATUS);
- if (new != last) {
- DPRINTFN(10,("ohci_poll: intrs=0x%04x\n", new));
- last = new;
- }
-#endif
-
- if (OREAD4(sc, OHCI_INTERRUPT_STATUS) & sc->sc_eintrs)
- ohci_intr1(sc);
-}
-
-usbd_status
-ohci_device_request(usbd_xfer_handle xfer)
-{
- struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
- usb_device_request_t *req = &xfer->request;
- usbd_device_handle dev = opipe->pipe.device;
- ohci_softc_t *sc = (ohci_softc_t *)dev->bus;
- ohci_soft_td_t *setup, *stat, *next, *tail;
- ohci_soft_ed_t *sed;
- int isread;
- int len;
- usbd_status err;
- int s;
-
- isread = req->bmRequestType & UT_READ;
- len = UGETW(req->wLength);
-
- DPRINTFN(3,("ohci_device_control type=0x%02x, request=0x%02x, "
- "wValue=0x%04x, wIndex=0x%04x len=%d, addr=%d, endpt=%d\n",
- req->bmRequestType, req->bRequest, UGETW(req->wValue),
- UGETW(req->wIndex), len, dev->address,
- opipe->pipe.endpoint->edesc->bEndpointAddress));
-
- setup = opipe->tail.td;
- stat = ohci_alloc_std(sc);
- if (stat == NULL) {
- err = USBD_NOMEM;
- goto bad1;
- }
- tail = ohci_alloc_std(sc);
- if (tail == NULL) {
- err = USBD_NOMEM;
- goto bad2;
- }
- tail->xfer = NULL;
-
- sed = opipe->sed;
- opipe->u.ctl.length = len;
- next = stat;
-
- /* Set up data transaction */
- if (len != 0) {
- ohci_soft_td_t *std = stat;
-
- err = ohci_alloc_std_chain(opipe, sc, len, isread, xfer,
- 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 &= htole32(~OHCI_TD_TOGGLE_MASK);
- std->td.td_flags |= htole32(OHCI_TD_TOGGLE_1);
- }
-
- memcpy(KERNADDR(&opipe->u.ctl.reqdma, 0), req, sizeof *req);
-
- setup->td.td_flags = htole32(OHCI_TD_SETUP | OHCI_TD_NOCC |
- OHCI_TD_TOGGLE_0 | OHCI_TD_SET_DI(6));
- setup->td.td_cbp = htole32(DMAADDR(&opipe->u.ctl.reqdma, 0));
- setup->nexttd = next;
- 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 = 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 = htole32(tail->physaddr);
- stat->td.td_be = 0;
- stat->flags = OHCI_CALL_DONE;
- stat->len = 0;
- stat->xfer = xfer;
-
-#ifdef USB_DEBUG
- if (ohcidebug > 5) {
- DPRINTF(("ohci_device_request:\n"));
- ohci_dump_ed(sed);
- ohci_dump_tds(setup);
- }
-#endif
-
- /* Insert ED in schedule */
- s = splusb();
- 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) {
- callout_reset(&xfer->timeout_handle, MS_TO_TICKS(xfer->timeout),
- ohci_timeout, xfer);
- }
- splx(s);
-
-#ifdef USB_DEBUG
- if (ohcidebug > 20) {
- delay(10000);
- DPRINTF(("ohci_device_request: status=%x\n",
- OREAD4(sc, OHCI_COMMAND_STATUS)));
- ohci_dumpregs(sc);
- printf("ctrl head:\n");
- ohci_dump_ed(sc->sc_ctrl_head);
- printf("sed:\n");
- ohci_dump_ed(sed);
- ohci_dump_tds(setup);
- }
-#endif
-
- return (USBD_NORMAL_COMPLETION);
-
- bad3:
- ohci_free_std(sc, tail);
- bad2:
- ohci_free_std(sc, stat);
- bad1:
- return (err);
-}
-
-/*
- * Add an ED to the schedule. Called at splusb().
- */
-void
-ohci_add_ed(ohci_soft_ed_t *sed, ohci_soft_ed_t *head)
-{
- DPRINTFN(8,("ohci_add_ed: sed=%p head=%p\n", sed, head));
-
- SPLUSBCHECK;
- sed->next = head->next;
- sed->ed.ed_nexted = head->ed.ed_nexted;
- head->next = sed;
- head->ed.ed_nexted = htole32(sed->physaddr);
-}
-
-/*
- * Remove an ED from the schedule. Called at splusb().
- */
-void
-ohci_rem_ed(ohci_soft_ed_t *sed, ohci_soft_ed_t *head)
-{
- ohci_soft_ed_t *p;
-
- SPLUSBCHECK;
-
- /* XXX */
- for (p = head; p != NULL && p->next != sed; p = p->next)
- ;
- if (p == NULL)
- panic("ohci_rem_ed: ED not found");
- p->next = sed->next;
- p->ed.ed_nexted = sed->ed.ed_nexted;
-}
-
-/*
- * When a transfer is completed the TD is added to the done queue by
- * the host controller. This queue is the processed by software.
- * Unfortunately the queue contains the physical address of the TD
- * and we have no simple way to translate this back to a kernel address.
- * To make the translation possible (and fast) we use a hash table of
- * TDs currently in the schedule. The physical address is used as the
- * hash value.
- */
-
-#define HASH(a) (((a) >> 4) % OHCI_HASH_SIZE)
-/* Called at splusb() */
-void
-ohci_hash_add_td(ohci_softc_t *sc, ohci_soft_td_t *std)
-{
- int h = HASH(std->physaddr);
-
- SPLUSBCHECK;
-
- LIST_INSERT_HEAD(&sc->sc_hash_tds[h], std, hnext);
-}
-
-/* Called at splusb() */
-void
-ohci_hash_rem_td(ohci_softc_t *sc, ohci_soft_td_t *std)
-{
- SPLUSBCHECK;
-
- LIST_REMOVE(std, hnext);
-}
-
-ohci_soft_td_t *
-ohci_hash_find_td(ohci_softc_t *sc, ohci_physaddr_t a)
-{
- int h = HASH(a);
- ohci_soft_td_t *std;
-
- /* if these are present they should be masked out at an earlier
- * stage.
- */
- KASSERT((a&~OHCI_HEADMASK) == 0, ("%s: 0x%b has lower bits set\n",
- device_get_nameunit(sc->sc_bus.bdev),
- (int) a, "\20\1HALT\2TOGGLE"));
-
- for (std = LIST_FIRST(&sc->sc_hash_tds[h]);
- std != NULL;
- std = LIST_NEXT(std, hnext))
- if (std->physaddr == a)
- return (std);
-
- DPRINTF(("%s: ohci_hash_find_td: addr 0x%08lx not found\n",
- device_get_nameunit(sc->sc_bus.bdev), (u_long) a));
- return (NULL);
-}
-
-/* Called at splusb() */
-void
-ohci_hash_add_itd(ohci_softc_t *sc, ohci_soft_itd_t *sitd)
-{
- int h = HASH(sitd->physaddr);
-
- SPLUSBCHECK;
-
- DPRINTFN(10,("ohci_hash_add_itd: sitd=%p physaddr=0x%08lx\n",
- sitd, (u_long)sitd->physaddr));
-
- LIST_INSERT_HEAD(&sc->sc_hash_itds[h], sitd, hnext);
-}
-
-/* Called at splusb() */
-void
-ohci_hash_rem_itd(ohci_softc_t *sc, ohci_soft_itd_t *sitd)
-{
- SPLUSBCHECK;
-
- DPRINTFN(10,("ohci_hash_rem_itd: sitd=%p physaddr=0x%08lx\n",
- sitd, (u_long)sitd->physaddr));
-
- LIST_REMOVE(sitd, hnext);
-}
-
-ohci_soft_itd_t *
-ohci_hash_find_itd(ohci_softc_t *sc, ohci_physaddr_t a)
-{
- int h = HASH(a);
- ohci_soft_itd_t *sitd;
-
- for (sitd = LIST_FIRST(&sc->sc_hash_itds[h]);
- sitd != NULL;
- sitd = LIST_NEXT(sitd, hnext))
- if (sitd->physaddr == a)
- return (sitd);
- return (NULL);
-}
-
-void
-ohci_timeout(void *addr)
-{
- struct ohci_xfer *oxfer = addr;
- struct ohci_pipe *opipe = (struct ohci_pipe *)oxfer->xfer.pipe;
- ohci_softc_t *sc = (ohci_softc_t *)opipe->pipe.device->bus;
-
- DPRINTF(("ohci_timeout: oxfer=%p\n", oxfer));
-
- if (sc->sc_dying) {
- ohci_abort_xfer(&oxfer->xfer, USBD_TIMEOUT);
- return;
- }
-
- /* Execute the abort in a process context. */
- usb_add_task(oxfer->xfer.pipe->device, &oxfer->abort_task,
- USB_TASKQ_HC);
-}
-
-void
-ohci_timeout_task(void *addr)
-{
- usbd_xfer_handle xfer = addr;
- int s;
-
- DPRINTF(("ohci_timeout_task: xfer=%p\n", xfer));
-
- s = splusb();
- ohci_abort_xfer(xfer, USBD_TIMEOUT);
- splx(s);
-}
-
-#ifdef USB_DEBUG
-void
-ohci_dump_tds(ohci_soft_td_t *std)
-{
- for (; std; std = std->nexttd)
- ohci_dump_td(std);
-}
-
-void
-ohci_dump_td(ohci_soft_td_t *std)
-{
- char sbuf[128];
-
- bitmask_snprintf((u_int32_t)le32toh(std->td.td_flags),
- "\20\23R\24OUT\25IN\31TOG1\32SETTOGGLE",
- sbuf, sizeof(sbuf));
-
- printf("TD(%p) at %08lx: %s delay=%d ec=%d cc=%d\ncbp=0x%08lx "
- "nexttd=0x%08lx be=0x%08lx\n",
- std, (u_long)std->physaddr, sbuf,
- 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
-ohci_dump_itd(ohci_soft_itd_t *sitd)
-{
- int i;
-
- printf("ITD(%p) at %08lx: sf=%d di=%d fc=%d cc=%d\n"
- "bp0=0x%08lx next=0x%08lx be=0x%08lx\n",
- sitd, (u_long)sitd->physaddr,
- OHCI_ITD_GET_SF(le32toh(sitd->itd.itd_flags)),
- OHCI_ITD_GET_DI(le32toh(sitd->itd.itd_flags)),
- OHCI_ITD_GET_FC(le32toh(sitd->itd.itd_flags)),
- OHCI_ITD_GET_CC(le32toh(sitd->itd.itd_flags)),
- (u_long)le32toh(sitd->itd.itd_bp0),
- (u_long)le32toh(sitd->itd.itd_nextitd),
- (u_long)le32toh(sitd->itd.itd_be));
- for (i = 0; i < OHCI_ITD_NOFFSET; i++)
- printf("offs[%d]=0x%04x ", i,
- (u_int)le16toh(sitd->itd.itd_offset[i]));
- printf("\n");
-}
-
-void
-ohci_dump_itds(ohci_soft_itd_t *sitd)
-{
- for (; sitd; sitd = sitd->nextitd)
- ohci_dump_itd(sitd);
-}
-
-void
-ohci_dump_ed(ohci_soft_ed_t *sed)
-{
- char sbuf[128], sbuf2[128];
-
- bitmask_snprintf((u_int32_t)le32toh(sed->ed.ed_flags),
- "\20\14OUT\15IN\16LOWSPEED\17SKIP\20ISO",
- sbuf, sizeof(sbuf));
- bitmask_snprintf((u_int32_t)le32toh(sed->ed.ed_headp),
- "\20\1HALT\2CARRY", sbuf2, sizeof(sbuf2));
-
- printf("ED(%p) at 0x%08lx: addr=%d endpt=%d maxp=%d flags=%s\ntailp=0x%08lx "
- "headflags=%s headp=0x%08lx nexted=0x%08lx\n",
- sed, (u_long)sed->physaddr,
- 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)), sbuf,
- (u_long)le32toh(sed->ed.ed_tailp), sbuf2,
- (u_long)le32toh(sed->ed.ed_headp),
- (u_long)le32toh(sed->ed.ed_nexted));
-}
-#endif
-
-usbd_status
-ohci_open(usbd_pipe_handle pipe)
-{
- usbd_device_handle dev = pipe->device;
- ohci_softc_t *sc = (ohci_softc_t *)dev->bus;
- usb_endpoint_descriptor_t *ed = pipe->endpoint->edesc;
- struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
- u_int8_t addr = dev->address;
- u_int8_t xfertype = ed->bmAttributes & UE_XFERTYPE;
- ohci_soft_ed_t *sed;
- ohci_soft_td_t *std;
- ohci_soft_itd_t *sitd;
- ohci_physaddr_t tdphys;
- u_int32_t fmt;
- usbd_status err;
- int s;
- int ival;
-
- DPRINTFN(1, ("ohci_open: pipe=%p, addr=%d, endpt=%d (%d)\n",
- pipe, addr, ed->bEndpointAddress, sc->sc_addr));
-
- if (sc->sc_dying)
- return (USBD_IOERROR);
-
- std = NULL;
- sed = NULL;
-
- if (addr == sc->sc_addr) {
- switch (ed->bEndpointAddress) {
- case USB_CONTROL_ENDPOINT:
- pipe->methods = &ohci_root_ctrl_methods;
- break;
- case UE_DIR_IN | OHCI_INTR_ENDPT:
- pipe->methods = &ohci_root_intr_methods;
- break;
- default:
- return (USBD_INVAL);
- }
- } else {
- sed = ohci_alloc_sed(sc);
- if (sed == NULL)
- goto bad0;
- opipe->sed = sed;
- if (xfertype == UE_ISOCHRONOUS) {
- sitd = ohci_alloc_sitd(sc);
- if (sitd == NULL)
- goto bad1;
- opipe->tail.itd = sitd;
- opipe->aborting = 0;
- tdphys = sitd->physaddr;
- fmt = OHCI_ED_FORMAT_ISO;
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN)
- fmt |= OHCI_ED_DIR_IN;
- else
- fmt |= OHCI_ED_DIR_OUT;
- } else {
- std = ohci_alloc_std(sc);
- if (std == NULL)
- goto bad1;
- opipe->tail.td = std;
- tdphys = std->physaddr;
- fmt = OHCI_ED_FORMAT_GEN | OHCI_ED_DIR_TD;
- }
- sed->ed.ed_flags = htole32(
- OHCI_ED_SET_FA(addr) |
- OHCI_ED_SET_EN(UE_GET_ADDR(ed->bEndpointAddress)) |
- (dev->speed == USB_SPEED_LOW ? OHCI_ED_SPEED : 0) |
- fmt |
- OHCI_ED_SET_MAXP(UGETW(ed->wMaxPacketSize)));
- sed->ed.ed_headp = htole32(tdphys |
- (pipe->endpoint->savedtoggle ? OHCI_TOGGLECARRY : 0));
- 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);
- if (err)
- goto bad;
- s = splusb();
- ohci_add_ed(sed, sc->sc_ctrl_head);
- splx(s);
- break;
- case UE_INTERRUPT:
- pipe->methods = &ohci_device_intr_methods;
- ival = pipe->interval;
- if (ival == USBD_DEFAULT_INTERVAL)
- ival = ed->bInterval;
- return (ohci_device_setintr(sc, opipe, ival));
- case UE_ISOCHRONOUS:
- pipe->methods = &ohci_device_isoc_methods;
- return (ohci_setup_isoc(pipe));
- case UE_BULK:
- pipe->methods = &ohci_device_bulk_methods;
- s = splusb();
- ohci_add_ed(sed, sc->sc_bulk_head);
- splx(s);
- break;
- }
- }
- return (USBD_NORMAL_COMPLETION);
-
- bad:
- if (std != NULL)
- ohci_free_std(sc, std);
- bad1:
- if (sed != NULL)
- ohci_free_sed(sc, sed);
- bad0:
- return (USBD_NOMEM);
-
-}
-
-/*
- * Close a reqular pipe.
- * Assumes that there are no pending transactions.
- */
-void
-ohci_close_pipe(usbd_pipe_handle pipe, ohci_soft_ed_t *head)
-{
- struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
- ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
- ohci_soft_ed_t *sed = opipe->sed;
- int s;
-
- s = splusb();
-#ifdef DIAGNOSTIC
- sed->ed.ed_flags |= htole32(OHCI_ED_SKIP);
- if ((le32toh(sed->ed.ed_tailp) & OHCI_HEADMASK) !=
- (le32toh(sed->ed.ed_headp) & OHCI_HEADMASK)) {
- ohci_soft_td_t *std;
- std = ohci_hash_find_td(sc, le32toh(sed->ed.ed_headp));
- printf("ohci_close_pipe: pipe not empty sed=%p hd=0x%x "
- "tl=0x%x pipe=%p, std=%p\n", sed,
- (int)le32toh(sed->ed.ed_headp),
- (int)le32toh(sed->ed.ed_tailp),
- pipe, std);
-#ifdef USB_DEBUG
- usbd_dump_pipe(&opipe->pipe);
-#endif
-#ifdef USB_DEBUG
- ohci_dump_ed(sed);
- if (std)
- ohci_dump_td(std);
-#endif
- usb_delay_ms(&sc->sc_bus, 2);
- 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
- ohci_rem_ed(sed, head);
- /* Make sure the host controller is not touching this ED */
- usb_delay_ms(&sc->sc_bus, 1);
- splx(s);
- pipe->endpoint->savedtoggle =
- (le32toh(sed->ed.ed_headp) & OHCI_TOGGLECARRY) ? 1 : 0;
- ohci_free_sed(sc, opipe->sed);
-}
-
-/*
- * Abort a device request.
- * If this routine is called at splusb() it guarantees that the request
- * will be removed from the hardware scheduling and that the callback
- * for it will be called with USBD_CANCELLED status.
- * It's impossible to guarantee that the requested transfer will not
- * have happened since the hardware runs concurrently.
- * If the transaction has already happened we rely on the ordinary
- * interrupt processing to process it.
- */
-void
-ohci_abort_xfer(usbd_xfer_handle xfer, usbd_status status)
-{
- struct ohci_xfer *oxfer = OXFER(xfer);
- struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
- ohci_softc_t *sc = (ohci_softc_t *)opipe->pipe.device->bus;
- ohci_soft_ed_t *sed = opipe->sed;
- ohci_soft_td_t *p, *n;
- ohci_physaddr_t headp;
- int s, hit;
-
- DPRINTF(("ohci_abort_xfer: xfer=%p pipe=%p sed=%p\n", xfer, opipe,sed));
-
- if (sc->sc_dying) {
- /* If we're dying, just do the software part. */
- s = splusb();
- xfer->status = status; /* make software ignore it */
- callout_stop(&xfer->timeout_handle);
- usb_rem_task(xfer->pipe->device, &OXFER(xfer)->abort_task);
- usb_transfer_complete(xfer);
- splx(s);
- return;
- }
-
- if (xfer->device->bus->intr_context || !curproc)
- panic("ohci_abort_xfer: not in process context");
-
- /*
- * If an abort is already in progress then just wait for it to
- * complete and return.
- */
- if (oxfer->ohci_xfer_flags & OHCI_XFER_ABORTING) {
- DPRINTFN(2, ("ohci_abort_xfer: already aborting\n"));
- /* No need to wait if we're aborting from a timeout. */
- if (status == USBD_TIMEOUT)
- return;
- /* Override the status which might be USBD_TIMEOUT. */
- xfer->status = status;
- DPRINTFN(2, ("ohci_abort_xfer: waiting for abort to finish\n"));
- oxfer->ohci_xfer_flags |= OHCI_XFER_ABORTWAIT;
- while (oxfer->ohci_xfer_flags & OHCI_XFER_ABORTING)
- tsleep(&oxfer->ohci_xfer_flags, PZERO, "ohciaw", 0);
- return;
- }
-
- /*
- * Step 1: Make interrupt routine and hardware ignore xfer.
- */
- s = splusb();
- oxfer->ohci_xfer_flags |= OHCI_XFER_ABORTING;
- xfer->status = status; /* make software ignore it */
- callout_stop(&xfer->timeout_handle);
- usb_rem_task(xfer->pipe->device, &OXFER(xfer)->abort_task);
- splx(s);
- DPRINTFN(1,("ohci_abort_xfer: stop ed=%p\n", sed));
- sed->ed.ed_flags |= htole32(OHCI_ED_SKIP); /* force hardware skip */
-
- /*
- * Step 2: Wait until we know hardware has finished any possible
- * use of the xfer. Also make sure the soft interrupt routine
- * has run.
- */
- usb_delay_ms(opipe->pipe.device->bus, 20); /* Hardware finishes in 1ms */
- s = splusb();
-#ifdef USB_USE_SOFTINTR
- sc->sc_softwake = 1;
-#endif /* USB_USE_SOFTINTR */
- usb_schedsoftintr(&sc->sc_bus);
-#ifdef USB_USE_SOFTINTR
- tsleep(&sc->sc_softwake, PZERO, "ohciab", 0);
-#endif /* USB_USE_SOFTINTR */
- splx(s);
-
- /*
- * Step 3: Remove any vestiges of the xfer from the hardware.
- * The complication here is that the hardware may have executed
- * beyond the xfer we're trying to abort. So as we're scanning
- * the TDs of this xfer we check if the hardware points to
- * any of them.
- */
- s = splusb(); /* XXX why? */
- p = xfer->hcpriv;
-#ifdef DIAGNOSTIC
- if (p == NULL) {
- oxfer->ohci_xfer_flags &= ~OHCI_XFER_ABORTING; /* XXX */
- splx(s);
- printf("ohci_abort_xfer: hcpriv is NULL\n");
- return;
- }
-#endif
-#ifdef USB_DEBUG
- if (ohcidebug > 1) {
- DPRINTF(("ohci_abort_xfer: sed=\n"));
- ohci_dump_ed(sed);
- ohci_dump_tds(p);
- }
-#endif
- headp = le32toh(sed->ed.ed_headp) & OHCI_HEADMASK;
- hit = 0;
- for (; p->xfer == xfer; p = n) {
- hit |= headp == p->physaddr;
- n = p->nexttd;
- ohci_free_std(sc, p);
- }
- /* Zap headp register if hardware pointed inside the xfer. */
- if (hit) {
- DPRINTFN(1,("ohci_abort_xfer: set hd=0x08%x, tl=0x%08x\n",
- (int)p->physaddr, (int)le32toh(sed->ed.ed_tailp)));
- sed->ed.ed_headp = htole32(p->physaddr); /* unlink TDs */
- } else {
- DPRINTFN(1,("ohci_abort_xfer: no hit\n"));
- }
-
- /*
- * Step 4: Turn on hardware again.
- */
- sed->ed.ed_flags &= htole32(~OHCI_ED_SKIP); /* remove hardware skip */
-
- /*
- * Step 5: Execute callback.
- */
- /* Do the wakeup first to avoid touching the xfer after the callback. */
- oxfer->ohci_xfer_flags &= ~OHCI_XFER_ABORTING;
- if (oxfer->ohci_xfer_flags & OHCI_XFER_ABORTWAIT) {
- oxfer->ohci_xfer_flags &= ~OHCI_XFER_ABORTWAIT;
- wakeup(&oxfer->ohci_xfer_flags);
- }
- usb_transfer_complete(xfer);
-
- splx(s);
-}
-
-/*
- * Data structures and routines to emulate the root hub.
- */
-static usb_device_descriptor_t ohci_devd = {
- USB_DEVICE_DESCRIPTOR_SIZE,
- UDESC_DEVICE, /* type */
- {0x00, 0x01}, /* USB version */
- UDCLASS_HUB, /* class */
- UDSUBCLASS_HUB, /* subclass */
- UDPROTO_FSHUB, /* protocol */
- 64, /* max packet */
- {0},{0},{0x00,0x01}, /* device id */
- 1,2,0, /* string indicies */
- 1 /* # of configurations */
-};
-
-static usb_config_descriptor_t ohci_confd = {
- USB_CONFIG_DESCRIPTOR_SIZE,
- UDESC_CONFIG,
- {USB_CONFIG_DESCRIPTOR_SIZE +
- USB_INTERFACE_DESCRIPTOR_SIZE +
- USB_ENDPOINT_DESCRIPTOR_SIZE},
- 1,
- 1,
- 0,
- UC_SELF_POWERED,
- 0 /* max power */
-};
-
-static usb_interface_descriptor_t ohci_ifcd = {
- USB_INTERFACE_DESCRIPTOR_SIZE,
- UDESC_INTERFACE,
- 0,
- 0,
- 1,
- UICLASS_HUB,
- UISUBCLASS_HUB,
- UIPROTO_FSHUB,
- 0
-};
-
-static usb_endpoint_descriptor_t ohci_endpd = {
- USB_ENDPOINT_DESCRIPTOR_SIZE,
- UDESC_ENDPOINT,
- UE_DIR_IN | OHCI_INTR_ENDPT,
- UE_INTERRUPT,
- {8, 0}, /* max packet */
- 255
-};
-
-static usb_hub_descriptor_t ohci_hubd = {
- USB_HUB_DESCRIPTOR_SIZE,
- UDESC_HUB,
- 0,
- {0,0},
- 0,
- 0,
- {0},
-};
-
-static int
-ohci_str(usb_string_descriptor_t *p, int l, const char *s)
-{
- int i;
-
- if (l == 0)
- return (0);
- p->bLength = 2 * strlen(s) + 2;
- if (l == 1)
- return (1);
- p->bDescriptorType = UDESC_STRING;
- l -= 2;
- for (i = 0; s[i] && l > 1; i++, l -= 2)
- USETW2(p->bString[i], 0, s[i]);
- return (2*i+2);
-}
-
-/*
- * Simulate a hardware hub by handling all the necessary requests.
- */
-static usbd_status
-ohci_root_ctrl_transfer(usbd_xfer_handle xfer)
-{
- usbd_status err;
-
- /* Insert last in queue. */
- err = usb_insert_transfer(xfer);
- if (err)
- return (err);
-
- /* Pipe isn't running, start first */
- return (ohci_root_ctrl_start(STAILQ_FIRST(&xfer->pipe->queue)));
-}
-
-static usbd_status
-ohci_root_ctrl_start(usbd_xfer_handle xfer)
-{
- ohci_softc_t *sc = (ohci_softc_t *)xfer->pipe->device->bus;
- usb_device_request_t *req;
- void *buf = NULL;
- int port, i;
- int s, len, value, index, l, totlen = 0;
- usb_port_status_t ps;
- usb_hub_descriptor_t hubd;
- usbd_status err;
- u_int32_t v;
-
- if (sc->sc_dying)
- return (USBD_IOERROR);
-
-#ifdef DIAGNOSTIC
- if (!(xfer->rqflags & URQ_REQUEST))
- /* XXX panic */
- return (USBD_INVAL);
-#endif
- req = &xfer->request;
-
- DPRINTFN(4,("ohci_root_ctrl_control type=0x%02x request=%02x\n",
- req->bmRequestType, req->bRequest));
-
- len = UGETW(req->wLength);
- value = UGETW(req->wValue);
- index = UGETW(req->wIndex);
-
- if (len != 0)
- buf = xfer->buffer;
-
-#define C(x,y) ((x) | ((y) << 8))
- switch(C(req->bRequest, req->bmRequestType)) {
- case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE):
- case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE):
- case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT):
- /*
- * DEVICE_REMOTE_WAKEUP and ENDPOINT_HALT are no-ops
- * for the integrated root hub.
- */
- break;
- case C(UR_GET_CONFIG, UT_READ_DEVICE):
- if (len > 0) {
- *(u_int8_t *)buf = sc->sc_conf;
- totlen = 1;
- }
- break;
- case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
- DPRINTFN(8,("ohci_root_ctrl_control wValue=0x%04x\n", value));
- switch(value >> 8) {
- case UDESC_DEVICE:
- if ((value & 0xff) != 0) {
- err = USBD_IOERROR;
- goto ret;
- }
- totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE);
- USETW(ohci_devd.idVendor, sc->sc_id_vendor);
- memcpy(buf, &ohci_devd, l);
- break;
- case UDESC_CONFIG:
- if ((value & 0xff) != 0) {
- err = USBD_IOERROR;
- goto ret;
- }
- totlen = l = min(len, USB_CONFIG_DESCRIPTOR_SIZE);
- memcpy(buf, &ohci_confd, l);
- buf = (char *)buf + l;
- len -= l;
- l = min(len, USB_INTERFACE_DESCRIPTOR_SIZE);
- totlen += l;
- memcpy(buf, &ohci_ifcd, l);
- buf = (char *)buf + l;
- len -= l;
- l = min(len, USB_ENDPOINT_DESCRIPTOR_SIZE);
- totlen += l;
- memcpy(buf, &ohci_endpd, l);
- break;
- case UDESC_STRING:
- if (len == 0)
- break;
- *(u_int8_t *)buf = 0;
- totlen = 1;
- switch (value & 0xff) {
- case 1: /* Vendor */
- totlen = ohci_str(buf, len, sc->sc_vendor);
- break;
- case 2: /* Product */
- totlen = ohci_str(buf, len, "OHCI root hub");
- break;
- }
- break;
- default:
- err = USBD_IOERROR;
- goto ret;
- }
- break;
- case C(UR_GET_INTERFACE, UT_READ_INTERFACE):
- if (len > 0) {
- *(u_int8_t *)buf = 0;
- totlen = 1;
- }
- break;
- case C(UR_GET_STATUS, UT_READ_DEVICE):
- if (len > 1) {
- USETW(((usb_status_t *)buf)->wStatus,UDS_SELF_POWERED);
- totlen = 2;
- }
- break;
- case C(UR_GET_STATUS, UT_READ_INTERFACE):
- case C(UR_GET_STATUS, UT_READ_ENDPOINT):
- if (len > 1) {
- USETW(((usb_status_t *)buf)->wStatus, 0);
- totlen = 2;
- }
- break;
- case C(UR_SET_ADDRESS, UT_WRITE_DEVICE):
- if (value >= USB_MAX_DEVICES) {
- err = USBD_IOERROR;
- goto ret;
- }
- sc->sc_addr = value;
- break;
- case C(UR_SET_CONFIG, UT_WRITE_DEVICE):
- if (value != 0 && value != 1) {
- err = USBD_IOERROR;
- goto ret;
- }
- sc->sc_conf = value;
- break;
- case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE):
- break;
- case C(UR_SET_FEATURE, UT_WRITE_DEVICE):
- case C(UR_SET_FEATURE, UT_WRITE_INTERFACE):
- case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT):
- err = USBD_IOERROR;
- goto ret;
- case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE):
- break;
- case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT):
- break;
- /* Hub requests */
- case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE):
- break;
- case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER):
- DPRINTFN(8, ("ohci_root_ctrl_control: UR_CLEAR_PORT_FEATURE "
- "port=%d feature=%d\n",
- index, value));
- if (index < 1 || index > sc->sc_noport) {
- err = USBD_IOERROR;
- goto ret;
- }
- port = OHCI_RH_PORT_STATUS(index);
- switch(value) {
- case UHF_PORT_ENABLE:
- OWRITE4(sc, port, UPS_CURRENT_CONNECT_STATUS);
- break;
- case UHF_PORT_SUSPEND:
- OWRITE4(sc, port, UPS_OVERCURRENT_INDICATOR);
- break;
- case UHF_PORT_POWER:
- /* Yes, writing to the LOW_SPEED bit clears power. */
- OWRITE4(sc, port, UPS_LOW_SPEED);
- break;
- case UHF_C_PORT_CONNECTION:
- OWRITE4(sc, port, UPS_C_CONNECT_STATUS << 16);
- break;
- case UHF_C_PORT_ENABLE:
- OWRITE4(sc, port, UPS_C_PORT_ENABLED << 16);
- break;
- case UHF_C_PORT_SUSPEND:
- OWRITE4(sc, port, UPS_C_SUSPEND << 16);
- break;
- case UHF_C_PORT_OVER_CURRENT:
- OWRITE4(sc, port, UPS_C_OVERCURRENT_INDICATOR << 16);
- break;
- case UHF_C_PORT_RESET:
- OWRITE4(sc, port, UPS_C_PORT_RESET << 16);
- break;
- default:
- err = USBD_IOERROR;
- goto ret;
- }
- switch(value) {
- case UHF_C_PORT_CONNECTION:
- case UHF_C_PORT_ENABLE:
- case UHF_C_PORT_SUSPEND:
- case UHF_C_PORT_OVER_CURRENT:
- case UHF_C_PORT_RESET:
- /* Enable RHSC interrupt if condition is cleared. */
- if ((OREAD4(sc, port) >> 16) == 0)
- ohci_rhsc_able(sc, 1);
- break;
- default:
- break;
- }
- break;
- case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE):
- if ((value & 0xff) != 0) {
- err = USBD_IOERROR;
- goto ret;
- }
- v = OREAD4(sc, OHCI_RH_DESCRIPTOR_A);
- hubd = ohci_hubd;
- hubd.bNbrPorts = sc->sc_noport;
- USETW(hubd.wHubCharacteristics,
- (v & OHCI_NPS ? UHD_PWR_NO_SWITCH :
- v & OHCI_PSM ? UHD_PWR_GANGED : UHD_PWR_INDIVIDUAL)
- /* XXX overcurrent */
- );
- hubd.bPwrOn2PwrGood = OHCI_GET_POTPGT(v);
- v = OREAD4(sc, OHCI_RH_DESCRIPTOR_B);
- for (i = 0, l = sc->sc_noport; l > 0; i++, l -= 8, v >>= 8)
- hubd.DeviceRemovable[i++] = (u_int8_t)v;
- hubd.bDescLength = USB_HUB_DESCRIPTOR_SIZE + i;
- l = min(len, hubd.bDescLength);
- totlen = l;
- memcpy(buf, &hubd, l);
- break;
- case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
- if (len != 4) {
- err = USBD_IOERROR;
- goto ret;
- }
- memset(buf, 0, len); /* ? XXX */
- totlen = len;
- break;
- case C(UR_GET_STATUS, UT_READ_CLASS_OTHER):
- DPRINTFN(8,("ohci_root_ctrl_transfer: get port status i=%d\n",
- index));
- if (index < 1 || index > sc->sc_noport) {
- err = USBD_IOERROR;
- goto ret;
- }
- if (len != 4) {
- err = USBD_IOERROR;
- goto ret;
- }
- v = OREAD4(sc, OHCI_RH_PORT_STATUS(index));
- DPRINTFN(8,("ohci_root_ctrl_transfer: port status=0x%04x\n",
- v));
- USETW(ps.wPortStatus, v);
- USETW(ps.wPortChange, v >> 16);
- l = min(len, sizeof ps);
- memcpy(buf, &ps, l);
- totlen = l;
- break;
- case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE):
- err = USBD_IOERROR;
- goto ret;
- case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE):
- break;
- case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER):
- if (index < 1 || index > sc->sc_noport) {
- err = USBD_IOERROR;
- goto ret;
- }
- port = OHCI_RH_PORT_STATUS(index);
- switch(value) {
- case UHF_PORT_ENABLE:
- OWRITE4(sc, port, UPS_PORT_ENABLED);
- break;
- case UHF_PORT_SUSPEND:
- OWRITE4(sc, port, UPS_SUSPEND);
- break;
- case UHF_PORT_RESET:
- DPRINTFN(5,("ohci_root_ctrl_transfer: reset port %d\n",
- index));
- OWRITE4(sc, port, UPS_RESET);
- for (i = 0; i < 5; i++) {
- usb_delay_ms(&sc->sc_bus,
- USB_PORT_ROOT_RESET_DELAY);
- if (sc->sc_dying) {
- err = USBD_IOERROR;
- goto ret;
- }
- if ((OREAD4(sc, port) & UPS_RESET) == 0)
- break;
- }
- DPRINTFN(8,("ohci port %d reset, status = 0x%04x\n",
- index, OREAD4(sc, port)));
- break;
- case UHF_PORT_POWER:
- DPRINTFN(2,("ohci_root_ctrl_transfer: set port power "
- "%d\n", index));
- OWRITE4(sc, port, UPS_PORT_POWER);
- break;
- default:
- err = USBD_IOERROR;
- goto ret;
- }
- break;
- default:
- err = USBD_IOERROR;
- goto ret;
- }
- xfer->actlen = totlen;
- err = USBD_NORMAL_COMPLETION;
- ret:
- xfer->status = err;
- s = splusb();
- hacksync(xfer); /* XXX to compensate for usb_transfer_complete */
- usb_transfer_complete(xfer);
- splx(s);
- return (USBD_IN_PROGRESS);
-}
-
-/* Abort a root control request. */
-static void
-ohci_root_ctrl_abort(usbd_xfer_handle xfer)
-{
- /* Nothing to do, all transfers are synchronous. */
-}
-
-/* Close the root pipe. */
-static void
-ohci_root_ctrl_close(usbd_pipe_handle pipe)
-{
- DPRINTF(("ohci_root_ctrl_close\n"));
- /* Nothing to do. */
-}
-
-static usbd_status
-ohci_root_intr_transfer(usbd_xfer_handle xfer)
-{
- usbd_status err;
-
- /* Insert last in queue. */
- err = usb_insert_transfer(xfer);
- if (err)
- return (err);
-
- /* Pipe isn't running, start first */
- return (ohci_root_intr_start(STAILQ_FIRST(&xfer->pipe->queue)));
-}
-
-static usbd_status
-ohci_root_intr_start(usbd_xfer_handle xfer)
-{
- usbd_pipe_handle pipe = xfer->pipe;
- ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
-
- if (sc->sc_dying)
- return (USBD_IOERROR);
-
- sc->sc_intrxfer = xfer;
-
- return (USBD_IN_PROGRESS);
-}
-
-/* Abort a root interrupt request. */
-static void
-ohci_root_intr_abort(usbd_xfer_handle xfer)
-{
- int s;
-
- if (xfer->pipe->intrxfer == xfer) {
- DPRINTF(("ohci_root_intr_abort: remove\n"));
- xfer->pipe->intrxfer = NULL;
- }
- xfer->status = USBD_CANCELLED;
- s = splusb();
- usb_transfer_complete(xfer);
- splx(s);
-}
-
-/* Close the root pipe. */
-static void
-ohci_root_intr_close(usbd_pipe_handle pipe)
-{
- ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
-
- DPRINTF(("ohci_root_intr_close\n"));
-
- sc->sc_intrxfer = NULL;
-}
-
-/************************/
-
-static usbd_status
-ohci_device_ctrl_transfer(usbd_xfer_handle xfer)
-{
- usbd_status err;
-
- /* Insert last in queue. */
- err = usb_insert_transfer(xfer);
- if (err)
- return (err);
-
- /* Pipe isn't running, start first */
- return (ohci_device_ctrl_start(STAILQ_FIRST(&xfer->pipe->queue)));
-}
-
-static usbd_status
-ohci_device_ctrl_start(usbd_xfer_handle xfer)
-{
- ohci_softc_t *sc = (ohci_softc_t *)xfer->pipe->device->bus;
- usbd_status err;
-
- if (sc->sc_dying)
- return (USBD_IOERROR);
-
-#ifdef DIAGNOSTIC
- if (!(xfer->rqflags & URQ_REQUEST)) {
- /* XXX panic */
- printf("ohci_device_ctrl_transfer: not a request\n");
- return (USBD_INVAL);
- }
-#endif
-
- err = ohci_device_request(xfer);
- if (err)
- return (err);
-
- if (sc->sc_bus.use_polling)
- ohci_waitintr(sc, xfer);
- return (USBD_IN_PROGRESS);
-}
-
-/* Abort a device control request. */
-static void
-ohci_device_ctrl_abort(usbd_xfer_handle xfer)
-{
- DPRINTF(("ohci_device_ctrl_abort: xfer=%p\n", xfer));
- ohci_abort_xfer(xfer, USBD_CANCELLED);
-}
-
-/* Close a device control pipe. */
-static void
-ohci_device_ctrl_close(usbd_pipe_handle pipe)
-{
- struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
- ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
-
- DPRINTF(("ohci_device_ctrl_close: pipe=%p\n", pipe));
- ohci_close_pipe(pipe, sc->sc_ctrl_head);
- ohci_free_std(sc, opipe->tail.td);
-}
-
-/************************/
-
-static void
-ohci_device_clear_toggle(usbd_pipe_handle pipe)
-{
- struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
-
- opipe->sed->ed.ed_headp &= htole32(~OHCI_TOGGLECARRY);
-}
-
-static void
-ohci_noop(usbd_pipe_handle pipe)
-{
-}
-
-static usbd_status
-ohci_device_bulk_transfer(usbd_xfer_handle xfer)
-{
- usbd_status err;
-
- /* Insert last in queue. */
- err = usb_insert_transfer(xfer);
- if (err)
- return (err);
-
- /* Pipe isn't running, start first */
- return (ohci_device_bulk_start(STAILQ_FIRST(&xfer->pipe->queue)));
-}
-
-static usbd_status
-ohci_device_bulk_start(usbd_xfer_handle xfer)
-{
- struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
- usbd_device_handle dev = opipe->pipe.device;
- ohci_softc_t *sc = (ohci_softc_t *)dev->bus;
- int addr = dev->address;
- ohci_soft_td_t *data, *tail, *tdp;
- ohci_soft_ed_t *sed;
- int s, len, isread, endpt;
- usbd_status err;
-
- if (sc->sc_dying)
- return (USBD_IOERROR);
-
-#ifdef DIAGNOSTIC
- if (xfer->rqflags & URQ_REQUEST) {
- /* XXX panic */
- printf("ohci_device_bulk_start: a request\n");
- return (USBD_INVAL);
- }
-#endif
-
- len = xfer->length;
- endpt = xfer->pipe->endpoint->edesc->bEndpointAddress;
- isread = UE_GET_DIR(endpt) == UE_DIR_IN;
- sed = opipe->sed;
-
- DPRINTFN(4,("ohci_device_bulk_start: xfer=%p len=%d isread=%d "
- "flags=%d endpt=%d\n", xfer, len, isread, xfer->flags,
- endpt));
-
- opipe->u.bulk.isread = isread;
- opipe->u.bulk.length = len;
-
- /* Update device address */
- 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);
- /* We want interrupt at the end of the transfer. */
- 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)
- return (err);
-
- tail->xfer = NULL;
- xfer->hcpriv = data;
-
- DPRINTFN(4,("ohci_device_bulk_start: ed_flags=0x%08x td_flags=0x%08x "
- "td_cbp=0x%08x td_be=0x%08x\n",
- (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 USB_DEBUG
- if (ohcidebug > 5) {
- ohci_dump_ed(sed);
- ohci_dump_tds(data);
- }
-#endif
-
- /* Insert ED in schedule */
- s = splusb();
- for (tdp = data; tdp != tail; tdp = tdp->nexttd) {
- tdp->xfer = xfer;
- }
- sed->ed.ed_tailp = htole32(tail->physaddr);
- opipe->tail.td = tail;
- sed->ed.ed_flags &= htole32(~OHCI_ED_SKIP);
- OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_BLF);
- if (xfer->timeout && !sc->sc_bus.use_polling) {
- callout_reset(&xfer->timeout_handle, MS_TO_TICKS(xfer->timeout),
- ohci_timeout, xfer);
- }
-
-#if 0
-/* This goes wrong if we are too slow. */
- if (ohcidebug > 10) {
- delay(10000);
- DPRINTF(("ohci_device_intr_transfer: status=%x\n",
- OREAD4(sc, OHCI_COMMAND_STATUS)));
- ohci_dump_ed(sed);
- ohci_dump_tds(data);
- }
-#endif
-
- splx(s);
-
- if (sc->sc_bus.use_polling)
- ohci_waitintr(sc, xfer);
-
- return (USBD_IN_PROGRESS);
-}
-
-static void
-ohci_device_bulk_abort(usbd_xfer_handle xfer)
-{
- DPRINTF(("ohci_device_bulk_abort: xfer=%p\n", xfer));
- ohci_abort_xfer(xfer, USBD_CANCELLED);
-}
-
-/*
- * Close a device bulk pipe.
- */
-static void
-ohci_device_bulk_close(usbd_pipe_handle pipe)
-{
- struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
- ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
-
- DPRINTF(("ohci_device_bulk_close: pipe=%p\n", pipe));
- ohci_close_pipe(pipe, sc->sc_bulk_head);
- ohci_free_std(sc, opipe->tail.td);
-}
-
-/************************/
-
-static usbd_status
-ohci_device_intr_transfer(usbd_xfer_handle xfer)
-{
- usbd_status err;
-
- /* Insert last in queue. */
- err = usb_insert_transfer(xfer);
- if (err)
- return (err);
-
- /* Pipe isn't running, start first */
- return (ohci_device_intr_start(STAILQ_FIRST(&xfer->pipe->queue)));
-}
-
-static usbd_status
-ohci_device_intr_start(usbd_xfer_handle xfer)
-{
- struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
- ohci_softc_t *sc = (ohci_softc_t *)opipe->pipe.device->bus;
- ohci_soft_ed_t *sed = opipe->sed;
- usbd_status err;
-
- if (sc->sc_dying)
- return (USBD_IOERROR);
-
- DPRINTFN(3, ("ohci_device_intr_start: xfer=%p len=%d "
- "flags=%d priv=%p\n",
- xfer, xfer->length, xfer->flags, xfer->priv));
-
-#ifdef DIAGNOSTIC
- if (xfer->rqflags & URQ_REQUEST)
- panic("ohci_device_intr_start: a request");
-#endif
-
- err = ohci_device_intr_insert(sc, xfer);
- if (err)
- return (err);
-
- sed->ed.ed_flags &= htole32(~OHCI_ED_SKIP);
-
- return (USBD_IN_PROGRESS);
-}
-
-/*
- * Insert an interrupt transfer into an endpoint descriptor list
- */
-static usbd_status
-ohci_device_intr_insert(ohci_softc_t *sc, usbd_xfer_handle xfer)
-{
- struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
- ohci_soft_ed_t *sed = opipe->sed;
- ohci_soft_td_t *data, *tail;
- ohci_physaddr_t dataphys, physend;
- int s;
-
- DPRINTFN(4, ("ohci_device_intr_insert: xfer=%p", xfer));
-
- data = opipe->tail.td;
- tail = ohci_alloc_std(sc);
- if (tail == NULL)
- return (USBD_NOMEM);
- tail->xfer = NULL;
-
- 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 |= htole32(OHCI_TD_R);
- /*
- * Assume a short mapping with no complications, which
- * should always be true for <= 4k buffers in contiguous
- * virtual memory. The data can take the following forms:
- * 1 segment in 1 OHCI page
- * 1 segment in 2 OHCI pages
- * 2 segments in 2 OHCI pages
- * (see comment in ohci_alloc_std_chain() for details)
- */
- KASSERT(xfer->length > 0 && xfer->length <= OHCI_PAGE_SIZE,
- ("ohci_device_intr_insert: bad length %d", xfer->length));
- dataphys = xfer->dmamap.segs[0].ds_addr;
- physend = dataphys + xfer->length - 1;
- if (xfer->dmamap.nsegs == 2) {
- KASSERT(OHCI_PAGE_OFFSET(dataphys +
- xfer->dmamap.segs[0].ds_len) == 0,
- ("ohci_device_intr_insert: bad seg 0 termination"));
- physend = xfer->dmamap.segs[1].ds_addr + xfer->length -
- xfer->dmamap.segs[0].ds_len - 1;
- } else {
- KASSERT(xfer->dmamap.nsegs == 1,
- ("ohci_device_intr_insert: bad seg count %d",
- (u_int)xfer->dmamap.nsegs));
- }
- data->td.td_cbp = htole32(dataphys);
- data->nexttd = tail;
- data->td.td_nexttd = htole32(tail->physaddr);
- data->td.td_be = htole32(physend);
- data->len = xfer->length;
- data->xfer = xfer;
- data->flags = OHCI_CALL_DONE | OHCI_ADD_LEN;
- xfer->hcpriv = data;
- xfer->actlen = 0;
-
-#ifdef USB_DEBUG
- if (ohcidebug > 5) {
- DPRINTF(("ohci_device_intr_insert:\n"));
- ohci_dump_ed(sed);
- ohci_dump_tds(data);
- }
-#endif
-
- /* Insert ED in schedule */
- s = splusb();
- sed->ed.ed_tailp = htole32(tail->physaddr);
- opipe->tail.td = tail;
- splx(s);
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-/* Abort a device control request. */
-static void
-ohci_device_intr_abort(usbd_xfer_handle xfer)
-{
- if (xfer->pipe->intrxfer == xfer) {
- DPRINTF(("ohci_device_intr_abort: remove\n"));
- xfer->pipe->intrxfer = NULL;
- }
- ohci_abort_xfer(xfer, USBD_CANCELLED);
-}
-
-/* Close a device interrupt pipe. */
-static void
-ohci_device_intr_close(usbd_pipe_handle pipe)
-{
- struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
- ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
- int nslots = opipe->u.intr.nslots;
- int pos = opipe->u.intr.pos;
- int j;
- ohci_soft_ed_t *p, *sed = opipe->sed;
- int s;
-
- DPRINTFN(1,("ohci_device_intr_close: pipe=%p nslots=%d pos=%d\n",
- pipe, nslots, pos));
- s = splusb();
- 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);
-#ifdef DIAGNOSTIC
- if ((le32toh(sed->ed.ed_tailp) & OHCI_HEADMASK) !=
- (le32toh(sed->ed.ed_headp) & OHCI_HEADMASK))
- panic("%s: Intr pipe %p still has TDs queued",
- device_get_nameunit(sc->sc_bus.bdev), pipe);
-#endif
-
- for (p = sc->sc_eds[pos]; p && p->next != sed; p = p->next)
- ;
-#ifdef DIAGNOSTIC
- if (p == NULL)
- panic("ohci_device_intr_close: ED not found");
-#endif
- p->next = sed->next;
- p->ed.ed_nexted = sed->ed.ed_nexted;
- splx(s);
-
- for (j = 0; j < nslots; j++)
- --sc->sc_bws[(pos * nslots + j) % OHCI_NO_INTRS];
-
- ohci_free_std(sc, opipe->tail.td);
- ohci_free_sed(sc, opipe->sed);
-}
-
-static usbd_status
-ohci_device_setintr(ohci_softc_t *sc, struct ohci_pipe *opipe, int ival)
-{
- int i, j, s, best;
- u_int npoll, slow, shigh, nslots;
- u_int bestbw, bw;
- ohci_soft_ed_t *hsed, *sed = opipe->sed;
-
- DPRINTFN(2, ("ohci_setintr: pipe=%p\n", opipe));
- if (ival == 0) {
- printf("ohci_setintr: 0 interval\n");
- return (USBD_INVAL);
- }
-
- npoll = OHCI_NO_INTRS;
- while (npoll > ival)
- npoll /= 2;
- DPRINTFN(2, ("ohci_setintr: ival=%d npoll=%d\n", ival, npoll));
-
- /*
- * We now know which level in the tree the ED must go into.
- * Figure out which slot has most bandwidth left over.
- * Slots to examine:
- * npoll
- * 1 0
- * 2 1 2
- * 4 3 4 5 6
- * 8 7 8 9 10 11 12 13 14
- * N (N-1) .. (N-1+N-1)
- */
- slow = npoll-1;
- shigh = slow + npoll;
- nslots = OHCI_NO_INTRS / npoll;
- for (best = i = slow, bestbw = ~0; i < shigh; i++) {
- bw = 0;
- for (j = 0; j < nslots; j++)
- bw += sc->sc_bws[(i * nslots + j) % OHCI_NO_INTRS];
- if (bw < bestbw) {
- best = i;
- bestbw = bw;
- }
- }
- DPRINTFN(2, ("ohci_setintr: best=%d(%d..%d) bestbw=%d\n",
- best, slow, shigh, bestbw));
-
- s = splusb();
- hsed = sc->sc_eds[best];
- sed->next = hsed->next;
- sed->ed.ed_nexted = hsed->ed.ed_nexted;
- hsed->next = sed;
- hsed->ed.ed_nexted = htole32(sed->physaddr);
- splx(s);
-
- for (j = 0; j < nslots; j++)
- ++sc->sc_bws[(best * nslots + j) % OHCI_NO_INTRS];
- opipe->u.intr.nslots = nslots;
- opipe->u.intr.pos = best;
-
- DPRINTFN(5, ("ohci_setintr: returns %p\n", opipe));
- return (USBD_NORMAL_COMPLETION);
-}
-
-/***********************/
-
-usbd_status
-ohci_device_isoc_transfer(usbd_xfer_handle xfer)
-{
- usbd_status err;
-
- DPRINTFN(5,("ohci_device_isoc_transfer: xfer=%p\n", xfer));
-
- /* Put it on our queue, */
- err = usb_insert_transfer(xfer);
-
- /* bail out on error, */
- if (err && err != USBD_IN_PROGRESS)
- return (err);
-
- /* XXX should check inuse here */
-
- /* insert into schedule, */
- ohci_device_isoc_enter(xfer);
-
- /* and start if the pipe wasn't running */
- if (!err)
- ohci_device_isoc_start(STAILQ_FIRST(&xfer->pipe->queue));
-
- return (err);
-}
-
-void
-ohci_device_isoc_enter(usbd_xfer_handle xfer)
-{
- struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
- usbd_device_handle dev = opipe->pipe.device;
- ohci_softc_t *sc = (ohci_softc_t *)dev->bus;
- ohci_soft_ed_t *sed = opipe->sed;
- struct iso *iso = &opipe->u.iso;
- struct usb_dma_mapping *dma = &xfer->dmamap;
- ohci_soft_itd_t *sitd, *nsitd;
- ohci_physaddr_t dataphys, bp0, physend, prevpage;
- int curlen, i, len, ncur, nframes, npages, seg, segoff;
- int s;
-
- DPRINTFN(1,("ohci_device_isoc_enter: used=%d next=%d xfer=%p "
- "nframes=%d\n",
- iso->inuse, iso->next, xfer, xfer->nframes));
-
- if (sc->sc_dying)
- return;
-
- if (iso->next == -1) {
- /* Not in use yet, schedule it a few frames ahead. */
- iso->next = le32toh(sc->sc_hcca->hcca_frame_number) + 5;
- DPRINTFN(2,("ohci_device_isoc_enter: start next=%d\n",
- iso->next));
- }
-
- sitd = opipe->tail.itd;
- nframes = xfer->nframes;
- xfer->hcpriv = sitd;
- seg = 0;
- segoff = 0;
- i = 0;
- while (i < nframes) {
- /*
- * Fill in as many ITD frames as possible.
- */
- KASSERT(seg < dma->nsegs, ("ohci_device_isoc_enter: overrun"));
- bp0 = dma->segs[seg].ds_addr + segoff;
- sitd->itd.itd_bp0 = htole32(bp0);
- prevpage = OHCI_PAGE(bp0);
- npages = 1;
-
- ncur = 0;
- while (ncur < OHCI_ITD_NOFFSET && i < nframes) {
- /* Find the frame start and end physical addresses. */
- len = xfer->frlengths[i];
- dataphys = dma->segs[seg].ds_addr + segoff;
- curlen = dma->segs[seg].ds_len - segoff;
- if (len > curlen) {
- KASSERT(seg + 1 < dma->nsegs,
- ("ohci_device_isoc_enter: overrun2"));
- seg++;
- segoff = len - curlen;
- } else {
- segoff += len;
- }
- KASSERT(segoff <= dma->segs[seg].ds_len,
- ("ohci_device_isoc_enter: overrun3"));
- physend = dma->segs[seg].ds_addr + segoff - 1;
-
- /* Check if there would be more than 2 pages . */
- if (OHCI_PAGE(dataphys) != prevpage) {
- prevpage = OHCI_PAGE(dataphys);
- npages++;
- }
- if (OHCI_PAGE(physend) != prevpage) {
- prevpage = OHCI_PAGE(physend);
- npages++;
- }
- if (npages > 2) {
- /* We cannot fit this frame now. */
- segoff -= len;
- if (segoff < 0) {
- seg--;
- segoff += dma->segs[seg].ds_len;
- }
- break;
- }
-
- sitd->itd.itd_be = htole32(physend);
- sitd->itd.itd_offset[ncur] =
- htole16(OHCI_ITD_MK_OFFS(OHCI_PAGE(dataphys) ==
- OHCI_PAGE(bp0) ? 0 : 1, dataphys));
- i++;
- ncur++;
- }
- if (segoff >= dma->segs[seg].ds_len) {
- KASSERT(segoff == dma->segs[seg].ds_len,
- ("ohci_device_isoc_enter: overlap"));
- seg++;
- segoff = 0;
- }
-
- /* Allocate next ITD */
- nsitd = ohci_alloc_sitd(sc);
- if (nsitd == NULL) {
- /* XXX what now? */
- printf("%s: isoc TD alloc failed\n",
- device_get_nameunit(sc->sc_bus.bdev));
- return;
- }
-
- /* Fill out remaining fields of current ITD */
- sitd->nextitd = nsitd;
- sitd->itd.itd_nextitd = htole32(nsitd->physaddr);
- sitd->xfer = xfer;
- if (i < nframes) {
- sitd->itd.itd_flags = htole32(
- OHCI_ITD_NOCC |
- OHCI_ITD_SET_SF(iso->next) |
- OHCI_ITD_SET_DI(6) | /* delay intr a little */
- OHCI_ITD_SET_FC(ncur));
- sitd->flags = OHCI_ITD_ACTIVE;
- } else {
- sitd->itd.itd_flags = htole32(
- OHCI_ITD_NOCC |
- OHCI_ITD_SET_SF(iso->next) |
- OHCI_ITD_SET_DI(0) |
- OHCI_ITD_SET_FC(ncur));
- sitd->flags = OHCI_CALL_DONE | OHCI_ITD_ACTIVE;
- }
- iso->next += ncur;
-
- sitd = nsitd;
- }
-
- iso->inuse += nframes;
-
- /* XXX pretend we did it all */
- xfer->actlen = 0;
- for (i = 0; i < nframes; i++)
- xfer->actlen += xfer->frlengths[i];
-
- xfer->status = USBD_IN_PROGRESS;
-
-#ifdef USB_DEBUG
- if (ohcidebug > 5) {
- DPRINTF(("ohci_device_isoc_enter: frame=%d\n",
- le32toh(sc->sc_hcca->hcca_frame_number)));
- ohci_dump_itds(xfer->hcpriv);
- ohci_dump_ed(sed);
- }
-#endif
-
- s = splusb();
- opipe->tail.itd = sitd;
- sed->ed.ed_flags &= htole32(~OHCI_ED_SKIP);
- sed->ed.ed_tailp = htole32(sitd->physaddr);
- splx(s);
-
-#ifdef USB_DEBUG
- if (ohcidebug > 5) {
- delay(150000);
- DPRINTF(("ohci_device_isoc_enter: after frame=%d\n",
- le32toh(sc->sc_hcca->hcca_frame_number)));
- ohci_dump_itds(xfer->hcpriv);
- ohci_dump_ed(sed);
- }
-#endif
-}
-
-usbd_status
-ohci_device_isoc_start(usbd_xfer_handle xfer)
-{
- struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
- ohci_softc_t *sc = (ohci_softc_t *)opipe->pipe.device->bus;
- ohci_soft_ed_t *sed;
- int s;
-
- DPRINTFN(5,("ohci_device_isoc_start: xfer=%p\n", xfer));
-
- if (sc->sc_dying)
- return (USBD_IOERROR);
-
-#ifdef DIAGNOSTIC
- if (xfer->status != USBD_IN_PROGRESS)
- printf("ohci_device_isoc_start: not in progress %p\n", xfer);
-#endif
-
- /* XXX anything to do? */
-
- s = splusb();
- sed = opipe->sed; /* Turn off ED skip-bit to start processing */
- sed->ed.ed_flags &= htole32(~OHCI_ED_SKIP); /* ED's ITD list.*/
- splx(s);
-
- return (USBD_IN_PROGRESS);
-}
-
-void
-ohci_device_isoc_abort(usbd_xfer_handle xfer)
-{
- struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
- ohci_softc_t *sc = (ohci_softc_t *)opipe->pipe.device->bus;
- ohci_soft_ed_t *sed;
- ohci_soft_itd_t *sitd, *sitdnext, *tmp_sitd;
- int s,undone,num_sitds;
-
- s = splusb();
- opipe->aborting = 1;
-
- DPRINTFN(1,("ohci_device_isoc_abort: xfer=%p\n", xfer));
-
- /* Transfer is already done. */
- if (xfer->status != USBD_NOT_STARTED &&
- xfer->status != USBD_IN_PROGRESS) {
- splx(s);
- printf("ohci_device_isoc_abort: early return\n");
- return;
- }
-
- /* Give xfer the requested abort code. */
- xfer->status = USBD_CANCELLED;
-
- sed = opipe->sed;
- sed->ed.ed_flags |= htole32(OHCI_ED_SKIP); /* force hardware skip */
-
- num_sitds = 0;
- sitd = xfer->hcpriv;
-#ifdef DIAGNOSTIC
- if (sitd == NULL) {
- splx(s);
- printf("ohci_device_isoc_abort: hcpriv==0\n");
- return;
- }
-#endif
- for (; sitd != NULL && sitd->xfer == xfer; sitd = sitd->nextitd) {
- num_sitds++;
-#ifdef DIAGNOSTIC
- DPRINTFN(1,("abort sets done sitd=%p\n", sitd));
- sitd->isdone = 1;
-#endif
- }
-
- splx(s);
-
- /*
- * Each sitd has up to OHCI_ITD_NOFFSET transfers, each can
- * take a usb 1ms cycle. Conservatively wait for it to drain.
- * Even with DMA done, it can take awhile for the "batch"
- * delivery of completion interrupts to occur thru the controller.
- */
-
- do {
- usb_delay_ms(&sc->sc_bus, 2*(num_sitds*OHCI_ITD_NOFFSET));
-
- undone = 0;
- tmp_sitd = xfer->hcpriv;
- for (; tmp_sitd != NULL && tmp_sitd->xfer == xfer;
- tmp_sitd = tmp_sitd->nextitd) {
- if (OHCI_CC_NO_ERROR ==
- OHCI_ITD_GET_CC(le32toh(tmp_sitd->itd.itd_flags)) &&
- tmp_sitd->flags & OHCI_ITD_ACTIVE &&
- (tmp_sitd->flags & OHCI_ITD_INTFIN) == 0)
- undone++;
- }
- } while( undone != 0 );
-
- /* Free the sitds */
- for (sitd = xfer->hcpriv; sitd->xfer == xfer;
- sitd = sitdnext) {
- sitdnext = sitd->nextitd;
- ohci_free_sitd(sc, sitd);
- }
-
- s = splusb();
-
- /* Run callback. */
- usb_transfer_complete(xfer);
-
- /* There is always a `next' sitd so link it up. */
- sed->ed.ed_headp = htole32(sitd->physaddr);
-
- sed->ed.ed_flags &= htole32(~OHCI_ED_SKIP); /* remove hardware skip */
-
- splx(s);
-}
-
-void
-ohci_device_isoc_done(usbd_xfer_handle xfer)
-{
- /* This null routine corresponds to non-isoc "done()" routines
- * that free the stds associated with an xfer after a completed
- * xfer interrupt. However, in the case of isoc transfers, the
- * sitds associated with the transfer have already been processed
- * and reallocated for the next iteration by
- * "ohci_device_isoc_transfer()".
- *
- * Routine "usb_transfer_complete()" is called at the end of every
- * relevant usb interrupt. "usb_transfer_complete()" indirectly
- * calls 1) "ohci_device_isoc_transfer()" (which keeps pumping the
- * pipeline by setting up the next transfer iteration) and 2) then
- * calls "ohci_device_isoc_done()". Isoc transfers have not been
- * working for the ohci usb because this routine was trashing the
- * xfer set up for the next iteration (thus, only the first
- * UGEN_NISOREQS xfers outstanding on an open would work). Perhaps
- * this could all be re-factored, but that's another pass...
- */
-}
-
-usbd_status
-ohci_setup_isoc(usbd_pipe_handle pipe)
-{
- struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
- ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
- struct iso *iso = &opipe->u.iso;
- int s;
-
- iso->next = -1;
- iso->inuse = 0;
-
- s = splusb();
- ohci_add_ed(opipe->sed, sc->sc_isoc_head);
- splx(s);
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-void
-ohci_device_isoc_close(usbd_pipe_handle pipe)
-{
- struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
- ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
- ohci_soft_ed_t *sed;
-
- DPRINTF(("ohci_device_isoc_close: pipe=%p\n", pipe));
-
- sed = opipe->sed;
- sed->ed.ed_flags |= htole32(OHCI_ED_SKIP); /* Stop device. */
-
- ohci_close_pipe(pipe, sc->sc_isoc_head); /* Stop isoc list, free ED.*/
-
- /* up to NISOREQs xfers still outstanding. */
-
-#ifdef DIAGNOSTIC
- opipe->tail.itd->isdone = 1;
-#endif
- ohci_free_sitd(sc, opipe->tail.itd); /* Next `avail free' sitd.*/
-}
diff --git a/sys/dev/usb/ohci_pci.c b/sys/dev/usb/ohci_pci.c
deleted file mode 100644
index fadffb6..0000000
--- a/sys/dev/usb/ohci_pci.c
+++ /dev/null
@@ -1,411 +0,0 @@
-/*-
- * 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * USB Open Host Controller driver.
- *
- * OHCI spec: http://www.intel.com/design/usb/ohci11d.pdf
- */
-
-/* The low level controller code for OHCI has been split into
- * PCI probes and OHCI specific code. This was done to facilitate the
- * sharing of code between *BSD's
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/bus.h>
-#include <sys/queue.h>
-#include <machine/bus.h>
-#include <sys/rman.h>
-#include <machine/resource.h>
-
-#include <dev/pci/pcivar.h>
-#include <dev/pci/pcireg.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdivar.h>
-#include <dev/usb/usb_mem.h>
-
-#include <dev/usb/ohcireg.h>
-#include <dev/usb/ohcivar.h>
-
-#define PCI_OHCI_VENDORID_ACERLABS 0x10b9
-#define PCI_OHCI_VENDORID_AMD 0x1022
-#define PCI_OHCI_VENDORID_APPLE 0x106b
-#define PCI_OHCI_VENDORID_ATI 0x1002
-#define PCI_OHCI_VENDORID_CMDTECH 0x1095
-#define PCI_OHCI_VENDORID_NEC 0x1033
-#define PCI_OHCI_VENDORID_NVIDIA 0x12D2
-#define PCI_OHCI_VENDORID_NVIDIA2 0x10DE
-#define PCI_OHCI_VENDORID_OPTI 0x1045
-#define PCI_OHCI_VENDORID_SIS 0x1039
-#define PCI_OHCI_VENDORID_SUN 0x108e
-
-#define PCI_OHCI_DEVICEID_ALADDIN_V 0x523710b9
-static const char *ohci_device_aladdin_v = "AcerLabs M5237 (Aladdin-V) USB controller";
-
-#define PCI_OHCI_DEVICEID_AMD756 0x740c1022
-static const char *ohci_device_amd756 = "AMD-756 USB Controller";
-
-#define PCI_OHCI_DEVICEID_AMD766 0x74141022
-static const char *ohci_device_amd766 = "AMD-766 USB Controller";
-
-#define PCI_OHCI_DEVICEID_SB400_1 0x43741002
-#define PCI_OHCI_DEVICEID_SB400_2 0x43751002
-static const char *ohci_device_sb400 = "ATI SB400 USB Controller";
-
-#define PCI_OHCI_DEVICEID_FIRELINK 0xc8611045
-static const char *ohci_device_firelink = "OPTi 82C861 (FireLink) USB controller";
-
-#define PCI_OHCI_DEVICEID_NEC 0x00351033
-static const char *ohci_device_nec = "NEC uPD 9210 USB controller";
-
-#define PCI_OHCI_DEVICEID_NFORCE3 0x00d710de
-static const char *ohci_device_nforce3 = "nVidia nForce3 USB Controller";
-
-#define PCI_OHCI_DEVICEID_USB0670 0x06701095
-static const char *ohci_device_usb0670 = "CMD Tech 670 (USB0670) USB controller";
-
-#define PCI_OHCI_DEVICEID_USB0673 0x06731095
-static const char *ohci_device_usb0673 = "CMD Tech 673 (USB0673) USB controller";
-
-#define PCI_OHCI_DEVICEID_SIS5571 0x70011039
-static const char *ohci_device_sis5571 = "SiS 5571 USB controller";
-
-#define PCI_OHCI_DEVICEID_KEYLARGO 0x0019106b
-static const char *ohci_device_keylargo = "Apple KeyLargo USB controller";
-
-#define PCI_OHCI_DEVICEID_PCIO2USB 0x1103108e
-static const char *ohci_device_pcio2usb = "Sun PCIO-2 USB controller";
-
-static const char *ohci_device_generic = "OHCI (generic) USB controller";
-
-#define PCI_OHCI_BASE_REG 0x10
-
-
-static device_attach_t ohci_pci_attach;
-static device_detach_t ohci_pci_detach;
-static device_suspend_t ohci_pci_suspend;
-static device_resume_t ohci_pci_resume;
-
-static int
-ohci_pci_suspend(device_t self)
-{
- ohci_softc_t *sc = device_get_softc(self);
- int err;
-
- err = bus_generic_suspend(self);
- if (err)
- return err;
- ohci_power(PWR_SUSPEND, sc);
-
- return 0;
-}
-
-static int
-ohci_pci_resume(device_t self)
-{
- ohci_softc_t *sc = device_get_softc(self);
-
- ohci_power(PWR_RESUME, sc);
- bus_generic_resume(self);
-
- return 0;
-}
-
-static const char *
-ohci_pci_match(device_t self)
-{
- u_int32_t device_id = pci_get_devid(self);
-
- switch (device_id) {
- case PCI_OHCI_DEVICEID_ALADDIN_V:
- return (ohci_device_aladdin_v);
- case PCI_OHCI_DEVICEID_AMD756:
- return (ohci_device_amd756);
- case PCI_OHCI_DEVICEID_AMD766:
- return (ohci_device_amd766);
- case PCI_OHCI_DEVICEID_SB400_1:
- case PCI_OHCI_DEVICEID_SB400_2:
- return (ohci_device_sb400);
- case PCI_OHCI_DEVICEID_USB0670:
- return (ohci_device_usb0670);
- case PCI_OHCI_DEVICEID_USB0673:
- return (ohci_device_usb0673);
- case PCI_OHCI_DEVICEID_FIRELINK:
- return (ohci_device_firelink);
- case PCI_OHCI_DEVICEID_NEC:
- return (ohci_device_nec);
- case PCI_OHCI_DEVICEID_NFORCE3:
- return (ohci_device_nforce3);
- case PCI_OHCI_DEVICEID_SIS5571:
- return (ohci_device_sis5571);
- case PCI_OHCI_DEVICEID_KEYLARGO:
- return (ohci_device_keylargo);
- case PCI_OHCI_DEVICEID_PCIO2USB:
- return (ohci_device_pcio2usb);
- default:
- if (pci_get_class(self) == PCIC_SERIALBUS
- && pci_get_subclass(self) == PCIS_SERIALBUS_USB
- && pci_get_progif(self) == PCI_INTERFACE_OHCI) {
- return (ohci_device_generic);
- }
- }
-
- return NULL; /* dunno */
-}
-
-static int
-ohci_pci_probe(device_t self)
-{
- const char *desc = ohci_pci_match(self);
-
- if (desc) {
- device_set_desc(self, desc);
- return BUS_PROBE_DEFAULT;
- } else {
- return ENXIO;
- }
-}
-
-static int
-ohci_pci_attach(device_t self)
-{
- ohci_softc_t *sc = device_get_softc(self);
- int err;
- int rid;
-
- /* XXX where does it say so in the spec? */
- sc->sc_bus.usbrev = USBREV_1_0;
-
- pci_enable_busmaster(self);
-
- /*
- * Some Sun PCIO-2 USB controllers have their intpin register
- * bogusly set to 0, although it should be 4. Correct that.
- */
- if (pci_get_devid(self) == PCI_OHCI_DEVICEID_PCIO2USB &&
- pci_get_intpin(self) == 0)
- pci_set_intpin(self, 4);
-
- rid = PCI_CBMEM;
- sc->io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid,
- RF_ACTIVE);
- if (!sc->io_res) {
- device_printf(self, "Could not map memory\n");
- return ENXIO;
- }
- sc->iot = rman_get_bustag(sc->io_res);
- sc->ioh = rman_get_bushandle(sc->io_res);
-
- rid = 0;
- sc->irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid,
- RF_SHAREABLE | RF_ACTIVE);
- if (sc->irq_res == NULL) {
- device_printf(self, "Could not allocate irq\n");
- ohci_pci_detach(self);
- return ENXIO;
- }
- sc->sc_bus.bdev = device_add_child(self, "usb", -1);
- if (!sc->sc_bus.bdev) {
- device_printf(self, "Could not add USB device\n");
- ohci_pci_detach(self);
- return ENOMEM;
- }
- device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
-
- /* ohci_pci_match will never return NULL if ohci_pci_probe succeeded */
- device_set_desc(sc->sc_bus.bdev, ohci_pci_match(self));
- switch (pci_get_vendor(self)) {
- case PCI_OHCI_VENDORID_ACERLABS:
- sprintf(sc->sc_vendor, "AcerLabs");
- break;
- case PCI_OHCI_VENDORID_AMD:
- sprintf(sc->sc_vendor, "AMD");
- break;
- case PCI_OHCI_VENDORID_APPLE:
- sprintf(sc->sc_vendor, "Apple");
- break;
- case PCI_OHCI_VENDORID_ATI:
- sprintf(sc->sc_vendor, "ATI");
- break;
- case PCI_OHCI_VENDORID_CMDTECH:
- sprintf(sc->sc_vendor, "CMDTECH");
- break;
- case PCI_OHCI_VENDORID_NEC:
- sprintf(sc->sc_vendor, "NEC");
- break;
- case PCI_OHCI_VENDORID_NVIDIA:
- case PCI_OHCI_VENDORID_NVIDIA2:
- sprintf(sc->sc_vendor, "nVidia");
- break;
- case PCI_OHCI_VENDORID_OPTI:
- sprintf(sc->sc_vendor, "OPTi");
- break;
- case PCI_OHCI_VENDORID_SIS:
- sprintf(sc->sc_vendor, "SiS");
- break;
- default:
- if (bootverbose)
- device_printf(self, "(New OHCI DeviceId=0x%08x)\n",
- pci_get_devid(self));
- sprintf(sc->sc_vendor, "(0x%04x)", pci_get_vendor(self));
- }
-
- err = bus_setup_intr(self, sc->irq_res, INTR_TYPE_BIO, NULL, ohci_intr,
- sc, &sc->ih);
- if (err) {
- device_printf(self, "Could not setup irq, %d\n", err);
- sc->ih = NULL;
- ohci_pci_detach(self);
- return ENXIO;
- }
-
- /* Allocate a parent dma tag for DMA maps */
- err = bus_dma_tag_create(bus_get_dma_tag(self), 1, 0,
- BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
- BUS_SPACE_MAXSIZE_32BIT, USB_DMA_NSEG, BUS_SPACE_MAXSIZE_32BIT, 0,
- NULL, NULL, &sc->sc_bus.parent_dmatag);
- if (err) {
- device_printf(self, "Could not allocate parent DMA tag (%d)\n",
- err);
- ohci_pci_detach(self);
- return ENXIO;
- }
- /* Allocate a dma tag for transfer buffers */
- err = bus_dma_tag_create(sc->sc_bus.parent_dmatag, 1, 0,
- BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
- BUS_SPACE_MAXSIZE_32BIT, USB_DMA_NSEG, BUS_SPACE_MAXSIZE_32BIT, 0,
- busdma_lock_mutex, &Giant, &sc->sc_bus.buffer_dmatag);
- if (err) {
- device_printf(self, "Could not allocate transfer tag (%d)\n",
- err);
- ohci_pci_detach(self);
- return ENXIO;
- }
-
- err = ohci_init(sc);
- if (!err) {
- sc->sc_flags |= OHCI_SCFLG_DONEINIT;
- err = device_probe_and_attach(sc->sc_bus.bdev);
- }
-
- if (err) {
- device_printf(self, "USB init failed\n");
- ohci_pci_detach(self);
- return EIO;
- }
- return 0;
-}
-
-static int
-ohci_pci_detach(device_t self)
-{
- ohci_softc_t *sc = device_get_softc(self);
-
- if (sc->sc_flags & OHCI_SCFLG_DONEINIT) {
- ohci_detach(sc, 0);
- sc->sc_flags &= ~OHCI_SCFLG_DONEINIT;
- }
-
- if (sc->sc_bus.parent_dmatag != NULL)
- bus_dma_tag_destroy(sc->sc_bus.parent_dmatag);
- if (sc->sc_bus.buffer_dmatag != NULL)
- bus_dma_tag_destroy(sc->sc_bus.buffer_dmatag);
-
- if (sc->irq_res && sc->ih) {
- int err = bus_teardown_intr(self, sc->irq_res, sc->ih);
-
- if (err)
- /* XXX or should we panic? */
- device_printf(self, "Could not tear down irq, %d\n",
- err);
- sc->ih = NULL;
- }
- if (sc->sc_bus.bdev) {
- device_delete_child(self, sc->sc_bus.bdev);
- sc->sc_bus.bdev = NULL;
- }
- if (sc->irq_res) {
- bus_release_resource(self, SYS_RES_IRQ, 0, sc->irq_res);
- sc->irq_res = NULL;
- }
- if (sc->io_res) {
- bus_release_resource(self, SYS_RES_MEMORY, PCI_CBMEM,
- sc->io_res);
- sc->io_res = NULL;
- sc->iot = 0;
- sc->ioh = 0;
- }
- return 0;
-}
-
-static device_method_t ohci_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, ohci_pci_probe),
- DEVMETHOD(device_attach, ohci_pci_attach),
- DEVMETHOD(device_detach, ohci_pci_detach),
- DEVMETHOD(device_suspend, ohci_pci_suspend),
- DEVMETHOD(device_resume, ohci_pci_resume),
- DEVMETHOD(device_shutdown, bus_generic_shutdown),
-
- /* Bus interface */
- DEVMETHOD(bus_print_child, bus_generic_print_child),
-
- {0, 0}
-};
-
-static driver_t ohci_driver = {
- "ohci",
- ohci_methods,
- sizeof(ohci_softc_t),
-};
-
-static devclass_t ohci_devclass;
-
-DRIVER_MODULE(ohci, pci, ohci_driver, ohci_devclass, 0, 0);
-DRIVER_MODULE(ohci, cardbus, ohci_driver, ohci_devclass, 0, 0);
-MODULE_DEPEND(ohci, usb, 1, 1, 1);
diff --git a/sys/dev/usb/ohcireg.h b/sys/dev/usb/ohcireg.h
deleted file mode 100644
index 429beb8..0000000
--- a/sys/dev/usb/ohcireg.h
+++ /dev/null
@@ -1,250 +0,0 @@
-/* $NetBSD: ohcireg.h,v 1.17 2000/04/01 09:27:35 augustss Exp $ */
-/* $FreeBSD$ */
-
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) 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.
- */
-
-#ifndef _DEV_PCI_OHCIREG_H_
-#define _DEV_PCI_OHCIREG_H_
-
-/*** PCI config registers ***/
-
-#define PCI_CBMEM 0x10 /* configuration base memory */
-
-#define PCI_INTERFACE_OHCI 0x10
-
-/*** OHCI registers */
-
-#define OHCI_REVISION 0x00 /* OHCI revision # */
-#define OHCI_REV_LO(rev) ((rev)&0xf)
-#define OHCI_REV_HI(rev) (((rev)>>4)&0xf)
-#define OHCI_REV_LEGACY(rev) ((rev) & 0x100)
-
-#define OHCI_CONTROL 0x04
-#define OHCI_CBSR_MASK 0x00000003 /* Control/Bulk Service Ratio */
-#define OHCI_RATIO_1_1 0x00000000
-#define OHCI_RATIO_1_2 0x00000001
-#define OHCI_RATIO_1_3 0x00000002
-#define OHCI_RATIO_1_4 0x00000003
-#define OHCI_PLE 0x00000004 /* Periodic List Enable */
-#define OHCI_IE 0x00000008 /* Isochronous Enable */
-#define OHCI_CLE 0x00000010 /* Control List Enable */
-#define OHCI_BLE 0x00000020 /* Bulk List Enable */
-#define OHCI_HCFS_MASK 0x000000c0 /* HostControllerFunctionalState */
-#define OHCI_HCFS_RESET 0x00000000
-#define OHCI_HCFS_RESUME 0x00000040
-#define OHCI_HCFS_OPERATIONAL 0x00000080
-#define OHCI_HCFS_SUSPEND 0x000000c0
-#define OHCI_IR 0x00000100 /* Interrupt Routing */
-#define OHCI_RWC 0x00000200 /* Remote Wakeup Connected */
-#define OHCI_RWE 0x00000400 /* Remote Wakeup Enabled */
-#define OHCI_COMMAND_STATUS 0x08
-#define OHCI_HCR 0x00000001 /* Host Controller Reset */
-#define OHCI_CLF 0x00000002 /* Control List Filled */
-#define OHCI_BLF 0x00000004 /* Bulk List Filled */
-#define OHCI_OCR 0x00000008 /* Ownership Change Request */
-#define OHCI_SOC_MASK 0x00030000 /* Scheduling Overrun Count */
-#define OHCI_INTERRUPT_STATUS 0x0c
-#define OHCI_SO 0x00000001 /* Scheduling Overrun */
-#define OHCI_WDH 0x00000002 /* Writeback Done Head */
-#define OHCI_SF 0x00000004 /* Start of Frame */
-#define OHCI_RD 0x00000008 /* Resume Detected */
-#define OHCI_UE 0x00000010 /* Unrecoverable Error */
-#define OHCI_FNO 0x00000020 /* Frame Number Overflow */
-#define OHCI_RHSC 0x00000040 /* Root Hub Status Change */
-#define OHCI_OC 0x40000000 /* Ownership Change */
-#define OHCI_MIE 0x80000000 /* Master Interrupt Enable */
-#define OHCI_INTERRUPT_ENABLE 0x10
-#define OHCI_INTERRUPT_DISABLE 0x14
-#define OHCI_HCCA 0x18
-#define OHCI_PERIOD_CURRENT_ED 0x1c
-#define OHCI_CONTROL_HEAD_ED 0x20
-#define OHCI_CONTROL_CURRENT_ED 0x24
-#define OHCI_BULK_HEAD_ED 0x28
-#define OHCI_BULK_CURRENT_ED 0x2c
-#define OHCI_DONE_HEAD 0x30
-#define OHCI_FM_INTERVAL 0x34
-#define OHCI_GET_IVAL(s) ((s) & 0x3fff)
-#define OHCI_GET_FSMPS(s) (((s) >> 16) & 0x7fff)
-#define OHCI_FIT 0x80000000
-#define OHCI_FM_REMAINING 0x38
-#define OHCI_FM_NUMBER 0x3c
-#define OHCI_PERIODIC_START 0x40
-#define OHCI_LS_THRESHOLD 0x44
-#define OHCI_RH_DESCRIPTOR_A 0x48
-#define OHCI_GET_NDP(s) ((s) & 0xff)
-#define OHCI_PSM 0x0100 /* Power Switching Mode */
-#define OHCI_NPS 0x0200 /* No Power Switching */
-#define OHCI_DT 0x0400 /* Device Type */
-#define OHCI_OCPM 0x0800 /* Overcurrent Protection Mode */
-#define OHCI_NOCP 0x1000 /* No Overcurrent Protection */
-#define OHCI_GET_POTPGT(s) ((s) >> 24)
-#define OHCI_RH_DESCRIPTOR_B 0x4c
-#define OHCI_RH_STATUS 0x50
-#define OHCI_LPS 0x00000001 /* Local Power Status */
-#define OHCI_OCI 0x00000002 /* OverCurrent Indicator */
-#define OHCI_DRWE 0x00008000 /* Device Remote Wakeup Enable */
-#define OHCI_LPSC 0x00010000 /* Local Power Status Change */
-#define OHCI_CCIC 0x00020000 /* OverCurrent Indicator Change */
-#define OHCI_CRWE 0x80000000 /* Clear Remote Wakeup Enable */
-#define OHCI_RH_PORT_STATUS(n) (0x50 + (n)*4) /* 1 based indexing */
-
-#define OHCI_LES (OHCI_PLE | OHCI_IE | OHCI_CLE | OHCI_BLE)
-#define OHCI_ALL_INTRS (OHCI_SO | OHCI_WDH | OHCI_SF | OHCI_RD | OHCI_UE | \
- OHCI_FNO | OHCI_RHSC | OHCI_OC)
-#define OHCI_NORMAL_INTRS (OHCI_WDH | OHCI_RD | OHCI_UE | OHCI_RHSC)
-
-#define OHCI_FSMPS(i) (((i-210)*6/7) << 16)
-#define OHCI_PERIODIC(i) ((i)*9/10)
-
-typedef u_int32_t ohci_physaddr_t;
-
-#define OHCI_NO_INTRS 32
-struct ohci_hcca {
- ohci_physaddr_t hcca_interrupt_table[OHCI_NO_INTRS];
- u_int32_t hcca_frame_number;
- ohci_physaddr_t hcca_done_head;
-#define OHCI_DONE_INTRS 1
-};
-#define OHCI_HCCA_SIZE 256
-#define OHCI_HCCA_ALIGN 256
-
-#define OHCI_PAGE_SIZE 0x1000
-#define OHCI_PAGE(x) ((x) &~ 0xfff)
-#define OHCI_PAGE_OFFSET(x) ((x) & 0xfff)
-#define OHCI_PAGE_MASK(x) ((x) & 0xfff)
-
-typedef struct {
- u_int32_t ed_flags;
-#define OHCI_ED_GET_FA(s) ((s) & 0x7f)
-#define OHCI_ED_ADDRMASK 0x0000007f
-#define OHCI_ED_SET_FA(s) (s)
-#define OHCI_ED_GET_EN(s) (((s) >> 7) & 0xf)
-#define OHCI_ED_SET_EN(s) ((s) << 7)
-#define OHCI_ED_DIR_MASK 0x00001800
-#define OHCI_ED_DIR_TD 0x00000000
-#define OHCI_ED_DIR_OUT 0x00000800
-#define OHCI_ED_DIR_IN 0x00001000
-#define OHCI_ED_SPEED 0x00002000
-#define OHCI_ED_SKIP 0x00004000
-#define OHCI_ED_FORMAT_GEN 0x00000000
-#define OHCI_ED_FORMAT_ISO 0x00008000
-#define OHCI_ED_GET_MAXP(s) (((s) >> 16) & 0x07ff)
-#define OHCI_ED_SET_MAXP(s) ((s) << 16)
-#define OHCI_ED_MAXPMASK (0x7ff << 16)
- ohci_physaddr_t ed_tailp;
- ohci_physaddr_t ed_headp;
-#define OHCI_HALTED 0x00000001
-#define OHCI_TOGGLECARRY 0x00000002
-#define OHCI_HEADMASK 0xfffffffc
- ohci_physaddr_t ed_nexted;
-} ohci_ed_t;
-/* #define OHCI_ED_SIZE 16 */
-#define OHCI_ED_ALIGN 16
-
-typedef struct {
- u_int32_t td_flags;
-#define OHCI_TD_R 0x00040000 /* Buffer Rounding */
-#define OHCI_TD_DP_MASK 0x00180000 /* Direction / PID */
-#define OHCI_TD_SETUP 0x00000000
-#define OHCI_TD_OUT 0x00080000
-#define OHCI_TD_IN 0x00100000
-#define OHCI_TD_GET_DI(x) (((x) >> 21) & 7) /* Delay Interrupt */
-#define OHCI_TD_SET_DI(x) ((x) << 21)
-#define OHCI_TD_NOINTR 0x00e00000
-#define OHCI_TD_INTR_MASK 0x00e00000
-#define OHCI_TD_TOGGLE_CARRY 0x00000000
-#define OHCI_TD_TOGGLE_0 0x02000000
-#define OHCI_TD_TOGGLE_1 0x03000000
-#define OHCI_TD_TOGGLE_MASK 0x03000000
-#define OHCI_TD_GET_EC(x) (((x) >> 26) & 3) /* Error Count */
-#define OHCI_TD_GET_CC(x) ((x) >> 28) /* Condition Code */
-#define OHCI_TD_NOCC 0xf0000000
- ohci_physaddr_t td_cbp; /* Current Buffer Pointer */
- ohci_physaddr_t td_nexttd; /* Next TD */
- ohci_physaddr_t td_be; /* Buffer End */
-} ohci_td_t;
-/* #define OHCI_TD_SIZE 16 */
-#define OHCI_TD_ALIGN 16
-
-#define OHCI_ITD_NOFFSET 8
-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_SET_DI(x) ((x) << 21)
-#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 */
- 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 OHCI_ITD_PAGE_SELECT 0x00001000
-#define OHCI_ITD_MK_OFFS(page, off) \
- (0xe000 | ((page) ? OHCI_ITD_PAGE_SELECT : 0) | ((off) & 0xfff))
-#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
-#define OHCI_CC_BIT_STUFFING 2
-#define OHCI_CC_DATA_TOGGLE_MISMATCH 3
-#define OHCI_CC_STALL 4
-#define OHCI_CC_DEVICE_NOT_RESPONDING 5
-#define OHCI_CC_PID_CHECK_FAILURE 6
-#define OHCI_CC_UNEXPECTED_PID 7
-#define OHCI_CC_DATA_OVERRUN 8
-#define OHCI_CC_DATA_UNDERRUN 9
-#define OHCI_CC_BUFFER_OVERRUN 12
-#define OHCI_CC_BUFFER_UNDERRUN 13
-#define OHCI_CC_NOT_ACCESSED 15
-
-/* Some delay needed when changing certain registers. */
-#define OHCI_ENABLE_POWER_DELAY 5
-#define OHCI_READ_DESC_DELAY 5
-
-#endif /* _DEV_PCI_OHCIREG_H_ */
diff --git a/sys/dev/usb/ohcivar.h b/sys/dev/usb/ohcivar.h
deleted file mode 100644
index 48f99e7..0000000
--- a/sys/dev/usb/ohcivar.h
+++ /dev/null
@@ -1,164 +0,0 @@
-/* $NetBSD: ohcivar.h,v 1.30 2001/12/31 12:20:35 augustss Exp $ */
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) 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.
- */
-
-typedef struct ohci_soft_ed {
- ohci_ed_t ed;
- struct ohci_soft_ed *next;
- ohci_physaddr_t physaddr;
-} ohci_soft_ed_t;
-#define OHCI_SED_SIZE ((sizeof (struct ohci_soft_ed) + OHCI_ED_ALIGN - 1) / OHCI_ED_ALIGN * OHCI_ED_ALIGN)
-#define OHCI_SED_CHUNK (PAGE_SIZE / OHCI_SED_SIZE)
-
-typedef struct ohci_soft_td {
- ohci_td_t td;
- struct ohci_soft_td *nexttd; /* mirrors nexttd in TD */
- struct ohci_soft_td *dnext; /* next in done list */
- ohci_physaddr_t physaddr;
- LIST_ENTRY(ohci_soft_td) hnext;
- usbd_xfer_handle xfer;
- u_int16_t len;
- u_int16_t flags;
-#define OHCI_CALL_DONE 0x0001
-#define OHCI_ADD_LEN 0x0002
-} ohci_soft_td_t;
-#define OHCI_STD_SIZE ((sizeof (struct ohci_soft_td) + OHCI_TD_ALIGN - 1) / OHCI_TD_ALIGN * OHCI_TD_ALIGN)
-#define OHCI_STD_CHUNK (PAGE_SIZE / OHCI_STD_SIZE)
-
-typedef struct ohci_soft_itd {
- ohci_itd_t itd;
- struct ohci_soft_itd *nextitd; /* mirrors nexttd in ITD */
- struct ohci_soft_itd *dnext; /* next in done list */
- ohci_physaddr_t physaddr;
- LIST_ENTRY(ohci_soft_itd) hnext;
- usbd_xfer_handle xfer;
- u_int16_t flags;
-#define OHCI_ITD_ACTIVE 0x0010 /* Hardware op in progress */
-#define OHCI_ITD_INTFIN 0x0020 /* Hw completion interrupt seen.*/
-#ifdef DIAGNOSTIC
- char isdone;
-#endif
-} ohci_soft_itd_t;
-#define OHCI_SITD_SIZE ((sizeof (struct ohci_soft_itd) + OHCI_ITD_ALIGN - 1) / OHCI_ITD_ALIGN * OHCI_ITD_ALIGN)
-#define OHCI_SITD_CHUNK (PAGE_SIZE / OHCI_SITD_SIZE)
-
-#define OHCI_NO_EDS (2*OHCI_NO_INTRS-1)
-
-#define OHCI_HASH_SIZE 128
-
-#define OHCI_SCFLG_DONEINIT 0x0001 /* ohci_init() done. */
-
-typedef struct ohci_softc {
- struct usbd_bus sc_bus; /* base device */
- int sc_flags;
- bus_space_tag_t iot;
- bus_space_handle_t ioh;
- bus_size_t sc_size;
-
- void *ih;
-
- struct resource *io_res;
- struct resource *irq_res;
-
- usb_dma_t sc_hccadma;
- struct ohci_hcca *sc_hcca;
- ohci_soft_ed_t *sc_eds[OHCI_NO_EDS];
- u_int sc_bws[OHCI_NO_INTRS];
-
- u_int32_t sc_eintrs; /* enabled interrupts */
-
- ohci_soft_ed_t *sc_isoc_head;
- ohci_soft_ed_t *sc_ctrl_head;
- ohci_soft_ed_t *sc_bulk_head;
-
- LIST_HEAD(, ohci_soft_td) sc_hash_tds[OHCI_HASH_SIZE];
- LIST_HEAD(, ohci_soft_itd) sc_hash_itds[OHCI_HASH_SIZE];
-
- int sc_noport;
- u_int8_t sc_addr; /* device address */
- u_int8_t sc_conf; /* device configuration */
-
-#ifdef USB_USE_SOFTINTR
- char sc_softwake;
-#endif /* USB_USE_SOFTINTR */
-
- ohci_soft_ed_t *sc_freeeds;
- ohci_soft_td_t *sc_freetds;
- ohci_soft_itd_t *sc_freeitds;
-
- STAILQ_HEAD(, usbd_xfer) sc_free_xfers; /* free xfers */
-
- usbd_xfer_handle sc_intrxfer;
-
- ohci_soft_itd_t *sc_sidone;
- ohci_soft_td_t *sc_sdone;
-
- char sc_vendor[16];
- int sc_id_vendor;
-
-#if defined(__NetBSD__) || defined(__OpenBSD__)
- void *sc_powerhook; /* cookie from power hook */
- void *sc_shutdownhook; /* cookie from shutdown hook */
-#endif
- u_int32_t sc_control; /* Preserved during suspend/standby */
- u_int32_t sc_intre;
-
- u_int sc_overrun_cnt;
- struct timeval sc_overrun_ntc;
-
- struct callout sc_tmo_rhsc;
- char sc_dying;
-} ohci_softc_t;
-
-struct ohci_xfer {
- struct usbd_xfer xfer;
- struct usb_task abort_task;
- u_int32_t ohci_xfer_flags;
-};
-#define OHCI_XFER_ABORTING 0x01 /* xfer is aborting. */
-#define OHCI_XFER_ABORTWAIT 0x02 /* abort completion is being awaited. */
-
-#define OXFER(xfer) ((struct ohci_xfer *)(xfer))
-#define MS_TO_TICKS(ms) ((ms) * hz / 1000)
-
-usbd_status ohci_init(ohci_softc_t *);
-void ohci_intr(void *);
-int ohci_detach(ohci_softc_t *, int);
-void ohci_shutdown(void *v);
-void ohci_power(int state, void *priv);
diff --git a/sys/dev/usb/rio500_usb.h b/sys/dev/usb/rio500_usb.h
deleted file mode 100644
index 5b53e2c..0000000
--- a/sys/dev/usb/rio500_usb.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*-
- ----------------------------------------------------------------------
-
- Copyright (C) 2000 Cesar Miquel (miquel@df.uba.ar)
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted under any licence of your choise which
- meets the open source licence definiton
- http://www.opensource.org/opd.html such as the GNU licence or the
- BSD licence.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License or the BSD license for more details.
-
- ----------------------------------------------------------------------
-
- Modified for FreeBSD by Iwasa Kazmi <kzmi@ca2.so-net.ne.jp>
-
- ---------------------------------------------------------------------- */
-
-/* $FreeBSD$ */
-
-#include <sys/ioccom.h>
-#ifndef USB_VENDOR_DIAMOND
-#define USB_VENDOR_DIAMOND 0x841
-#endif
-#ifndef USB_PRODUCT_DIAMOND_RIO500USB
-#define USB_PRODUCT_DIAMOND_RIO500USB 0x1
-#endif
-
-struct RioCommand
-{
- uint16_t length;
- int request;
- int requesttype;
- int value;
- int index;
- void *buffer;
- int timeout;
-};
-
-#define RIO_SEND_COMMAND _IOWR('U', 200, struct RioCommand)
-#define RIO_RECV_COMMAND _IOWR('U', 201, struct RioCommand)
-
-#define RIO_DIR_OUT 0x0
-#define RIO_DIR_IN 0x1
diff --git a/sys/dev/usb/rt2573_ucode.h b/sys/dev/usb/rt2573_ucode.h
deleted file mode 100644
index f2040f3..0000000
--- a/sys/dev/usb/rt2573_ucode.h
+++ /dev/null
@@ -1,213 +0,0 @@
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 2005-2006, Ralink Technology, Corp.
- * Paul Lin <paul_lin@ralinktech.com.tw>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * This file contains the loadable 8051 microcode for the Ralink RT2573
- * chipset.
- */
-
-static const uint8_t rt2573_ucode[] = {
- 0x02, 0x13, 0x25, 0x12, 0x10, 0xd9, 0x02, 0x12, 0x58, 0x02, 0x13,
- 0x58, 0x02, 0x13, 0x5a, 0xc0, 0xd0, 0x75, 0xd0, 0x18, 0x12, 0x13,
- 0x5c, 0xd0, 0xd0, 0x22, 0x02, 0x14, 0x5c, 0x02, 0x14, 0xe7, 0xed,
- 0x4c, 0x70, 0x44, 0x90, 0x01, 0xa8, 0x74, 0x80, 0xf0, 0xef, 0x30,
- 0xe5, 0x07, 0xe4, 0x90, 0x00, 0x0f, 0xf0, 0x80, 0x2c, 0xe5, 0x40,
- 0x24, 0xc0, 0x60, 0x13, 0x24, 0xc0, 0x60, 0x16, 0x24, 0xc0, 0x60,
- 0x19, 0x24, 0xc0, 0x70, 0x1a, 0xe4, 0x90, 0x00, 0x0b, 0xf0, 0x80,
- 0x13, 0xe4, 0x90, 0x00, 0x13, 0xf0, 0x80, 0x0c, 0xe4, 0x90, 0x00,
- 0x1b, 0xf0, 0x80, 0x05, 0xe4, 0x90, 0x00, 0x23, 0xf0, 0xe4, 0x90,
- 0x01, 0xa8, 0xf0, 0xd3, 0x22, 0x90, 0x02, 0x02, 0xed, 0xf0, 0x90,
- 0x02, 0x01, 0xef, 0xf0, 0xd3, 0x22, 0xef, 0x24, 0xc0, 0x60, 0x1f,
- 0x24, 0xc0, 0x60, 0x2e, 0x24, 0xc0, 0x60, 0x3d, 0x24, 0xc0, 0x70,
- 0x53, 0x90, 0x00, 0x0b, 0xe0, 0x30, 0xe1, 0x02, 0xc3, 0x22, 0x90,
- 0x00, 0x09, 0xe0, 0xfe, 0x90, 0x00, 0x08, 0x80, 0x37, 0x90, 0x00,
- 0x13, 0xe0, 0x30, 0xe1, 0x02, 0xc3, 0x22, 0x90, 0x00, 0x11, 0xe0,
- 0xfe, 0x90, 0x00, 0x10, 0x80, 0x24, 0x90, 0x00, 0x1b, 0xe0, 0x30,
- 0xe1, 0x02, 0xc3, 0x22, 0x90, 0x00, 0x19, 0xe0, 0xfe, 0x90, 0x00,
- 0x18, 0x80, 0x11, 0x90, 0x00, 0x23, 0xe0, 0x30, 0xe1, 0x02, 0xc3,
- 0x22, 0x90, 0x00, 0x21, 0xe0, 0xfe, 0x90, 0x00, 0x20, 0xe0, 0xfd,
- 0xee, 0xf5, 0x37, 0xed, 0xf5, 0x38, 0xd3, 0x22, 0x30, 0x09, 0x20,
- 0x20, 0x04, 0x0b, 0x90, 0x02, 0x08, 0xe0, 0x54, 0x0f, 0x70, 0x03,
- 0x02, 0x12, 0x57, 0xc2, 0x09, 0x90, 0x02, 0x00, 0xe0, 0x44, 0x04,
- 0xf0, 0x74, 0x04, 0x12, 0x0c, 0x3a, 0xc2, 0x04, 0xc2, 0x07, 0x90,
- 0x02, 0x01, 0xe0, 0x30, 0xe0, 0x03, 0x00, 0x80, 0xf6, 0x90, 0x03,
- 0x26, 0xe0, 0x20, 0xe2, 0x03, 0x02, 0x12, 0x57, 0x90, 0x02, 0x08,
- 0xe0, 0x70, 0x1b, 0x20, 0x07, 0x03, 0x02, 0x12, 0x57, 0x90, 0x03,
- 0x12, 0xe0, 0x64, 0x22, 0x60, 0x03, 0x02, 0x12, 0x57, 0xd2, 0x09,
- 0xc2, 0x07, 0x74, 0x02, 0x12, 0x0c, 0x3a, 0x22, 0x90, 0x02, 0x03,
- 0xe0, 0x30, 0xe4, 0x47, 0x20, 0x06, 0x44, 0xe5, 0x3c, 0x60, 0x34,
- 0xe5, 0x40, 0x24, 0xc0, 0x60, 0x14, 0x24, 0xc0, 0x60, 0x18, 0x24,
- 0xc0, 0x60, 0x1c, 0x24, 0xc0, 0x70, 0x22, 0x90, 0x00, 0x0b, 0xe0,
- 0x30, 0xe1, 0x1b, 0x22, 0x90, 0x00, 0x13, 0xe0, 0x30, 0xe1, 0x13,
- 0x22, 0x90, 0x00, 0x1b, 0xe0, 0x30, 0xe1, 0x0b, 0x22, 0x90, 0x00,
- 0x23, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x12, 0x57, 0x90, 0x02, 0x03,
- 0x74, 0x01, 0xf0, 0x00, 0xe0, 0x54, 0xc0, 0xf5, 0x40, 0xe5, 0x40,
- 0x24, 0xc0, 0x60, 0x20, 0x24, 0xc0, 0x60, 0x30, 0x24, 0xc0, 0x60,
- 0x40, 0x24, 0xc0, 0x70, 0x56, 0x90, 0x00, 0x0b, 0xe0, 0x30, 0xe1,
- 0x03, 0x02, 0x12, 0x57, 0x90, 0x00, 0x09, 0xe0, 0xfe, 0x90, 0x00,
- 0x08, 0x80, 0x3a, 0x90, 0x00, 0x13, 0xe0, 0x30, 0xe1, 0x03, 0x02,
- 0x12, 0x57, 0x90, 0x00, 0x11, 0xe0, 0xfe, 0x90, 0x00, 0x10, 0x80,
- 0x26, 0x90, 0x00, 0x1b, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x12, 0x57,
- 0x90, 0x00, 0x19, 0xe0, 0xfe, 0x90, 0x00, 0x18, 0x80, 0x12, 0x90,
- 0x00, 0x23, 0xe0, 0x30, 0xe1, 0x03, 0x02, 0x12, 0x57, 0x90, 0x00,
- 0x21, 0xe0, 0xfe, 0x90, 0x00, 0x20, 0xe0, 0xfd, 0xee, 0xf5, 0x37,
- 0xed, 0xf5, 0x38, 0x90, 0x03, 0x27, 0x74, 0x82, 0xf0, 0x90, 0x02,
- 0x01, 0xe5, 0x40, 0xf0, 0x90, 0x02, 0x06, 0xe0, 0xf5, 0x3c, 0xc3,
- 0xe5, 0x38, 0x95, 0x3a, 0xe5, 0x37, 0x95, 0x39, 0x50, 0x21, 0xe5,
- 0x40, 0x44, 0x05, 0xff, 0xe5, 0x37, 0xa2, 0xe7, 0x13, 0xfc, 0xe5,
- 0x38, 0x13, 0xfd, 0x12, 0x10, 0x20, 0xe5, 0x3c, 0x30, 0xe2, 0x04,
- 0xd2, 0x06, 0x80, 0x02, 0xc2, 0x06, 0x53, 0x3c, 0x01, 0x22, 0x30,
- 0x0b, 0x07, 0xe4, 0x90, 0x02, 0x02, 0xf0, 0x80, 0x06, 0x90, 0x02,
- 0x02, 0x74, 0x20, 0xf0, 0xe5, 0x40, 0x44, 0x01, 0x90, 0x02, 0x01,
- 0xf0, 0x90, 0x02, 0x01, 0xe0, 0x30, 0xe0, 0x03, 0x00, 0x80, 0xf6,
- 0x90, 0x03, 0x27, 0x74, 0x02, 0xf0, 0xaf, 0x40, 0x12, 0x10, 0x74,
- 0x40, 0xa5, 0x00, 0x80, 0xf6, 0x22, 0x90, 0x7f, 0xf8, 0xe0, 0xb4,
- 0x02, 0x03, 0x12, 0x16, 0x38, 0x90, 0x02, 0x01, 0xe0, 0x30, 0xe0,
- 0x03, 0x00, 0x80, 0xf6, 0x90, 0x03, 0x26, 0xe0, 0x20, 0xe1, 0x07,
- 0xe5, 0x3b, 0x70, 0x03, 0x02, 0x13, 0x24, 0xe5, 0x3b, 0x70, 0x15,
- 0x90, 0x03, 0x24, 0xe0, 0x75, 0xf0, 0x40, 0xa4, 0xf5, 0x36, 0x85,
- 0xf0, 0x35, 0x75, 0x24, 0x83, 0x75, 0x3b, 0x01, 0x80, 0x03, 0x75,
- 0x24, 0x03, 0xd3, 0xe5, 0x36, 0x95, 0x3a, 0xe5, 0x35, 0x95, 0x39,
- 0x40, 0x36, 0x90, 0x02, 0x01, 0xe0, 0x30, 0xe0, 0x03, 0x00, 0x80,
- 0xf6, 0x90, 0x03, 0x27, 0xe5, 0x24, 0xf0, 0x90, 0x00, 0x0f, 0xe0,
- 0x30, 0xe1, 0x04, 0x30, 0x0e, 0xf6, 0x22, 0x30, 0x0b, 0x07, 0xe4,
- 0x90, 0x02, 0x02, 0xf0, 0x80, 0x06, 0x90, 0x02, 0x02, 0x74, 0x20,
- 0xf0, 0x90, 0x02, 0x01, 0x74, 0x21, 0xf0, 0x75, 0x24, 0x03, 0x80,
- 0x3d, 0xe5, 0x35, 0xa2, 0xe7, 0x13, 0xfe, 0xe5, 0x36, 0x13, 0xfd,
- 0xac, 0x06, 0x90, 0x02, 0x01, 0xe0, 0x30, 0xe0, 0x03, 0x00, 0x80,
- 0xf6, 0x90, 0x03, 0x27, 0xe5, 0x24, 0xf0, 0x90, 0x00, 0x0f, 0xe0,
- 0x30, 0xe1, 0x04, 0x30, 0x0e, 0xf6, 0x22, 0x7f, 0x25, 0x12, 0x10,
- 0x20, 0xe5, 0x36, 0xb5, 0x3a, 0x08, 0xe5, 0x35, 0xb5, 0x39, 0x03,
- 0x00, 0x80, 0x04, 0xe4, 0xf5, 0x3b, 0x22, 0xc3, 0xe5, 0x36, 0x95,
- 0x3a, 0xf5, 0x36, 0xe5, 0x35, 0x95, 0x39, 0xf5, 0x35, 0x02, 0x12,
- 0x96, 0x22, 0x75, 0xa8, 0x0f, 0x90, 0x03, 0x06, 0x74, 0x01, 0xf0,
- 0x90, 0x03, 0x07, 0xf0, 0x90, 0x03, 0x08, 0x04, 0xf0, 0x90, 0x03,
- 0x09, 0x74, 0x6c, 0xf0, 0x90, 0x03, 0x0a, 0x74, 0xff, 0xf0, 0x90,
- 0x03, 0x02, 0x74, 0x1f, 0xf0, 0x90, 0x03, 0x00, 0x74, 0x04, 0xf0,
- 0x90, 0x03, 0x25, 0x74, 0x31, 0xf0, 0xd2, 0xaf, 0x22, 0x00, 0x22,
- 0x00, 0x22, 0x90, 0x03, 0x05, 0xe0, 0x30, 0xe0, 0x0b, 0xe0, 0x44,
- 0x01, 0xf0, 0x30, 0x09, 0x02, 0xd2, 0x04, 0xc2, 0x07, 0x22, 0x8d,
- 0x24, 0xa9, 0x07, 0x90, 0x7f, 0xfc, 0xe0, 0x75, 0x25, 0x00, 0xf5,
- 0x26, 0xa3, 0xe0, 0x75, 0x27, 0x00, 0xf5, 0x28, 0xa3, 0xe0, 0xff,
- 0xa3, 0xe0, 0xfd, 0xe9, 0x30, 0xe5, 0x14, 0x54, 0xc0, 0x60, 0x05,
- 0x43, 0x05, 0x03, 0x80, 0x03, 0x53, 0x05, 0xfc, 0xef, 0x54, 0x3f,
- 0x44, 0x40, 0xff, 0x80, 0x06, 0x53, 0x07, 0x3f, 0x53, 0x05, 0xf0,
- 0xe5, 0x24, 0x30, 0xe0, 0x05, 0x43, 0x05, 0x10, 0x80, 0x03, 0x53,
- 0x05, 0xef, 0x90, 0x7f, 0xfc, 0xe5, 0x26, 0xf0, 0xa3, 0xe5, 0x28,
- 0xf0, 0xa3, 0xef, 0xf0, 0xa3, 0xed, 0xf0, 0x22, 0x8f, 0x24, 0xa9,
- 0x05, 0x90, 0x7f, 0xfc, 0xe0, 0x75, 0x25, 0x00, 0xf5, 0x26, 0xa3,
- 0xe0, 0x75, 0x27, 0x00, 0xf5, 0x28, 0xa3, 0xe0, 0xff, 0xa3, 0xe0,
- 0xfd, 0xe5, 0x24, 0x30, 0xe5, 0x0b, 0x43, 0x05, 0x0f, 0xef, 0x54,
- 0x3f, 0x44, 0x40, 0xff, 0x80, 0x06, 0x53, 0x05, 0xf0, 0x53, 0x07,
- 0x3f, 0xe9, 0x30, 0xe0, 0x05, 0x43, 0x05, 0x10, 0x80, 0x03, 0x53,
- 0x05, 0xef, 0x90, 0x7f, 0xfc, 0xe5, 0x26, 0xf0, 0xa3, 0xe5, 0x28,
- 0xf0, 0xa3, 0xef, 0xf0, 0xa3, 0xed, 0xf0, 0x22, 0x90, 0x7f, 0xfc,
- 0xe0, 0xf9, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfb,
- 0xef, 0x30, 0xe5, 0x0b, 0x43, 0x03, 0x0f, 0xec, 0x54, 0x3f, 0x44,
- 0x40, 0xfc, 0x80, 0x06, 0x53, 0x03, 0xf0, 0x53, 0x04, 0x3f, 0xed,
- 0x30, 0xe0, 0x07, 0xef, 0x54, 0xc0, 0x60, 0x07, 0x80, 0x0a, 0xef,
- 0x54, 0xc0, 0x60, 0x05, 0x43, 0x03, 0x10, 0x80, 0x03, 0x53, 0x03,
- 0xef, 0x90, 0x7f, 0xfc, 0xe9, 0xf0, 0xa3, 0xee, 0xf0, 0xa3, 0xec,
- 0xf0, 0xa3, 0xeb, 0xf0, 0x22, 0xe5, 0x4b, 0xfd, 0x54, 0x1f, 0x90,
- 0x7f, 0xf8, 0xf0, 0xe5, 0x4a, 0xf5, 0x09, 0x90, 0x30, 0x38, 0xe0,
- 0x90, 0x7f, 0xfc, 0xf0, 0x90, 0x30, 0x39, 0xe0, 0x90, 0x7f, 0xfd,
- 0xf0, 0x90, 0x30, 0x3a, 0xe0, 0x90, 0x7f, 0xfe, 0xf0, 0x90, 0x30,
- 0x3b, 0xe0, 0x90, 0x7f, 0xff, 0xf0, 0xed, 0x30, 0xe5, 0x0c, 0x54,
- 0xc0, 0x60, 0x0d, 0x90, 0x7f, 0xf0, 0xe5, 0x47, 0xf0, 0x80, 0x05,
- 0xe4, 0x90, 0x7f, 0xf0, 0xf0, 0x90, 0x7f, 0xf8, 0xe0, 0x14, 0x60,
- 0x08, 0x24, 0xfe, 0x60, 0x0d, 0x24, 0x03, 0x80, 0x12, 0xaf, 0x05,
- 0xad, 0x09, 0x12, 0x13, 0xc5, 0x80, 0x10, 0xaf, 0x05, 0xad, 0x09,
- 0x12, 0x14, 0x12, 0x80, 0x07, 0xaf, 0x05, 0xad, 0x09, 0x12, 0x13,
- 0x6f, 0x90, 0x7f, 0xfc, 0xe0, 0x90, 0x30, 0x38, 0xf0, 0x90, 0x7f,
- 0xfd, 0xe0, 0x90, 0x30, 0x39, 0xf0, 0x90, 0x7f, 0xfe, 0xe0, 0x90,
- 0x30, 0x3a, 0xf0, 0x90, 0x7f, 0xff, 0xe0, 0x90, 0x30, 0x3b, 0xf0,
- 0x22, 0xe5, 0x4b, 0x64, 0x01, 0x60, 0x03, 0x02, 0x15, 0x71, 0xf5,
- 0x4b, 0xe5, 0x44, 0x45, 0x43, 0x70, 0x03, 0x02, 0x15, 0xa0, 0x12,
- 0x0c, 0x14, 0x12, 0x0b, 0x86, 0x50, 0xfb, 0x90, 0x00, 0x00, 0xe0,
- 0xf5, 0x25, 0x12, 0x15, 0xb4, 0xc2, 0x92, 0xe4, 0xf5, 0x24, 0xe5,
- 0x24, 0xc3, 0x95, 0x25, 0x50, 0x49, 0x7e, 0x00, 0x7f, 0x4c, 0x74,
- 0x40, 0x25, 0x24, 0xf5, 0x82, 0xe4, 0x34, 0x01, 0xad, 0x82, 0xfc,
- 0x75, 0x2b, 0x02, 0x7b, 0x10, 0x12, 0x07, 0x1e, 0xc2, 0x93, 0x12,
- 0x15, 0xa1, 0x7d, 0xa0, 0x12, 0x15, 0xd0, 0xe5, 0x24, 0x54, 0x0f,
- 0x24, 0x4c, 0xf8, 0xe6, 0xfd, 0xaf, 0x4b, 0xae, 0x4a, 0x12, 0x15,
- 0xd8, 0x05, 0x4b, 0xe5, 0x4b, 0x70, 0x02, 0x05, 0x4a, 0x12, 0x0a,
- 0x5f, 0x05, 0x24, 0xe5, 0x24, 0x54, 0x0f, 0x70, 0xd5, 0xd2, 0x93,
- 0x80, 0xb0, 0xc3, 0xe5, 0x44, 0x95, 0x25, 0xf5, 0x44, 0xe5, 0x43,
- 0x94, 0x00, 0xf5, 0x43, 0x02, 0x14, 0xf2, 0x12, 0x15, 0xb4, 0xc2,
- 0x93, 0xc2, 0x92, 0x12, 0x15, 0xa1, 0x7d, 0x80, 0x12, 0x15, 0xd0,
- 0x7d, 0xaa, 0x74, 0x55, 0xff, 0xfe, 0x12, 0x15, 0xd8, 0x7d, 0x55,
- 0x7f, 0xaa, 0x7e, 0x2a, 0x12, 0x15, 0xd8, 0x7d, 0x30, 0xaf, 0x4b,
- 0xae, 0x4a, 0x12, 0x15, 0xd8, 0x12, 0x0a, 0x5f, 0xd2, 0x93, 0x22,
- 0x7d, 0xaa, 0x74, 0x55, 0xff, 0xfe, 0x12, 0x15, 0xd8, 0x7d, 0x55,
- 0x7f, 0xaa, 0x7e, 0x2a, 0x12, 0x15, 0xd8, 0x22, 0xad, 0x47, 0x7f,
- 0x34, 0x7e, 0x30, 0x12, 0x15, 0xd8, 0x7d, 0xff, 0x7f, 0x35, 0x7e,
- 0x30, 0x12, 0x15, 0xd8, 0xe4, 0xfd, 0x7f, 0x37, 0x7e, 0x30, 0x12,
- 0x15, 0xd8, 0x22, 0x74, 0x55, 0xff, 0xfe, 0x12, 0x15, 0xd8, 0x22,
- 0x8f, 0x82, 0x8e, 0x83, 0xed, 0xf0, 0x22, 0xe4, 0xfc, 0x90, 0x7f,
- 0xf0, 0xe0, 0xaf, 0x09, 0x14, 0x60, 0x14, 0x14, 0x60, 0x15, 0x14,
- 0x60, 0x16, 0x14, 0x60, 0x17, 0x14, 0x60, 0x18, 0x24, 0x05, 0x70,
- 0x16, 0xe4, 0xfc, 0x80, 0x12, 0x7c, 0x01, 0x80, 0x0e, 0x7c, 0x03,
- 0x80, 0x0a, 0x7c, 0x07, 0x80, 0x06, 0x7c, 0x0f, 0x80, 0x02, 0x7c,
- 0x1f, 0xec, 0x6f, 0xf4, 0x54, 0x1f, 0xfc, 0x90, 0x30, 0x34, 0xe0,
- 0x54, 0xe0, 0x4c, 0xfd, 0xa3, 0xe0, 0xfc, 0x43, 0x04, 0x1f, 0x7f,
- 0x34, 0x7e, 0x30, 0x12, 0x15, 0xd8, 0xad, 0x04, 0x0f, 0x12, 0x15,
- 0xd8, 0xe4, 0xfd, 0x7f, 0x37, 0x02, 0x15, 0xd8, 0x02, 0x15, 0xdf,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07,
- 0x29, 0xe9
-};
diff --git a/sys/dev/usb/sl811hs.c b/sys/dev/usb/sl811hs.c
deleted file mode 100644
index 3620d5f..0000000
--- a/sys/dev/usb/sl811hs.c
+++ /dev/null
@@ -1,1654 +0,0 @@
-/* $NetBSD: sl811hs.c,v 1.5 2005/02/27 00:27:02 perry Exp $ */
-
-/*
- * Copyright (c) 2001 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Tetsuya Isaki.
- *
- * 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.
- */
-
-
-/*
- * ScanLogic SL811HS/T USB Host Controller
- */
-/*
- * !! HIGHLY EXPERIMENTAL CODE !!
- */
-
-#include <sys/cdefs.h>
-//_RCSID(0, "$NetBSD: sl811hs.c,v 1.5 2005/02/27 00:27:02 perry Exp $");
-
-#include "opt_slhci.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/proc.h>
-#include <sys/bus.h>
-#include <sys/malloc.h>
-
-#include <machine/bus.h>
-#include <machine/cpu.h>
-#include <sys/module.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdivar.h>
-#include <dev/usb/usb_mem.h>
-#include <dev/usb/usb_port.h>
-#include "usbdevs.h"
-
-#include <dev/usb/sl811hsreg.h>
-#include <dev/usb/sl811hsvar.h>
-
-__FBSDID("$FreeBSD$");
-
-static inline u_int8_t sl11read(struct slhci_softc *, int);
-static inline void sl11write(struct slhci_softc *, int, u_int8_t);
-static inline void sl11read_region(struct slhci_softc *, u_char *, int, int);
-static inline void sl11write_region(struct slhci_softc *, int, u_char *, int);
-
-static void sl11_reset(struct slhci_softc *);
-static void sl11_speed(struct slhci_softc *);
-
-static usbd_status slhci_open(usbd_pipe_handle);
-static void slhci_softintr(void *);
-static void slhci_poll(struct usbd_bus *);
-static void slhci_poll_hub(void *);
-static void slhci_poll_device(void *arg);
-static usbd_status slhci_allocm(struct usbd_bus *, usb_dma_t *, u_int32_t);
-static void slhci_freem(struct usbd_bus *, usb_dma_t *);
-static usbd_xfer_handle slhci_allocx(struct usbd_bus *);
-static void slhci_freex(struct usbd_bus *, usbd_xfer_handle);
-
-static int slhci_str(usb_string_descriptor_t *, int, const char *);
-
-static usbd_status slhci_root_ctrl_transfer(usbd_xfer_handle);
-static usbd_status slhci_root_ctrl_start(usbd_xfer_handle);
-static void slhci_root_ctrl_abort(usbd_xfer_handle);
-static void slhci_root_ctrl_close(usbd_pipe_handle);
-static void slhci_root_ctrl_done(usbd_xfer_handle);
-
-static usbd_status slhci_root_intr_transfer(usbd_xfer_handle);
-static usbd_status slhci_root_intr_start(usbd_xfer_handle);
-static void slhci_root_intr_abort(usbd_xfer_handle);
-static void slhci_root_intr_close(usbd_pipe_handle);
-static void slhci_root_intr_done(usbd_xfer_handle);
-
-static usbd_status slhci_device_ctrl_transfer(usbd_xfer_handle);
-static usbd_status slhci_device_ctrl_start(usbd_xfer_handle);
-static void slhci_device_ctrl_abort(usbd_xfer_handle);
-static void slhci_device_ctrl_close(usbd_pipe_handle);
-static void slhci_device_ctrl_done(usbd_xfer_handle);
-
-static usbd_status slhci_device_intr_transfer(usbd_xfer_handle);
-static usbd_status slhci_device_intr_start(usbd_xfer_handle);
-static void slhci_device_intr_abort(usbd_xfer_handle);
-static void slhci_device_intr_close(usbd_pipe_handle);
-static void slhci_device_intr_done(usbd_xfer_handle);
-
-static usbd_status slhci_device_isoc_transfer(usbd_xfer_handle);
-static usbd_status slhci_device_isoc_start(usbd_xfer_handle);
-static void slhci_device_isoc_abort(usbd_xfer_handle);
-static void slhci_device_isoc_close(usbd_pipe_handle);
-static void slhci_device_isoc_done(usbd_xfer_handle);
-
-static usbd_status slhci_device_bulk_transfer(usbd_xfer_handle);
-static usbd_status slhci_device_bulk_start(usbd_xfer_handle);
-static void slhci_device_bulk_abort(usbd_xfer_handle);
-static void slhci_device_bulk_close(usbd_pipe_handle);
-static void slhci_device_bulk_done(usbd_xfer_handle);
-
-static int slhci_transaction(struct slhci_softc *,
- usbd_pipe_handle, u_int8_t, int, u_char *, u_int8_t);
-static void slhci_noop(usbd_pipe_handle);
-static void slhci_abort_xfer(usbd_xfer_handle, usbd_status);
-static void slhci_device_clear_toggle(usbd_pipe_handle);
-
-extern int usbdebug;
-
-/* For root hub */
-#define SLHCI_INTR_ENDPT (1)
-
-#ifdef SLHCI_DEBUG
-#define D_TRACE (0x0001) /* function trace */
-#define D_MSG (0x0002) /* debug messages */
-#define D_XFER (0x0004) /* transfer messages (noisy!) */
-#define D_MEM (0x0008) /* memory allocation */
-
-int slhci_debug = D_MSG | D_XFER;
-#define DPRINTF(z,x) if((slhci_debug&(z))!=0)printf x
-void print_req(usb_device_request_t *);
-void print_req_hub(usb_device_request_t *);
-void print_dumpreg(struct slhci_softc *);
-void print_xfer(usbd_xfer_handle);
-#else
-#define DPRINTF(z,x)
-#endif
-
-
-/* XXX: sync with argument */
-static const char *sltypestr [] = {
- "SL11H/T",
- "SL811HS/T",
-};
-
-
-struct usbd_bus_methods slhci_bus_methods = {
- slhci_open,
- slhci_softintr,
- slhci_poll,
- slhci_allocm,
- slhci_freem,
- slhci_allocx,
- slhci_freex,
-};
-
-struct usbd_pipe_methods slhci_root_ctrl_methods = {
- slhci_root_ctrl_transfer,
- slhci_root_ctrl_start,
- slhci_root_ctrl_abort,
- slhci_root_ctrl_close,
- slhci_noop,
- slhci_root_ctrl_done,
-};
-
-struct usbd_pipe_methods slhci_root_intr_methods = {
- slhci_root_intr_transfer,
- slhci_root_intr_start,
- slhci_root_intr_abort,
- slhci_root_intr_close,
- slhci_noop,
- slhci_root_intr_done,
-};
-
-struct usbd_pipe_methods slhci_device_ctrl_methods = {
- slhci_device_ctrl_transfer,
- slhci_device_ctrl_start,
- slhci_device_ctrl_abort,
- slhci_device_ctrl_close,
- slhci_noop,
- slhci_device_ctrl_done,
-};
-
-struct usbd_pipe_methods slhci_device_intr_methods = {
- slhci_device_intr_transfer,
- slhci_device_intr_start,
- slhci_device_intr_abort,
- slhci_device_intr_close,
- slhci_device_clear_toggle,
- slhci_device_intr_done,
-};
-
-struct usbd_pipe_methods slhci_device_isoc_methods = {
- slhci_device_isoc_transfer,
- slhci_device_isoc_start,
- slhci_device_isoc_abort,
- slhci_device_isoc_close,
- slhci_noop,
- slhci_device_isoc_done,
-};
-
-struct usbd_pipe_methods slhci_device_bulk_methods = {
- slhci_device_bulk_transfer,
- slhci_device_bulk_start,
- slhci_device_bulk_abort,
- slhci_device_bulk_close,
- slhci_noop,
- slhci_device_bulk_done,
-};
-
-struct slhci_pipe {
- struct usbd_pipe pipe;
-};
-
-
-/*
- * SL811HS Register read/write routine
- */
-static inline u_int8_t
-sl11read(struct slhci_softc *sc, int reg)
-{
-#if 1
- int b;
- DELAY(80);
- bus_space_write_1(sc->sc_iot, sc->sc_ioh, SL11_IDX_ADDR, reg);
- b = bus_space_read_1(sc->sc_iot, sc->sc_ioh, SL11_IDX_DATA);
- return b;
-#else
- outb(0x4000, reg&0xff);
- return (inb(0x4001)&0xff);
-#endif
-}
-
-static inline void
-sl11write(struct slhci_softc *sc, int reg, u_int8_t data)
-{
-#if 1
- DELAY(80);
- bus_space_write_1(sc->sc_iot, sc->sc_ioh, SL11_IDX_ADDR, reg);
- bus_space_write_1(sc->sc_iot, sc->sc_ioh, SL11_IDX_DATA, data);
-#else
- outb(0x4000, reg&0xff);
- outb(0x4000, data&0xff);
-#endif
-}
-
-static inline void
-sl11read_region(struct slhci_softc *sc, u_char *buf, int reg, int len)
-{
- int i;
- bus_space_write_1(sc->sc_iot, sc->sc_ioh, SL11_IDX_ADDR, reg);
- for (i = 0; i < len; i++)
- buf[i] = bus_space_read_1(sc->sc_iot, sc->sc_ioh, SL11_IDX_DATA);
-}
-
-static inline void
-sl11write_region(struct slhci_softc *sc, int reg, u_char *buf, int len)
-{
- int i;
- bus_space_write_1(sc->sc_iot, sc->sc_ioh, SL11_IDX_ADDR, reg);
- for (i = 0; i < len; i++)
- bus_space_write_1(sc->sc_iot, sc->sc_ioh, SL11_IDX_DATA, buf[i]);
-}
-
-/*
- * USB bus reset. From sl811hs_appnote.pdf, p22
- */
-static void
-sl11_reset(struct slhci_softc *sc)
-{
- u_int8_t r;
-
- DPRINTF(D_TRACE, ("%s() ", __FUNCTION__));
- // r = sl11read(sc, SL11_CTRL);
- r = 0;
- sl11write(sc, SL11_CTRL, r | SL11_CTRL_RESETENGINE);
- delay_ms(250);
- sl11write(sc, SL11_CTRL, r | SL11_CTRL_JKSTATE | SL11_CTRL_RESETENGINE); delay_ms(150);
- sl11write(sc, SL11_CTRL, r | SL11_CTRL_RESETENGINE);
- delay_ms(10);
- sl11write(sc, SL11_CTRL, r);
-}
-
-/*
- * Detect the speed of attached device.
- */
-static void
-sl11_speed(struct slhci_softc *sc)
-{
- u_int8_t r;
-
- sl11write(sc, SL11_ISR, 0xff);
- r = sl11read(sc, SL11_ISR);
- if ((r & SL11_ISR_RESET)) {
- DPRINTF(D_MSG, ("NC "));
- sl11write(sc, SL11_ISR, SL11_ISR_RESET);
- sc->sc_connect = 0;
- }
-
- if ((sl11read(sc, SL11_ISR) & SL11_ISR_RESET)) {
- sl11write(sc, SL11_ISR, 0xff);
- } else {
- u_int8_t pol = 0, ctrl = 0;
-
- sc->sc_connect = 1;
- if (r & SL11_ISR_DATA) {
- DPRINTF(D_MSG, ("FS "));
- pol = 0;
- ctrl = SL11_CTRL_EOF2;
- sc->sc_fullspeed = 1;
- } else {
- DPRINTF(D_MSG, ("LS "));
- pol = SL811_CSOF_POLARITY;
- ctrl = SL11_CTRL_LOWSPEED;
- sc->sc_fullspeed = 0;
- }
- sl11write(sc, SL811_CSOF, pol | SL811_CSOF_MASTER | 0x2e);
- sl11write(sc, SL11_DATA, 0xe0);
- sl11write(sc, SL11_CTRL, ctrl | SL11_CTRL_ENABLESOF);
- }
-
- sl11write(sc, SL11_E0PID, (SL11_PID_SOF << 4) + 0);
- sl11write(sc, SL11_E0DEV, 0);
- sl11write(sc, SL11_E0CTRL, SL11_EPCTRL_ARM);
- delay_ms(30);
-}
-
-/*
- * If detect some known controller, return the type.
- * If does not, return -1.
- */
-int
-sl811hs_find(struct slhci_softc *sc)
-{
- int rev;
- sc->sc_sltype = -1;
-
- rev = sl11read(sc, SL11_REV) >> 4;
- if (rev >= SLTYPE_SL11H && rev <= SLTYPE_SL811HS_R14)
- sc->sc_sltype = rev;
- return sc->sc_sltype;
-}
-
-/*
- * Attach SL11H/SL811HS. Return 0 if success.
- */
-int
-slhci_attach(struct slhci_softc *sc)
-{
- int rev;
- /* Detect and check the controller type */
-
- rev = sl811hs_find(sc);
- if (rev == -1)
- return -1;
-
- printf("%s: ScanLogic %s USB Host Controller",
- device_get_nameunit(sc->sc_bus.bdev), sltypestr[(rev > 0)]);
- switch (rev) {
- case SLTYPE_SL11H:
- break;
- case SLTYPE_SL811HS_R12:
- printf(" (rev 1.2)");
- break;
- case SLTYPE_SL811HS_R14:
- printf(" (rev 1.4)");
- break;
- default:
- printf(" (unknown revision)");
- break;
- }
- printf("\n");
-
-
- /* Initialize sc */
- sc->sc_bus.usbrev = USBREV_1_1;
- sc->sc_bus.methods = &slhci_bus_methods;
- sc->sc_bus.pipe_size = sizeof(struct slhci_pipe);
- sc->sc_bus.parent_dmatag = NULL; /* XXX */
- sc->sc_bus.buffer_dmatag = NULL; /* XXX */
- STAILQ_INIT(&sc->sc_free_xfers);
-
- usb_callout_init(sc->sc_poll_handle);
-
- /* Disable interrupt, then wait 40msec */
- sl11write(sc, SL11_IER, 0x00);
- delay_ms(40);
-
- /* Initialize controller */
- sl11write(sc, SL811_CSOF, SL811_CSOF_MASTER | 0x2e);
- delay_ms(40);
-
- sl11write(sc, SL11_ISR, 0xff);
-
- /* Disable interrupt, then wait 40msec */
- sl11write(sc, SL11_IER, 0x00);
-
- /* Reset USB engine */
- sl11write(sc, SL11_CTRL, SL11_CTRL_JKSTATE| SL11_CTRL_RESETENGINE);
- delay_ms(40);
- sl11write(sc, SL11_CTRL, 0x00);
- delay_ms(10);
-
- /* USB Bus reset for GET_PORT_STATUS */
- sl11_reset(sc);
- sc->sc_flags = SLF_ATTACHED;
-
- /* Enable interrupt */
- sl11write(sc, SL11_IER, SL11_IER_INSERT);
- /* x68k Nereid USB controller needs it */
- if (sc->sc_enable_intr)
- sc->sc_enable_intr(sc->sc_arg, INTR_ON);
-#ifdef USB_DEBUG
- usbdebug = 0;
-#endif
-
- return 0;
-}
-
-int
-slhci_intr(void *arg)
-{
- struct slhci_softc *sc = arg;
- u_int8_t r;
-#ifdef SLHCI_DEBUG
- char bitbuf[256];
-#endif
-
-
- if((sc->sc_flags & SLF_ATTACHED) == 0)
- return 0;
-
- r = sl11read(sc, SL11_ISR);
-
-
-
- sl11write(sc, SL11_ISR, SL11_ISR_DATA | SL11_ISR_SOFTIMER);
-
- if ((r & SL11_ISR_RESET)) {
- sc->sc_flags |= SLF_RESET;
- sl11write(sc, SL11_ISR, SL11_ISR_RESET);
- }
- if ((r & SL11_ISR_INSERT)) {
- sc->sc_flags |= SLF_INSERT;
- sl11write(sc, SL11_ISR, SL11_ISR_INSERT);
- }
-
-#ifdef SLHCI_DEBUG
- bitmask_snprintf(r,
- (sl11read(sc, SL11_CTRL) & SL11_CTRL_SUSPEND)
- ? "\20\x8""D+\7RESUME\6INSERT\5SOF\4res\3""BABBLE\2USBB\1USBA"
- : "\20\x8""D+\7RESET\6INSERT\5SOF\4res\3""BABBLE\2USBB\1USBA",
- bitbuf, sizeof(bitbuf));
- DPRINTF(D_XFER, ("I=%s ", bitbuf));
-#endif /* SLHCI_DEBUG */
-
- return 0;
-}
-
-usbd_status
-slhci_open(usbd_pipe_handle pipe)
-{
- usbd_device_handle dev = pipe->device;
- struct slhci_softc *sc = (struct slhci_softc *)dev->bus;
- usb_endpoint_descriptor_t *ed = pipe->endpoint->edesc;
-
- DPRINTF(D_TRACE, ("slhci_open(addr=%d,ep=%d,scaddr=%d)",
- dev->address, ed->bEndpointAddress, sc->sc_addr));
-
- if (dev->address == sc->sc_addr) {
- switch (ed->bEndpointAddress) {
- case USB_CONTROL_ENDPOINT:
- pipe->methods = &slhci_root_ctrl_methods;
- break;
- case UE_DIR_IN | SLHCI_INTR_ENDPT:
- pipe->methods = &slhci_root_intr_methods;
- break;
- default:
- printf("open:endpointErr!\n");
- return USBD_INVAL;
- }
- } else {
- switch (ed->bmAttributes & UE_XFERTYPE) {
- case UE_CONTROL:
- DPRINTF(D_MSG, ("control "));
- pipe->methods = &slhci_device_ctrl_methods;
- break;
- case UE_INTERRUPT:
- DPRINTF(D_MSG, ("interrupt "));
- pipe->methods = &slhci_device_intr_methods;
- break;
- case UE_ISOCHRONOUS:
- DPRINTF(D_MSG, ("isochronous "));
- pipe->methods = &slhci_device_isoc_methods;
- break;
- case UE_BULK:
- DPRINTF(D_MSG, ("bluk "));
- pipe->methods = &slhci_device_bulk_methods;
- break;
- }
- }
- return USBD_NORMAL_COMPLETION;
-}
-
-void
-slhci_softintr(void *arg)
-{
- DPRINTF(D_TRACE, ("%s()", __FUNCTION__));
-}
-
-void
-slhci_poll(struct usbd_bus *bus)
-{
- DPRINTF(D_TRACE, ("%s()", __FUNCTION__));
-}
-
-/*
- * Emulation of interrupt transfer for status change endpoint
- * of root hub.
- */
-void
-slhci_poll_hub(void *arg)
-{
- usbd_xfer_handle xfer = arg;
- usbd_pipe_handle pipe = xfer->pipe;
- struct slhci_softc *sc = (struct slhci_softc *)pipe->device->bus;
- int s;
- u_char *p;
-
- usb_callout(sc->sc_poll_handle, sc->sc_interval, slhci_poll_hub, xfer);
-
- /* USB spec 11.13.3 (p.260) */
- p = xfer->buffer;
- p[0] = 0;
- if ((sc->sc_flags & (SLF_INSERT | SLF_RESET))) {
- p[0] = 2;
- DPRINTF(D_TRACE, ("!"));
- }
-
- /* no change, return NAK */
- if (p[0] == 0)
- return;
-
- xfer->actlen = 1;
- xfer->status = USBD_NORMAL_COMPLETION;
- s = splusb();
- xfer->device->bus->intr_context++;
- usb_transfer_complete(xfer);
- xfer->device->bus->intr_context--;
- splx(s);
-}
-
-usbd_status
-slhci_allocm(struct usbd_bus *bus, usb_dma_t *dma, u_int32_t size)
-{
- struct slhci_softc *sc = (struct slhci_softc *)bus;
-
- DPRINTF(D_MEM, ("SLallocm"));
- return usb_allocmem(&sc->sc_bus, size, 0, dma);
-}
-
-void
-slhci_freem(struct usbd_bus *bus, usb_dma_t *dma)
-{
- struct slhci_softc *sc = (struct slhci_softc *)bus;
-
- DPRINTF(D_MEM, ("SLfreem"));
- usb_freemem(&sc->sc_bus, dma);
-}
-
-usbd_xfer_handle
-slhci_allocx(struct usbd_bus *bus)
-{
- struct slhci_softc *sc = (struct slhci_softc *)bus;
- usbd_xfer_handle xfer;
-
- DPRINTF(D_MEM, ("SLallocx"));
-
- xfer = STAILQ_FIRST(&sc->sc_free_xfers);
- if (xfer) {
- STAILQ_REMOVE_HEAD(&sc->sc_free_xfers, next);
-#ifdef DIAGNOSTIC
- if (xfer->busy_free != XFER_FREE) {
- printf("slhci_allocx: xfer=%p not free, 0x%08x\n",
- xfer, xfer->busy_free);
- }
-#endif
- } else {
- xfer = malloc(sizeof(*xfer), M_USB, M_NOWAIT);
- }
-
- if (xfer) {
- memset(xfer, 0, sizeof(*xfer));
-#ifdef DIAGNOSTIC
- xfer->busy_free = XFER_BUSY;
-#endif
- }
-
- return xfer;
-}
-
-void
-slhci_freex(struct usbd_bus *bus, usbd_xfer_handle xfer)
-{
- struct slhci_softc *sc = (struct slhci_softc *)bus;
-
- DPRINTF(D_MEM, ("SLfreex"));
-
-#ifdef DIAGNOSTIC
- if (xfer->busy_free != XFER_BUSY) {
- printf("slhci_freex: xfer=%p not busy, 0x%08x\n",
- xfer, xfer->busy_free);
- return;
- }
- xfer->busy_free = XFER_FREE;
-#endif
- STAILQ_INSERT_HEAD(&sc->sc_free_xfers, xfer, next);
-}
-
-void
-slhci_noop(usbd_pipe_handle pipe)
-{
- DPRINTF(D_TRACE, ("%s()", __FUNCTION__));
-}
-
-/*
- * Data structures and routines to emulate the root hub.
- */
-usb_device_descriptor_t slhci_devd = {
- USB_DEVICE_DESCRIPTOR_SIZE,
- UDESC_DEVICE, /* type */
- {0x01, 0x01}, /* USB version */
- UDCLASS_HUB, /* class */
- UDSUBCLASS_HUB, /* subclass */
- 0, /* protocol */
- 64, /* max packet */
- {USB_VENDOR_SCANLOGIC & 0xff, /* vendor ID (low) */
- USB_VENDOR_SCANLOGIC >> 8 }, /* vendor ID (high) */
- {0} /* ? */, /* product ID */
- {0}, /* device */
- 1, /* index to manufacturer */
- 2, /* index to product */
- 0, /* index to serial number */
- 1 /* number of configurations */
-};
-
-usb_config_descriptor_t slhci_confd = {
- USB_CONFIG_DESCRIPTOR_SIZE,
- UDESC_CONFIG,
- {USB_CONFIG_DESCRIPTOR_SIZE +
- USB_INTERFACE_DESCRIPTOR_SIZE +
- USB_ENDPOINT_DESCRIPTOR_SIZE},
- 1, /* number of interfaces */
- 1, /* configuration value */
- 0, /* index to configuration */
- UC_SELF_POWERED, /* attributes */
- 15 /* max current is 30mA... */
-};
-
-usb_interface_descriptor_t slhci_ifcd = {
- USB_INTERFACE_DESCRIPTOR_SIZE,
- UDESC_INTERFACE,
- 0, /* interface number */
- 0, /* alternate setting */
- 1, /* number of endpoint */
- UICLASS_HUB, /* class */
- UISUBCLASS_HUB, /* subclass */
- 0, /* protocol */
- 0 /* index to interface */
-};
-
-usb_endpoint_descriptor_t slhci_endpd = {
- USB_ENDPOINT_DESCRIPTOR_SIZE,
- UDESC_ENDPOINT,
- UE_DIR_IN | SLHCI_INTR_ENDPT, /* endpoint address */
- UE_INTERRUPT, /* attributes */
- {8}, /* max packet size */
- 255 /* interval */
-};
-
-usb_hub_descriptor_t slhci_hubd = {
- USB_HUB_DESCRIPTOR_SIZE,
- UDESC_HUB,
- 1, /* number of ports */
- {UHD_PWR_INDIVIDUAL | UHD_OC_NONE, 0}, /* hub characteristics */
- 20 /* ? */, /* 5:power on to power good */
- 50, /* 6:maximum current */
- { 0x00 }, /* both ports are removable */
- { 0x00 } /* port power control mask */
-};
-
-static int
-slhci_str(usb_string_descriptor_t *p, int l, const char *s)
-{
- int i;
-
- if (l == 0)
- return 0;
- p->bLength = 2 * strlen(s) + 2;
- if (l == 1)
- return 1;
- p->bDescriptorType = UDESC_STRING;
- l -= 2;
- for (i = 0; s[i] && l > 1; i++, l -= 2)
- USETW2(p->bString[i], 0, s[i]);
- return 2 * i + 2;
-}
-
-usbd_status
-slhci_root_ctrl_transfer(usbd_xfer_handle xfer)
-{
- usbd_status error;
-
- DPRINTF(D_TRACE, ("SLRCtrans "));
-
- /* Insert last in queue */
- error = usb_insert_transfer(xfer);
- if (error) {
- DPRINTF(D_MSG, ("usb_insert_transfer returns err! "));
- return error;
- }
-
- /*
- * Pipe isn't running (otherwise error would be USBD_INPROG),
- * so start it first.
- */
- return slhci_root_ctrl_start(STAILQ_FIRST(&xfer->pipe->queue));
-}
-
-usbd_status
-slhci_root_ctrl_start(usbd_xfer_handle xfer)
-{
- struct slhci_softc *sc = (struct slhci_softc *)xfer->pipe->device->bus;
- usb_device_request_t *req;
- int len, value, index, l, s, status;
- int totlen = 0;
- void *buf = NULL;
- usb_port_status_t ps;
- usbd_status error;
- char slbuf[50];
- u_int8_t r;
-
- DPRINTF(D_TRACE, ("SLRCstart "));
-
- req = &xfer->request;
-
- len = UGETW(req->wLength);
- value = UGETW(req->wValue);
- index = UGETW(req->wIndex);
-
- if (len)
- buf = xfer->buffer;
-
-#ifdef SLHCI_DEBUG
- if ((slhci_debug & D_TRACE))
- print_req_hub(req);
-#endif
-
-#define C(x,y) ((x) | ((y) << 8))
- switch (C(req->bRequest, req->bmRequestType)) {
- case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE):
- case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE):
- case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT):
- DPRINTF(D_MSG, ("UR_CLEAR_FEATURE "));
- break;
- case C(UR_GET_CONFIG, UT_READ_DEVICE):
- DPRINTF(D_MSG, ("UR_GET_CONFIG "));
- if (len > 0) {
- *(u_int8_t *)buf = sc->sc_conf;
- totlen = 1;
- }
- break;
- case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
- switch (value >> 8) {
- case UDESC_DEVICE:
- DPRINTF(D_MSG, ("UDESC_DEVICE "));
- if ((value & 0xff) != 0) {
- error = USBD_IOERROR;
- goto ret;
- }
- totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE);
- memcpy(buf, &slhci_devd, l);
- break;
- case UDESC_CONFIG:
- DPRINTF(D_MSG, ("UDESC_CONFIG "));
- if ((value & 0xff) != 0) {
- error = USBD_IOERROR;
- goto ret;
- }
- totlen = l = min(len, USB_CONFIG_DESCRIPTOR_SIZE);
- memcpy(buf, &slhci_confd, l);
- buf = (char *)buf + l;
- len -= l;
-
- l = min(len, USB_INTERFACE_DESCRIPTOR_SIZE);
- totlen += l;
- memcpy(buf, &slhci_ifcd, l);
- buf = (char *)buf + l;
- len -= l;
-
- l = min(len, USB_ENDPOINT_DESCRIPTOR_SIZE);
- totlen += l;
- memcpy(buf, &slhci_endpd, l);
- break;
- case UDESC_STRING:
- DPRINTF(D_MSG, ("UDESC_STR "));
- if (len == 0)
- break;
- *(u_int8_t *)buf = 0;
- totlen = 1;
- switch (value & 0xff) {
- case 0:
- break;
- case 1: /* Vendor */
- totlen = slhci_str(buf, len, "ScanLogic");
- break;
- case 2: /* Product */
- snprintf(slbuf, sizeof(slbuf), "%s root hub",
- sltypestr[sc->sc_sltype>0]);
- totlen = slhci_str(buf, len, slbuf);
- break;
- default:
- printf("strerr%d ", value & 0xff);
- break;
- }
- break;
- default:
- printf("unknownGetDescriptor=%x", value);
- error = USBD_IOERROR;
- break;
- }
- break;
- case C(UR_GET_INTERFACE, UT_READ_INTERFACE):
- /* Get Interface, 9.4.4 */
- if (len > 0) {
- *(u_int8_t *)buf = 0;
- totlen = 1;
- }
- break;
- case C(UR_GET_STATUS, UT_READ_DEVICE):
- /* Get Status from device, 9.4.5 */
- if (len > 1) {
- USETW(((usb_status_t *)buf)->wStatus, UDS_SELF_POWERED);
- totlen = 2;
- }
- break;
- case C(UR_GET_STATUS, UT_READ_INTERFACE):
- case C(UR_GET_STATUS, UT_READ_ENDPOINT):
- /* Get Status from interface, endpoint, 9.4.5 */
- if (len > 1) {
- USETW(((usb_status_t *)buf)->wStatus, 0);
- totlen = 2;
- }
- break;
- case C(UR_SET_ADDRESS, UT_WRITE_DEVICE):
- /* Set Address, 9.4.6 */
- DPRINTF(D_MSG, ("UR_SET_ADDRESS "));
- if (value >= USB_MAX_DEVICES) {
- error = USBD_IOERROR;
- goto ret;
- }
- sc->sc_addr = value;
- break;
- case C(UR_SET_CONFIG, UT_WRITE_DEVICE):
- /* Set Configuration, 9.4.7 */
- DPRINTF(D_MSG, ("UR_SET_CONFIG "));
- if (value != 0 && value != 1) {
- error = USBD_IOERROR;
- goto ret;
- }
- sc->sc_conf = value;
- break;
- case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE):
- /* Set Descriptor, 9.4.8, not supported */
- DPRINTF(D_MSG, ("UR_SET_DESCRIPTOR,WRITE_DEVICE not supported\n"));
- break;
- case C(UR_SET_FEATURE, UT_WRITE_DEVICE):
- case C(UR_SET_FEATURE, UT_WRITE_INTERFACE):
- case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT):
- /* Set Feature, 9.4.9, not supported */
- DPRINTF(D_MSG, ("UR_SET_FEATURE not supported\n"));
- error = USBD_IOERROR;
- break;
- case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE):
- /* Set Interface, 9.4.10, not supported */
- break;
- case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT):
- /* Synch Frame, 9.4.11, not supported */
- break;
-
- /*
- * Hub specific requests
- */
- case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE):
- /* Clear Hub Feature, 11.16.2.1, not supported */
- DPRINTF(D_MSG, ("ClearHubFeature not supported\n"));
- break;
- case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER):
- /* Clear Port Feature, 11.16.2.2 */
- if (index != 1) {
- error = USBD_IOERROR;
- goto ret;
- }
- switch (value) {
- case UHF_PORT_POWER:
- DPRINTF(D_MSG, ("POWER_OFF "));
- sc->sc_powerstat = POWER_OFF;
- /* x68k Nereid USB controller needs it */
- if (sc->sc_enable_power)
- sc->sc_enable_power(sc, sc->sc_powerstat);
- break;
- case UHF_PORT_SUSPEND:
- DPRINTF(D_MSG, ("SUSPEND "));
- sl11write(sc, SL11_CTRL,
- sl11read(sc, SL11_CTRL) & ~SL11_CTRL_SUSPEND);
- break;
- case UHF_C_PORT_CONNECTION:
- sc->sc_change &= ~UPS_C_CONNECT_STATUS;
- break;
- case UHF_C_PORT_RESET:
- sc->sc_change &= ~UPS_C_PORT_RESET;
- break;
- case UHF_PORT_ENABLE:
- break;
- case UHF_C_PORT_SUSPEND:
- case UHF_C_PORT_ENABLE:
- case UHF_C_PORT_OVER_CURRENT:
- default:
- printf("ClrPortFeatERR:value=0x%x ", value);
- error = USBD_IOERROR;
- break;
- }
- //DPRINTF(D_XFER, ("CH=%04x ", sc->sc_change));
- break;
- case C(UR_GET_BUS_STATE, UT_READ_CLASS_OTHER):
- /* Get Bus State, 11.16.2.3, not supported */
- /* shall return a STALL... */
- break;
- case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE):
- /* Get Hub Descriptor, 11.16.2.4 */
- if (value != 0) {
- error = USBD_IOERROR;
- goto ret;
- }
- l = min(len, USB_HUB_DESCRIPTOR_SIZE);
- totlen = l;
- memcpy(buf, &slhci_hubd, l);
- break;
- case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
- /* Get Hub Status, 11.16.2.5 */
- DPRINTF(D_MSG, ("UR_GET_STATUS RCD"));
- if (len != 4) {
- error = USBD_IOERROR;
- goto ret;
- }
- memset(buf, 0, len);
- totlen = len;
- break;
- case C(UR_GET_STATUS, UT_READ_CLASS_OTHER):
- /* Get Port Status, 11.16.2.6 */
- if (index != 1 || len != 4) {
- printf("index=%d,len=%d ", index, len);
- error = USBD_IOERROR;
- goto ret;
- }
- /*
- * change
- * o port is always enabled.
- * o cannot detect over current.
- */
- s = splusb();
- sc->sc_change &= ~(UPS_C_CONNECT_STATUS | UPS_C_PORT_RESET);
- if ((sc->sc_flags & SLF_INSERT)) {
- sc->sc_flags &= ~SLF_INSERT;
- sc->sc_change |= UPS_C_CONNECT_STATUS;
- }
- if ((sc->sc_flags & SLF_RESET)) {
- sc->sc_flags &= ~SLF_RESET;
- sc->sc_change |= UPS_C_PORT_RESET;
- }
- splx(s);
- /*
- * XXX It can recognize that device is detached,
- * while there is sl11_speed() here.
- */
- if (sc->sc_change)
- sl11_speed(sc);
- /*
- * status
- * o port is always enabled.
- * o cannot detect over current.
- */
- status = 0;
- if (sc->sc_connect)
- status |= UPS_CURRENT_CONNECT_STATUS | UPS_PORT_ENABLED;
- r = sl11read(sc, SL11_CTRL);
- if (r & SL11_CTRL_SUSPEND)
- status |= UPS_SUSPEND;
- if (sc->sc_powerstat)
- status |= UPS_PORT_POWER;
- if (!sc->sc_fullspeed)
- status |= UPS_LOW_SPEED;
-
- //DPRINTF(D_XFER, ("ST=%04x,CH=%04x ", status, sc->sc_change));
- USETW(ps.wPortStatus, status);
- USETW(ps.wPortChange, sc->sc_change);
- l = min(len, sizeof(ps));
- memcpy(buf, &ps, l);
- totlen = l;
- break;
- case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE):
- /* Set Hub Descriptor, 11.16.2.7, not supported */
- /* STALL ? */
- error = USBD_IOERROR;
- break;
- case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE):
- /* Set Hub Feature, 11.16.2.8, not supported */
- break;
- case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER):
- /* Set Port Feature, 11.16.2.9 */
- if (index != 1) {
- printf("index=%d ", index);
- error = USBD_IOERROR;
- goto ret;
- }
- switch (value) {
- case UHF_PORT_RESET:
- DPRINTF(D_MSG, ("PORT_RESET "));
- sl11_reset(sc);
- sl11_speed(sc);
- sc->sc_change = 0;
- break;
- case UHF_PORT_POWER:
- DPRINTF(D_MSG, ("PORT_POWER "));
- sc->sc_powerstat = POWER_ON;
- /* x68k Nereid USB controller needs it */
- if (sc->sc_enable_power)
- sc->sc_enable_power(sc, sc->sc_powerstat);
- delay_ms(25);
- break;
- default:
- printf("SetPortFeatERR=0x%x ", value);
- error = USBD_IOERROR;
- break;
- }
- break;
- default:
- DPRINTF(D_MSG, ("ioerr(UR=%02x,UT=%02x) ",
- req->bRequest, req->bmRequestType));
- error = USBD_IOERROR;
- goto ret;
- }
- xfer->actlen = totlen;
- error = USBD_NORMAL_COMPLETION;
- ret:
- xfer->status = error;
- s = splusb();
- usb_transfer_complete(xfer);
- splx(s);
- return USBD_IN_PROGRESS;
-}
-
-void
-slhci_root_ctrl_abort(usbd_xfer_handle xfer)
-{
- DPRINTF(D_TRACE, ("SLRCabort "));
-}
-
-void
-slhci_root_ctrl_close(usbd_pipe_handle pipe)
-{
- DPRINTF(D_TRACE, ("SLRCclose "));
-}
-
-void
-slhci_root_ctrl_done(usbd_xfer_handle xfer)
-{
- DPRINTF(D_TRACE, ("SLRCdone\n"));
-}
-
-static usbd_status
-slhci_root_intr_transfer(usbd_xfer_handle xfer)
-{
- usbd_status error;
-
- DPRINTF(D_TRACE, ("SLRItransfer "));
-
- /* Insert last in queue */
- error = usb_insert_transfer(xfer);
- if (error)
- return error;
-
- /*
- * Pipe isn't running (otherwise error would be USBD_INPROG),
- * start first.
- */
- return slhci_root_intr_start(STAILQ_FIRST(&xfer->pipe->queue));
-}
-
-static usbd_status
-slhci_root_intr_start(usbd_xfer_handle xfer)
-{
- usbd_pipe_handle pipe = xfer->pipe;
- struct slhci_softc *sc = (struct slhci_softc *)pipe->device->bus;
-
- DPRINTF(D_TRACE, ("SLRIstart "));
-
- sc->sc_interval = MS_TO_TICKS(xfer->pipe->endpoint->edesc->bInterval);
- usb_callout(sc->sc_poll_handle, sc->sc_interval, slhci_poll_hub, xfer);
- sc->sc_intr_xfer = xfer;
- return USBD_IN_PROGRESS;
-}
-
-static void
-slhci_root_intr_abort(usbd_xfer_handle xfer)
-{
- DPRINTF(D_TRACE, ("SLRIabort "));
-}
-
-static void
-slhci_root_intr_close(usbd_pipe_handle pipe)
-{
- struct slhci_softc *sc = (struct slhci_softc *)pipe->device->bus;
-
- DPRINTF(D_TRACE, ("SLRIclose "));
-
- usb_uncallout(sc->sc_poll_handle, slhci_poll_hub, sc->sc_intr_xfer);
- sc->sc_intr_xfer = NULL;
-}
-
-static void
-slhci_root_intr_done(usbd_xfer_handle xfer)
-{
- //DPRINTF(D_XFER, ("RIdn "));
-}
-
-static usbd_status
-slhci_device_ctrl_transfer(usbd_xfer_handle xfer)
-{
- usbd_status error;
-
- DPRINTF(D_TRACE, ("C"));
-
- error = usb_insert_transfer(xfer);
- if (error)
- return error;
-
- return slhci_device_ctrl_start(STAILQ_FIRST(&xfer->pipe->queue));
-}
-
-static usbd_status
-slhci_device_ctrl_start(usbd_xfer_handle xfer)
-{
- usb_device_request_t *req = &xfer->request;
- usbd_pipe_handle pipe = xfer->pipe;
- struct slhci_softc *sc = (struct slhci_softc *)pipe->device->bus;
- usbd_status status = USBD_NORMAL_COMPLETION;
- u_char *buf;
- int pid = SL11_PID_OUT;
- int len, actlen, size;
- int s;
- u_int8_t toggle = 0;
-
- DPRINTF(D_TRACE, ("st "));
-#ifdef SLHCI_DEBUG
- if ((slhci_debug & D_TRACE))
- print_req_hub(req);
-#endif
-
- /* SETUP transaction */
- if (slhci_transaction(sc, pipe, SL11_PID_SETUP,
- sizeof(*req), (u_char*)req, toggle) == -1) {
- status = USBD_IOERROR;
- goto ret;
- }
- toggle ^= SL11_EPCTRL_DATATOGGLE;
-
- /* DATA transaction */
- actlen = 0;
- len = UGETW(req->wLength);
- if (len) {
- buf = xfer->buffer;
- if (req->bmRequestType & UT_READ)
- pid = SL11_PID_IN;
- for (; actlen < len; ) {
- size = min(len - actlen, 8/* Minimum size */);
- if (slhci_transaction(sc, pipe, pid, size, buf, toggle) == -1)
- break;
- toggle ^= SL11_EPCTRL_DATATOGGLE;
- buf += size;
- actlen += size;
- }
- }
- xfer->actlen = actlen;
-
- /* ACK (status) */
- if (pid == SL11_PID_IN)
- pid = SL11_PID_OUT;
- else
- pid = SL11_PID_IN;
- if (slhci_transaction(sc, pipe, pid, 0, NULL, toggle) == -1)
- status = USBD_IOERROR;
-
- ret:
- xfer->status = status;
-
-#ifdef SLHCI_DEBUG
- if((slhci_debug & D_TRACE) && UGETW(req->wLength) > 0){
- int i;
- for(i=0; i < UGETW(req->wLength); i++)
- printf("%02x", ((unsigned char *)xfer->buffer)[i]);
- printf(" ");
- }
-#endif
- s = splusb();
- usb_transfer_complete(xfer);
- splx(s);
- return USBD_IN_PROGRESS;
-}
-
-static void
-slhci_device_ctrl_abort(usbd_xfer_handle xfer)
-{
- DPRINTF(D_TRACE, ("Cab "));
- slhci_abort_xfer(xfer, USBD_CANCELLED);
-}
-
-static void
-slhci_device_ctrl_close(usbd_pipe_handle pipe)
-{
- DPRINTF(D_TRACE, ("Ccl "));
-}
-
-static void
-slhci_device_ctrl_done(usbd_xfer_handle xfer)
-{
- DPRINTF(D_TRACE, ("Cdn "));
-}
-
-static usbd_status
-slhci_device_intr_transfer(usbd_xfer_handle xfer)
-{
- usbd_status error;
-
- DPRINTF(D_TRACE, ("INTRtrans "));
-
- error = usb_insert_transfer(xfer);
- if (error)
- return error;
-
- return slhci_device_intr_start(STAILQ_FIRST(&xfer->pipe->queue));
-}
-
-static usbd_status
-slhci_device_intr_start(usbd_xfer_handle xfer)
-{
- usbd_pipe_handle pipe = xfer->pipe;
- struct slhci_xfer *sx;
-
- DPRINTF(D_TRACE, ("INTRstart "));
-
- sx = malloc(sizeof(*sx), M_USB, M_NOWAIT);
- if (sx == NULL)
- goto reterr;
- memset(sx, 0, sizeof(*sx));
- sx->sx_xfer = xfer;
- xfer->hcpriv = sx;
-
- /* initialize callout */
- usb_callout_init(sx->sx_callout_t);
- usb_callout(sx->sx_callout_t,
- MS_TO_TICKS(pipe->endpoint->edesc->bInterval),
- slhci_poll_device, sx);
-
- /* ACK */
- return USBD_IN_PROGRESS;
-
- reterr:
- return USBD_IOERROR;
-}
-
-static void
-slhci_poll_device(void *arg)
-{
- struct slhci_xfer *sx = (struct slhci_xfer *)arg;
- usbd_xfer_handle xfer = sx->sx_xfer;
- usbd_pipe_handle pipe = xfer->pipe;
- struct slhci_softc *sc = (struct slhci_softc *)pipe->device->bus;
- void *buf;
- int pid;
- int r;
- int s;
-
- DPRINTF(D_TRACE, ("pldev"));
-
- usb_callout(sx->sx_callout_t,
- MS_TO_TICKS(pipe->endpoint->edesc->bInterval),
- slhci_poll_device, sx);
-
- /* interrupt transfer */
- pid = (UE_GET_DIR(pipe->endpoint->edesc->bEndpointAddress) == UE_DIR_IN)
- ? SL11_PID_IN : SL11_PID_OUT;
- buf = xfer->buffer;
-
- r = slhci_transaction(sc, pipe, pid, xfer->length, buf, 0/*toggle*/);
- if (r < 0) {
- DPRINTF(D_MSG, ("%s error", __FUNCTION__));
- return;
- }
- /* no change, return NAK */
- if (r == 0)
- return;
-
- xfer->status = USBD_NORMAL_COMPLETION;
- s = splusb();
- xfer->device->bus->intr_context++;
- usb_transfer_complete(xfer);
- xfer->device->bus->intr_context--;
- splx(s);
-}
-
-static void
-slhci_device_intr_abort(usbd_xfer_handle xfer)
-{
- struct slhci_xfer *sx;
-
- DPRINTF(D_TRACE, ("INTRabort "));
-
- sx = xfer->hcpriv;
- if (sx) {
- usb_uncallout(sx->sx_callout_t, slhci_poll_device, sx);
- free(sx, M_USB);
- xfer->hcpriv = NULL;
- } else {
- printf("%s: sx == NULL!\n", __FUNCTION__);
- }
- slhci_abort_xfer(xfer, USBD_CANCELLED);
-}
-
-static void
-slhci_device_intr_close(usbd_pipe_handle pipe)
-{
- DPRINTF(D_TRACE, ("INTRclose "));
-}
-
-static void
-slhci_device_intr_done(usbd_xfer_handle xfer)
-{
- DPRINTF(D_TRACE, ("INTRdone "));
-}
-
-static usbd_status
-slhci_device_isoc_transfer(usbd_xfer_handle xfer)
-{
- DPRINTF(D_TRACE, ("S"));
- return USBD_NORMAL_COMPLETION;
-}
-
-static usbd_status
-slhci_device_isoc_start(usbd_xfer_handle xfer)
-{
- DPRINTF(D_TRACE, ("st "));
- return USBD_NORMAL_COMPLETION;
-}
-
-static void
-slhci_device_isoc_abort(usbd_xfer_handle xfer)
-{
- DPRINTF(D_TRACE, ("Sab "));
-}
-
-static void
-slhci_device_isoc_close(usbd_pipe_handle pipe)
-{
- DPRINTF(D_TRACE, ("Scl "));
-}
-
-static void
-slhci_device_isoc_done(usbd_xfer_handle xfer)
-{
- DPRINTF(D_TRACE, ("Sdn "));
-}
-
-static usbd_status
-slhci_device_bulk_transfer(usbd_xfer_handle xfer)
-{
- DPRINTF(D_TRACE, ("B"));
- return USBD_NORMAL_COMPLETION;
-}
-
-static usbd_status
-slhci_device_bulk_start(usbd_xfer_handle xfer)
-{
- DPRINTF(D_TRACE, ("st "));
- return USBD_NORMAL_COMPLETION;
-}
-
-static void
-slhci_device_bulk_abort(usbd_xfer_handle xfer)
-{
- DPRINTF(D_TRACE, ("Bab "));
-}
-
-static void
-slhci_device_bulk_close(usbd_pipe_handle pipe)
-{
- DPRINTF(D_TRACE, ("Bcl "));
-}
-
-static void
-slhci_device_bulk_done(usbd_xfer_handle xfer)
-{
- DPRINTF(D_TRACE, ("Bdn "));
-}
-
-#define DATA0_RD (0x03)
-#define DATA0_WR (0x07)
-#define SLHCI_TIMEOUT (5000)
-
-/*
- * Do a transaction.
- * return 1 if ACK, 0 if NAK, -1 if error.
- */
-static int
-slhci_transaction(struct slhci_softc *sc, usbd_pipe_handle pipe,
- u_int8_t pid, int len, u_char *buf, u_int8_t toggle)
-{
-#ifdef SLHCI_DEBUG
- char str[64];
- int i;
-#endif
- int timeout;
- int ls_via_hub = 0;
- int pl;
- u_int8_t isr;
- u_int8_t result = 0;
- u_int8_t devaddr = pipe->device->address;
- u_int8_t endpointaddr = pipe->endpoint->edesc->bEndpointAddress;
- u_int8_t endpoint;
- u_int8_t cmd = DATA0_RD;
-
- endpoint = UE_GET_ADDR(endpointaddr);
- DPRINTF(D_XFER, ("\n(%x,%d%s%d,%d) ",
- pid, len, (pid == SL11_PID_IN) ? "<-" : "->", devaddr, endpoint));
-
- /* Set registers */
- sl11write(sc, SL11_E0ADDR, 0x40);
- sl11write(sc, SL11_E0LEN, len);
- sl11write(sc, SL11_E0PID, (pid << 4) + endpoint);
- sl11write(sc, SL11_E0DEV, devaddr);
-
- /* Set buffer unless PID_IN */
- if (pid != SL11_PID_IN) {
- if (len > 0)
- sl11write_region(sc, 0x40, buf, len);
- cmd = DATA0_WR;
- }
-
- /* timing ? */
- pl = (len >> 3) + 3;
-
- /* Low speed device via HUB */
- /* XXX does not work... */
- if ((sc->sc_fullspeed) && pipe->device->speed == USB_SPEED_LOW) {
- pl = len + 16;
- cmd |= SL11_EPCTRL_PREAMBLE;
-
- /*
- * SL811HS/T rev 1.2 has a bug, when it got PID_IN
- * from LowSpeed device via HUB.
- */
- if (sc->sc_sltype == SLTYPE_SL811HS_R12 && pid == SL11_PID_IN) {
- ls_via_hub = 1;
- DPRINTF(D_MSG, ("LSvH "));
- }
- }
-
- /* timing ? */
- if (sl11read(sc, SL811_CSOF) <= (u_int8_t)pl)
- cmd |= SL11_EPCTRL_SOF;
-
- /* Transfer */
- sl11write(sc, SL11_ISR, 0xff);
- sl11write(sc, SL11_E0CTRL, cmd | toggle);
-
- /* Polling */
- for (timeout = SLHCI_TIMEOUT; timeout; timeout--) {
- isr = sl11read(sc, SL11_ISR);
- if ((isr & SL11_ISR_USBA))
- break;
- }
-
- /* Check result status */
- result = sl11read(sc, SL11_E0STAT);
- if (!(result & SL11_EPSTAT_NAK) && ls_via_hub) {
- /* Resend PID_IN within 20usec */
- sl11write(sc, SL11_ISR, 0xff);
- sl11write(sc, SL11_E0CTRL, SL11_EPCTRL_ARM);
- }
-
- sl11write(sc, SL11_ISR, 0xff);
-
- DPRINTF(D_XFER, ("t=%d i=%x ", SLHCI_TIMEOUT - timeout, isr));
-#ifdef SLHCI_DEBUG
- bitmask_snprintf(result,
- "\20\x8STALL\7NAK\6OV\5SETUP\4DATA1\3TIMEOUT\2ERR\1ACK",
- str, sizeof(str));
- DPRINTF(D_XFER, ("STAT=%s ", str));
-#endif
-
- if ((result & SL11_EPSTAT_ERROR))
- return -1;
-
- if ((result & SL11_EPSTAT_NAK))
- return 0;
-
- /* Read buffer if PID_IN */
- if (pid == SL11_PID_IN && len > 0) {
- sl11read_region(sc, buf, 0x40, len);
-#ifdef SLHCI_DEBUG
- for (i = 0; i < len; i++)
- DPRINTF(D_XFER, ("%02X ", buf[i]));
-#endif
- }
-
- return 1;
-}
-
-void
-slhci_abort_xfer(usbd_xfer_handle xfer, usbd_status status)
-{
- xfer->status = status;
- usb_transfer_complete(xfer);
-}
-
-void
-slhci_device_clear_toggle(usbd_pipe_handle pipe)
-{
- DPRINTF(D_TRACE, ("SLdevice_clear_toggle "));
-}
-
-#ifdef SLHCI_DEBUG
-void
-print_req(usb_device_request_t *r)
-{
- char *xmes[]={
- "GETSTAT",
- "CLRFEAT",
- "res",
- "SETFEAT",
- "res",
- "SETADDR",
- "GETDESC",
- "SETDESC",
- "GETCONF",
- "SETCONF",
- "GETIN/F",
- "SETIN/F",
- "SYNC_FR"
- };
- int req, type, value, index, len;
-
- req = r->bRequest;
- type = r->bmRequestType;
- value = UGETW(r->wValue);
- index = UGETW(r->wIndex);
- len = UGETW(r->wLength);
-
- printf("%x,%s,v=%d,i=%d,l=%d ",
- type, xmes[req], value, index, len);
-}
-
-void
-print_req_hub(usb_device_request_t *r)
-{
- struct {
- int req;
- int type;
- char *str;
- } conf[] = {
- { 1, 0x20, "ClrHubFeat" },
- { 1, 0x23, "ClrPortFeat" },
- { 2, 0xa3, "GetBusState" },
- { 6, 0xa0, "GetHubDesc" },
- { 0, 0xa0, "GetHubStat" },
- { 0, 0xa3, "GetPortStat" },
- { 7, 0x20, "SetHubDesc" },
- { 3, 0x20, "SetHubFeat" },
- { 3, 0x23, "SetPortFeat" },
- {-1, 0, NULL},
- };
- int i;
- int value, index, len;
-
- value = UGETW(r->wValue);
- index = UGETW(r->wIndex);
- len = UGETW(r->wLength);
- for (i = 0; ; i++) {
- if (conf[i].req == -1 )
- return print_req(r);
- if (r->bmRequestType == conf[i].type && r->bRequest == conf[i].req) {
- printf("%s", conf[i].str);
- break;
- }
- }
- printf(",v=%d,i=%d,l=%d ", value, index, len);
-}
-
-void
-print_dumpreg(struct slhci_softc *sc)
-{
- printf("00=%02x,01=%02x,02=%02x,03=%02x,04=%02x,"
- "08=%02x,09=%02x,0A=%02x,0B=%02x,0C=%02x,",
- sl11read(sc, 0), sl11read(sc, 1),
- sl11read(sc, 2), sl11read(sc, 3),
- sl11read(sc, 4), sl11read(sc, 8),
- sl11read(sc, 9), sl11read(sc, 10),
- sl11read(sc, 11), sl11read(sc, 12)
- );
- printf("CR1=%02x,IER=%02x,0D=%02x,0E=%02x,0F=%02x ",
- sl11read(sc, 5), sl11read(sc, 6),
- sl11read(sc, 13), sl11read(sc, 14), sl11read(sc, 15)
- );
-}
-
-void
-print_xfer(usbd_xfer_handle xfer)
-{
- printf("xfer: length=%d, actlen=%d, flags=%x, timeout=%d,",
- xfer->length, xfer->actlen, xfer->flags, xfer->timeout);
- printf("request{ ");
- print_req_hub(&xfer->request);
- printf("} ");
-}
-#endif /* SLHCI_DEBUG */
diff --git a/sys/dev/usb/sl811hsreg.h b/sys/dev/usb/sl811hsreg.h
deleted file mode 100644
index f9c0328..0000000
--- a/sys/dev/usb/sl811hsreg.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/* $NetBSD$ */
-/* $FreeBSD$ */
-
-
-/*
- * Copyright (c) 2001 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Tetsuya Isaki.
- *
- * 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.
- */
-
-/*
- * ScanLogic SL811HS/T USB Host Controller
- */
-
-#define SL11_IDX_ADDR (0x00)
-#define SL11_IDX_DATA (0x01)
-#define SL11_PORTSIZE (0x02)
-
-#define SL11_E0BASE (0x00) /* Base of Control0 */
-#define SL11_E0CTRL (0x00) /* Host Control Register */
-#define SL11_E0ADDR (0x01) /* Host Base Address */
-#define SL11_E0LEN (0x02) /* Host Base Length */
-#define SL11_E0STAT (0x03) /* USB Status (Read) */
-#define SL11_E0PID SL11_E0STAT /* Host PID, Device Endpoint (Write) */
-#define SL11_E0CONT (0x04) /* Transfer Count (Read) */
-#define SL11_E0DEV SL11_E0CONT /* Host Device Address (Write) */
-
-#define SL11_E1BASE (0x08) /* Base of Control1 */
-#define SL11_E1CTRL (SL11_E1BASE + SL11_E0CTRL)
-#define SL11_E1ADDR (SL11_E1BASE + SL11_E0ADDR)
-#define SL11_E1LEN (SL11_E1BASE + SL11_E0LEN)
-#define SL11_E1STAT (SL11_E1BASE + SL11_E0STAT)
-#define SL11_E1PID (SL11_E1BASE + SL11_E0PID)
-#define SL11_E1CONT (SL11_E1BASE + SL11_E0CONT)
-#define SL11_E1DEV (SL11_E1BASE + SL11_E0DEV)
-
-#define SL11_CTRL (0x05) /* Control Register1 */
-#define SL11_IER (0x06) /* Interrupt Enable Register */
-#define SL11_ISR (0x0d) /* Interrupt Status Register */
-#define SL11_DATA (0x0e) /* SOF Counter Low (Write) */
-#define SL11_REV SL11_DATA /* HW Revision Register (Read) */
-#define SL811_CSOF (0x0f) /* SOF Counter High(R), Control2(W) */
-#define SL11_MEM (0x10) /* Memory Buffer (0x10 - 0xff) */
-
-#define SL11_EPCTRL_ARM (0x01)
-#define SL11_EPCTRL_ENABLE (0x02)
-#define SL11_EPCTRL_DIRECTION (0x04)
-#define SL11_EPCTRL_ISO (0x10)
-#define SL11_EPCTRL_SOF (0x20)
-#define SL11_EPCTRL_DATATOGGLE (0x40)
-#define SL11_EPCTRL_PREAMBLE (0x80)
-
-#define SL11_EPPID_PIDMASK (0xf0)
-#define SL11_EPPID_EPMASK (0x0f)
-
-#define SL11_EPSTAT_ACK (0x01)
-#define SL11_EPSTAT_ERROR (0x02)
-#define SL11_EPSTAT_TIMEOUT (0x04)
-#define SL11_EPSTAT_SEQUENCE (0x08)
-#define SL11_EPSTAT_SETUP (0x10)
-#define SL11_EPSTAT_OVERFLOW (0x20)
-#define SL11_EPSTAT_NAK (0x40)
-#define SL11_EPSTAT_STALL (0x80)
-
-#define SL11_CTRL_ENABLESOF (0x01)
-#define SL11_CTRL_EOF2 (0x04)
-#define SL11_CTRL_RESETENGINE (0x08)
-#define SL11_CTRL_JKSTATE (0x10)
-#define SL11_CTRL_LOWSPEED (0x20)
-#define SL11_CTRL_SUSPEND (0x40)
-
-#define SL11_IER_USBA (0x01) /* USB-A done */
-#define SL11_IER_USBB (0x02) /* USB-B done */
-#define SL11_IER_BABBLE (0x04) /* Babble detection */
-#define SL11_IER_SOFTIMER (0x10) /* 1ms SOF timer */
-#define SL11_IER_INSERT (0x20) /* Slave Insert/Remove detection */
-#define SL11_IER_RESET (0x40) /* USB Reset/Resume */
-
-#define SL11_ISR_USBA (0x01) /* USB-A done */
-#define SL11_ISR_USBB (0x02) /* USB-B done */
-#define SL11_ISR_BABBLE (0x04) /* Babble detection */
-#define SL11_ISR_SOFTIMER (0x10) /* 1ms SOF timer */
-#define SL11_ISR_INSERT (0x20) /* Slave Insert/Remove detection */
-#define SL11_ISR_RESET (0x40) /* USB Reset/Resume */
-#define SL11_ISR_DATA (0x80) /* Value of the Data+ pin */
-
-#define SL11_REV_USBA (0x01) /* USB-A */
-#define SL11_REV_USBB (0x02) /* USB-B */
-#define SL11_REV_REVMASK (0xf0) /* HW Revision */
-#define SL11_REV_REVSL11H (0x00) /* HW is SL11H */
-#define SL11_REV_REVSL811HS (0x10) /* HW is SL811HS */
-
-#define SL811_CSOF_SOFMASK (0x3f) /* SOF High Counter */
-#define SL811_CSOF_POLARITY (0x40) /* Change polarity */
-#define SL811_CSOF_MASTER (0x80) /* Master/Slave selection */
-
diff --git a/sys/dev/usb/sl811hsvar.h b/sys/dev/usb/sl811hsvar.h
deleted file mode 100644
index 6f5e6d6..0000000
--- a/sys/dev/usb/sl811hsvar.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/* $NetBSD$ */
-/* $FreeBSD$ */
-
-/*
- * Copyright (c) 2001 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Tetsuya Isaki.
- *
- * 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.
- */
-
-/*
- * ScanLogic SL811HS/T USB Host Controller
- */
-
-#define MS_TO_TICKS(ms) ((ms) * hz / 1000)
-#define delay_ms(X) \
- pause("slhci", MS_TO_TICKS(X))
-
-#define SL11_PID_OUT (0x1)
-#define SL11_PID_IN (0x9)
-#define SL11_PID_SOF (0x5)
-#define SL11_PID_SETUP (0xd)
-
-struct slhci_xfer {
- usbd_xfer_handle sx_xfer;
- usb_callout_t sx_callout_t;
-};
-
-struct slhci_softc {
- struct usbd_bus sc_bus;
- bus_space_tag_t sc_iot;
- bus_space_handle_t sc_ioh;
-
-#ifdef __FreeBSD__
- void *ih;
- struct resource *io_res;
- struct resource *irq_res;
-#endif
-
- void (*sc_enable_power)(void *, int);
- void (*sc_enable_intr)(void *, int);
- void *sc_arg;
- int sc_powerstat;
-#define POWER_ON (1)
-#define POWER_OFF (0)
-#define INTR_ON (1)
-#define INTR_OFF (0)
-
- struct device *sc_parent; /* parent device */
- int sc_sltype; /* revision */
-#define SLTYPE_SL11H (0x00)
-#define SLTYPE_SL811HS (0x01)
-#define SLTYPE_SL811HS_R12 SLTYPE_SL811HS
-#define SLTYPE_SL811HS_R14 (0x02)
-
- u_int8_t sc_addr; /* device address of root hub */
- u_int8_t sc_conf;
- STAILQ_HEAD(, usbd_xfer) sc_free_xfers;
-
- /* Information for the root hub interrupt pipe */
- int sc_interval;
- usbd_xfer_handle sc_intr_xfer;
- usb_callout_t sc_poll_handle;
-
- int sc_flags;
-#define SLF_RESET (0x01)
-#define SLF_INSERT (0x02)
-#define SLF_ATTACHED (0x04)
-
- /* Root HUB specific members */
- int sc_fullspeed;
- int sc_connect; /* XXX */
- int sc_change;
-};
-
-int sl811hs_find(struct slhci_softc *);
-int slhci_attach(struct slhci_softc *);
-int slhci_intr(void *);
diff --git a/sys/dev/usb/slhci_pccard.c b/sys/dev/usb/slhci_pccard.c
deleted file mode 100644
index 794b81d..0000000
--- a/sys/dev/usb/slhci_pccard.c
+++ /dev/null
@@ -1,206 +0,0 @@
-/*-
- * Copyright (C) 2005 Takanori Watanabe. 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.
- *
- * THIS SOFTWARE IS PROVIDED BY AUTHOR 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 AUTHOR 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.
- *
- */
-
-
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/malloc.h>
-#include <sys/sema.h>
-#include <sys/taskqueue.h>
-#include <vm/uma.h>
-#include <machine/stdarg.h>
-#include <machine/resource.h>
-#include <machine/bus.h>
-#include <sys/rman.h>
-#include <dev/pccard/pccard_cis.h>
-#include <dev/pccard/pccardreg.h>
-#include <dev/pccard/pccardvar.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdivar.h>
-#include <dev/usb/usb_mem.h>
-#include <dev/usb/usb_port.h>
-#include <dev/usb/sl811hsvar.h>
-#include "pccarddevs.h"
-
-__FBSDID("$FreeBSD$");
-
-static void slhci_pccard_intr(void *arg);
-
-static const struct pccard_product slhci_pccard_products[] = {
- PCMCIA_CARD(RATOC, REX_CFU1),
- {NULL}
-};
-
-static int
-slhci_pccard_probe(device_t dev)
-{
- const struct pccard_product *pp;
- u_int32_t fcn = PCCARD_FUNCTION_UNSPEC;
- int error = 0;
-
- if ((error = pccard_get_function(dev, &fcn)))
- return error;
-
- /* if it says its a disk we should register it */
- if (fcn == PCCARD_FUNCTION_DISK)
- return 0;
-
- /* match other devices here, primarily cdrom/dvd rom */
- if ((pp = pccard_product_lookup(dev, slhci_pccard_products,
- sizeof(slhci_pccard_products[0]), NULL))) {
- if (pp->pp_name)
- device_set_desc(dev, pp->pp_name);
- return 0;
- }
- return ENXIO;
-}
-
-static int
-slhci_pccard_detach(device_t dev)
-{
- struct slhci_softc *sc = device_get_softc(dev);
- bus_generic_detach(dev);
-
- if (sc->ih)
- bus_teardown_intr(dev, sc->irq_res, sc->ih);
- if (sc->io_res)
- bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->io_res);
- if (sc->irq_res)
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res);
- if (sc->sc_bus.bdev)
- device_delete_child(dev, sc->sc_bus.bdev);
- return 0;
-}
-
-static int
-slhci_pccard_attach(device_t dev)
-{
- struct slhci_softc *sc = device_get_softc(dev);
- int error = ENXIO;
- int rid = 0;
- if ((sc->io_res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE)) == NULL) {
- return ENOMEM;
- }
- sc->sc_iot = rman_get_bustag(sc->io_res);
- sc->sc_ioh = rman_get_bushandle(sc->io_res);
-
- if (sl811hs_find(sc) == -1) {
- error = ENXIO;
- goto out;
- }
-
- rid = 0;
- if ((sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_SHAREABLE | RF_ACTIVE)) == NULL) {
- printf("CANNOT ALLOC IRQ\n");
- error = ENOMEM;
- goto out;
- }
- sc->sc_iot = rman_get_bustag(sc->io_res);
- sc->sc_ioh = rman_get_bushandle(sc->io_res);
- sc->sc_bus.bdev = device_add_child(dev, "usb", -1);
- if (!sc->sc_bus.bdev) {
- device_printf(dev, "Could not add USB device\n");
- }
- device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
- error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_BIO, NULL, slhci_pccard_intr, sc, &sc->ih);
- if (error)
- goto out;
-#if 1
-
- if (slhci_attach(sc) == -1) {
- printf("MI attach NO\n");
- goto out;
- }
-
- error = device_probe_and_attach(sc->sc_bus.bdev);
-
- if (error) {
- printf("Probing USB bus %x\n", error);
- goto out;
- }
-#endif
- printf("ATTACHED\n");
- return 0;
-out:
- slhci_pccard_detach(dev);
- return error;
-}
-
-#if 0
-static void
-slhci_pccard_enable_power(void *arg, int mode)
-{
-#if 0
- struct slhci_softc *sc = arg;
- u_int8_t r;
-#endif
-}
-
-static void
-slhci_pccard_enable_intr(void *arg, int mode)
-{
-#if 0
- struct slhci_softc *sc = arg;
- u_int8_t r;
-#endif
-}
-
-#endif
-static void
-slhci_pccard_intr(void *arg)
-{
-#if 1
- struct slhci_softc *sc = arg;
- sc = sc;
- slhci_intr(sc);
-#endif
-}
-
-static device_method_t slhci_pccard_methods[] = {
- /* device interface */
- DEVMETHOD(device_probe, slhci_pccard_probe),
- DEVMETHOD(device_attach, slhci_pccard_attach),
- DEVMETHOD(device_detach, slhci_pccard_detach),
-
- {0, 0}
-};
-
-static driver_t slhci_pccard_driver = {
- "slhci",
- slhci_pccard_methods,
- sizeof(struct slhci_softc),
-};
-
-devclass_t slhci_devclass;
-
-DRIVER_MODULE(slhci, pccard, slhci_pccard_driver, slhci_devclass, 0, 0);
-MODULE_DEPEND(slhci, usb, 1, 1, 1);
diff --git a/sys/dev/usb/u3g.c b/sys/dev/usb/u3g.c
deleted file mode 100644
index 8c6f67e..0000000
--- a/sys/dev/usb/u3g.c
+++ /dev/null
@@ -1,799 +0,0 @@
-/*
- * Copyright (c) 2008 AnyWi Technologies
- * Author: Andrea Guzzo <aguzzo@anywi.com>
- * * based on uark.c 1.1 2006/08/14 08:30:22 jsg *
- * * parts from ubsa.c 183348 2008-09-25 12:00:56Z phk *
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * $FreeBSD$
- */
-
-/*
- * Notes:
- * - The detour through the tty layer is ridiculously expensive wrt buffering
- * due to the high speeds.
- * We should consider adding a simple r/w device which allows attaching of PPP
- * in a more efficient way.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/ioccom.h>
-#include <sys/fcntl.h>
-#include <sys/conf.h>
-#include <sys/tty.h>
-#include <sys/file.h>
-#include <sys/selinfo.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-
-#include <dev/usb/ucomvar.h>
-
-#if __FreeBSD_version >= 800000
-#include "opt_u3g.h"
-#endif
-#include "usbdevs.h"
-
-//#define U3G_DEBUG
-#ifdef U3G_DEBUG
-#define DPRINTF(x...) do { if (u3gdebug) device_printf(sc->sc_dev, ##x); } while (0)
-int u3gdebug = 1;
-#else
-#define DPRINTF(x...) /* nop */
-#endif
-
-#define U3G_MAXPORTS 4
-#define U3G_CONFIG_INDEX 0
-
-struct u3g_softc {
- struct ucom_softc sc_ucom[U3G_MAXPORTS];
- device_t sc_dev;
- usbd_device_handle sc_udev;
- u_int8_t sc_speed;
- u_int8_t sc_flags;
- u_char sc_numports;
-};
-
-static int u3g_open(void *addr, int portno);
-static void u3g_close(void *addr, int portno);
-
-struct ucom_callback u3g_callback = {
- NULL,
- NULL,
- NULL,
- NULL,
- u3g_open,
- u3g_close,
- NULL,
- NULL,
-};
-
-
-struct u3g_speeds_s {
- u_int32_t ispeed;
- u_int32_t ospeed;
-};
-
-static const struct u3g_speeds_s u3g_speeds[] = {
-#define U3GSP_GPRS 0
- {64000, 64000},
-#define U3GSP_EDGE 1
- {384000, 64000},
-#define U3GSP_CDMA 2
- {384000, 64000},
-#define U3GSP_UMTS 3
- {384000, 64000},
-#define U3GSP_HSDPA 4
- {1200000, 384000},
-#define U3GSP_HSUPA 5
- {1200000, 384000},
-#define U3GSP_HSPA 6
- {7200000, 384000},
-};
-
-#define U3GIBUFSIZE 1024
-#define U3GOBUFSIZE 1024
-
-/*
- * Various supported device vendors/products.
- */
-struct u3g_dev_type_s {
- struct usb_devno devno;
- u_int8_t speed;
- u_int8_t flags;
-#define U3GFL_NONE 0x00
-#define U3GFL_HUAWEI_INIT 0x01 // Requires init command (Huawei cards)
-#define U3GFL_SCSI_EJECT 0x02 // Requires SCSI eject command (Novatel)
-#define U3GFL_SIERRA_INIT 0x04 // Requires init command (Sierra cards)
-#define U3GFL_CMOTECH_INIT 0x08 // Requires init command (CMOTECH cards)
-#define U3GFL_STUB_WAIT 0x80 // Device reappears after a short delay
-};
-
-// Note: The entries marked with XXX should be checked for the correct speed
-// indication to set the buffer sizes.
-static const struct u3g_dev_type_s u3g_devs[] = {
- /* OEM: Option */
- {{ USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GT3G }, U3GSP_UMTS, U3GFL_NONE },
- {{ USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GT3GQUAD }, U3GSP_UMTS, U3GFL_NONE },
- {{ USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GT3GPLUS }, U3GSP_UMTS, U3GFL_NONE },
- {{ USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GTMAX36 }, U3GSP_HSDPA, U3GFL_NONE },
- {{ USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GTMAXHSUPA }, U3GSP_HSDPA, U3GFL_NONE },
- {{ USB_VENDOR_OPTION, USB_PRODUCT_OPTION_VODAFONEMC3G }, U3GSP_UMTS, U3GFL_NONE },
- /* OEM: Qualcomm, Inc. */
- {{ USB_VENDOR_QUALCOMMINC, USB_PRODUCT_QUALCOMMINC_ZTE_STOR }, U3GSP_CDMA, U3GFL_SCSI_EJECT },
- {{ USB_VENDOR_QUALCOMMINC, USB_PRODUCT_QUALCOMMINC_CDMA_MSM }, U3GSP_CDMA, U3GFL_SCSI_EJECT },
- /* OEM: Huawei */
- {{ USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_MOBILE }, U3GSP_HSDPA, U3GFL_HUAWEI_INIT },
- {{ USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E220 }, U3GSP_HSPA, U3GFL_HUAWEI_INIT },
- /* OEM: Novatel */
- {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_CDMA_MODEM }, U3GSP_CDMA, U3GFL_SCSI_EJECT },
- {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_ES620 }, U3GSP_UMTS, U3GFL_SCSI_EJECT }, // XXX
- {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_MC950D }, U3GSP_HSUPA, U3GFL_SCSI_EJECT },
- {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U720 }, U3GSP_UMTS, U3GFL_SCSI_EJECT }, // XXX
- {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U727 }, U3GSP_UMTS, U3GFL_SCSI_EJECT }, // XXX
- {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U740 }, U3GSP_HSDPA, U3GFL_SCSI_EJECT },
- {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U740_2 }, U3GSP_HSDPA, U3GFL_SCSI_EJECT },
- {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U870 }, U3GSP_UMTS, U3GFL_SCSI_EJECT }, // XXX
- {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_V620 }, U3GSP_UMTS, U3GFL_SCSI_EJECT }, // XXX
- {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_V640 }, U3GSP_UMTS, U3GFL_SCSI_EJECT }, // XXX
- {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_V720 }, U3GSP_UMTS, U3GFL_SCSI_EJECT }, // XXX
- {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_V740 }, U3GSP_HSDPA, U3GFL_SCSI_EJECT },
- {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_X950D }, U3GSP_HSUPA, U3GFL_SCSI_EJECT },
- {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_XU870 }, U3GSP_HSDPA, U3GFL_SCSI_EJECT },
- {{ USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_ZEROCD }, U3GSP_HSUPA, U3GFL_SCSI_EJECT },
- {{ USB_VENDOR_DELL, USB_PRODUCT_DELL_U740 }, U3GSP_HSDPA, U3GFL_SCSI_EJECT },
- /* OEM: Merlin */
- {{ USB_VENDOR_MERLIN, USB_PRODUCT_MERLIN_V620 }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- /* OEM: Sierra Wireless: */
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD580 }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD595 }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC595U }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC597E }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_C597 }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC880 }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC880E }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC880U }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC881 }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC881E }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC881U }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_EM5625 }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5720 }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5720_2 }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5725 }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MINI5725 }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD875 }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8755 }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8755_2 }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8755_3 }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8765 }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC875U }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8775_2 }, U3GSP_HSDPA, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8780 }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8781 }, U3GSP_UMTS, U3GFL_NONE }, // XXX
- {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_TRUINSTALL }, U3GSP_UMTS, U3GFL_SIERRA_INIT },
- {{ USB_VENDOR_HP, USB_PRODUCT_HP_HS2300 }, U3GSP_HSDPA, U3GFL_NONE },
- /* OEM: CMOTECH */
- {{ USB_VENDOR_CMOTECH, USB_PRODUCT_CMOTECH_CGU628 }, U3GSP_HSDPA, U3GFL_CMOTECH_INIT },
- {{ USB_VENDOR_CMOTECH, USB_PRODUCT_CMOTECH_DISK }, U3GSP_HSDPA, U3GFL_NONE },
-};
-#define u3g_lookup(v, p) ((const struct u3g_dev_type_s *)usb_lookup(u3g_devs, v, p))
-
-static int
-u3g_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
- const struct u3g_dev_type_s *u3g_dev_type;
-
- if (!uaa->iface)
- return UMATCH_NONE;
-
- u3g_dev_type = u3g_lookup(uaa->vendor, uaa->product);
- if (!u3g_dev_type)
- return UMATCH_NONE;
-
- if (u3g_dev_type->flags&U3GFL_HUAWEI_INIT) {
- /* If the interface class of the first interface is no longer
- * mass storage the card has changed to modem (see u3g_attach()
- * below).
- */
- usb_interface_descriptor_t *id;
- id = usbd_get_interface_descriptor(uaa->iface);
- if (!id || id->bInterfaceClass == UICLASS_MASS)
- return UMATCH_NONE;
- }
-
- return UMATCH_VENDOR_PRODUCT_CONF_IFACE;
-}
-
-static int
-u3g_attach(device_t self)
-{
- struct u3g_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- const struct u3g_dev_type_s *u3g_dev_type;
- usbd_device_handle dev = uaa->device;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
- int i, n;
- usb_config_descriptor_t *cd;
- char devnamefmt[32];
-
-#if __FreeBSD_version < 700000
- char *devinfo = malloc(1024, M_USBDEV, M_WAITOK);
- usbd_devinfo(dev, 0, devinfo);
- device_printf(self, "%s\n", devinfo);
- free(devinfo, M_USBDEV);
-#endif
-
- /* get the config descriptor */
- cd = usbd_get_config_descriptor(dev);
- if (cd == NULL) {
- device_printf(self, "failed to get configuration descriptor\n");
- return ENXIO;
- }
-
- sc->sc_dev = self;
- sc->sc_udev = dev;
-
- u3g_dev_type = u3g_lookup(uaa->vendor, uaa->product);
- sc->sc_flags = u3g_dev_type->flags;
- sc->sc_speed = u3g_dev_type->speed;
-
- sprintf(devnamefmt,"U%d.%%d", device_get_unit(self));
- int portno = 0;
- for (i = 0; i < uaa->nifaces && portno < U3G_MAXPORTS; i++) {
- if (uaa->ifaces[i] == NULL)
- continue;
-
- id = usbd_get_interface_descriptor(uaa->ifaces[i]);
- if (id && id->bInterfaceClass == UICLASS_MASS) {
- /* We attach to the interface instead of the device as
- * some devices have a built-in SD card reader.
- * Claim the first umass device (cdX) as it contains
- * only Windows drivers anyway (CD-ROM), hiding it.
- */
-#ifndef U3G_DEBUG
- if (!bootverbose)
- if (uaa->vendor == USB_VENDOR_HUAWEI)
- if (id->bInterfaceNumber == 2)
- uaa->ifaces[i] = NULL;
-#endif
- continue;
- }
-
- int bulkin_no = -1, bulkout_no = -1;
- int claim_iface = 0;
- for (n = 0; n < id->bNumEndpoints && portno < U3G_MAXPORTS; n++) {
- ed = usbd_interface2endpoint_descriptor(uaa->ifaces[i], n);
- if (ed == NULL)
- continue;
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN
- && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
- bulkin_no = ed->bEndpointAddress;
- else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT
- && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
- bulkout_no = ed->bEndpointAddress;
-
- /* If we have found a pair of bulk-in/-out endpoints
- * create a serial port for it. Note: We assume that
- * the bulk-in and bulk-out endpoints appear in pairs.
- */
- if (bulkin_no != -1 && bulkout_no != -1) {
- struct ucom_softc *ucom = &sc->sc_ucom[portno];
-
- ucom->sc_dev = self;
- ucom->sc_udev = dev;
- ucom->sc_iface = uaa->ifaces[i];
- ucom->sc_bulkin_no = bulkin_no;
- ucom->sc_bulkout_no = bulkout_no;
- ucom->sc_ibufsize = U3GIBUFSIZE;
- ucom->sc_ibufsizepad = U3GIBUFSIZE;
- ucom->sc_obufsize = U3GOBUFSIZE;
- ucom->sc_opkthdrlen = 0;
-
- ucom->sc_callback = &u3g_callback;
- ucom->sc_parent = sc;
- ucom->sc_portno = portno;
-
- DPRINTF("port=%d iface=%d in=0x%x out=0x%x\n",
- portno, i,
- ucom->sc_bulkin_no,
- ucom->sc_bulkout_no);
-#if __FreeBSD_version < 700000
- ucom_attach_tty(ucom, MINOR_CALLOUT, devnamefmt, portno);
-#elif __FreeBSD_version < 800000
- ucom_attach_tty(ucom, TS_CALLOUT, devnamefmt, portno);
-#else
- ucom_attach_tty(ucom, devnamefmt, portno);
-#endif
-
- claim_iface = 1;
- portno++;
- bulkin_no = bulkout_no = -1;
- }
- }
- if (claim_iface)
- uaa->ifaces[i] = NULL; // claim the interface
- }
- sc->sc_numports = portno;
-
- device_printf(self, "configured %d serial ports (%s)\n",
- sc->sc_numports, devnamefmt);
- return 0;
-}
-
-static int
-u3g_detach(device_t self)
-{
- struct u3g_softc *sc = device_get_softc(self);
- int rv = 0;
- int i;
-
- for (i = 0; i < sc->sc_numports; i++) {
- sc->sc_ucom[i].sc_dying = 1;
- rv = ucom_detach(&sc->sc_ucom[i]);
- if (rv != 0) {
- device_printf(self, "ucom_detach(U%d.%d\n", device_get_unit(self), i);
- return rv;
- }
- }
-
- return 0;
-}
-
-static int
-u3g_open(void *addr, int portno)
-{
-#if __FreeBSD_version < 800000
- /* Supply generous buffering for these cards to avoid disappointments
- * when setting the speed incorrectly. Only do this for the first port
- * assuming that the rest of the ports are used for diagnostics only
- * anyway.
- * Note: We abuse the fact that ucom sets the speed through
- * ispeed/ospeed, not through ispeedwat/ospeedwat.
- */
- if (portno == 0) {
- struct u3g_softc *sc = addr;
- struct ucom_softc *ucom = &sc->sc_ucom[portno];
- struct tty *tp = ucom->sc_tty;
-
- tp->t_ispeedwat = u3g_speeds[sc->sc_speed].ispeed;
- tp->t_ospeedwat = u3g_speeds[sc->sc_speed].ospeed;
-
- /* Avoid excessive buffer sizes.
- * XXX The values here should be checked. Lower them and see
- * whether 'lost chars' messages appear.
- */
- if (tp->t_ispeedwat > 384000)
- tp->t_ispeedwat = 384000;
- if (tp->t_ospeedwat > 384000)
- tp->t_ospeedwat = 384000;
-
- ttsetwater(tp);
- }
-#endif
-
- return 0;
-}
-
-static void
-u3g_close(void *addr, int portno)
-{
-#if __FreeBSD_version < 800000
- if (portno == 0) { /* see u3g_open() */
- /* Reduce the buffers allocated above again */
- struct u3g_softc *sc = addr;
- struct ucom_softc *ucom = &sc->sc_ucom[portno];
- struct tty *tp = ucom->sc_tty;
-#ifdef U3G_DEBUG
- device_t self = sc->sc_dev;
-#endif
-
- tp->t_ispeedwat = (speed_t)-1;
- tp->t_ospeedwat = (speed_t)-1;
-
- ttsetwater(tp);
- }
-#endif
-}
-
-static device_method_t u3g_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, u3g_match),
- DEVMETHOD(device_attach, u3g_attach),
- DEVMETHOD(device_detach, u3g_detach),
-
- { 0, 0 }
-};
-
-static driver_t u3g_driver = {
- "ucom",
- u3g_methods,
- sizeof (struct u3g_softc)
-};
-
-DRIVER_MODULE(u3g, uhub, u3g_driver, ucom_devclass, usbd_driver_load, 0);
-MODULE_DEPEND(u3g, usb, 1, 1, 1);
-MODULE_DEPEND(u3g, ucom, UCOM_MINVER, UCOM_PREFVER, UCOM_MAXVER);
-MODULE_VERSION(u3g, 1);
-
-/*******************************************************************
- ****** Stub driver to hide devices that need to reinitialise ******
- *******************************************************************/
-
-struct u3gstub_softc {
- device_t sc_dev;
- usbd_device_handle sc_udev;
- usbd_pipe_handle sc_pipe_out, sc_pipe_in;
- usbd_xfer_handle sc_xfer;
-};
-
-static int
-u3gstub_huawei_init(struct u3gstub_softc *sc, struct usb_attach_arg *uaa)
-{
- usb_device_request_t req;
-
- req.bmRequestType = UT_WRITE_DEVICE;
- req.bRequest = UR_SET_FEATURE;
- USETW(req.wValue, UF_DEVICE_REMOTE_WAKEUP);
- USETW(req.wIndex, UHF_PORT_SUSPEND);
- USETW(req.wLength, 0);
-
- (void) usbd_do_request(uaa->device, &req, 0); /* ignore any error */
-
- return 1;
-}
-
-static void
-u3gstub_BBB_cb(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status err)
-{
- struct u3gstub_softc *sc = (struct u3gstub_softc *) priv;
- unsigned char cmd[13];
-
- if (err) {
- device_printf(sc->sc_dev,
- "Failed to send CD eject command to "
- "change to modem mode\n");
- } else {
- usbd_setup_xfer(sc->sc_xfer, sc->sc_pipe_in, NULL, cmd, sizeof(cmd),
- 0, USBD_DEFAULT_TIMEOUT, NULL);
- int err = usbd_transfer(sc->sc_xfer) != USBD_NORMAL_COMPLETION;
- if (err != USBD_NORMAL_COMPLETION && err != USBD_IN_PROGRESS)
- DPRINTF("failed to start transfer (CSW)\n");
- }
-}
-
-static int
-u3gstub_scsi_eject(struct u3gstub_softc *sc, struct usb_attach_arg *uaa)
-{
- /* See definition of umass_bbb_cbw_t in sys/dev/usb/umass.c and struct
- * scsi_start_stop_unit in sys/cam/scsi/scsi_all.h .
- */
- unsigned char cmd[31] = {
- 0x55, 0x53, 0x42, 0x43, /* 0..3: Command Block Wrapper (CBW) signature */
- 0x01, 0x00, 0x00, 0x00, /* 4..7: CBW Tag, unique 32-bit number */
- 0x00, 0x00, 0x00, 0x00, /* 8..11: CBW Transfer Length, no data here */
- 0x00, /* 12: CBW Flag: output */
- 0x00, /* 13: CBW Lun */
- 0x06, /* 14: CBW Length */
-
- 0x1b, /* 15+0: opcode: SCSI START/STOP */
- 0x00, /* 15+1: byte2: Not immediate */
- 0x00, 0x00, /* 15+2..3: reserved */
- 0x02, /* 15+4: Load/Eject command */
- 0x00, /* 15+5: control */
- 0x00, 0x00, 0x00, 0x00, /* 15+6..15: unused */
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00
- };
-
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed = NULL;
- int i;
-
-
- /* Find the bulk-out endpoints */
- id = usbd_get_interface_descriptor(uaa->iface);
- for (i = 0 ; i < id->bNumEndpoints; i++) {
- ed = usbd_interface2endpoint_descriptor(uaa->iface, i);
- if (ed != NULL
- && (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT) {
- if (usbd_open_pipe(uaa->iface,
- ed->bEndpointAddress,
- USBD_EXCLUSIVE_USE,
- &sc->sc_pipe_out)
- != USBD_NORMAL_COMPLETION) {
- DPRINTF("failed to open bulk-out pipe on endpoint %d\n",
- ed->bEndpointAddress);
- return 0;
- }
- } else {
- if (usbd_open_pipe(uaa->iface,
- ed->bEndpointAddress,
- USBD_EXCLUSIVE_USE,
- &sc->sc_pipe_in)
- != USBD_NORMAL_COMPLETION) {
- DPRINTF("failed to open bulk-in pipe on endpoint %d\n",
- ed->bEndpointAddress);
- return 0;
- }
- }
- }
- if (sc->sc_pipe_out && sc->sc_pipe_in)
- break;
- }
-
- if (i == id->bNumEndpoints) {
- DPRINTF("failed to find bulk-out pipe\n");
- return 0;
- }
-
- sc->sc_xfer = usbd_alloc_xfer(uaa->device);
- if (sc->sc_xfer == NULL) {
- DPRINTF("failed to allocate xfer\n");
- return 0;
- }
-
- usbd_setup_xfer(sc->sc_xfer, sc->sc_pipe_out, NULL, cmd, sizeof(cmd),
- 0, USBD_DEFAULT_TIMEOUT, u3gstub_BBB_cb);
- int err = usbd_transfer(sc->sc_xfer) != USBD_NORMAL_COMPLETION;
- if (err != USBD_NORMAL_COMPLETION && err != USBD_IN_PROGRESS) {
- DPRINTF("failed to start transfer (CBW)\n");
- return 0;
- }
-
- return 1;
-}
-
-static int
-u3gstub_cmotech_init(struct u3gstub_softc *sc, struct usb_attach_arg *uaa)
-{
- /* See definition of umass_bbb_cbw_t in sys/dev/usb/umass.c
- * in sys/cam/scsi/scsi_all.h .
- */
- unsigned char cmd[31] = {
- 0x55, 0x53, 0x42, 0x43, /* 0..3: Command Block Wrapper (CBW) signature */
- 0x01, 0x00, 0x00, 0x00, /* 4..7: CBW Tag, unique 32-bit number */
- 0x00, 0x00, 0x00, 0x00, /* 8..11: CBW Transfer Length, no data here */
- 0x80, /* 12: CBW Flag: output, so 0 */
- 0x00, /* 13: CBW Lun */
- 0x08, /* 14: CBW Length */
-
- 0xff, /* 15+0 */
- 0x52, /* 15+1 */
- 0x44, /* 15+2 */
- 0x45, /* 15+2 */
- 0x56, /* 15+4 */
- 0x43, /* 15+5 */
- 0x48, /* 15+5 */
- 0x47, /* 15+5 */
- 0x00, 0x00, 0x00, 0x00, /* 15+8..15: unused */
- 0x00, 0x00, 0x00, 0x00
- };
-
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed = NULL;
- int i;
-
-
- /* Find the bulk-out endpoints */
- id = usbd_get_interface_descriptor(uaa->iface);
- for (i = 0 ; i < id->bNumEndpoints ; i++) {
- ed = usbd_interface2endpoint_descriptor(uaa->iface, i);
- if (ed != NULL
- && (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT) {
- if (usbd_open_pipe(uaa->iface,
- ed->bEndpointAddress,
- USBD_EXCLUSIVE_USE,
- &sc->sc_pipe_out)
- != USBD_NORMAL_COMPLETION) {
- DPRINTF("failed to open bulk-out pipe on endpoint %d\n",
- ed->bEndpointAddress);
- return 0;
- }
- } else {
- if (usbd_open_pipe(uaa->iface,
- ed->bEndpointAddress,
- USBD_EXCLUSIVE_USE,
- &sc->sc_pipe_in)
- != USBD_NORMAL_COMPLETION) {
- DPRINTF("failed to open bulk-in pipe on endpoint %d\n",
- ed->bEndpointAddress);
- return 0;
- }
- }
- }
- if (sc->sc_pipe_out && sc->sc_pipe_in)
- break;
- }
-
- if (i == id->bNumEndpoints) {
- DPRINTF("failed to find bulk-out pipe\n");
- return 0;
- }
-
- sc->sc_xfer = usbd_alloc_xfer(uaa->device);
- if (sc->sc_xfer == NULL) {
- DPRINTF("failed to allocate xfer\n");
- return 0;
- }
-
- usbd_setup_xfer(sc->sc_xfer, sc->sc_pipe_out, NULL, cmd, sizeof(cmd),
- 0, USBD_DEFAULT_TIMEOUT, u3gstub_BBB_cb);
- int err = usbd_transfer(sc->sc_xfer) != USBD_NORMAL_COMPLETION;
- if (err != USBD_NORMAL_COMPLETION && err != USBD_IN_PROGRESS) {
- DPRINTF("failed to start transfer (CBW)\n");
- return 0;
- }
-
- return 1;
-}
-
-static int
-u3gstub_sierra_init(struct u3gstub_softc *sc, struct usb_attach_arg *uaa)
-{
- usb_device_request_t req;
-
- req.bmRequestType = UT_VENDOR;
- req.bRequest = UR_SET_INTERFACE;
- USETW(req.wValue, UF_DEVICE_REMOTE_WAKEUP);
- USETW(req.wIndex, UHF_PORT_CONNECTION);
- USETW(req.wLength, 0);
-
- (void) usbd_do_request(uaa->device, &req, 0); /* ignore any error */
-
- return 1;
-}
-
-static int
-u3gstub_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
- const struct u3g_dev_type_s *u3g_dev_type;
- usb_interface_descriptor_t *id;
-
- /* This stub handles 3G modem devices (E220, Mobile, etc.) with
- * auto-install flash disks for Windows/MacOSX on the first interface.
- * After some command or some delay they change appearance to a modem.
- */
-
- if (!uaa->iface)
- return UMATCH_NONE;
-
- u3g_dev_type = u3g_lookup(uaa->vendor, uaa->product);
- if (!u3g_dev_type)
- return UMATCH_NONE;
-
- if (u3g_dev_type->flags&U3GFL_HUAWEI_INIT
- || u3g_dev_type->flags&U3GFL_SCSI_EJECT
- || u3g_dev_type->flags&U3GFL_SIERRA_INIT
- || u3g_dev_type->flags&U3GFL_CMOTECH_INIT
- || u3g_dev_type->flags&U3GFL_STUB_WAIT) {
- /* We assume that if the first interface is still a mass
- * storage device the device has not yet changed appearance.
- */
- id = usbd_get_interface_descriptor(uaa->iface);
- if (id && id->bInterfaceNumber == 0
- && id->bInterfaceClass == UICLASS_MASS) {
-#ifndef U3G_DEBUG
- if (!bootverbose)
- device_quiet(self);
-#endif
-
- return UMATCH_VENDOR_PRODUCT;
- }
- }
-
- return UMATCH_NONE;
-}
-
-static int
-u3gstub_attach(device_t self)
-{
- struct u3gstub_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- const struct u3g_dev_type_s *u3g_dev_type;
- int i;
-
-#ifndef U3G_DEBUG
- if (!bootverbose)
- device_quiet(self);
-#endif
-
- sc->sc_dev = self;
- sc->sc_udev = uaa->device;
-
- for (i = 0; i < uaa->nifaces; i++)
- uaa->ifaces[i] = NULL; // claim all interfaces
-
- u3g_dev_type = u3g_lookup(uaa->vendor, uaa->product);
- if (u3g_dev_type->flags&U3GFL_HUAWEI_INIT) {
- if (bootverbose)
- device_printf(sc->sc_dev,
- "changing Huawei modem to modem mode\n");
- if (!u3gstub_huawei_init(sc, uaa))
- return ENXIO;
- } else if (u3g_dev_type->flags&U3GFL_SCSI_EJECT) {
- if (bootverbose)
- device_printf(sc->sc_dev, "sending CD eject command to "
- "change to modem mode\n");
- if (!u3gstub_scsi_eject(sc, uaa))
- return ENXIO;
- } else if (u3g_dev_type->flags&U3GFL_SIERRA_INIT) {
- if (bootverbose)
- device_printf(sc->sc_dev,
- "changing Sierra modem to modem mode\n");
- if (!u3gstub_sierra_init(sc, uaa))
- return ENXIO;
- } else if (u3g_dev_type->flags&U3GFL_CMOTECH_INIT) {
- if (bootverbose)
- device_printf(sc->sc_dev,
- "changing CMOTECH modem to modem mode\n");
- if (!u3gstub_cmotech_init(sc, uaa))
- return ENXIO;
- } else if (u3g_dev_type->flags&U3GFL_STUB_WAIT) {
- if (bootverbose)
- device_printf(sc->sc_dev, "waiting for modem to change "
- "to modem mode\n");
- /* nop */
- }
-
- return 0;
-}
-
-static int
-u3gstub_detach(device_t self)
-{
- struct u3gstub_softc *sc = device_get_softc(self);
-
- if (sc->sc_xfer)
- usbd_free_xfer(sc->sc_xfer);
-
- if (sc->sc_pipe_in) {
- usbd_abort_pipe(sc->sc_pipe_in);
- usbd_close_pipe(sc->sc_pipe_in);
- }
- if (sc->sc_pipe_out) {
- usbd_abort_pipe(sc->sc_pipe_out);
- usbd_close_pipe(sc->sc_pipe_out);
- }
-
- return 0;
-}
-
-static device_method_t u3gstub_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, u3gstub_match),
- DEVMETHOD(device_attach, u3gstub_attach),
- DEVMETHOD(device_detach, u3gstub_detach),
-
- { 0, 0 }
-};
-
-static driver_t u3gstub_driver = {
- "u3g",
- u3gstub_methods,
- sizeof (struct u3gstub_softc)
-};
-
-DRIVER_MODULE(u3gstub, uhub, u3gstub_driver, ucom_devclass, usbd_driver_load, 0);
-MODULE_DEPEND(u3gstub, usb, 1, 1, 1);
diff --git a/sys/dev/usb/uark.c b/sys/dev/usb/uark.c
deleted file mode 100644
index af85819..0000000
--- a/sys/dev/usb/uark.c
+++ /dev/null
@@ -1,339 +0,0 @@
-/* $OpenBSD: uark.c,v 1.1 2006/08/14 08:30:22 jsg Exp $ */
-
-/*
- * Copyright (c) 2006 Jonathan Gray <jsg@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * $FreeBSD$
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/ioccom.h>
-#include <sys/fcntl.h>
-#include <sys/conf.h>
-#include <sys/tty.h>
-#include <sys/file.h>
-#include <sys/selinfo.h>
-#include <sys/sysctl.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include "usbdevs.h"
-
-#include <dev/usb/ucomvar.h>
-
-#ifdef UARK_DEBUG
-#define DPRINTFN(n, x) do { \
- if (uarkdebug > (n)) \
- printf x; \
-} while (0)
-int uarkebug = 0;
-#else
-#define DPRINTFN(n, x)
-#endif
-#define DPRINTF(x) DPRINTFN(0, x)
-
-#define UARKBUFSZ 256
-#define UARK_CONFIG_NO 0
-#define UARK_IFACE_NO 0
-
-#define UARK_SET_DATA_BITS(x) (x - 5)
-
-#define UARK_PARITY_NONE 0x00
-#define UARK_PARITY_ODD 0x08
-#define UARK_PARITY_EVEN 0x18
-
-#define UARK_STOP_BITS_1 0x00
-#define UARK_STOP_BITS_2 0x04
-
-#define UARK_BAUD_REF 3000000
-
-#define UARK_WRITE 0x40
-#define UARK_READ 0xc0
-
-#define UARK_REQUEST 0xfe
-
-#define UARK_CONFIG_INDEX 0
-#define UARK_IFACE_INDEX 0
-
-struct uark_softc {
- struct ucom_softc sc_ucom;
- usbd_interface_handle sc_iface;
-
- u_char sc_msr;
- u_char sc_lsr;
-};
-
-static void uark_get_status(void *, int portno, u_char *lsr, u_char *msr);
-static void uark_set(void *, int, int, int);
-static int uark_param(void *, int, struct termios *);
-static void uark_break(void *, int, int);
-static int uark_cmd(struct uark_softc *, uint16_t, uint16_t);
-
-struct ucom_callback uark_callback = {
- uark_get_status,
- uark_set,
- uark_param,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
-};
-
-static const struct usb_devno uark_devs[] = {
- { USB_VENDOR_ARKMICRO, USB_PRODUCT_ARKMICRO_ARK3116 }
-};
-
-static int
-uark_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
-
- if (uaa->iface != NULL)
- return (UMATCH_NONE);
-
- return (usb_lookup(uark_devs, uaa->vendor, uaa->product) != NULL) ?
- UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
-}
-
-static int
-uark_attach(device_t self)
-{
- struct uark_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usbd_device_handle dev = uaa->device;
- usbd_interface_handle iface;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
- usbd_status error;
- int i;
- struct ucom_softc *ucom = &sc->sc_ucom;
-
- ucom->sc_dev = self;
- ucom->sc_udev = dev;
-
- if (uaa->iface == NULL) {
- /* Move the device into the configured state. */
- error = usbd_set_config_index(dev, UARK_CONFIG_INDEX, 1);
- if (error) {
- device_printf(ucom->sc_dev,
- "failed to set configuration, err=%s\n",
- usbd_errstr(error));
- goto bad;
- }
- error =
- usbd_device2interface_handle(dev, UARK_IFACE_INDEX, &iface);
- if (error) {
- device_printf(ucom->sc_dev,
- "failed to get interface, err=%s\n",
- usbd_errstr(error));
- goto bad;
- }
- } else
- iface = uaa->iface;
-
- id = usbd_get_interface_descriptor(iface);
- ucom->sc_iface = iface;
-
- ucom->sc_bulkin_no = ucom->sc_bulkout_no = -1;
- for (i = 0; i < id->bNumEndpoints; i++) {
- ed = usbd_interface2endpoint_descriptor(iface, i);
- if (ed == NULL) {
- device_printf(ucom->sc_dev,
- "could not read endpoint descriptor\n");
- goto bad;
- }
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
- ucom->sc_bulkin_no = ed->bEndpointAddress;
- else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
- ucom->sc_bulkout_no = ed->bEndpointAddress;
- }
- if (ucom->sc_bulkin_no == -1 || ucom->sc_bulkout_no == -1) {
- device_printf(ucom->sc_dev, "missing endpoint\n");
- goto bad;
- }
- ucom->sc_parent = sc;
- ucom->sc_ibufsize = UARKBUFSZ;
- ucom->sc_obufsize = UARKBUFSZ;
- ucom->sc_ibufsizepad = UARKBUFSZ;
- ucom->sc_opkthdrlen = 0;
-
- ucom->sc_callback = &uark_callback;
-
- DPRINTF(("uark: in=0x%x out=0x%x\n", ucom->sc_bulkin_no, ucom->sc_bulkout_no));
- ucom_attach(&sc->sc_ucom);
- return 0;
-
-bad:
- DPRINTF(("uark_attach: ATTACH ERROR\n"));
- ucom->sc_dying = 1;
- return ENXIO;
-}
-
-static int
-uark_detach(device_t self)
-{
- struct uark_softc *sc = device_get_softc(self);
- int rv = 0;
-
- DPRINTF(("uark_detach: sc=%p\n", sc));
- sc->sc_ucom.sc_dying = 1;
- rv = ucom_detach(&sc->sc_ucom);
-
- return (rv);
-}
-
-static void
-uark_set(void *vsc, int portno, int reg, int onoff)
-{
- struct uark_softc *sc = vsc;
-
- switch (reg) {
- case UCOM_SET_BREAK:
- uark_break(sc, portno, onoff);
- return;
- /* NOTREACHED */
- case UCOM_SET_DTR:
- case UCOM_SET_RTS:
- default:
- return;
- /* NOTREACHED */
- }
-}
-
-static int
-uark_param(void *vsc, int portno, struct termios *t)
-{
- struct uark_softc *sc = (struct uark_softc *)vsc;
- int data, divisor;
- speed_t speed = t->c_ospeed;
-
- if (speed < 300 || speed > 115200)
- return (EINVAL);
- divisor = (UARK_BAUD_REF + speed / 2) / speed;
- /* Check that we're within 3% of the requested rate. */
- if (speed * divisor < UARK_BAUD_REF * 100 / 103 ||
- speed * divisor > UARK_BAUD_REF * 100 / 97)
- return (EINVAL);
- uark_cmd(sc, 3, 0x83);
- uark_cmd(sc, 0, divisor & 0xFF);
- uark_cmd(sc, 1, divisor >> 8);
- uark_cmd(sc, 3, 0x03);
-
- if (ISSET(t->c_cflag, CSTOPB))
- data = UARK_STOP_BITS_2;
- else
- data = UARK_STOP_BITS_1;
-
- if (ISSET(t->c_cflag, PARENB)) {
- if (ISSET(t->c_cflag, PARODD))
- data |= UARK_PARITY_ODD;
- else
- data |= UARK_PARITY_EVEN;
- } else
- data |= UARK_PARITY_NONE;
-
- switch (ISSET(t->c_cflag, CSIZE)) {
- case CS5:
- data |= UARK_SET_DATA_BITS(5);
- break;
- case CS6:
- data |= UARK_SET_DATA_BITS(6);
- break;
- case CS7:
- data |= UARK_SET_DATA_BITS(7);
- break;
- case CS8:
- data |= UARK_SET_DATA_BITS(8);
- break;
- }
- uark_cmd(sc, 3, 0x00);
- uark_cmd(sc, 3, data);
-
- return (0);
-}
-
-void
-uark_get_status(void *vsc, int portno, u_char *lsr, u_char *msr)
-{
- struct uark_softc *sc = vsc;
-
- if (msr != NULL)
- *msr = sc->sc_msr;
- if (lsr != NULL)
- *lsr = sc->sc_lsr;
-}
-
-void
-uark_break(void *vsc, int portno, int onoff)
-{
-#ifdef UARK_DEBUG
- struct uark_softc *sc = vsc;
-
- device_printf(sc->sc_dev, "%s: break %s!\n", onoff ? "on" : "off");
- if (onoff)
- /* break on */
- uark_cmd(sc, 4, 0x01);
- else
- uark_cmd(sc, 4, 0x00);
-#endif
-}
-
-int
-uark_cmd(struct uark_softc *sc, uint16_t index, uint16_t value)
-{
- usb_device_request_t req;
- usbd_status err;
- struct ucom_softc *ucom = &sc->sc_ucom;
-
- req.bmRequestType = UARK_WRITE;
- req.bRequest = UARK_REQUEST;
- USETW(req.wValue, value);
- USETW(req.wIndex, index);
- USETW(req.wLength, 0);
- err = usbd_do_request(ucom->sc_udev, &req, NULL);
-
- if (err)
- return (EIO);
-
- return (0);
-}
-
-static device_method_t uark_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, uark_match),
- DEVMETHOD(device_attach, uark_attach),
- DEVMETHOD(device_detach, uark_detach),
-
- { 0, 0 }
-};
-
-static driver_t uark_driver = {
- "ucom",
- uark_methods,
- sizeof (struct uark_softc)
-};
-
-DRIVER_MODULE(uark, uhub, uark_driver, ucom_devclass, usbd_driver_load, 0);
-MODULE_DEPEND(uark, usb, 1, 1, 1);
-MODULE_DEPEND(uark, ucom, UCOM_MINVER, UCOM_PREFVER, UCOM_MAXVER);
diff --git a/sys/dev/usb/ubsa.c b/sys/dev/usb/ubsa.c
deleted file mode 100644
index b66cce8..0000000
--- a/sys/dev/usb/ubsa.c
+++ /dev/null
@@ -1,742 +0,0 @@
-/*-
- * Copyright (c) 2002, Alexander Kabaev <kan.FreeBSD.org>.
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-/*-
- * Copyright (c) 2001 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Ichiro FUKUHARA (ichiro@ichiro.org).
- *
- * 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.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/ioccom.h>
-#include <sys/fcntl.h>
-#include <sys/taskqueue.h>
-#include <sys/conf.h>
-#include <sys/tty.h>
-#include <sys/file.h>
-#include <sys/selinfo.h>
-#include <sys/proc.h>
-#include <sys/poll.h>
-#include <sys/sysctl.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbcdc.h>
-
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include "usbdevs.h"
-#include <dev/usb/usb_quirks.h>
-
-#include <dev/usb/ucomvar.h>
-
-#ifdef USB_DEBUG
-static int ubsadebug = 0;
-SYSCTL_NODE(_hw_usb, OID_AUTO, ubsa, CTLFLAG_RW, 0, "USB ubsa");
-SYSCTL_INT(_hw_usb_ubsa, OID_AUTO, debug, CTLFLAG_RW,
- &ubsadebug, 0, "ubsa debug level");
-
-#define DPRINTFN(n, x) do { \
- if (ubsadebug > (n)) \
- printf x; \
- } while (0)
-#else
-#define DPRINTFN(n, x)
-#endif
-#define DPRINTF(x) DPRINTFN(0, x)
-
-#define UBSA_MODVER 1 /* module version */
-
-#define UBSA_CONFIG_INDEX 1
-#define UBSA_IFACE_INDEX 0
-
-#define UBSA_INTR_INTERVAL 100 /* ms */
-
-#define UBSA_SET_BAUDRATE 0x00
-#define UBSA_SET_STOP_BITS 0x01
-#define UBSA_SET_DATA_BITS 0x02
-#define UBSA_SET_PARITY 0x03
-#define UBSA_SET_DTR 0x0A
-#define UBSA_SET_RTS 0x0B
-#define UBSA_SET_BREAK 0x0C
-#define UBSA_SET_FLOW_CTRL 0x10
-
-#define UBSA_PARITY_NONE 0x00
-#define UBSA_PARITY_EVEN 0x01
-#define UBSA_PARITY_ODD 0x02
-#define UBSA_PARITY_MARK 0x03
-#define UBSA_PARITY_SPACE 0x04
-
-#define UBSA_FLOW_NONE 0x0000
-#define UBSA_FLOW_OCTS 0x0001
-#define UBSA_FLOW_ODSR 0x0002
-#define UBSA_FLOW_IDSR 0x0004
-#define UBSA_FLOW_IDTR 0x0008
-#define UBSA_FLOW_IRTS 0x0010
-#define UBSA_FLOW_ORTS 0x0020
-#define UBSA_FLOW_UNKNOWN 0x0040
-#define UBSA_FLOW_OXON 0x0080
-#define UBSA_FLOW_IXON 0x0100
-
-/* line status register */
-#define UBSA_LSR_TSRE 0x40 /* Transmitter empty: byte sent */
-#define UBSA_LSR_TXRDY 0x20 /* Transmitter buffer empty */
-#define UBSA_LSR_BI 0x10 /* Break detected */
-#define UBSA_LSR_FE 0x08 /* Framing error: bad stop bit */
-#define UBSA_LSR_PE 0x04 /* Parity error */
-#define UBSA_LSR_OE 0x02 /* Overrun, lost incoming byte */
-#define UBSA_LSR_RXRDY 0x01 /* Byte ready in Receive Buffer */
-#define UBSA_LSR_RCV_MASK 0x1f /* Mask for incoming data or error */
-
-/* modem status register */
-/* All deltas are from the last read of the MSR. */
-#define UBSA_MSR_DCD 0x80 /* Current Data Carrier Detect */
-#define UBSA_MSR_RI 0x40 /* Current Ring Indicator */
-#define UBSA_MSR_DSR 0x20 /* Current Data Set Ready */
-#define UBSA_MSR_CTS 0x10 /* Current Clear to Send */
-#define UBSA_MSR_DDCD 0x08 /* DCD has changed state */
-#define UBSA_MSR_TERI 0x04 /* RI has toggled low to high */
-#define UBSA_MSR_DDSR 0x02 /* DSR has changed state */
-#define UBSA_MSR_DCTS 0x01 /* CTS has changed state */
-
-struct ubsa_softc {
- struct ucom_softc sc_ucom;
-
- int sc_iface_number; /* interface number */
-
- usbd_interface_handle sc_intr_iface; /* interrupt interface */
- int sc_intr_number; /* interrupt number */
- usbd_pipe_handle sc_intr_pipe; /* interrupt pipe */
- u_char *sc_intr_buf; /* interrupt buffer */
- int sc_isize;
-
- u_char sc_dtr; /* current DTR state */
- u_char sc_rts; /* current RTS state */
-
- u_char sc_lsr; /* Local status register */
- u_char sc_msr; /* ubsa status register */
- struct task sc_task;
-};
-
-static void ubsa_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
-static void ubsa_notify(void *, int count);
-
-static void ubsa_get_status(void *, int, u_char *, u_char *);
-static void ubsa_set(void *, int, int, int);
-static int ubsa_param(void *, int, struct termios *);
-static int ubsa_open(void *, int);
-static void ubsa_close(void *, int);
-
-static int ubsa_request(struct ubsa_softc *, u_int8_t, u_int16_t);
-static void ubsa_dtr(struct ubsa_softc *, int);
-static void ubsa_rts(struct ubsa_softc *, int);
-static void ubsa_baudrate(struct ubsa_softc *, speed_t);
-static void ubsa_parity(struct ubsa_softc *, tcflag_t);
-static void ubsa_databits(struct ubsa_softc *, tcflag_t);
-static void ubsa_stopbits(struct ubsa_softc *, tcflag_t);
-static void ubsa_flow(struct ubsa_softc *, tcflag_t, tcflag_t);
-
-struct ucom_callback ubsa_callback = {
- ubsa_get_status,
- ubsa_set,
- ubsa_param,
- NULL,
- ubsa_open,
- ubsa_close,
- NULL,
- NULL
-};
-
-static const struct ubsa_product {
- uint16_t vendor;
- uint16_t product;
-} ubsa_products [] = {
- /* AnyData ADU-500A */
- { USB_VENDOR_ANYDATA, USB_PRODUCT_ANYDATA_ADU_500A },
- /* AnyData ADU-E100A/H */
- { USB_VENDOR_ANYDATA, USB_PRODUCT_ANYDATA_ADU_E100X },
- /* Axesstel MV100H */
- { USB_VENDOR_AXESSTEL, USB_PRODUCT_AXESSTEL_DATAMODEM },
- /* BELKIN F5U103 */
- { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5U103 },
- /* BELKIN F5U120 */
- { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5U120 },
- /* GoHubs GO-COM232 */
- { USB_VENDOR_ETEK, USB_PRODUCT_ETEK_1COM },
- /* GoHubs GO-COM232 */
- { USB_VENDOR_GOHUBS, USB_PRODUCT_GOHUBS_GOCOM232 },
- /* Peracom */
- { USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_SERIAL1 },
- { 0, 0 }
-};
-
-static device_probe_t ubsa_match;
-static device_attach_t ubsa_attach;
-static device_detach_t ubsa_detach;
-
-static device_method_t ubsa_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, ubsa_match),
- DEVMETHOD(device_attach, ubsa_attach),
- DEVMETHOD(device_detach, ubsa_detach),
- { 0, 0 }
-};
-
-static driver_t ubsa_driver = {
- "ucom",
- ubsa_methods,
- sizeof (struct ubsa_softc)
-};
-
-DRIVER_MODULE(ubsa, uhub, ubsa_driver, ucom_devclass, usbd_driver_load, 0);
-MODULE_DEPEND(ubsa, usb, 1, 1, 1);
-MODULE_DEPEND(ubsa, ucom, UCOM_MINVER, UCOM_PREFVER, UCOM_MAXVER);
-MODULE_VERSION(ubsa, UBSA_MODVER);
-
-static int
-ubsa_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
- int i;
-
- if (uaa->iface != NULL)
- return (UMATCH_NONE);
-
- for (i = 0; ubsa_products[i].vendor != 0; i++) {
- if (ubsa_products[i].vendor == uaa->vendor &&
- ubsa_products[i].product == uaa->product) {
- return (UMATCH_VENDOR_PRODUCT);
- }
- }
- return (UMATCH_NONE);
-}
-
-static int
-ubsa_attach(device_t self)
-{
- struct ubsa_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usbd_device_handle dev;
- struct ucom_softc *ucom;
- usb_config_descriptor_t *cdesc;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
- usbd_status err;
- int i;
-
- dev = uaa->device;
- ucom = &sc->sc_ucom;
-
- /*
- * initialize rts, dtr variables to something
- * different from boolean 0, 1
- */
- sc->sc_dtr = -1;
- sc->sc_rts = -1;
-
- ucom->sc_dev = self;
- ucom->sc_udev = dev;
- ucom->sc_iface = uaa->iface;
-
- DPRINTF(("ubsa attach: sc = %p\n", sc));
-
- /* initialize endpoints */
- ucom->sc_bulkin_no = ucom->sc_bulkout_no = -1;
- sc->sc_intr_number = -1;
- sc->sc_intr_pipe = NULL;
-
- /* Move the device into the configured state. */
- err = usbd_set_config_index(dev, UBSA_CONFIG_INDEX, 1);
- if (err) {
- device_printf(ucom->sc_dev, "failed to set configuration: %s\n",
- usbd_errstr(err));
- ucom->sc_dying = 1;
- goto error;
- }
-
- /* get the config descriptor */
- cdesc = usbd_get_config_descriptor(ucom->sc_udev);
-
- if (cdesc == NULL) {
- device_printf(ucom->sc_dev,
- "failed to get configuration descriptor\n");
- ucom->sc_dying = 1;
- goto error;
- }
-
- /* get the first interface */
- err = usbd_device2interface_handle(dev, UBSA_IFACE_INDEX,
- &ucom->sc_iface);
- if (err) {
- device_printf(ucom->sc_dev, "failed to get interface: %s\n",
- usbd_errstr(err));
- ucom->sc_dying = 1;
- goto error;
- }
-
- /* Find the endpoints */
-
- id = usbd_get_interface_descriptor(ucom->sc_iface);
- sc->sc_iface_number = id->bInterfaceNumber;
-
- for (i = 0; i < id->bNumEndpoints; i++) {
- ed = usbd_interface2endpoint_descriptor(ucom->sc_iface, i);
- if (ed == NULL) {
- device_printf(ucom->sc_dev,
- "no endpoint descriptor for %d\n", i);
- ucom->sc_dying = 1;
- goto error;
- }
-
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
- sc->sc_intr_number = ed->bEndpointAddress;
- sc->sc_isize = UGETW(ed->wMaxPacketSize);
- } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
- ucom->sc_bulkin_no = ed->bEndpointAddress;
- ucom->sc_ibufsize = UGETW(ed->wMaxPacketSize);
- } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
- ucom->sc_bulkout_no = ed->bEndpointAddress;
- ucom->sc_obufsize = UGETW(ed->wMaxPacketSize);
- }
- }
-
- if (sc->sc_intr_number == -1) {
- device_printf(ucom->sc_dev, "Could not find interrupt in\n");
- ucom->sc_dying = 1;
- goto error;
- }
-
- /* keep interface for interrupt */
- sc->sc_intr_iface = ucom->sc_iface;
-
- if (ucom->sc_bulkin_no == -1) {
- device_printf(ucom->sc_dev, "Could not find data bulk in\n");
- ucom->sc_dying = 1;
- goto error;
- }
-
- if (ucom->sc_bulkout_no == -1) {
- device_printf(ucom->sc_dev, "Could not find data bulk out\n");
- ucom->sc_dying = 1;
- goto error;
- }
-
- ucom->sc_parent = sc;
- ucom->sc_portno = UCOM_UNK_PORTNO;
- /* bulkin, bulkout set above */
- ucom->sc_ibufsize = 1024;
- ucom->sc_obufsize = 1024;
- ucom->sc_ibufsizepad = ucom->sc_ibufsize;
- ucom->sc_opkthdrlen = 0;
- ucom->sc_callback = &ubsa_callback;
-
- DPRINTF(("ubsa: in = 0x%x, out = 0x%x, intr = 0x%x\n",
- ucom->sc_bulkin_no, ucom->sc_bulkout_no, sc->sc_intr_number));
-
- TASK_INIT(&sc->sc_task, 0, ubsa_notify, sc);
- ucom_attach(ucom);
- return 0;
-
-error:
- return ENXIO;
-}
-
-static int
-ubsa_detach(device_t self)
-{
- struct ubsa_softc *sc = device_get_softc(self);
- int rv;
-
- DPRINTF(("ubsa_detach: sc = %p\n", sc));
-
- if (sc->sc_intr_pipe != NULL) {
- usbd_abort_pipe(sc->sc_intr_pipe);
- usbd_close_pipe(sc->sc_intr_pipe);
- free(sc->sc_intr_buf, M_USBDEV);
- sc->sc_intr_pipe = NULL;
- }
-
- sc->sc_ucom.sc_dying = 1;
-#if 0
- taskqueue_drain(taskqueue_swi_giant);
-#endif
- rv = ucom_detach(&sc->sc_ucom);
-
- return (rv);
-}
-
-static int
-ubsa_request(struct ubsa_softc *sc, u_int8_t request, u_int16_t value)
-{
- usb_device_request_t req;
- usbd_status err;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = request;
- USETW(req.wValue, value);
- USETW(req.wIndex, sc->sc_iface_number);
- USETW(req.wLength, 0);
-
- err = usbd_do_request(sc->sc_ucom.sc_udev, &req, 0);
- if (err)
- device_printf(sc->sc_ucom.sc_dev, "ubsa_request(%x, %x): %s\n",
- request, value, usbd_errstr(err));
- return (err);
-}
-
-static void
-ubsa_dtr(struct ubsa_softc *sc, int onoff)
-{
-
- DPRINTF(("ubsa_dtr: onoff = %d\n", onoff));
-
- if (sc->sc_dtr == onoff)
- return;
- sc->sc_dtr = onoff;
-
- ubsa_request(sc, UBSA_SET_DTR, onoff ? 1 : 0);
-}
-
-static void
-ubsa_rts(struct ubsa_softc *sc, int onoff)
-{
-
- DPRINTF(("ubsa_rts: onoff = %d\n", onoff));
-
- if (sc->sc_rts == onoff)
- return;
- sc->sc_rts = onoff;
-
- ubsa_request(sc, UBSA_SET_RTS, onoff ? 1 : 0);
-}
-
-static void
-ubsa_break(struct ubsa_softc *sc, int onoff)
-{
-
- DPRINTF(("ubsa_rts: onoff = %d\n", onoff));
-
- ubsa_request(sc, UBSA_SET_BREAK, onoff ? 1 : 0);
-}
-
-static void
-ubsa_set(void *addr, int portno, int reg, int onoff)
-{
- struct ubsa_softc *sc;
-
- sc = addr;
- switch (reg) {
- case UCOM_SET_DTR:
- ubsa_dtr(sc, onoff);
- break;
- case UCOM_SET_RTS:
- ubsa_rts(sc, onoff);
- break;
- case UCOM_SET_BREAK:
- ubsa_break(sc, onoff);
- break;
- default:
- break;
- }
-}
-
-static void
-ubsa_baudrate(struct ubsa_softc *sc, speed_t speed)
-{
- u_int16_t value = 0;
-
- DPRINTF(("ubsa_baudrate: speed = %d\n", speed));
-
- switch(speed) {
- case B0:
- break;
- case B300:
- case B600:
- case B1200:
- case B2400:
- case B4800:
- case B9600:
- case B19200:
- case B38400:
- case B57600:
- case B115200:
- case B230400:
- value = B230400 / speed;
- break;
- default:
- device_printf(sc->sc_ucom.sc_dev,
- "ubsa_param: unsupported baud, forcing default of 9600\n");
- value = B230400 / B9600;
- break;
- };
-
- if (speed == B0) {
- ubsa_flow(sc, 0, 0);
- ubsa_dtr(sc, 0);
- ubsa_rts(sc, 0);
- } else
- ubsa_request(sc, UBSA_SET_BAUDRATE, value);
-}
-
-static void
-ubsa_parity(struct ubsa_softc *sc, tcflag_t cflag)
-{
- int value;
-
- DPRINTF(("ubsa_parity: cflag = 0x%x\n", cflag));
-
- if (cflag & PARENB)
- value = (cflag & PARODD) ? UBSA_PARITY_ODD : UBSA_PARITY_EVEN;
- else
- value = UBSA_PARITY_NONE;
-
- ubsa_request(sc, UBSA_SET_PARITY, value);
-}
-
-static void
-ubsa_databits(struct ubsa_softc *sc, tcflag_t cflag)
-{
- int value;
-
- DPRINTF(("ubsa_databits: cflag = 0x%x\n", cflag));
-
- switch (cflag & CSIZE) {
- case CS5: value = 0; break;
- case CS6: value = 1; break;
- case CS7: value = 2; break;
- case CS8: value = 3; break;
- default:
- device_printf(sc->sc_ucom.sc_dev,
- "ubsa_param: unsupported databits requested, "
- "forcing default of 8\n");
- value = 3;
- }
-
- ubsa_request(sc, UBSA_SET_DATA_BITS, value);
-}
-
-static void
-ubsa_stopbits(struct ubsa_softc *sc, tcflag_t cflag)
-{
- int value;
-
- DPRINTF(("ubsa_stopbits: cflag = 0x%x\n", cflag));
-
- value = (cflag & CSTOPB) ? 1 : 0;
-
- ubsa_request(sc, UBSA_SET_STOP_BITS, value);
-}
-
-static void
-ubsa_flow(struct ubsa_softc *sc, tcflag_t cflag, tcflag_t iflag)
-{
- int value;
-
- DPRINTF(("ubsa_flow: cflag = 0x%x, iflag = 0x%x\n", cflag, iflag));
-
- value = 0;
- if (cflag & CRTSCTS)
- value |= UBSA_FLOW_OCTS | UBSA_FLOW_IRTS;
- if (iflag & (IXON|IXOFF))
- value |= UBSA_FLOW_OXON | UBSA_FLOW_IXON;
-
- ubsa_request(sc, UBSA_SET_FLOW_CTRL, value);
-}
-
-static int
-ubsa_param(void *addr, int portno, struct termios *ti)
-{
- struct ubsa_softc *sc;
-
- sc = addr;
-
- DPRINTF(("ubsa_param: sc = %p\n", sc));
-
- ubsa_baudrate(sc, ti->c_ospeed);
- ubsa_parity(sc, ti->c_cflag);
- ubsa_databits(sc, ti->c_cflag);
- ubsa_stopbits(sc, ti->c_cflag);
- ubsa_flow(sc, ti->c_cflag, ti->c_iflag);
-
- return (0);
-}
-
-static int
-ubsa_open(void *addr, int portno)
-{
- struct ubsa_softc *sc;
- int err;
-
- sc = addr;
- if (sc->sc_ucom.sc_dying)
- return (ENXIO);
-
- DPRINTF(("ubsa_open: sc = %p\n", sc));
-
- if (sc->sc_intr_number != -1 && sc->sc_intr_pipe == NULL) {
- sc->sc_intr_buf = malloc(sc->sc_isize, M_USBDEV, M_WAITOK);
- err = usbd_open_pipe_intr(sc->sc_intr_iface,
- sc->sc_intr_number,
- USBD_SHORT_XFER_OK,
- &sc->sc_intr_pipe,
- sc,
- sc->sc_intr_buf,
- sc->sc_isize,
- ubsa_intr,
- UBSA_INTR_INTERVAL);
- if (err) {
- device_printf(sc->sc_ucom.sc_dev,
- "cannot open interrupt pipe (addr %d)\n",
- sc->sc_intr_number);
- return (EIO);
- }
- }
-
- return (0);
-}
-
-static void
-ubsa_close(void *addr, int portno)
-{
- struct ubsa_softc *sc;
- int err;
-
- sc = addr;
- if (sc->sc_ucom.sc_dying)
- return;
-
- DPRINTF(("ubsa_close: close\n"));
-
- if (sc->sc_intr_pipe != NULL) {
- err = usbd_abort_pipe(sc->sc_intr_pipe);
- if (err)
- device_printf(sc->sc_ucom.sc_dev,
- "abort interrupt pipe failed: %s\n",
- usbd_errstr(err));
- err = usbd_close_pipe(sc->sc_intr_pipe);
- if (err)
- device_printf(sc->sc_ucom.sc_dev,
- "close interrupt pipe failed: %s\n",
- usbd_errstr(err));
- free(sc->sc_intr_buf, M_USBDEV);
- sc->sc_intr_pipe = NULL;
- }
-}
-
-static void
-ubsa_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- struct ubsa_softc *sc;
- u_char *buf;
-
- sc = priv;
- buf = sc->sc_intr_buf;
- if (sc->sc_ucom.sc_dying)
- return;
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
- return;
-
- DPRINTF(("%s: ubsa_intr: abnormal status: %s\n",
- device_get_nameunit(sc->sc_ucom.sc_dev),
- usbd_errstr(status)));
- usbd_clear_endpoint_stall_async(sc->sc_intr_pipe);
- return;
- }
-
- /* incidentally, Belkin adapter status bits match UART 16550 bits */
- sc->sc_lsr = buf[2];
- sc->sc_msr = buf[3];
-
- DPRINTF(("%s: ubsa lsr = 0x%02x, msr = 0x%02x\n",
- device_get_nameunit(sc->sc_ucom.sc_dev), sc->sc_lsr, sc->sc_msr));
-
- taskqueue_enqueue(taskqueue_swi_giant, &sc->sc_task);
-}
-
-/* Handle delayed events. */
-static void
-ubsa_notify(void *arg, int count)
-{
- struct ubsa_softc *sc;
-
- sc = arg;
- ucom_status_change(&sc->sc_ucom);
-}
-
-static void
-ubsa_get_status(void *addr, int portno, u_char *lsr, u_char *msr)
-{
- struct ubsa_softc *sc;
-
- DPRINTF(("ubsa_get_status\n"));
-
- sc = addr;
- if (lsr != NULL)
- *lsr = sc->sc_lsr;
- if (msr != NULL)
- *msr = sc->sc_msr;
-}
diff --git a/sys/dev/usb/ubser.c b/sys/dev/usb/ubser.c
deleted file mode 100644
index 29994b9..0000000
--- a/sys/dev/usb/ubser.c
+++ /dev/null
@@ -1,882 +0,0 @@
-/*-
- * Copyright (c) 2004 Bernd Walter <ticso@freebsd.org>
- *
- * $URL: https://devel.bwct.de/svn/projects/ubser/ubser.c $
- * $Date: 2004-02-29 01:53:10 +0100 (Sun, 29 Feb 2004) $
- * $Author: ticso $
- * $Rev: 1127 $
- */
-
-/*-
- * Copyright (c) 2001-2002, Shunsuke Akiyama <akiyama@jp.FreeBSD.org>.
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- */
-
-/*-
- * Copyright (c) 2000 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net).
- *
- * 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * BWCT serial adapter driver
- */
-
-#include <sys/cdefs.h>
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/malloc.h>
-#include <sys/bus.h>
-#include <sys/ioccom.h>
-#include <sys/fcntl.h>
-#include <sys/conf.h>
-#include <sys/serial.h>
-#include <sys/tty.h>
-#include <sys/clist.h>
-#include <sys/file.h>
-
-#include <sys/selinfo.h>
-
-#include <sys/sysctl.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbhid.h>
-
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include "usbdevs.h"
-
-#include <dev/usb/ubser.h>
-
-#ifdef USB_DEBUG
-static int ubserdebug = 0;
-SYSCTL_NODE(_hw_usb, OID_AUTO, ubser, CTLFLAG_RW, 0, "USB ubser");
-SYSCTL_INT(_hw_usb_ubser, OID_AUTO, debug, CTLFLAG_RW,
- &ubserdebug, 0, "ubser debug level");
-#define DPRINTF(x) do { \
- if (ubserdebug) \
- printf x; \
- } while (0)
-
-#define DPRINTFN(n, x) do { \
- if (ubserdebug > (n)) \
- printf x; \
- } while (0)
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-#define ISSET(t, f) ((t) & (f))
-#define SET(t, f) (t) |= (f)
-#define CLR(t, f) (t) &= ~((unsigned)(f))
-
-struct ubser_port {
- int p_port;
- struct ubser_softc *p_sc;
- usbd_xfer_handle p_oxfer; /* write request */
- u_char *p_obuf; /* write buffer */
- struct tty *p_tty;
-};
-
-struct ubser_softc {
- device_t sc_dev;
- usbd_device_handle sc_udev;
- usbd_interface_handle sc_iface; /* data interface */
- int sc_ifaceno;
-
- int sc_refcnt;
- u_char sc_dying;
- u_char sc_opening;
- int sc_state;
- uint8_t sc_numser;
-
- int sc_bulkin_no; /* bulk in endpoint address */
- usbd_pipe_handle sc_bulkin_pipe; /* bulk in pipe */
- usbd_xfer_handle sc_ixfer; /* read request */
- u_char *sc_ibuf; /* read buffer */
- u_int sc_ibufsize; /* read buffer size */
- u_int sc_ibufsizepad; /* read buffer size padded */
-
- int sc_bulkout_no; /* bulk out endpoint address */
- usbd_pipe_handle sc_bulkout_pipe;/* bulk out pipe */
- u_int sc_obufsize; /* write buffer size */
- u_int sc_opkthdrlen; /* header length of
- output packet */
-
- struct ubser_port *sc_port;
-};
-
-static int ubserparam(struct tty *, struct termios *);
-static void ubserstart(struct tty *);
-static void ubserstop(struct tty *, int);
-static usbd_status ubserstartread(struct ubser_softc *);
-static void ubserreadcb(usbd_xfer_handle, usbd_private_handle, usbd_status);
-static void ubserwritecb(usbd_xfer_handle, usbd_private_handle, usbd_status);
-static void ubser_cleanup(struct ubser_softc *sc);
-
-static t_break_t ubserbreak;
-static t_open_t ubseropen;
-static t_close_t ubserclose;
-static t_modem_t ubsermodem;
-
-static device_probe_t ubser_match;
-static device_attach_t ubser_attach;
-static device_detach_t ubser_detach;
-
-static device_method_t ubser_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, ubser_match),
- DEVMETHOD(device_attach, ubser_attach),
- DEVMETHOD(device_detach, ubser_detach),
-
- { 0, 0 }
-};
-
-static driver_t ubser_driver = {
- "ubser",
- ubser_methods,
- sizeof(struct ubser_softc)
-};
-
-static devclass_t ubser_devclass;
-
-static int
-ubser_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usb_string_descriptor_t us;
- usb_interface_descriptor_t *id;
- usb_device_descriptor_t *dd;
- int err, size;
-
- if (uaa->iface == NULL)
- return (UMATCH_NONE);
-
- DPRINTFN(20,("ubser: vendor=0x%x, product=0x%x\n",
- uaa->vendor, uaa->product));
-
- dd = usbd_get_device_descriptor(uaa->device);
- if (dd == NULL) {
- printf("ubser: failed to get device descriptor\n");
- return (UMATCH_NONE);
- }
-
- id = usbd_get_interface_descriptor(uaa->iface);
- if (id == NULL) {
- printf("ubser: failed to get interface descriptor\n");
- return (UMATCH_NONE);
- }
-
- err = usbd_get_string_desc(uaa->device, dd->iManufacturer, 0, &us,
- &size);
- if (err != 0)
- return (UMATCH_NONE);
-
- /* check if this is a BWCT vendor specific ubser interface */
- if (strcmp((char*)us.bString, "B\0W\0C\0T\0") == 0 &&
- id->bInterfaceClass == 0xff && id->bInterfaceSubClass == 0x00)
- return (UMATCH_VENDOR_IFACESUBCLASS);
-
- return (UMATCH_NONE);
-}
-
-static int
-ubser_attach(device_t self)
-{
- struct ubser_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usbd_device_handle udev = uaa->device;
- usb_endpoint_descriptor_t *ed;
- usb_interface_descriptor_t *id;
- usb_device_request_t req;
- struct tty *tp;
- usbd_status err;
- int i;
- int alen;
- uint8_t epcount;
- struct ubser_port *pp;
-
- sc->sc_dev = self;
-
- DPRINTFN(10,("\nubser_attach: sc=%p\n", sc));
-
- sc->sc_udev = udev = uaa->device;
- sc->sc_iface = uaa->iface;
- sc->sc_numser = 0;
- sc->sc_port = NULL;
-
- /* get interface index */
- id = usbd_get_interface_descriptor(uaa->iface);
- if (id == NULL) {
- printf("ubser: failed to get interface descriptor\n");
- return (UMATCH_NONE);
- }
- sc->sc_ifaceno = id->bInterfaceNumber;
-
- /* get number of serials */
- req.bmRequestType = UT_READ_VENDOR_INTERFACE;
- req.bRequest = VENDOR_GET_NUMSER;
- USETW(req.wValue, 0);
- USETW(req.wIndex, sc->sc_ifaceno);
- USETW(req.wLength, 1);
- err = usbd_do_request_flags(udev, &req, &sc->sc_numser,
- USBD_SHORT_XFER_OK, &alen, USBD_DEFAULT_TIMEOUT);
- if (err) {
- device_printf(self, "failed to get number of serials\n");
- goto bad;
- } else if (alen != 1) {
- device_printf(self, "bogus answer on get_numser\n");
- goto bad;
- }
- if (sc->sc_numser > MAX_SER)
- sc->sc_numser = MAX_SER;
- device_printf(self, "found %i serials\n", sc->sc_numser);
-
- sc->sc_port = malloc(sizeof(*sc->sc_port) * sc->sc_numser,
- M_USBDEV, M_WAITOK);
-
- /* find our bulk endpoints */
- epcount = 0;
- (void)usbd_endpoint_count(sc->sc_iface, &epcount);
- sc->sc_bulkin_no = -1;
- sc->sc_bulkout_no = -1;
- for (i = 0; i < epcount; i++) {
- ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
- if (ed == NULL) {
- device_printf(self, "couldn't get ep %d\n", i);
- return ENXIO;
- }
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
- sc->sc_bulkin_no = ed->bEndpointAddress;
- sc->sc_ibufsizepad = UGETW(ed->wMaxPacketSize);
- sc->sc_ibufsizepad = UGETW(ed->wMaxPacketSize) - 1;
- } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
- sc->sc_bulkout_no = ed->bEndpointAddress;
- sc->sc_obufsize = UGETW(ed->wMaxPacketSize) - 1;
- sc->sc_opkthdrlen = 1;
- }
- }
- if (sc->sc_bulkin_no == -1 || sc->sc_bulkout_no == -1) {
- device_printf(self, "could not find bulk in/out endpoint\n");
- sc->sc_dying = 1;
- goto bad;
- }
-
- /* Open the bulk pipes */
- /* Bulk-in pipe */
- err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkin_no, 0,
- &sc->sc_bulkin_pipe);
- if (err) {
- device_printf(self, "open bulk in error (addr %d): %s\n",
- sc->sc_bulkin_no, usbd_errstr(err));
- goto fail_0;
- }
- /* Bulk-out pipe */
- err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkout_no,
- USBD_EXCLUSIVE_USE, &sc->sc_bulkout_pipe);
- if (err) {
- device_printf(self, "open bulk out error (addr %d): %s\n",
- sc->sc_bulkout_no, usbd_errstr(err));
- goto fail_1;
- }
-
- /* Allocate a request and an input buffer */
- sc->sc_ixfer = usbd_alloc_xfer(sc->sc_udev);
- if (sc->sc_ixfer == NULL) {
- goto fail_2;
- }
-
- sc->sc_ibuf = usbd_alloc_buffer(sc->sc_ixfer,
- sc->sc_ibufsizepad);
- if (sc->sc_ibuf == NULL) {
- goto fail_3;
- }
-
- for (i = 0; i < sc->sc_numser; i++) {
- pp = &sc->sc_port[i];
- pp->p_port = i;
- pp->p_sc = sc;
- tp = pp->p_tty = ttyalloc();
- tp->t_sc = pp;
- DPRINTF(("ubser_attach: tty_attach tp = %p\n", tp));
- tp->t_oproc = ubserstart;
- tp->t_param = ubserparam;
- tp->t_stop = ubserstop;
- tp->t_break = ubserbreak;
- tp->t_open = ubseropen;
- tp->t_close = ubserclose;
- tp->t_modem = ubsermodem;
- ttycreate(tp, 0, "y%r%r", device_get_unit(sc->sc_dev), i);
- }
-
-
- for (i = 0; i < sc->sc_numser; i++) {
- sc->sc_port[i].p_oxfer = NULL;
- sc->sc_port[i].p_obuf = NULL;
- }
- for (i = 0; i < sc->sc_numser; i++) {
- sc->sc_port[i].p_oxfer = usbd_alloc_xfer(sc->sc_udev);
- if (sc->sc_port[i].p_oxfer == NULL) {
- goto fail_4;
- }
-
- sc->sc_port[i].p_obuf = usbd_alloc_buffer(sc->sc_port[i].p_oxfer,
- sc->sc_obufsize +
- sc->sc_opkthdrlen);
- if (sc->sc_port[i].p_obuf == NULL) {
- goto fail_4;
- }
- }
-
- ubserstartread(sc);
- return 0;
-
-fail_4:
- for (i = 0; i < sc->sc_numser; i++) {
- if (sc->sc_port[i].p_oxfer != NULL) {
- usbd_free_xfer(sc->sc_port[i].p_oxfer);
- sc->sc_port[i].p_oxfer = NULL;
- }
- }
-fail_3:
- usbd_free_xfer(sc->sc_ixfer);
- sc->sc_ixfer = NULL;
-fail_2:
- usbd_close_pipe(sc->sc_bulkout_pipe);
- sc->sc_bulkout_pipe = NULL;
-fail_1:
- usbd_close_pipe(sc->sc_bulkin_pipe);
- sc->sc_bulkin_pipe = NULL;
-fail_0:
- sc->sc_opening = 0;
- wakeup(&sc->sc_opening);
-
-bad:
- ubser_cleanup(sc);
- if (sc->sc_port != NULL) {
- for (i = 0; i < sc->sc_numser; i++) {
- pp = &sc->sc_port[i];
- if (pp->p_tty != NULL)
- ttyfree(pp->p_tty);
- }
- free(sc->sc_port, M_USBDEV);
- sc->sc_port = NULL;
- }
-
- DPRINTF(("ubser_attach: ATTACH ERROR\n"));
- return ENXIO;
-}
-
-static int
-ubser_detach(device_t self)
-{
- struct ubser_softc *sc = device_get_softc(self);
- int i;
- struct ubser_port *pp;
-
- DPRINTF(("ubser_detach: sc=%p\n", sc));
-
- sc->sc_dying = 1;
- for (i = 0; i < sc->sc_numser; i++) {
- pp = &sc->sc_port[i];
- if (pp->p_tty != NULL)
- ttygone(pp->p_tty);
- }
-
- if (sc->sc_bulkin_pipe != NULL)
- usbd_abort_pipe(sc->sc_bulkin_pipe);
- if (sc->sc_bulkout_pipe != NULL)
- usbd_abort_pipe(sc->sc_bulkout_pipe);
-
- if (sc->sc_port != NULL) {
- for (i = 0; i < sc->sc_numser; i++) {
- pp = &sc->sc_port[i];
- if (pp->p_tty != NULL)
- ttyfree(pp->p_tty);
- }
- free(sc->sc_port, M_USBDEV);
- sc->sc_port = NULL;
- }
-
- if (--sc->sc_refcnt >= 0) {
- /* Wait for processes to go away. */
- usb_detach_wait(sc->sc_dev);
- }
-
- return (0);
-}
-
-static int
-ubserparam(struct tty *tp, struct termios *t)
-{
- struct ubser_softc *sc;
- struct ubser_port *pp;
-
- pp = tp->t_sc;
- sc = pp->p_sc;
-
- if (sc->sc_dying)
- return (EIO);
-
- DPRINTF(("ubserparam: sc = %p\n", sc));
-
- /*
- * The firmware on our devices can only do 8n1@9600bps
- * without handshake.
- * We refuse to accept other configurations.
- */
-
- /* enshure 9600bps */
- switch (t->c_ospeed) {
- case 9600:
- break;
- default:
- return (EINVAL);
- }
-
- /* 2 stop bits not possible */
- if (ISSET(t->c_cflag, CSTOPB))
- return (EINVAL);
-
- /* XXX parity handling not possible with current firmware */
- if (ISSET(t->c_cflag, PARENB))
- return (EINVAL);
-
- /* we can only do 8 data bits */
- switch (ISSET(t->c_cflag, CSIZE)) {
- case CS8:
- break;
- default:
- return (EINVAL);
- }
-
- /* we can't do any kind of hardware handshaking */
- if ((t->c_cflag &
- (CRTS_IFLOW | CDTR_IFLOW |CDSR_OFLOW |CCAR_OFLOW)) != 0)
- return (EINVAL);
-
- /*
- * XXX xon/xoff not supported by the firmware!
- * This is handled within FreeBSD only and may overflow buffers
- * because of delayed reaction due to device buffering.
- */
-
- ttsetwater(tp);
-
- return (0);
-}
-
-static void
-ubserstart(struct tty *tp)
-{
- struct ubser_softc *sc;
- struct ubser_port *pp;
- struct cblock *cbp;
- usbd_status err;
- u_char *data;
- int cnt;
- uint8_t serial;
-
- pp = tp->t_sc;
- sc = pp->p_sc;
- serial = pp->p_port;
- DPRINTF(("ubserstart: sc = %p, tp = %p\n", sc, tp));
-
- if (sc->sc_dying)
- return;
-
- if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP)) {
- ttwwakeup(tp);
- DPRINTF(("ubserstart: stopped\n"));
- return;
- }
-
- if (tp->t_outq.c_cc <= tp->t_olowat) {
- if (ISSET(tp->t_state, TS_SO_OLOWAT)) {
- CLR(tp->t_state, TS_SO_OLOWAT);
- wakeup(TSA_OLOWAT(tp));
- }
- selwakeuppri(&tp->t_wsel, TTIPRI);
- if (tp->t_outq.c_cc == 0) {
- if (ISSET(tp->t_state, TS_BUSY | TS_SO_OCOMPLETE) ==
- TS_SO_OCOMPLETE && tp->t_outq.c_cc == 0) {
- CLR(tp->t_state, TS_SO_OCOMPLETE);
- wakeup(TSA_OCOMPLETE(tp));
- }
- return;
- }
- }
-
- /* Grab the first contiguous region of buffer space. */
- data = tp->t_outq.c_cf;
- cbp = (struct cblock *) ((intptr_t) tp->t_outq.c_cf & ~CROUND);
- cnt = min((char *) (cbp+1) - tp->t_outq.c_cf, tp->t_outq.c_cc);
-
- if (cnt == 0) {
- DPRINTF(("ubserstart: cnt == 0\n"));
- return;
- }
-
- SET(tp->t_state, TS_BUSY);
-
- if (cnt + sc->sc_opkthdrlen > sc->sc_obufsize) {
- DPRINTF(("ubserstart: big buffer %d chars\n", cnt));
- cnt = sc->sc_obufsize;
- }
- sc->sc_port[serial].p_obuf[0] = serial;
- memcpy(sc->sc_port[serial].p_obuf + sc->sc_opkthdrlen, data, cnt);
-
-
- DPRINTF(("ubserstart: %d chars\n", cnt));
- usbd_setup_xfer(sc->sc_port[serial].p_oxfer, sc->sc_bulkout_pipe,
- (usbd_private_handle)tp, sc->sc_port[serial].p_obuf,
- cnt + sc->sc_opkthdrlen,
- USBD_NO_COPY, USBD_NO_TIMEOUT, ubserwritecb);
- /* What can we do on error? */
- err = usbd_transfer(sc->sc_port[serial].p_oxfer);
- if (err != USBD_IN_PROGRESS)
- printf("ubserstart: err=%s\n", usbd_errstr(err));
-
- ttwwakeup(tp);
-}
-
-static void
-ubserstop(struct tty *tp, int flag)
-{
- struct ubser_softc *sc;
-
- sc = tp->t_sc;
-
- DPRINTF(("ubserstop: %d\n", flag));
-
- if (flag & FWRITE) {
- DPRINTF(("ubserstop: write\n"));
- if (ISSET(tp->t_state, TS_BUSY)) {
- /* XXX do what? */
- if (!ISSET(tp->t_state, TS_TTSTOP))
- SET(tp->t_state, TS_FLUSH);
- }
- }
-
- DPRINTF(("ubserstop: done\n"));
-}
-
-static void
-ubserwritecb(usbd_xfer_handle xfer, usbd_private_handle p, usbd_status status)
-{
- struct tty *tp;
- struct ubser_softc *sc;
- struct ubser_port *pp;
- u_int32_t cc;
-
- tp = (struct tty *)p;
- pp = tp->t_sc;
- sc = pp->p_sc;
-
- DPRINTF(("ubserwritecb: status = %d\n", status));
-
- if (status == USBD_CANCELLED || sc->sc_dying)
- goto error;
-
- if (status != USBD_NORMAL_COMPLETION) {
- device_printf(sc->sc_dev, "ubserwritecb: %s\n",
- usbd_errstr(status));
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall_async(sc->sc_bulkin_pipe);
- /* XXX we should restart after some delay. */
- goto error;
- }
-
- usbd_get_xfer_status(xfer, NULL, NULL, &cc, NULL);
- DPRINTF(("ubserwritecb: cc = %d\n", cc));
- if (cc <= sc->sc_opkthdrlen) {
- device_printf(sc->sc_dev, "sent size too small, cc = %d\n",
- cc);
- goto error;
- }
-
- /* convert from USB bytes to tty bytes */
- cc -= sc->sc_opkthdrlen;
-
- CLR(tp->t_state, TS_BUSY);
- if (ISSET(tp->t_state, TS_FLUSH))
- CLR(tp->t_state, TS_FLUSH);
- else
- ndflush(&tp->t_outq, cc);
- ttyld_start(tp);
-
- return;
-
-error:
- CLR(tp->t_state, TS_BUSY);
- return;
-}
-
-static usbd_status
-ubserstartread(struct ubser_softc *sc)
-{
- usbd_status err;
-
- DPRINTF(("ubserstartread: start\n"));
-
- if (sc->sc_bulkin_pipe == NULL)
- return (USBD_NORMAL_COMPLETION);
-
- usbd_setup_xfer(sc->sc_ixfer, sc->sc_bulkin_pipe,
- (usbd_private_handle)sc,
- sc->sc_ibuf, sc->sc_ibufsizepad,
- USBD_SHORT_XFER_OK | USBD_NO_COPY,
- USBD_NO_TIMEOUT, ubserreadcb);
-
- err = usbd_transfer(sc->sc_ixfer);
- if (err != USBD_IN_PROGRESS) {
- DPRINTF(("ubserstartread: err = %s\n", usbd_errstr(err)));
- return (err);
- }
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-static void
-ubserreadcb(usbd_xfer_handle xfer, usbd_private_handle p, usbd_status status)
-{
- struct ubser_softc *sc = (struct ubser_softc *)p;
- struct tty *tp;
- usbd_status err;
- u_int32_t cc;
- u_char *cp;
- int lostcc;
-
- if (status == USBD_IOERROR) {
- device_printf(sc->sc_dev, "ubserreadcb: %s - restarting\n",
- usbd_errstr(status));
- goto resubmit;
- }
-
- DPRINTF(("ubserreadcb: status = %d\n", status));
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status != USBD_CANCELLED) {
- device_printf(sc->sc_dev, "ubserreadcb: %s\n",
- usbd_errstr(status));
- }
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall_async(sc->sc_bulkin_pipe);
- return;
- }
-
- usbd_get_xfer_status(xfer, NULL, (void **)&cp, &cc, NULL);
-
- DPRINTF(("ubserreadcb: got %d bytes from device\n", cc));
- if (cc == 0)
- goto resubmit;
-
- if (cc > sc->sc_ibufsizepad) {
- device_printf(sc->sc_dev, "invalid receive data size, %d chars\n",
- cc);
- goto resubmit;
- }
-
- /* parse header */
- if (cc < 1)
- goto resubmit;
- DPRINTF(("ubserreadcb: got %d chars for serial %d\n", cc - 1, *cp));
- tp = sc->sc_port[*cp].p_tty;
- cp++;
- cc--;
-
- if (cc < 1)
- goto resubmit;
-
- if (!(tp->t_state & TS_ISOPEN)) /* drop data for unused serials */
- goto resubmit;
-
- if (tp->t_state & TS_CAN_BYPASS_L_RINT) {
- if (tp->t_rawq.c_cc + cc > tp->t_ihiwat
- && (tp->t_iflag & IXOFF)
- && !(tp->t_state & TS_TBLOCK))
- ttyblock(tp);
- lostcc = b_to_q((char *)cp, cc, &tp->t_rawq);
- tp->t_rawcc += cc;
- ttwakeup(tp);
- if (tp->t_state & TS_TTSTOP
- && (tp->t_iflag & IXANY
- || tp->t_cc[VSTART] == tp->t_cc[VSTOP])) {
- tp->t_state &= ~TS_TTSTOP;
- tp->t_lflag &= ~FLUSHO;
- ubserstart(tp);
- }
- if (lostcc > 0)
- device_printf(sc->sc_dev, "lost %d chars\n", lostcc);
- } else {
- /* Give characters to tty layer. */
- while (cc > 0) {
- DPRINTFN(7, ("ubserreadcb: char = 0x%02x\n", *cp));
- if (ttyld_rint(tp, *cp) == -1) {
- /* XXX what should we do? */
- device_printf(sc->sc_dev, "lost %d chars\n",
- cc);
- break;
- }
- cc--;
- cp++;
- }
- }
-
-resubmit:
- err = ubserstartread(sc);
- if (err) {
- device_printf(sc->sc_dev, "read start failed\n");
- /* XXX what should we do now? */
- }
-
-}
-
-static void
-ubser_cleanup(struct ubser_softc *sc)
-{
- int i;
- struct ubser_port *pp;
-
- DPRINTF(("ubser_cleanup: closing pipes\n"));
-
- if (sc->sc_bulkin_pipe != NULL) {
- usbd_abort_pipe(sc->sc_bulkin_pipe);
- usbd_close_pipe(sc->sc_bulkin_pipe);
- sc->sc_bulkin_pipe = NULL;
- }
- if (sc->sc_bulkout_pipe != NULL) {
- usbd_abort_pipe(sc->sc_bulkout_pipe);
- usbd_close_pipe(sc->sc_bulkout_pipe);
- sc->sc_bulkout_pipe = NULL;
- }
- if (sc->sc_ixfer != NULL) {
- usbd_free_xfer(sc->sc_ixfer);
- sc->sc_ixfer = NULL;
- }
- for (i = 0; i < sc->sc_numser; i++) {
- pp = &sc->sc_port[i];
- if (pp->p_oxfer != NULL) {
- usbd_free_xfer(pp->p_oxfer);
- pp->p_oxfer = NULL;
- }
- }
-}
-
-static int
-ubseropen(struct tty *tp, struct cdev *dev)
-{
- struct ubser_softc *sc;
- struct ubser_port *pp;
-
- pp = tp->t_sc;
- sc = pp->p_sc;
-
- sc->sc_refcnt++; /* XXX: wrong refcnt on error later on */
- return (0);
-}
-
-static void
-ubserclose(struct tty *tp)
-{
- struct ubser_softc *sc;
- struct ubser_port *pp;
-
- pp = tp->t_sc;
- sc = pp->p_sc;
- if (--sc->sc_refcnt < 0)
- usb_detach_wakeup(sc->sc_dev);
-}
-
-static void
-ubserbreak(struct tty *tp, int sig)
-{
- usb_device_request_t req;
- struct ubser_softc *sc;
- struct ubser_port *pp;
- int error;
- int alen;
-
- pp = tp->t_sc;
- sc = pp->p_sc;
- if (sig) {
- DPRINTF(("ubser_break: TIOCSBRK\n"));
- req.bmRequestType = UT_READ_VENDOR_INTERFACE;
- req.bRequest = VENDOR_SET_BREAK;
- USETW(req.wValue, pp->p_port);
- USETW(req.wIndex, sc->sc_ifaceno);
- USETW(req.wLength, 0);
- error = usbd_do_request_flags(sc->sc_udev, &req, &sc->sc_numser,
- USBD_SHORT_XFER_OK, &alen, USBD_DEFAULT_TIMEOUT);
- }
-}
-
-static int
-ubsermodem(struct tty *tp, int sigon, int sigoff)
-{
-
- return (SER_DTR | SER_RTS | SER_DCD);
-}
-
-MODULE_DEPEND(ubser, usb, 1, 1, 1);
-DRIVER_MODULE(ubser, uhub, ubser_driver, ubser_devclass, usbd_driver_load, 0);
diff --git a/sys/dev/usb/ubser.h b/sys/dev/usb/ubser.h
deleted file mode 100644
index f256d4a..0000000
--- a/sys/dev/usb/ubser.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*-
- * Copyright (c) 2003 Bernd Walter <ticso@freebsd.org>
- *
- * $URL: https://devel.bwct.de/svn/projects/ubser/ubser.h $
- * $Date: 2004-02-29 01:53:10 +0100 (Sun, 29 Feb 2004) $
- * $Author: ticso $
- * $Rev: 1127 $
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- * $FreeBSD$
- */
-
-#ifndef UBSER_H
-#define UBSER_H
-
-#define MAX_SER 32
-
-/* Vendor Interface Requests */
-#define VENDOR_GET_NUMSER 0x01
-#define VENDOR_SET_BREAK 0x02
-#define VENDOR_CLEAR_BREAK 0x03
-
-#endif /* UBSER_H */
diff --git a/sys/dev/usb/uchcom.c b/sys/dev/usb/uchcom.c
deleted file mode 100644
index 85b2629..0000000
--- a/sys/dev/usb/uchcom.c
+++ /dev/null
@@ -1,1036 +0,0 @@
-/* $NetBSD: uchcom.c,v 1.1 2007/09/03 17:57:37 tshiozak Exp $ */
-
-/*-
- * Copyright (c) 2007, Takanori Watanabe
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- */
-
-/*
- * Copyright (c) 2007 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Takuya SHIOZAKI (tshiozak@netbsd.org).
- *
- * 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * driver for WinChipHead CH341/340, the worst USB-serial chip in the world.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/conf.h>
-#include <sys/tty.h>
-#include <sys/file.h>
-#include <sys/select.h>
-#include <sys/proc.h>
-#include <sys/bus.h>
-#include <sys/poll.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbcdc.h>
-
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include <dev/usb/usb_quirks.h>
-
-#include <dev/usb/ucomvar.h>
-#include "usbdevs.h"
-
-#ifdef UCHCOM_DEBUG
-#define DPRINTFN(n, x) if (uchcomdebug > (n)) logprintf x
-int uchcomdebug = 0;
-#else
-#define DPRINTFN(n, x)
-#endif
-#define DPRINTF(x) DPRINTFN(0, x)
-
-#define UCHCOM_IFACE_INDEX 0
-#define UCHCOM_CONFIG_INDEX 0
-
-#define UCHCOM_REV_CH340 0x0250
-#define UCHCOM_INPUT_BUF_SIZE 8
-
-#define UCHCOM_REQ_GET_VERSION 0x5F
-#define UCHCOM_REQ_READ_REG 0x95
-#define UCHCOM_REQ_WRITE_REG 0x9A
-#define UCHCOM_REQ_RESET 0xA1
-#define UCHCOM_REQ_SET_DTRRTS 0xA4
-
-#define UCHCOM_REG_STAT1 0x06
-#define UCHCOM_REG_STAT2 0x07
-#define UCHCOM_REG_BPS_PRE 0x12
-#define UCHCOM_REG_BPS_DIV 0x13
-#define UCHCOM_REG_BPS_MOD 0x14
-#define UCHCOM_REG_BPS_PAD 0x0F
-#define UCHCOM_REG_BREAK1 0x05
-#define UCHCOM_REG_BREAK2 0x18
-#define UCHCOM_REG_LCR1 0x18
-#define UCHCOM_REG_LCR2 0x25
-
-#define UCHCOM_VER_20 0x20
-
-#define UCHCOM_BASE_UNKNOWN 0
-#define UCHCOM_BPS_MOD_BASE 20000000
-#define UCHCOM_BPS_MOD_BASE_OFS 1100
-
-#define UCHCOM_DTR_MASK 0x20
-#define UCHCOM_RTS_MASK 0x40
-
-#define UCHCOM_BRK1_MASK 0x01
-#define UCHCOM_BRK2_MASK 0x40
-
-#define UCHCOM_LCR1_MASK 0xAF
-#define UCHCOM_LCR2_MASK 0x07
-#define UCHCOM_LCR1_PARENB 0x80
-#define UCHCOM_LCR2_PAREVEN 0x07
-#define UCHCOM_LCR2_PARODD 0x06
-#define UCHCOM_LCR2_PARMARK 0x05
-#define UCHCOM_LCR2_PARSPACE 0x04
-
-#define UCHCOM_INTR_STAT1 0x02
-#define UCHCOM_INTR_STAT2 0x03
-#define UCHCOM_INTR_LEAST 4
-
-#define UCHCOMIBUFSIZE 256
-#define UCHCOMOBUFSIZE 256
-
-struct uchcom_softc
-{
- struct ucom_softc sc_ucom;
-
- /* */
- int sc_intr_endpoint;
- int sc_intr_size;
- usbd_pipe_handle sc_intr_pipe;
- u_char *sc_intr_buf;
- /* */
- uint8_t sc_version;
- int sc_dtr;
- int sc_rts;
- u_char sc_lsr;
- u_char sc_msr;
- int sc_lcr1;
- int sc_lcr2;
-};
-
-struct uchcom_endpoints
-{
- int ep_bulkin;
- int ep_bulkout;
- int ep_intr;
- int ep_intr_size;
-};
-
-struct uchcom_divider
-{
- uint8_t dv_prescaler;
- uint8_t dv_div;
- uint8_t dv_mod;
-};
-
-struct uchcom_divider_record
-{
- uint32_t dvr_high;
- uint32_t dvr_low;
- uint32_t dvr_base_clock;
- struct uchcom_divider dvr_divider;
-};
-
-static const struct uchcom_divider_record dividers[] =
-{
- { 307200, 307200, UCHCOM_BASE_UNKNOWN, { 7, 0xD9, 0 } },
- { 921600, 921600, UCHCOM_BASE_UNKNOWN, { 7, 0xF3, 0 } },
- { 2999999, 23530, 6000000, { 3, 0, 0 } },
- { 23529, 2942, 750000, { 2, 0, 0 } },
- { 2941, 368, 93750, { 1, 0, 0 } },
- { 367, 1, 11719, { 0, 0, 0 } },
-};
-#define NUM_DIVIDERS (sizeof (dividers) / sizeof (dividers[0]))
-
-static const struct usb_devno uchcom_devs[] = {
- { USB_VENDOR_WCH, USB_PRODUCT_WCH_CH341SER },
-};
-#define uchcom_lookup(v, p) usb_lookup(uchcom_devs, v, p)
-
-static void uchcom_get_status(void *, int, u_char *, u_char *);
-static void uchcom_set(void *, int, int, int);
-static int uchcom_param(void *, int, struct termios *);
-static int uchcom_open(void *, int);
-static void uchcom_close(void *, int);
-static void uchcom_intr(usbd_xfer_handle, usbd_private_handle,
- usbd_status);
-
-static int set_config(device_t );
-static int find_ifaces(struct uchcom_softc *, usbd_interface_handle *);
-static int find_endpoints(struct uchcom_softc *,
- struct uchcom_endpoints *);
-static void close_intr_pipe(struct uchcom_softc *);
-
-static int uchcom_match(device_t );
-static int uchcom_attach(device_t );
-static int uchcom_detach(device_t );
-
-struct ucom_callback uchcom_callback = {
- .ucom_get_status = uchcom_get_status,
- .ucom_set = uchcom_set,
- .ucom_param = uchcom_param,
- .ucom_ioctl = NULL,
- .ucom_open = uchcom_open,
- .ucom_close = uchcom_close,
- .ucom_read = NULL,
- .ucom_write = NULL,
-};
-
-
-
-
-/* ----------------------------------------------------------------------
- * driver entry points
- */
-
-static int uchcom_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
-
- return (uchcom_lookup(uaa->vendor, uaa->product) != NULL ?
- UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
-}
-
-static int uchcom_attach(device_t self)
-{
- struct uchcom_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usbd_device_handle dev = uaa->device;
-
- struct uchcom_endpoints endpoints;
- struct ucom_softc *ucom = &sc->sc_ucom;
-
- ucom->sc_dev = self;
- ucom->sc_udev = dev;
-
- ucom->sc_dying = 0;
- sc->sc_dtr = sc->sc_rts = -1;
- sc->sc_lsr = sc->sc_msr = 0;
-
- DPRINTF(("\n\nuchcom attach: sc=%p\n", sc));
-
- if (set_config(self))
- goto failed;
-
- switch (uaa->release) {
- case UCHCOM_REV_CH340:
- device_printf(self, "CH340 detected\n");
- break;
- default:
- device_printf(self, "CH341 detected\n");
- break;
- }
-
- if (find_ifaces(sc, &ucom->sc_iface))
- goto failed;
-
- if (find_endpoints(sc, &endpoints))
- goto failed;
-
- sc->sc_intr_endpoint = endpoints.ep_intr;
- sc->sc_intr_size = endpoints.ep_intr_size;
-
- /* setup ucom layer */
- ucom->sc_portno = UCOM_UNK_PORTNO;
- ucom->sc_bulkin_no = endpoints.ep_bulkin;
- ucom->sc_bulkout_no = endpoints.ep_bulkout;
- ucom->sc_ibufsize = UCHCOMIBUFSIZE;
- ucom->sc_obufsize = UCHCOMOBUFSIZE;
- ucom->sc_ibufsizepad = UCHCOMIBUFSIZE;
- ucom->sc_opkthdrlen = 0;
- ucom->sc_parent = sc;
-
- ucom->sc_callback = &uchcom_callback;
-
- ucom_attach(&sc->sc_ucom);
-
- return 0;
-
-failed:
- ucom->sc_dying = 1;
- return ENXIO;
-}
-
-static int uchcom_detach(device_t self)
-{
- struct uchcom_softc *sc = device_get_softc(self);
- struct ucom_softc *ucom = &sc->sc_ucom ;
- int rv = 0;
-
- DPRINTF(("uchcom_detach: sc=%p flags=%d\n", sc, flags));
-
- close_intr_pipe(sc);
-
- ucom->sc_dying = 1;
-
- rv = ucom_detach(ucom);
-
- return rv;
-}
-static int
-set_config(device_t dev)
-{
- struct uchcom_softc *sc = device_get_softc(dev);
- struct ucom_softc *ucom = &sc->sc_ucom;
- usbd_status err;
-
- err = usbd_set_config_index(ucom->sc_udev, UCHCOM_CONFIG_INDEX, 1);
- if (err) {
- device_printf(dev, "failed to set configuration: %s\n",
- usbd_errstr(err));
- return -1;
- }
-
- return 0;
-}
-
-static int
-find_ifaces(struct uchcom_softc *sc, usbd_interface_handle *riface)
-{
- usbd_status err;
- struct ucom_softc *ucom = &sc->sc_ucom;
-
- err = usbd_device2interface_handle(ucom->sc_udev, UCHCOM_IFACE_INDEX,
- riface);
- if (err) {
- device_printf(ucom->sc_dev, "failed to get interface: %s\n",
- usbd_errstr(err));
- return -1;
- }
-
- return 0;
-}
-
-static int
-find_endpoints(struct uchcom_softc *sc, struct uchcom_endpoints *endpoints)
-{
- struct ucom_softc *ucom= &sc->sc_ucom;
- int i, bin=-1, bout=-1, intr=-1, isize=0;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
-
- id = usbd_get_interface_descriptor(ucom->sc_iface);
-
- for (i = 0; i < id->bNumEndpoints; i++) {
- ed = usbd_interface2endpoint_descriptor(ucom->sc_iface, i);
- if (ed == NULL) {
- device_printf(ucom->sc_dev, "no endpoint descriptor for %d\n", i);
- return -1;
- }
-
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
- intr = ed->bEndpointAddress;
- isize = UGETW(ed->wMaxPacketSize);
- } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
- bin = ed->bEndpointAddress;
- } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
- bout = ed->bEndpointAddress;
- }
- }
-
- if (intr == -1 || bin == -1 || bout == -1) {
- if (intr == -1) {
- device_printf(ucom->sc_dev, "no interrupt end point\n");
- }
- if (bin == -1) {
- device_printf(ucom->sc_dev, "no data bulk in end point\n");
-
- }
- if (bout == -1) {
- device_printf(ucom->sc_dev, "no data bulk out end point\n");
- }
- return -1;
- }
- if (isize < UCHCOM_INTR_LEAST) {
- device_printf(ucom->sc_dev, "intr pipe is too short");
- return -1;
- }
-
- DPRINTF(("%s: bulkin=%d, bulkout=%d, intr=%d, isize=%d\n",
- USBDEVNAME(sc->sc_dev), bin, bout, intr, isize));
-
- endpoints->ep_intr = intr;
- endpoints->ep_intr_size = isize;
- endpoints->ep_bulkin = bin;
- endpoints->ep_bulkout = bout;
-
- return 0;
-}
-
-
-/* ----------------------------------------------------------------------
- * low level i/o
- */
-
-static __inline usbd_status
-generic_control_out(struct uchcom_softc *sc, uint8_t reqno,
- uint16_t value, uint16_t index)
-{
- usb_device_request_t req;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = reqno;
- USETW(req.wValue, value);
- USETW(req.wIndex, index);
- USETW(req.wLength, 0);
-
- return usbd_do_request(sc->sc_ucom.sc_udev, &req, 0);
-}
-
-static __inline usbd_status
-generic_control_in(struct uchcom_softc *sc, uint8_t reqno,
- uint16_t value, uint16_t index, void *buf, int buflen,
- int *actlen)
-{
- usb_device_request_t req;
-
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = reqno;
- USETW(req.wValue, value);
- USETW(req.wIndex, index);
- USETW(req.wLength, (uint16_t)buflen);
-
- return usbd_do_request_flags(sc->sc_ucom.sc_udev, &req, buf,
- USBD_SHORT_XFER_OK, actlen,
- USBD_DEFAULT_TIMEOUT);
-}
-
-static __inline usbd_status
-write_reg(struct uchcom_softc *sc,
- uint8_t reg1, uint8_t val1, uint8_t reg2, uint8_t val2)
-{
- DPRINTF(("uchcom: write reg 0x%02X<-0x%02X, 0x%02X<-0x%02X\n",
- (unsigned)reg1, (unsigned)val1,
- (unsigned)reg2, (unsigned)val2));
- return generic_control_out(
- sc, UCHCOM_REQ_WRITE_REG,
- reg1|((uint16_t)reg2<<8), val1|((uint16_t)val2<<8));
-}
-
-static __inline usbd_status
-read_reg(struct uchcom_softc *sc,
- uint8_t reg1, uint8_t *rval1, uint8_t reg2, uint8_t *rval2)
-{
- uint8_t buf[UCHCOM_INPUT_BUF_SIZE];
- usbd_status err;
- int actin;
-
- err = generic_control_in(
- sc, UCHCOM_REQ_READ_REG,
- reg1|((uint16_t)reg2<<8), 0, buf, sizeof buf, &actin);
- if (err)
- return err;
-
- DPRINTF(("uchcom: read reg 0x%02X->0x%02X, 0x%02X->0x%02X\n",
- (unsigned)reg1, (unsigned)buf[0],
- (unsigned)reg2, (unsigned)buf[1]));
-
- if (rval1) *rval1 = buf[0];
- if (rval2) *rval2 = buf[1];
-
- return USBD_NORMAL_COMPLETION;
-}
-
-static __inline usbd_status
-get_version(struct uchcom_softc *sc, uint8_t *rver)
-{
- uint8_t buf[UCHCOM_INPUT_BUF_SIZE];
- usbd_status err;
- int actin;
-
- err = generic_control_in(
- sc, UCHCOM_REQ_GET_VERSION, 0, 0, buf, sizeof buf, &actin);
- if (err)
- return err;
-
- if (rver) *rver = buf[0];
-
- return USBD_NORMAL_COMPLETION;
-}
-
-static __inline usbd_status
-get_status(struct uchcom_softc *sc, uint8_t *rval)
-{
- return read_reg(sc, UCHCOM_REG_STAT1, rval, UCHCOM_REG_STAT2, NULL);
-}
-
-static __inline usbd_status
-set_dtrrts_10(struct uchcom_softc *sc, uint8_t val)
-{
- return write_reg(sc, UCHCOM_REG_STAT1, val, UCHCOM_REG_STAT1, val);
-}
-
-static __inline usbd_status
-set_dtrrts_20(struct uchcom_softc *sc, uint8_t val)
-{
- return generic_control_out(sc, UCHCOM_REQ_SET_DTRRTS, val, 0);
-}
-
-
-/* ----------------------------------------------------------------------
- * middle layer
- */
-
-static int
-update_version(struct uchcom_softc *sc)
-{
- usbd_status err;
-
- err = get_version(sc, &sc->sc_version);
- if (err) {
- device_printf(sc->sc_ucom.sc_dev, "cannot get version: %s\n",
- usbd_errstr(err));
- return EIO;
- }
-
- return 0;
-}
-
-static void
-convert_status(struct uchcom_softc *sc, uint8_t cur)
-{
- sc->sc_dtr = !(cur & UCHCOM_DTR_MASK);
- sc->sc_rts = !(cur & UCHCOM_RTS_MASK);
-
- cur = ~cur & 0x0F;
- sc->sc_msr = (cur << 4) | ((sc->sc_msr >> 4) ^ cur);
-}
-
-static int
-update_status(struct uchcom_softc *sc)
-{
- usbd_status err;
- uint8_t cur;
-
- err = get_status(sc, &cur);
- if (err) {
- device_printf(sc->sc_ucom.sc_dev,
- "cannot update status: %s\n",
- usbd_errstr(err));
- return EIO;
- }
- convert_status(sc, cur);
-
- return 0;
-}
-
-
-static int
-set_dtrrts(struct uchcom_softc *sc, int dtr, int rts)
-{
- usbd_status err;
- uint8_t val = 0;
-
- if (dtr) val |= UCHCOM_DTR_MASK;
- if (rts) val |= UCHCOM_RTS_MASK;
-
- if (sc->sc_version < UCHCOM_VER_20)
- err = set_dtrrts_10(sc, ~val);
- else
- err = set_dtrrts_20(sc, ~val);
-
- if (err) {
- device_printf(sc->sc_ucom.sc_dev, "cannot set DTR/RTS: %s\n",
- usbd_errstr(err));
- return EIO;
- }
-
- return 0;
-}
-
-static int
-set_break(struct uchcom_softc *sc, int onoff)
-{
- usbd_status err;
- uint8_t brk1, brk2;
-
- err = read_reg(sc, UCHCOM_REG_BREAK1, &brk1, UCHCOM_REG_BREAK2, &brk2);
- if (err)
- return EIO;
- if (onoff) {
- /* on - clear bits */
- brk1 &= ~UCHCOM_BRK1_MASK;
- brk2 &= ~UCHCOM_BRK2_MASK;
- } else {
- /* off - set bits */
- brk1 |= UCHCOM_BRK1_MASK;
- brk2 |= UCHCOM_BRK2_MASK;
- }
- err = write_reg(sc, UCHCOM_REG_BREAK1, brk1, UCHCOM_REG_BREAK2, brk2);
- if (err)
- return EIO;
-
- return 0;
-}
-
-static int
-calc_divider_settings(struct uchcom_divider *dp, uint32_t rate)
-{
- int i;
- const struct uchcom_divider_record *rp;
- uint32_t div, rem, mod;
-
- /* find record */
- for (i=0; i<NUM_DIVIDERS; i++) {
- if (dividers[i].dvr_high >= rate &&
- dividers[i].dvr_low <= rate) {
- rp = &dividers[i];
- goto found;
- }
- }
- return -1;
-
-found:
- dp->dv_prescaler = rp->dvr_divider.dv_prescaler;
- if (rp->dvr_base_clock == UCHCOM_BASE_UNKNOWN)
- dp->dv_div = rp->dvr_divider.dv_div;
- else {
- div = rp->dvr_base_clock / rate;
- rem = rp->dvr_base_clock % rate;
- if (div==0 || div>=0xFF)
- return -1;
- if ((rem<<1) >= rate)
- div += 1;
- dp->dv_div = (uint8_t)-div;
- }
-
- mod = UCHCOM_BPS_MOD_BASE/rate + UCHCOM_BPS_MOD_BASE_OFS;
- mod = mod + mod/2;
-
- dp->dv_mod = mod / 0x100;
-
- return 0;
-}
-
-static int
-set_dte_rate(struct uchcom_softc *sc, uint32_t rate)
-{
- usbd_status err;
- struct uchcom_divider dv;
-
- if (calc_divider_settings(&dv, rate))
- return EINVAL;
-
- if ((err = write_reg(sc,
- UCHCOM_REG_BPS_PRE, dv.dv_prescaler,
- UCHCOM_REG_BPS_DIV, dv.dv_div)) ||
- (err = write_reg(sc,
- UCHCOM_REG_BPS_MOD, dv.dv_mod,
- UCHCOM_REG_BPS_PAD, 0))) {
- device_printf(sc->sc_ucom.sc_dev, " cannot set DTE rate: %s\n",
- usbd_errstr(err));
- return EIO;
- }
-
- return 0;
-}
-
-static int
-set_line_control(struct uchcom_softc *sc, tcflag_t cflag)
-{
- usbd_status err;
- uint8_t lcr1 = 0, lcr2 = 0;
-
- err = read_reg(sc, UCHCOM_REG_LCR1, &lcr1, UCHCOM_REG_LCR2, &lcr2);
- if (err) {
- device_printf(sc->sc_ucom.sc_dev, " cannot get LCR: %s\n",
- usbd_errstr(err));
- return EIO;
- }
-
- lcr1 &= ~UCHCOM_LCR1_MASK;
- lcr2 &= ~UCHCOM_LCR2_MASK;
-
- /*
- * XXX: it is difficult to handle the line control appropriately:
- * - CS8, !CSTOPB and any parity mode seems ok, but
- * - the chip doesn't have the function to calculate parity
- * in !CS8 mode.
- * - it is unclear that the chip supports CS5,6 mode.
- * - it is unclear how to handle stop bits.
- */
-
- switch (ISSET(cflag, CSIZE)) {
- case CS5:
- case CS6:
- case CS7:
- return EINVAL;
- case CS8:
- break;
- }
-
- if (ISSET(cflag, PARENB)) {
- lcr1 |= UCHCOM_LCR1_PARENB;
- if (ISSET(cflag, PARODD))
- lcr2 |= UCHCOM_LCR2_PARODD;
- else
- lcr2 |= UCHCOM_LCR2_PAREVEN;
- }
-
- err = write_reg(sc, UCHCOM_REG_LCR1, lcr1, UCHCOM_REG_LCR2, lcr2);
- if (err) {
- device_printf(sc->sc_ucom.sc_dev, "cannot set LCR: %s\n",
- usbd_errstr(err));
- return EIO;
- }
-
- return 0;
-}
-
-static int
-clear_chip(struct uchcom_softc *sc)
-{
- usbd_status err;
-
- DPRINTF(("%s: clear\n", USBDEVNAME(sc->sc_dev)));
- err = generic_control_out(sc, UCHCOM_REQ_RESET, 0, 0);
- if (err) {
- device_printf(sc->sc_ucom.sc_dev, "cannot clear: %s\n",
- usbd_errstr(err));
- return EIO;
- }
-
- return 0;
-}
-
-static int
-reset_chip(struct uchcom_softc *sc)
-{
- usbd_status err;
- uint8_t lcr1, lcr2, pre, div, mod;
- uint16_t val=0, idx=0;
-
- err = read_reg(sc, UCHCOM_REG_LCR1, &lcr1, UCHCOM_REG_LCR2, &lcr2);
- if (err)
- goto failed;
-
- err = read_reg(sc, UCHCOM_REG_BPS_PRE, &pre, UCHCOM_REG_BPS_DIV, &div);
- if (err)
- goto failed;
-
- err = read_reg(sc, UCHCOM_REG_BPS_MOD, &mod, UCHCOM_REG_BPS_PAD, NULL);
- if (err)
- goto failed;
-
- val |= (uint16_t)(lcr1&0xF0) << 8;
- val |= 0x01;
- val |= (uint16_t)(lcr2&0x0F) << 8;
- val |= 0x02;
- idx |= pre & 0x07;
- val |= 0x04;
- idx |= (uint16_t)div << 8;
- val |= 0x08;
- idx |= mod & 0xF8;
- val |= 0x10;
-
- DPRINTF(("%s: reset v=0x%04X, i=0x%04X\n",
- USBDEVNAME(sc->sc_dev), val, idx));
-
- err = generic_control_out(sc, UCHCOM_REQ_RESET, val, idx);
- if (err)
- goto failed;
-
- return 0;
-
-failed:
- device_printf(sc->sc_ucom.sc_dev, "cannot reset: %s\n",
- usbd_errstr(err));
- return EIO;
-}
-
-static int
-setup_comm(struct uchcom_softc *sc)
-{
- int ret;
-
- ret = update_version(sc);
- if (ret)
- return ret;
-
- ret = clear_chip(sc);
- if (ret)
- return ret;
-
- ret = set_dte_rate(sc, TTYDEF_SPEED);
- if (ret)
- return ret;
-
- ret = set_line_control(sc, CS8);
- if (ret)
- return ret;
-
- ret = update_status(sc);
- if (ret)
- return ret;
-
- ret = reset_chip(sc);
- if (ret)
- return ret;
-
- ret = set_dte_rate(sc, TTYDEF_SPEED); /* XXX */
- if (ret)
- return ret;
-
- sc->sc_dtr = sc->sc_rts = 1;
- ret = set_dtrrts(sc, sc->sc_dtr, sc->sc_rts);
- if (ret)
- return ret;
-
- return 0;
-}
-
-static int
-setup_intr_pipe(struct uchcom_softc *sc)
-{
- usbd_status err;
- struct ucom_softc *ucom = &sc->sc_ucom;
- if (sc->sc_intr_endpoint != -1 && sc->sc_intr_pipe == NULL) {
- sc->sc_intr_buf = malloc(sc->sc_intr_size, M_USBDEV, M_WAITOK);
- err = usbd_open_pipe_intr(ucom->sc_iface,
- sc->sc_intr_endpoint,
- USBD_SHORT_XFER_OK,
- &sc->sc_intr_pipe, sc,
- sc->sc_intr_buf,
- sc->sc_intr_size,
- uchcom_intr, USBD_DEFAULT_INTERVAL);
- if (err) {
- device_printf(ucom->sc_dev,
- "cannot open interrupt pipe: %s\n",
- usbd_errstr(err));
- return EIO;
- }
- }
- return 0;
-}
-
-static void
-close_intr_pipe(struct uchcom_softc *sc)
-{
- usbd_status err;
- struct ucom_softc *ucom = &sc->sc_ucom;
- if (ucom->sc_dying)
- return;
-
- if (sc->sc_intr_pipe != NULL) {
- err = usbd_abort_pipe(sc->sc_intr_pipe);
- if (err)
- device_printf(ucom->sc_dev,
- "abort interrupt pipe failed: %s\n",
- usbd_errstr(err));
- err = usbd_close_pipe(sc->sc_intr_pipe);
- if (err)
- device_printf(ucom->sc_dev,
- " close interrupt pipe failed: %s\n",
- usbd_errstr(err));
- free(sc->sc_intr_buf, M_USBDEV);
- sc->sc_intr_pipe = NULL;
- }
-}
-
-
-/* ----------------------------------------------------------------------
- * methods for ucom
- */
-void
-uchcom_get_status(void *arg, int portno, u_char *rlsr, u_char *rmsr)
-{
- struct uchcom_softc *sc = arg;
-
- if (sc->sc_ucom.sc_dying)
- return;
-
- *rlsr = sc->sc_lsr;
- *rmsr = sc->sc_msr;
-}
-
-void
-uchcom_set(void *arg, int portno, int reg, int onoff)
-{
- struct uchcom_softc *sc = arg;
-
- if (sc->sc_ucom.sc_dying)
- return;
-
- switch (reg) {
- case UCOM_SET_DTR:
- sc->sc_dtr = !!onoff;
- set_dtrrts(sc, sc->sc_dtr, sc->sc_rts);
- break;
- case UCOM_SET_RTS:
- sc->sc_rts = !!onoff;
- set_dtrrts(sc, sc->sc_dtr, sc->sc_rts);
- break;
- case UCOM_SET_BREAK:
- set_break(sc, onoff);
- break;
- }
-}
-
-int
-uchcom_param(void *arg, int portno, struct termios *t)
-{
- struct uchcom_softc *sc = arg;
- int ret;
-
- if (sc->sc_ucom.sc_dying)
- return 0;
-
- ret = set_line_control(sc, t->c_cflag);
- if (ret)
- return ret;
-
- ret = set_dte_rate(sc, t->c_ospeed);
- if (ret)
- return ret;
-
- return 0;
-}
-
-int
-uchcom_open(void *arg, int portno)
-{
- int ret;
- struct uchcom_softc *sc = arg;
-
- if (sc->sc_ucom.sc_dying)
- return EIO;
-
- ret = setup_intr_pipe(sc);
- if (ret)
- return ret;
-
- ret = setup_comm(sc);
- if (ret)
- return ret;
-
- return 0;
-}
-
-void
-uchcom_close(void *arg, int portno)
-{
- struct uchcom_softc *sc = arg;
-
- if (sc->sc_ucom.sc_dying)
- return;
-
- close_intr_pipe(sc);
-}
-
-
-/* ----------------------------------------------------------------------
- * callback when the modem status is changed.
- */
-void
-uchcom_intr(usbd_xfer_handle xfer, usbd_private_handle priv,
- usbd_status status)
-{
- struct uchcom_softc *sc = priv;
- u_char *buf = sc->sc_intr_buf;
-
- if (sc->sc_ucom.sc_dying)
- return;
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
- return;
-
- DPRINTF(("%s: abnormal status: %s\n",
- USBDEVNAME(sc->sc_dev), usbd_errstr(status)));
- usbd_clear_endpoint_stall_async(sc->sc_intr_pipe);
- return;
- }
- DPRINTF(("%s: intr: 0x%02X 0x%02X 0x%02X 0x%02X "
- "0x%02X 0x%02X 0x%02X 0x%02X\n",
- USBDEVNAME(sc->sc_dev),
- (unsigned)buf[0], (unsigned)buf[1],
- (unsigned)buf[2], (unsigned)buf[3],
- (unsigned)buf[4], (unsigned)buf[5],
- (unsigned)buf[6], (unsigned)buf[7]));
-
- convert_status(sc, buf[UCHCOM_INTR_STAT1]);
- ucom_status_change(&sc->sc_ucom);
-}
-
-static device_method_t uchcom_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, uchcom_match),
- DEVMETHOD(device_attach, uchcom_attach),
- DEVMETHOD(device_detach, uchcom_detach),
-
- { 0, 0 }
-};
-
-static driver_t uchcom_driver = {
- "ucom",
- uchcom_methods,
- sizeof (struct uchcom_softc)
-};
-
-DRIVER_MODULE(uchcom, uhub, uchcom_driver, ucom_devclass, usbd_driver_load, 0);
-MODULE_DEPEND(uchcom, usb, 1, 1, 1);
-MODULE_DEPEND(uchcom, ucom, UCOM_MINVER, UCOM_PREFVER, UCOM_MAXVER);
diff --git a/sys/dev/usb/ucom.c b/sys/dev/usb/ucom.c
deleted file mode 100644
index ae263a0..0000000
--- a/sys/dev/usb/ucom.c
+++ /dev/null
@@ -1,829 +0,0 @@
-/* $NetBSD: ucom.c,v 1.40 2001/11/13 06:24:54 lukem Exp $ */
-
-/*-
- * Copyright (c) 2001-2003, 2005, 2008
- * Shunsuke Akiyama <akiyama@jp.FreeBSD.org>.
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*-
- * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) 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.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/ioccom.h>
-#include <sys/fcntl.h>
-#include <sys/conf.h>
-#include <sys/serial.h>
-#include <sys/tty.h>
-#include <sys/file.h>
-#include <sys/selinfo.h>
-#include <sys/proc.h>
-#include <sys/poll.h>
-#include <sys/sysctl.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbcdc.h>
-
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include "usbdevs.h"
-#include <dev/usb/usb_quirks.h>
-
-#include <dev/usb/ucomvar.h>
-
-#ifdef USB_DEBUG
-static int ucomdebug = 0;
-SYSCTL_NODE(_hw_usb, OID_AUTO, ucom, CTLFLAG_RW, 0, "USB ucom");
-SYSCTL_INT(_hw_usb_ucom, OID_AUTO, debug, CTLFLAG_RW,
- &ucomdebug, 0, "ucom debug level");
-#define DPRINTF(x) do { \
- if (ucomdebug) \
- printf x; \
- } while (0)
-
-#define DPRINTFN(n, x) do { \
- if (ucomdebug > (n)) \
- printf x; \
- } while (0)
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n, x)
-#endif
-
-static int ucom_modevent(module_t, int, void *);
-static void ucom_cleanup(struct ucom_softc *);
-static void ucom_shutdown(struct ucom_softc *);
-static void ucom_dtr(struct ucom_softc *, int);
-static void ucom_rts(struct ucom_softc *, int);
-static void ucombreak(struct ucom_softc *, int);
-static usbd_status ucomstartread(struct ucom_softc *);
-static void ucomreadcb(usbd_xfer_handle, usbd_private_handle, usbd_status);
-static void ucomwritecb(usbd_xfer_handle, usbd_private_handle, usbd_status);
-static void ucomstopread(struct ucom_softc *);
-
-static tsw_open_t ucomtty_open;
-static tsw_close_t ucomtty_close;
-static tsw_outwakeup_t ucomtty_outwakeup;
-static tsw_ioctl_t ucomtty_ioctl;
-static tsw_param_t ucomtty_param;
-static tsw_modem_t ucomtty_modem;
-static tsw_free_t ucomtty_free;
-
-static struct ttydevsw ucomtty_class = {
- .tsw_flags = TF_INITLOCK|TF_CALLOUT,
- .tsw_open = ucomtty_open,
- .tsw_close = ucomtty_close,
- .tsw_outwakeup = ucomtty_outwakeup,
- .tsw_ioctl = ucomtty_ioctl,
- .tsw_param = ucomtty_param,
- .tsw_modem = ucomtty_modem,
- .tsw_free = ucomtty_free,
-};
-
-devclass_t ucom_devclass;
-
-static moduledata_t ucom_mod = {
- "ucom",
- ucom_modevent,
- NULL
-};
-
-DECLARE_MODULE(ucom, ucom_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE);
-MODULE_DEPEND(ucom, usb, 1, 1, 1);
-MODULE_VERSION(ucom, UCOM_MODVER);
-
-static int
-ucom_modevent(module_t mod, int type, void *data)
-{
- switch (type) {
- case MOD_LOAD:
- case MOD_UNLOAD:
- return (0);
- default:
- return (EOPNOTSUPP);
- }
-}
-
-void
-ucom_attach_tty(struct ucom_softc *sc, char* fmt, int unit)
-{
- struct tty *tp;
-
- sc->sc_tty = tp = tty_alloc(&ucomtty_class, sc, &Giant);
- tty_makedev(tp, NULL, fmt, unit);
-}
-
-int
-ucom_attach(struct ucom_softc *sc)
-{
-
- ucom_attach_tty(sc, "U%d", device_get_unit(sc->sc_dev));
-
- DPRINTF(("ucom_attach: ttycreate: tp = %p, %s\n",
- sc->sc_tty, sc->sc_tty->t_dev->si_name));
-
- return (0);
-}
-
-int
-ucom_detach(struct ucom_softc *sc)
-{
- DPRINTF(("ucom_detach: sc = %p, tp = %p\n", sc, sc->sc_tty));
-
- tty_lock(sc->sc_tty);
- sc->sc_dying = 1;
-
- if (sc->sc_bulkin_pipe != NULL)
- usbd_abort_pipe(sc->sc_bulkin_pipe);
- if (sc->sc_bulkout_pipe != NULL)
- usbd_abort_pipe(sc->sc_bulkout_pipe);
-
- tty_rel_gone(sc->sc_tty);
-
- return (0);
-}
-
-static void
-ucom_shutdown(struct ucom_softc *sc)
-{
- struct tty *tp = sc->sc_tty;
-
- DPRINTF(("ucom_shutdown\n"));
- /*
- * Hang up if necessary. Wait a bit, so the other side has time to
- * notice even if we immediately open the port again.
- */
- if (tp->t_termios.c_cflag & HUPCL) {
- (void)ucomtty_modem(tp, 0, SER_DTR);
-#if 0
- (void)tsleep(sc, TTIPRI, "ucomsd", hz);
-#endif
- }
-}
-
-static int
-ucomtty_open(struct tty *tp)
-{
- struct ucom_softc *sc = tty_softc(tp);
- usbd_status err;
- int error;
-
- if (sc->sc_dying)
- return (ENXIO);
-
- DPRINTF(("%s: ucomtty_open: tp = %p\n", device_get_nameunit(sc->sc_dev), tp));
-
- sc->sc_poll = 0;
- sc->sc_lsr = sc->sc_msr = sc->sc_mcr = 0;
-
- (void)ucomtty_modem(tp, SER_DTR | SER_RTS, 0);
-
- /* Device specific open */
- if (sc->sc_callback->ucom_open != NULL) {
- error = sc->sc_callback->ucom_open(sc->sc_parent,
- sc->sc_portno);
- if (error) {
- ucom_cleanup(sc);
- return (error);
- }
- }
-
- DPRINTF(("ucomtty_open: open pipes in = %d out = %d\n",
- sc->sc_bulkin_no, sc->sc_bulkout_no));
-
- /* Open the bulk pipes */
- /* Bulk-in pipe */
- err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkin_no, 0,
- &sc->sc_bulkin_pipe);
- if (err) {
- printf("%s: open bulk in error (addr %d): %s\n",
- device_get_nameunit(sc->sc_dev), sc->sc_bulkin_no,
- usbd_errstr(err));
- error = EIO;
- goto fail;
- }
- /* Bulk-out pipe */
- err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkout_no,
- USBD_EXCLUSIVE_USE, &sc->sc_bulkout_pipe);
- if (err) {
- printf("%s: open bulk out error (addr %d): %s\n",
- device_get_nameunit(sc->sc_dev), sc->sc_bulkout_no,
- usbd_errstr(err));
- error = EIO;
- goto fail;
- }
-
- /* Allocate a request and an input buffer and start reading. */
- sc->sc_ixfer = usbd_alloc_xfer(sc->sc_udev);
- if (sc->sc_ixfer == NULL) {
- error = ENOMEM;
- goto fail;
- }
-
- sc->sc_ibuf = usbd_alloc_buffer(sc->sc_ixfer,
- sc->sc_ibufsizepad);
- if (sc->sc_ibuf == NULL) {
- error = ENOMEM;
- goto fail;
- }
-
- sc->sc_oxfer = usbd_alloc_xfer(sc->sc_udev);
- if (sc->sc_oxfer == NULL) {
- error = ENOMEM;
- goto fail;
- }
-
- sc->sc_obuf = usbd_alloc_buffer(sc->sc_oxfer,
- sc->sc_obufsize +
- sc->sc_opkthdrlen);
- if (sc->sc_obuf == NULL) {
- error = ENOMEM;
- goto fail;
- }
-
- sc->sc_state |= UCS_RXSTOP;
- ucomstartread(sc);
-
- sc->sc_poll = 1;
-
- return (0);
-
-fail:
- ucom_cleanup(sc);
- return (error);
-}
-
-static void
-ucomtty_close(struct tty *tp)
-{
- struct ucom_softc *sc = tty_softc(tp);
-
- DPRINTF(("%s: ucomtty_close \n", device_get_nameunit(sc->sc_dev)));
-
- ucom_cleanup(sc);
-
- if (sc->sc_callback->ucom_close != NULL)
- sc->sc_callback->ucom_close(sc->sc_parent, sc->sc_portno);
-}
-
-static int
-ucomtty_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *p)
-{
- struct ucom_softc *sc = tty_softc(tp);
- int error;
-
- if (sc->sc_dying)
- return (EIO);
-
- DPRINTF(("ucomioctl: cmd = 0x%08lx\n", cmd));
-
- switch (cmd) {
- case TIOCSBRK:
- ucombreak(sc, 1);
- return (0);
- case TIOCCBRK:
- ucombreak(sc, 0);
- return (0);
- }
-
- error = ENOIOCTL;
- if (sc->sc_callback->ucom_ioctl != NULL)
- error = sc->sc_callback->ucom_ioctl(sc->sc_parent,
- sc->sc_portno,
- cmd, data, p);
- return (error);
-}
-
-static int
-ucomtty_modem(struct tty *tp, int sigon, int sigoff)
-{
- struct ucom_softc *sc = tty_softc(tp);
- int mcr;
- int msr;
- int onoff;
-
- if (sigon == 0 && sigoff == 0) {
- mcr = sc->sc_mcr;
- if (ISSET(mcr, SER_DTR))
- sigon |= SER_DTR;
- if (ISSET(mcr, SER_RTS))
- sigon |= SER_RTS;
-
- msr = sc->sc_msr;
- if (ISSET(msr, SER_CTS))
- sigon |= SER_CTS;
- if (ISSET(msr, SER_DCD))
- sigon |= SER_DCD;
- if (ISSET(msr, SER_DSR))
- sigon |= SER_DSR;
- if (ISSET(msr, SER_RI))
- sigon |= SER_RI;
- return (sigon);
- }
-
- mcr = sc->sc_mcr;
- if (ISSET(sigon, SER_DTR))
- mcr |= SER_DTR;
- if (ISSET(sigoff, SER_DTR))
- mcr &= ~SER_DTR;
- if (ISSET(sigon, SER_RTS))
- mcr |= SER_RTS;
- if (ISSET(sigoff, SER_RTS))
- mcr &= ~SER_RTS;
- sc->sc_mcr = mcr;
-
- onoff = ISSET(sc->sc_mcr, SER_DTR) ? 1 : 0;
- ucom_dtr(sc, onoff);
-
- onoff = ISSET(sc->sc_mcr, SER_RTS) ? 1 : 0;
- ucom_rts(sc, onoff);
-
- return (0);
-}
-
-static void
-ucombreak(struct ucom_softc *sc, int onoff)
-{
- DPRINTF(("ucombreak: onoff = %d\n", onoff));
-
- if (sc->sc_callback->ucom_set == NULL)
- return;
- sc->sc_callback->ucom_set(sc->sc_parent, sc->sc_portno,
- UCOM_SET_BREAK, onoff);
-}
-
-static void
-ucom_dtr(struct ucom_softc *sc, int onoff)
-{
- DPRINTF(("ucom_dtr: onoff = %d\n", onoff));
-
- if (sc->sc_callback->ucom_set == NULL)
- return;
- sc->sc_callback->ucom_set(sc->sc_parent, sc->sc_portno,
- UCOM_SET_DTR, onoff);
-}
-
-static void
-ucom_rts(struct ucom_softc *sc, int onoff)
-{
- DPRINTF(("ucom_rts: onoff = %d\n", onoff));
-
- if (sc->sc_callback->ucom_set == NULL)
- return;
- sc->sc_callback->ucom_set(sc->sc_parent, sc->sc_portno,
- UCOM_SET_RTS, onoff);
-}
-
-void
-ucom_status_change(struct ucom_softc *sc)
-{
- struct tty *tp = sc->sc_tty;
- u_char old_msr;
- int onoff;
-
- if (sc->sc_callback->ucom_get_status == NULL) {
- sc->sc_lsr = 0;
- sc->sc_msr = 0;
- return;
- }
-
- old_msr = sc->sc_msr;
- sc->sc_callback->ucom_get_status(sc->sc_parent, sc->sc_portno,
- &sc->sc_lsr, &sc->sc_msr);
- if (ISSET((sc->sc_msr ^ old_msr), SER_DCD)) {
- if (sc->sc_poll == 0)
- return;
- onoff = ISSET(sc->sc_msr, SER_DCD) ? 1 : 0;
- DPRINTF(("ucom_status_change: DCD changed to %d\n", onoff));
- ttydisc_modem(tp, onoff);
- }
-}
-
-static int
-ucomtty_param(struct tty *tp, struct termios *t)
-{
- struct ucom_softc *sc = tty_softc(tp);
- int error;
- usbd_status uerr;
-
- if (sc->sc_dying)
- return (EIO);
-
- DPRINTF(("ucomtty_param: sc = %p\n", sc));
-
- /* Check requested parameters. */
- if (t->c_ospeed < 0) {
- DPRINTF(("ucomtty_param: negative ospeed\n"));
- return (EINVAL);
- }
- if (t->c_ispeed && t->c_ispeed != t->c_ospeed) {
- DPRINTF(("ucomtty_param: mismatch ispeed and ospeed\n"));
- return (EINVAL);
- }
- t->c_ispeed = t->c_ospeed;
-
- if (sc->sc_callback->ucom_param == NULL)
- return (0);
-
- ucomstopread(sc);
-
- error = sc->sc_callback->ucom_param(sc->sc_parent, sc->sc_portno, t);
- if (error) {
- DPRINTF(("ucomtty_param: callback: error = %d\n", error));
- return (error);
- }
-
-#if 0
- ttsetwater(tp);
-#endif
-
- if (t->c_cflag & CRTS_IFLOW) {
- sc->sc_state |= UCS_RTS_IFLOW;
- } else if (sc->sc_state & UCS_RTS_IFLOW) {
- sc->sc_state &= ~UCS_RTS_IFLOW;
- (void)ucomtty_modem(tp, SER_RTS, 0);
- }
-
-#if 0
- ttyldoptim(tp);
-#endif
-
- uerr = ucomstartread(sc);
- if (uerr != USBD_NORMAL_COMPLETION)
- return (EIO);
-
- return (0);
-}
-
-static void
-ucomtty_free(void *sc)
-{
- /*
- * Our softc gets deallocated earlier on.
- * XXX: we should make sure the TTY device name doesn't get
- * recycled before we end up here!
- */
-}
-
-static void
-ucomtty_outwakeup(struct tty *tp)
-{
- struct ucom_softc *sc = tty_softc(tp);
- usbd_status err;
- size_t cnt;
-
- DPRINTF(("ucomtty_outwakeup: sc = %p\n", sc));
-
- if (sc->sc_dying)
- return;
-
- /*
- * If there's no sc_oxfer, then ucomclose has removed it. The buffer
- * has just been flushed in the ttyflush() in ttyclose(). ttyflush()
- * then calls tt_stop(). ucomstop calls ucomstart, so the right thing
- * to do here is just abort if sc_oxfer is NULL, as everything else
- * is cleaned up elsewhere.
- */
- if (sc->sc_oxfer == NULL)
- return;
-
- /* XXX: hardware flow control. We should use inwakeup here. */
-#if 0
- if (tp->t_state & TS_TBLOCK) {
- if (ISSET(sc->sc_mcr, SER_RTS) &&
- ISSET(sc->sc_state, UCS_RTS_IFLOW)) {
- DPRINTF(("ucomtty_outwakeup: clear RTS\n"));
- (void)ucomtty_modem(tp, 0, SER_RTS);
- }
- } else {
- if (!ISSET(sc->sc_mcr, SER_RTS) &&
- tp->t_rawq.c_cc <= tp->t_ilowat &&
- ISSET(sc->sc_state, UCS_RTS_IFLOW)) {
- DPRINTF(("ucomtty_outwakeup: set RTS\n"));
- (void)ucomtty_modem(tp, SER_RTS, 0);
- }
- }
-#endif
-
- if (sc->sc_state & UCS_TXBUSY)
- return;
-
- sc->sc_state |= UCS_TXBUSY;
- if (sc->sc_callback->ucom_write != NULL)
- cnt = sc->sc_callback->ucom_write(sc->sc_parent,
- sc->sc_portno, tp, sc->sc_obuf, sc->sc_obufsize);
- else
- cnt = ttydisc_getc(tp, sc->sc_obuf, sc->sc_obufsize);
-
- if (cnt == 0) {
- DPRINTF(("ucomtty_outwakeup: cnt == 0\n"));
- sc->sc_state &= ~UCS_TXBUSY;
- return;
- }
- sc->sc_obufactive = cnt;
-
- DPRINTF(("ucomtty_outwakeup: %zu chars\n", cnt));
- usbd_setup_xfer(sc->sc_oxfer, sc->sc_bulkout_pipe,
- (usbd_private_handle)sc, sc->sc_obuf, cnt,
- USBD_NO_COPY, USBD_NO_TIMEOUT, ucomwritecb);
- /* What can we do on error? */
- err = usbd_transfer(sc->sc_oxfer);
- if (err != USBD_IN_PROGRESS) {
- printf("ucomtty_outwakeup: err=%s\n", usbd_errstr(err));
- sc->sc_state &= ~UCS_TXBUSY;
- }
-}
-
-#if 0
-static void
-ucomstop(struct tty *tp, int flag)
-{
- struct ucom_softc *sc = tty_softc(tp);
- int s;
-
- DPRINTF(("ucomstop: %d\n", flag));
-
- if ((flag & FREAD) && (sc->sc_state & UCS_RXSTOP) == 0) {
- DPRINTF(("ucomstop: read\n"));
- ucomstopread(sc);
- ucomstartread(sc);
- }
-
- if (flag & FWRITE) {
- DPRINTF(("ucomstop: write\n"));
- if (ISSET(tp->t_state, TS_BUSY)) {
- /* XXX do what? */
- if (!ISSET(tp->t_state, TS_TTSTOP))
- SET(tp->t_state, TS_FLUSH);
- }
- }
-
- ucomtty_outwakeup(tp);
-
- DPRINTF(("ucomstop: done\n"));
-}
-#endif
-
-static void
-ucomwritecb(usbd_xfer_handle xfer, usbd_private_handle p, usbd_status status)
-{
- struct ucom_softc *sc = (struct ucom_softc *)p;
- struct tty *tp = sc->sc_tty;
- u_int32_t cc;
-
- DPRINTF(("ucomwritecb: status = %d\n", status));
-
- if (status == USBD_CANCELLED || sc->sc_dying)
- return;
-
- if (status != USBD_NORMAL_COMPLETION) {
- printf("%s: ucomwritecb: %s\n",
- device_get_nameunit(sc->sc_dev), usbd_errstr(status));
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall_async(sc->sc_bulkin_pipe);
- /* XXX we should restart after some delay. */
- return;
- }
-
- usbd_get_xfer_status(xfer, NULL, NULL, &cc, NULL);
- DPRINTF(("ucomwritecb: cc = %d\n", cc));
- if (cc <= sc->sc_opkthdrlen) {
- printf("%s: sent size too small, cc = %d\n",
- device_get_nameunit(sc->sc_dev), cc);
- return;
- }
-
- /* convert from USB bytes to tty bytes */
- cc -= sc->sc_opkthdrlen;
- if (cc != sc->sc_obufactive)
- panic("Partial write of %d of %d bytes, not supported\n",
- cc, sc->sc_obufactive);
-
- sc->sc_state &= ~UCS_TXBUSY;
-#if 0
- CLR(tp->t_state, TS_BUSY);
- if (ISSET(tp->t_state, TS_FLUSH))
- CLR(tp->t_state, TS_FLUSH);
- else
- ndflush(&tp->t_outq, cc);
-#endif
- ucomtty_outwakeup(tp);
-}
-
-static usbd_status
-ucomstartread(struct ucom_softc *sc)
-{
- usbd_status err;
-
- DPRINTF(("ucomstartread: start\n"));
-
- if (sc->sc_bulkin_pipe == NULL || (sc->sc_state & UCS_RXSTOP) == 0)
- return (USBD_NORMAL_COMPLETION);
- sc->sc_state &= ~UCS_RXSTOP;
-
- usbd_setup_xfer(sc->sc_ixfer, sc->sc_bulkin_pipe,
- (usbd_private_handle)sc,
- sc->sc_ibuf, sc->sc_ibufsize,
- USBD_SHORT_XFER_OK | USBD_NO_COPY,
- USBD_NO_TIMEOUT, ucomreadcb);
-
- err = usbd_transfer(sc->sc_ixfer);
- if (err && err != USBD_IN_PROGRESS) {
- sc->sc_state |= UCS_RXSTOP;
- DPRINTF(("ucomstartread: err = %s\n", usbd_errstr(err)));
- return (err);
- }
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-void
-ucomrxchars(struct ucom_softc *sc, u_char *cp, u_int32_t cc)
-{
- struct tty *tp = sc->sc_tty;
-
- /* Give characters to tty layer. */
- if (ttydisc_can_bypass(tp)) {
- DPRINTFN(7, ("ucomreadcb: buf = %*D\n", cc, cp, ""));
- cc -= ttydisc_rint_bypass(tp, cp, cc);
- } else {
- while (cc > 0) {
- DPRINTFN(7, ("ucomreadcb: char = 0x%02x\n", *cp));
- if (ttydisc_rint(tp, *cp, 0) == -1)
- break;
- cc--;
- cp++;
- }
- }
- if (cc > 0)
- device_printf(sc->sc_dev, "lost %d chars\n", cc);
- ttydisc_rint_done(tp);
-}
-
-static void
-ucomreadcb(usbd_xfer_handle xfer, usbd_private_handle p, usbd_status status)
-{
- struct ucom_softc *sc = (struct ucom_softc *)p;
- struct tty *tp = sc->sc_tty;
- usbd_status err;
- u_int32_t cc;
- u_char *cp;
-
- (void)tp; /* Used for debugging */
- DPRINTF(("ucomreadcb: status = %d\n", status));
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (!(sc->sc_state & UCS_RXSTOP))
- printf("%s: ucomreadcb: %s\n",
- device_get_nameunit(sc->sc_dev), usbd_errstr(status));
- sc->sc_state |= UCS_RXSTOP;
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall_async(sc->sc_bulkin_pipe);
- /* XXX we should restart after some delay. */
- return;
- }
- sc->sc_state |= UCS_RXSTOP;
-
- usbd_get_xfer_status(xfer, NULL, (void **)&cp, &cc, NULL);
- DPRINTF(("ucomreadcb: got %d chars, tp = %p\n", cc, tp));
- if (cc == 0)
- goto resubmit;
-
- if (sc->sc_callback->ucom_read != NULL)
- sc->sc_callback->ucom_read(sc->sc_parent, sc->sc_portno,
- &cp, &cc);
-
- if (cc > sc->sc_ibufsize) {
- printf("%s: invalid receive data size, %d chars\n",
- device_get_nameunit(sc->sc_dev), cc);
- goto resubmit;
- }
- if (cc > 0)
- ucomrxchars(sc, cp, cc);
-
- resubmit:
- err = ucomstartread(sc);
- if (err) {
- printf("%s: read start failed\n", device_get_nameunit(sc->sc_dev));
- /* XXX what should we dow now? */
- }
-
-#if 0
- if ((sc->sc_state & UCS_RTS_IFLOW) && !ISSET(sc->sc_mcr, SER_RTS)
- && !(tp->t_state & TS_TBLOCK))
- ucomtty_modem(tp, SER_RTS, 0);
-#endif
-}
-
-static void
-ucom_cleanup(struct ucom_softc *sc)
-{
- DPRINTF(("ucom_cleanup: closing pipes\n"));
-
- ucom_shutdown(sc);
- if (sc->sc_bulkin_pipe != NULL) {
- sc->sc_state |= UCS_RXSTOP;
- usbd_abort_pipe(sc->sc_bulkin_pipe);
- usbd_close_pipe(sc->sc_bulkin_pipe);
- sc->sc_bulkin_pipe = NULL;
- }
- if (sc->sc_bulkout_pipe != NULL) {
- usbd_abort_pipe(sc->sc_bulkout_pipe);
- usbd_close_pipe(sc->sc_bulkout_pipe);
- sc->sc_bulkout_pipe = NULL;
- }
- if (sc->sc_ixfer != NULL) {
- usbd_free_xfer(sc->sc_ixfer);
- sc->sc_ixfer = NULL;
- }
- if (sc->sc_oxfer != NULL) {
- usbd_free_xfer(sc->sc_oxfer);
- sc->sc_oxfer = NULL;
- }
-}
-
-static void
-ucomstopread(struct ucom_softc *sc)
-{
- usbd_status err;
-
- DPRINTF(("ucomstopread: enter\n"));
-
- if (!(sc->sc_state & UCS_RXSTOP)) {
- sc->sc_state |= UCS_RXSTOP;
- if (sc->sc_bulkin_pipe == NULL) {
- DPRINTF(("ucomstopread: bulkin pipe NULL\n"));
- return;
- }
- err = usbd_abort_pipe(sc->sc_bulkin_pipe);
- if (err) {
- DPRINTF(("ucomstopread: err = %s\n",
- usbd_errstr(err)));
- }
- }
-
- DPRINTF(("ucomstopread: leave\n"));
-}
diff --git a/sys/dev/usb/ucomvar.h b/sys/dev/usb/ucomvar.h
deleted file mode 100644
index 4433a1a..0000000
--- a/sys/dev/usb/ucomvar.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/* $NetBSD: ucomvar.h,v 1.9 2001/01/23 21:56:17 augustss Exp $ */
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 2001-2002, Shunsuke Akiyama <akiyama@jp.FreeBSD.org>.
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- */
-
-/*-
- * Copyright (c) 1999 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) 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.
- */
-
-/* Module interface related macros */
-#define UCOM_MODVER 1
-
-#define UCOM_MINVER 1
-#define UCOM_PREFVER UCOM_MODVER
-#define UCOM_MAXVER 1
-
-/* Macros to clear/set/test flags. */
-#define SET(t, f) (t) |= (f)
-#define CLR(t, f) (t) &= ~((unsigned)(f))
-#define ISSET(t, f) ((t) & (f))
-
-#define UCOM_CALLOUT_MASK 0x80
-
-#define UCOMUNIT_MASK 0x3ff7f
-#define UCOMDIALOUT_MASK 0x80000
-#define UCOMCALLUNIT_MASK 0x40000
-
-#define UCOMUNIT(x) (dev2unit(x) & UCOMUNIT_MASK)
-#define UCOMDIALOUT(x) (dev2unit(x) & UCOMDIALOUT_MASK)
-#define UCOMCALLUNIT(x) (dev2unit(x) & UCOMCALLUNIT_MASK)
-
-#define UCOM_UNK_PORTNO -1 /* XXX */
-
-struct tty;
-struct ucom_softc;
-
-struct ucom_callback {
- void (*ucom_get_status)(void *, int, u_char *, u_char *);
- void (*ucom_set)(void *, int, int, int);
-#define UCOM_SET_DTR 1
-#define UCOM_SET_RTS 2
-#define UCOM_SET_BREAK 3
- int (*ucom_param)(void *, int, struct termios *);
- int (*ucom_ioctl)(void *, int, u_long, caddr_t, struct thread *);
- int (*ucom_open)(void *, int);
- void (*ucom_close)(void *, int);
- void (*ucom_read)(void *, int, u_char **, u_int32_t *);
- size_t (*ucom_write)(void *, int, struct tty *, u_char *, u_int32_t);
-};
-
-/* line status register */
-#define ULSR_RCV_FIFO 0x80
-#define ULSR_TSRE 0x40 /* Transmitter empty: byte sent */
-#define ULSR_TXRDY 0x20 /* Transmitter buffer empty */
-#define ULSR_BI 0x10 /* Break detected */
-#define ULSR_FE 0x08 /* Framing error: bad stop bit */
-#define ULSR_PE 0x04 /* Parity error */
-#define ULSR_OE 0x02 /* Overrun, lost incoming byte */
-#define ULSR_RXRDY 0x01 /* Byte ready in Receive Buffer */
-#define ULSR_RCV_MASK 0x1f /* Mask for incoming data or error */
-
-/* ucom state declarations */
-#define UCS_RXSTOP 0x0001 /* Rx stopped */
-#define UCS_TXBUSY 0x0002 /* Tx busy */
-#define UCS_RTS_IFLOW 0x0008 /* use RTS input flow control */
-
-struct ucom_softc {
- device_t sc_dev; /* base device */
- usbd_device_handle sc_udev; /* USB device */
- usbd_interface_handle sc_iface; /* data interface */
-
- int sc_bulkin_no; /* bulk in endpoint address */
- usbd_pipe_handle sc_bulkin_pipe; /* bulk in pipe */
- usbd_xfer_handle sc_ixfer; /* read request */
- u_char *sc_ibuf; /* read buffer */
- u_int sc_ibufsize; /* read buffer size */
- u_int sc_ibufsizepad; /* read buffer size padded */
-
- int sc_bulkout_no; /* bulk out endpoint address */
- usbd_pipe_handle sc_bulkout_pipe;/* bulk out pipe */
- usbd_xfer_handle sc_oxfer; /* write request */
- u_char *sc_obuf; /* write buffer */
- u_int sc_obufsize; /* write buffer size */
- u_int sc_opkthdrlen; /* header length of
- output packet */
- u_int sc_obufactive; /* Active bytes in buffer */
-
- struct ucom_callback *sc_callback;
- void *sc_parent;
- int sc_portno;
-
- struct tty *sc_tty; /* our tty */
-
- int sc_state;
-
- int sc_poll;
-
- u_char sc_lsr;
- u_char sc_msr;
- u_char sc_mcr;
-
- u_char sc_dying; /* disconnecting */
-
-};
-
-extern devclass_t ucom_devclass;
-
-void ucom_attach_tty(struct ucom_softc *, char*, int);
-int ucom_attach(struct ucom_softc *);
-int ucom_detach(struct ucom_softc *);
-void ucom_status_change(struct ucom_softc *);
-void ucomrxchars(struct ucom_softc *sc, u_char *cp, u_int32_t cc);
diff --git a/sys/dev/usb/ucycom.c b/sys/dev/usb/ucycom.c
deleted file mode 100644
index ecf115f..0000000
--- a/sys/dev/usb/ucycom.c
+++ /dev/null
@@ -1,543 +0,0 @@
-/*-
- * Copyright (c) 2004 Dag-Erling Coïdan Smørgrav
- * 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
- * in this position and unchanged.
- * 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. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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$
- */
-
-/*
- * Device driver for Cypress CY7C637xx and CY7C640/1xx series USB to
- * RS232 bridges.
- *
- * Normally, a driver for a USB-to-serial chip would hang off the ucom(4)
- * driver, but ucom(4) was written under the assumption that all USB-to-
- * serial chips use bulk pipes for I/O, while the Cypress parts use HID
- * reports.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/conf.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/sysctl.h>
-#include <sys/bus.h>
-#include <sys/tty.h>
-
-#include "usbdevs.h"
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include <dev/usb/usbhid.h>
-#include <dev/usb/hid.h>
-
-#define UCYCOM_EP_INPUT 0
-#define UCYCOM_EP_OUTPUT 1
-
-#define UCYCOM_MAX_IOLEN 32U
-
-struct ucycom_softc {
- device_t sc_dev;
- struct tty *sc_tty;
- int sc_error;
- unsigned long sc_cintr;
- unsigned long sc_cin;
- unsigned long sc_clost;
- unsigned long sc_cout;
-
- /* usb parameters */
- usbd_device_handle sc_usbdev;
- usbd_interface_handle sc_iface;
- usbd_pipe_handle sc_pipe;
- uint8_t sc_iep; /* input endpoint */
- uint8_t sc_fid; /* feature report id*/
- uint8_t sc_iid; /* input report id */
- uint8_t sc_oid; /* output report id */
- size_t sc_flen; /* feature report length */
- size_t sc_ilen; /* input report length */
- size_t sc_olen; /* output report length */
- uint8_t sc_ibuf[UCYCOM_MAX_IOLEN];
-
- /* model and settings */
- uint32_t sc_model;
-#define MODEL_CY7C63743 0x63743
-#define MODEL_CY7C64013 0x64013
- uint32_t sc_baud;
- uint8_t sc_cfg;
-#define UCYCOM_CFG_RESET 0x80
-#define UCYCOM_CFG_PARODD 0x20
-#define UCYCOM_CFG_PAREN 0x10
-#define UCYCOM_CFG_STOPB 0x08
-#define UCYCOM_CFG_DATAB 0x03
- uint8_t sc_ist; /* status flags from last input */
- uint8_t sc_ost; /* status flags for next output */
-
- /* flags */
- char sc_dying;
-};
-
-static device_probe_t ucycom_probe;
-static device_attach_t ucycom_attach;
-static device_detach_t ucycom_detach;
-static t_open_t ucycom_open;
-static t_close_t ucycom_close;
-static void ucycom_start(struct tty *);
-static void ucycom_stop(struct tty *, int);
-static int ucycom_param(struct tty *, struct termios *);
-static int ucycom_configure(struct ucycom_softc *, uint32_t, uint8_t);
-static void ucycom_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
-
-static device_method_t ucycom_methods[] = {
- DEVMETHOD(device_probe, ucycom_probe),
- DEVMETHOD(device_attach, ucycom_attach),
- DEVMETHOD(device_detach, ucycom_detach),
- { 0, 0 }
-};
-
-static driver_t ucycom_driver = {
- "ucycom",
- ucycom_methods,
- sizeof(struct ucycom_softc),
-};
-
-static devclass_t ucycom_devclass;
-
-DRIVER_MODULE(ucycom, uhub, ucycom_driver, ucycom_devclass, usbd_driver_load, 0);
-MODULE_VERSION(ucycom, 1);
-MODULE_DEPEND(ucycom, usb, 1, 1, 1);
-
-/*
- * Supported devices
- */
-
-static struct ucycom_device {
- uint16_t vendor;
- uint16_t product;
- uint32_t model;
-} ucycom_devices[] = {
- { USB_VENDOR_DELORME, USB_PRODUCT_DELORME_EARTHMATE, MODEL_CY7C64013 },
- { 0, 0, 0 },
-};
-
-#define UCYCOM_DEFAULT_RATE 4800
-#define UCYCOM_DEFAULT_CFG 0x03 /* N-8-1 */
-
-/*****************************************************************************
- *
- * Driver interface
- *
- */
-
-static int
-ucycom_probe(device_t dev)
-{
- struct usb_attach_arg *uaa;
- struct ucycom_device *ud;
-
- uaa = device_get_ivars(dev);
- if (uaa->iface != NULL)
- return (UMATCH_NONE);
- for (ud = ucycom_devices; ud->model != 0; ++ud)
- if (ud->vendor == uaa->vendor && ud->product == uaa->product)
- return (UMATCH_VENDOR_PRODUCT);
- return (UMATCH_NONE);
-}
-
-static int
-ucycom_attach(device_t dev)
-{
- struct usb_attach_arg *uaa;
- struct ucycom_softc *sc;
- struct ucycom_device *ud;
- usb_endpoint_descriptor_t *ued;
- void *urd;
- int error, urdlen;
-
- /* get arguments and softc */
- uaa = device_get_ivars(dev);
- sc = device_get_softc(dev);
- bzero(sc, sizeof *sc);
- sc->sc_dev = dev;
- sc->sc_usbdev = uaa->device;
-
- /* get chip model */
- for (ud = ucycom_devices; ud->model != 0; ++ud)
- if (ud->vendor == uaa->vendor && ud->product == uaa->product)
- sc->sc_model = ud->model;
- if (sc->sc_model == 0) {
- device_printf(dev, "unsupported device\n");
- return (ENXIO);
- }
- device_printf(dev, "Cypress CY7C%X USB to RS232 bridge\n", sc->sc_model);
-
- /* select configuration */
- error = usbd_set_config_index(sc->sc_usbdev, 0, 1 /* verbose */);
- if (error != 0) {
- device_printf(dev, "failed to select configuration: %s\n",
- usbd_errstr(error));
- return (ENXIO);
- }
-
- /* get first interface handle */
- error = usbd_device2interface_handle(sc->sc_usbdev, 0, &sc->sc_iface);
- if (error != 0) {
- device_printf(dev, "failed to get interface handle: %s\n",
- usbd_errstr(error));
- return (ENXIO);
- }
-
- /* get report descriptor */
- error = usbd_read_report_desc(sc->sc_iface, &urd, &urdlen, M_USBDEV);
- if (error != 0) {
- device_printf(dev, "failed to get report descriptor: %s\n",
- usbd_errstr(error));
- return (ENXIO);
- }
-
- /* get report sizes */
- sc->sc_flen = hid_report_size(urd, urdlen, hid_feature, &sc->sc_fid);
- sc->sc_ilen = hid_report_size(urd, urdlen, hid_input, &sc->sc_iid);
- sc->sc_olen = hid_report_size(urd, urdlen, hid_output, &sc->sc_oid);
-
- if (sc->sc_ilen > UCYCOM_MAX_IOLEN || sc->sc_olen > UCYCOM_MAX_IOLEN) {
- device_printf(dev, "I/O report size too big (%zu, %zu, %u)\n",
- sc->sc_ilen, sc->sc_olen, UCYCOM_MAX_IOLEN);
- return (ENXIO);
- }
-
- /* get and verify input endpoint descriptor */
- ued = usbd_interface2endpoint_descriptor(sc->sc_iface, UCYCOM_EP_INPUT);
- if (ued == NULL) {
- device_printf(dev, "failed to get input endpoint descriptor\n");
- return (ENXIO);
- }
- if (UE_GET_DIR(ued->bEndpointAddress) != UE_DIR_IN) {
- device_printf(dev, "not an input endpoint\n");
- return (ENXIO);
- }
- if ((ued->bmAttributes & UE_XFERTYPE) != UE_INTERRUPT) {
- device_printf(dev, "not an interrupt endpoint\n");
- return (ENXIO);
- }
- sc->sc_iep = ued->bEndpointAddress;
-
- /* set up tty */
- sc->sc_tty = ttyalloc();
- sc->sc_tty->t_sc = sc;
- sc->sc_tty->t_oproc = ucycom_start;
- sc->sc_tty->t_stop = ucycom_stop;
- sc->sc_tty->t_param = ucycom_param;
- sc->sc_tty->t_open = ucycom_open;
- sc->sc_tty->t_close = ucycom_close;
-
- SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
- SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
- OID_AUTO, "intr", CTLFLAG_RD, &sc->sc_cintr, 0,
- "interrupt count");
- SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
- SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
- OID_AUTO, "in", CTLFLAG_RD, &sc->sc_cin, 0,
- "input bytes read");
- SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
- SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
- OID_AUTO, "lost", CTLFLAG_RD, &sc->sc_clost, 0,
- "input bytes lost");
- SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
- SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
- OID_AUTO, "out", CTLFLAG_RD, &sc->sc_cout, 0,
- "output bytes");
-
- /* create character device node */
- ttycreate(sc->sc_tty, 0, "y%r", device_get_unit(sc->sc_dev));
-
- return (0);
-}
-
-static int
-ucycom_detach(device_t dev)
-{
- struct ucycom_softc *sc;
-
- sc = device_get_softc(dev);
-
- ttyfree(sc->sc_tty);
-
- return (0);
-}
-
-/*****************************************************************************
- *
- * Device interface
- *
- */
-
-static int
-ucycom_open(struct tty *tp, struct cdev *cdev)
-{
- struct ucycom_softc *sc = tp->t_sc;
- int error;
-
- /* set default configuration */
- ucycom_configure(sc, UCYCOM_DEFAULT_RATE, UCYCOM_DEFAULT_CFG);
-
- /* open interrupt pipe */
- error = usbd_open_pipe_intr(sc->sc_iface, sc->sc_iep, 0,
- &sc->sc_pipe, sc, sc->sc_ibuf, sc->sc_ilen,
- ucycom_intr, USBD_DEFAULT_INTERVAL);
- if (error != 0) {
- device_printf(sc->sc_dev, "failed to open interrupt pipe: %s\n",
- usbd_errstr(error));
- return (ENXIO);
- }
-
- if (bootverbose)
- device_printf(sc->sc_dev, "%s bypass l_rint()\n",
- (sc->sc_tty->t_state & TS_CAN_BYPASS_L_RINT) ?
- "can" : "can't");
-
- /* done! */
- return (0);
-}
-
-static void
-ucycom_close(struct tty *tp)
-{
- struct ucycom_softc *sc = tp->t_sc;
-
- /* stop interrupts and close the interrupt pipe */
- usbd_abort_pipe(sc->sc_pipe);
- usbd_close_pipe(sc->sc_pipe);
- sc->sc_pipe = 0;
-
- return;
-}
-
-/*****************************************************************************
- *
- * TTY interface
- *
- */
-
-static void
-ucycom_start(struct tty *tty)
-{
- struct ucycom_softc *sc = tty->t_sc;
- uint8_t report[sc->sc_olen];
- int error, len;
-
- while (sc->sc_error == 0 && sc->sc_tty->t_outq.c_cc > 0) {
- switch (sc->sc_model) {
- case MODEL_CY7C63743:
- len = q_to_b(&sc->sc_tty->t_outq,
- report + 1, sc->sc_olen - 1);
- sc->sc_cout += len;
- report[0] = len;
- len += 1;
- break;
- case MODEL_CY7C64013:
- len = q_to_b(&sc->sc_tty->t_outq,
- report + 2, sc->sc_olen - 2);
- sc->sc_cout += len;
- report[0] = 0;
- report[1] = len;
- len += 2;
- break;
- default:
- panic("unsupported model (driver error)");
- }
-
- while (len < sc->sc_olen)
- report[len++] = 0;
- error = usbd_set_report(sc->sc_iface, UHID_OUTPUT_REPORT,
- sc->sc_oid, report, sc->sc_olen);
-#if 0
- if (error != 0) {
- device_printf(sc->sc_dev,
- "failed to set output report: %s\n",
- usbd_errstr(error));
- sc->sc_error = error;
- }
-#endif
- }
-}
-
-static void
-ucycom_stop(struct tty *tty, int flags)
-{
- struct ucycom_softc *sc;
-
- sc = tty->t_sc;
- if (bootverbose)
- device_printf(sc->sc_dev, "%s()\n", __func__);
-}
-
-static int
-ucycom_param(struct tty *tty, struct termios *t)
-{
- struct ucycom_softc *sc;
- uint32_t baud;
- uint8_t cfg;
- int error;
-
- sc = tty->t_sc;
-
- if (t->c_ispeed != t->c_ospeed)
- return (EINVAL);
- baud = t->c_ispeed;
-
- if (t->c_cflag & CIGNORE) {
- cfg = sc->sc_cfg;
- } else {
- cfg = 0;
- switch (t->c_cflag & CSIZE) {
- case CS8:
- ++cfg;
- case CS7:
- ++cfg;
- case CS6:
- ++cfg;
- case CS5:
- break;
- default:
- return (EINVAL);
- }
- if (t->c_cflag & CSTOPB)
- cfg |= UCYCOM_CFG_STOPB;
- if (t->c_cflag & PARENB)
- cfg |= UCYCOM_CFG_PAREN;
- if (t->c_cflag & PARODD)
- cfg |= UCYCOM_CFG_PARODD;
- }
-
- error = ucycom_configure(sc, baud, cfg);
- return (error);
-}
-
-/*****************************************************************************
- *
- * Hardware interface
- *
- */
-
-static int
-ucycom_configure(struct ucycom_softc *sc, uint32_t baud, uint8_t cfg)
-{
- uint8_t report[sc->sc_flen];
- int error;
-
- switch (baud) {
- case 600:
- case 1200:
- case 2400:
- case 4800:
- case 9600:
- case 19200:
- case 38400:
- case 57600:
-#if 0
- /*
- * Stock chips only support standard baud rates in the 600 - 57600
- * range, but higher rates can be achieved using custom firmware.
- */
- case 115200:
- case 153600:
- case 192000:
-#endif
- break;
- default:
- return (EINVAL);
- }
-
- if (bootverbose)
- device_printf(sc->sc_dev, "%d baud, %c-%d-%d\n", baud,
- (cfg & UCYCOM_CFG_PAREN) ?
- ((cfg & UCYCOM_CFG_PARODD) ? 'O' : 'E') : 'N',
- 5 + (cfg & UCYCOM_CFG_DATAB),
- (cfg & UCYCOM_CFG_STOPB) ? 2 : 1);
- report[0] = baud & 0xff;
- report[1] = (baud >> 8) & 0xff;
- report[2] = (baud >> 16) & 0xff;
- report[3] = (baud >> 24) & 0xff;
- report[4] = cfg;
- error = usbd_set_report(sc->sc_iface, UHID_FEATURE_REPORT,
- sc->sc_fid, report, sc->sc_flen);
- if (error != 0) {
- device_printf(sc->sc_dev, "%s\n", usbd_errstr(error));
- return (EIO);
- }
- sc->sc_baud = baud;
- sc->sc_cfg = cfg;
- return (0);
-}
-
-static void
-ucycom_intr(usbd_xfer_handle xfer, usbd_private_handle scp, usbd_status status)
-{
- struct ucycom_softc *sc = scp;
- uint8_t *data;
- int i, len, lost;
-
- sc->sc_cintr++;
-
- switch (sc->sc_model) {
- case MODEL_CY7C63743:
- sc->sc_ist = sc->sc_ibuf[0] & ~0x07;
- len = sc->sc_ibuf[0] & 0x07;
- data = sc->sc_ibuf + 1;
- break;
- case MODEL_CY7C64013:
- sc->sc_ist = sc->sc_ibuf[0] & ~0x07;
- len = sc->sc_ibuf[1];
- data = sc->sc_ibuf + 2;
- break;
- default:
- panic("unsupported model (driver error)");
- }
-
- switch (status) {
- case USBD_NORMAL_COMPLETION:
- break;
- default:
- /* XXX */
- return;
- }
-
- if (sc->sc_tty->t_state & TS_CAN_BYPASS_L_RINT) {
- /* XXX flow control! */
- lost = b_to_q(data, len, &sc->sc_tty->t_rawq);
- sc->sc_tty->t_rawcc += len - lost;
- ttwakeup(sc->sc_tty);
- } else {
- for (i = 0, lost = len; i < len; ++i, --lost)
- if (ttyld_rint(sc->sc_tty, data[i]) != 0)
- break;
- }
- sc->sc_cin += len - lost;
- sc->sc_clost += lost;
-}
diff --git a/sys/dev/usb/udbp.c b/sys/dev/usb/udbp.c
deleted file mode 100644
index 523184f..0000000
--- a/sys/dev/usb/udbp.c
+++ /dev/null
@@ -1,860 +0,0 @@
-/*-
- * Copyright (c) 1996-2000 Whistle Communications, Inc.
- * 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. Neither the name of author 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 NICK HIBMA 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 AUTHOR 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.
- *
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/* Driver for arbitrary double bulk pipe devices.
- * The driver assumes that there will be the same driver on the other side.
- *
- * XXX Some more information on what the framing of the IP packets looks like.
- *
- * To take full advantage of bulk transmission, packets should be chosen
- * between 1k and 5k in size (1k to make sure the sending side starts
- * straming, and <5k to avoid overflowing the system with small TDs).
- */
-
-
-/* probe/attach/detach:
- * Connect the driver to the hardware and netgraph
- *
- * udbp_setup_out_transfer(sc);
- * Setup an outbound transfer. Only one transmit can be active at the same
- * time.
- * XXX If it is required that the driver is able to queue multiple requests
- * let me know. That is slightly difficult, due to the fact that we
- * cannot call usbd_alloc_xfer in int context.
- *
- * udbp_setup_in_transfer(sc)
- * Prepare an in transfer that will be waiting for data to come in. It
- * is submitted and sits there until data is available.
- * The callback resubmits a new transfer on completion.
- *
- * The reason we submit a bulk in transfer is that USB does not know about
- * interrupts. The bulk transfer continuously polls the device for data.
- * While the device has no data available, the device NAKs the TDs. As soon
- * as there is data, the transfer happens and the data comes flowing in.
- *
- * In case you were wondering, interrupt transfers happen exactly that way.
- * It therefore doesn't make sense to use the interrupt pipe to signal
- * 'data ready' and then schedule a bulk transfer to fetch it. That would
- * incur a 2ms delay at least, without reducing bandwidth requirements.
- *
- */
-
-
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/conf.h>
-#include <sys/file.h>
-#include <sys/selinfo.h>
-#include <sys/poll.h>
-#include <sys/mbuf.h>
-#include <sys/socket.h>
-#include <sys/ctype.h>
-#include <sys/errno.h>
-#include <sys/sysctl.h>
-#include <net/if.h>
-#include <machine/bus.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include <dev/usb/usbdivar.h>
-#include <dev/usb/usbhid.h>
-
-#include "usbdevs.h"
-
-
-#include <netgraph/ng_message.h>
-#include <netgraph/ng_parse.h>
-#include <dev/usb/udbp.h>
-#include <netgraph/netgraph.h>
-
-#ifdef USB_DEBUG
-#define DPRINTF(x) if (udbpdebug) printf x
-#define DPRINTFN(n,x) if (udbpdebug>(n)) printf x
-int udbpdebug = 0;
-SYSCTL_NODE(_hw_usb, OID_AUTO, udbp, CTLFLAG_RW, 0, "USB udbp");
-SYSCTL_INT(_hw_usb_udbp, OID_AUTO, debug, CTLFLAG_RW,
- &udbpdebug, 0, "udbp debug level");
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-#define MS_TO_TICKS(ms) ((ms) * hz / 1000)
-
-#define UDBP_TIMEOUT 2000 /* timeout on outbound transfers, in msecs */
-#define UDBP_BUFFERSIZE 2048 /* maximum number of bytes in one transfer */
-
-
-struct udbp_softc {
- device_t sc_dev; /* base device */
- usbd_interface_handle sc_iface;
-
- usbd_pipe_handle sc_bulkin_pipe;
- int sc_bulkin;
- usbd_xfer_handle sc_bulkin_xfer;
- void *sc_bulkin_buffer;
- int sc_bulkin_bufferlen;
- int sc_bulkin_datalen;
-
- usbd_pipe_handle sc_bulkout_pipe;
- int sc_bulkout;
- usbd_xfer_handle sc_bulkout_xfer;
- void *sc_bulkout_buffer;
- int sc_bulkout_bufferlen;
- int sc_bulkout_datalen;
-
- int flags;
-# define DISCONNECTED 0x01
-# define OUT_BUSY 0x02
-# define NETGRAPH_INITIALISED 0x04
- node_p node; /* back pointer to node */
- hook_p hook; /* pointer to the hook */
- u_int packets_in; /* packets in from downstream */
- u_int packets_out; /* packets out towards downstream */
- struct ifqueue xmitq_hipri; /* hi-priority transmit queue */
- struct ifqueue xmitq; /* low-priority transmit queue */
-
-};
-typedef struct udbp_softc *udbp_p;
-
-
-
-static ng_constructor_t ng_udbp_constructor;
-static ng_rcvmsg_t ng_udbp_rcvmsg;
-static ng_shutdown_t ng_udbp_rmnode;
-static ng_newhook_t ng_udbp_newhook;
-static ng_connect_t ng_udbp_connect;
-static ng_rcvdata_t ng_udbp_rcvdata;
-static ng_disconnect_t ng_udbp_disconnect;
-
-/* Parse type for struct ngudbpstat */
-static const struct ng_parse_struct_field
- ng_udbp_stat_type_fields[] = NG_UDBP_STATS_TYPE_INFO;
-static const struct ng_parse_type ng_udbp_stat_type = {
- &ng_parse_struct_type,
- &ng_udbp_stat_type_fields
-};
-
-/* List of commands and how to convert arguments to/from ASCII */
-static const struct ng_cmdlist ng_udbp_cmdlist[] = {
- {
- NGM_UDBP_COOKIE,
- NGM_UDBP_GET_STATUS,
- "getstatus",
- NULL,
- &ng_udbp_stat_type,
- },
- {
- NGM_UDBP_COOKIE,
- NGM_UDBP_SET_FLAG,
- "setflag",
- &ng_parse_int32_type,
- NULL
- },
- { 0 }
-};
-
-/* Netgraph node type descriptor */
-static struct ng_type ng_udbp_typestruct = {
- .version = NG_ABI_VERSION,
- .name = NG_UDBP_NODE_TYPE,
- .constructor = ng_udbp_constructor,
- .rcvmsg = ng_udbp_rcvmsg,
- .shutdown = ng_udbp_rmnode,
- .newhook = ng_udbp_newhook,
- .connect = ng_udbp_connect,
- .rcvdata = ng_udbp_rcvdata,
- .disconnect = ng_udbp_disconnect,
- .cmdlist = ng_udbp_cmdlist,
-};
-
-static int udbp_setup_in_transfer (udbp_p sc);
-static void udbp_in_transfer_cb (usbd_xfer_handle xfer,
- usbd_private_handle priv,
- usbd_status err);
-
-static int udbp_setup_out_transfer (udbp_p sc);
-static void udbp_out_transfer_cb (usbd_xfer_handle xfer,
- usbd_private_handle priv,
- usbd_status err);
-
-static device_probe_t udbp_match;
-static device_attach_t udbp_attach;
-static device_detach_t udbp_detach;
-
-static device_method_t udbp_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, udbp_match),
- DEVMETHOD(device_attach, udbp_attach),
- DEVMETHOD(device_detach, udbp_detach),
-
- { 0, 0 }
-};
-
-static driver_t udbp_driver = {
- "udbp",
- udbp_methods,
- sizeof(struct udbp_softc)
-};
-
-static devclass_t udbp_devclass;
-
-static int
-udbp_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usb_interface_descriptor_t *id;
- if (!uaa->iface)
- return (UMATCH_NONE);
- id = usbd_get_interface_descriptor(uaa->iface);
-
- /* XXX Julian, add the id of the device if you have one to test
- * things with. run 'usbdevs -v' and note the 3 ID's that appear.
- * The Vendor Id and Product Id are in hex and the Revision Id is in
- * bcd. But as usual if the revision is 0x101 then you should compare
- * the revision id in the device descriptor with 0x101
- * Or go search the file usbdevs.h. Maybe the device is already in
- * there.
- */
- if ((uaa->vendor == USB_VENDOR_NETCHIP &&
- uaa->product == USB_PRODUCT_NETCHIP_TURBOCONNECT))
- return (UMATCH_VENDOR_PRODUCT);
-
- if ((uaa->vendor == USB_VENDOR_PROLIFIC &&
- (uaa->product == USB_PRODUCT_PROLIFIC_PL2301 ||
- uaa->product == USB_PRODUCT_PROLIFIC_PL2302)))
- return (UMATCH_VENDOR_PRODUCT);
-
- if ((uaa->vendor == USB_VENDOR_ANCHOR &&
- uaa->product == USB_PRODUCT_ANCHOR_EZLINK))
- return (UMATCH_VENDOR_PRODUCT);
-
- if ((uaa->vendor == USB_VENDOR_GENESYS &&
- uaa->product == USB_PRODUCT_GENESYS_GL620USB))
- return (UMATCH_VENDOR_PRODUCT);
-
- return (UMATCH_NONE);
-}
-
-static int
-udbp_attach(device_t self)
-{
- struct udbp_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usbd_interface_handle iface = uaa->iface;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed, *ed_bulkin = NULL, *ed_bulkout = NULL;
- usbd_status err;
- int i;
- static int ngudbp_done_init=0;
-
- sc->flags |= DISCONNECTED;
- /* fetch the interface handle for the first interface */
- (void) usbd_device2interface_handle(uaa->device, 0, &iface);
- id = usbd_get_interface_descriptor(iface);
- sc->sc_dev = self;
-
- /* Find the two first bulk endpoints */
- for (i = 0 ; i < id->bNumEndpoints; i++) {
- ed = usbd_interface2endpoint_descriptor(iface, i);
- if (!ed) {
- device_printf(self, "could not read endpoint descriptor\n");
- return ENXIO;
- }
-
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN
- && (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
- ed_bulkin = ed;
- } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT
- && (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
- ed_bulkout = ed;
- }
-
- if (ed_bulkin && ed_bulkout) /* found all we need */
- break;
- }
-
- /* Verify that we goething sensible */
- if (ed_bulkin == NULL || ed_bulkout == NULL) {
- device_printf(self, "bulk-in and/or bulk-out endpoint not found\n");
- return ENXIO;
- }
-
- if (ed_bulkin->wMaxPacketSize[0] != ed_bulkout->wMaxPacketSize[0] ||
- ed_bulkin->wMaxPacketSize[1] != ed_bulkout->wMaxPacketSize[1]) {
- device_printf(self,
- "bulk-in and bulk-out have different packet sizes %d %d %d %d\n",
- ed_bulkin->wMaxPacketSize[0],
- ed_bulkout->wMaxPacketSize[0],
- ed_bulkin->wMaxPacketSize[1],
- ed_bulkout->wMaxPacketSize[1]);
- return ENXIO;
- }
-
- sc->sc_bulkin = ed_bulkin->bEndpointAddress;
- sc->sc_bulkout = ed_bulkout->bEndpointAddress;
-
- DPRINTF(("%s: Bulk-in: 0x%02x, bulk-out 0x%02x, packet size = %d\n",
- device_get_nameunit(sc->sc_dev), sc->sc_bulkin, sc->sc_bulkout,
- ed_bulkin->wMaxPacketSize[0]));
-
- /* Allocate the in transfer struct */
- sc->sc_bulkin_xfer = usbd_alloc_xfer(uaa->device);
- if (!sc->sc_bulkin_xfer) {
- goto bad;
- }
- sc->sc_bulkout_xfer = usbd_alloc_xfer(uaa->device);
- if (!sc->sc_bulkout_xfer) {
- goto bad;
- }
- sc->sc_bulkin_buffer = malloc(UDBP_BUFFERSIZE, M_USBDEV, M_WAITOK);
- if (!sc->sc_bulkin_buffer) {
- goto bad;
- }
- sc->sc_bulkout_buffer = malloc(UDBP_BUFFERSIZE, M_USBDEV, M_WAITOK);
- if (!sc->sc_bulkout_xfer || !sc->sc_bulkout_buffer) {
- goto bad;
- }
- sc->sc_bulkin_bufferlen = UDBP_BUFFERSIZE;
- sc->sc_bulkout_bufferlen = UDBP_BUFFERSIZE;
-
- /* We have decided on which endpoints to use, now open the pipes */
- err = usbd_open_pipe(iface, sc->sc_bulkin,
- USBD_EXCLUSIVE_USE, &sc->sc_bulkin_pipe);
- if (err) {
- device_printf(self, "cannot open bulk-in pipe (addr %d)\n",
- sc->sc_bulkin);
- goto bad;
- }
- err = usbd_open_pipe(iface, sc->sc_bulkout,
- USBD_EXCLUSIVE_USE, &sc->sc_bulkout_pipe);
- if (err) {
- device_printf(self, "cannot open bulk-out pipe (addr %d)\n",
- sc->sc_bulkout);
- goto bad;
- }
-
- if (!ngudbp_done_init){
- ngudbp_done_init=1;
- if (ng_newtype(&ng_udbp_typestruct)) {
- printf("ngudbp install failed\n");
- goto bad;
- }
- }
-
- if ((err = ng_make_node_common(&ng_udbp_typestruct, &sc->node)) == 0) {
- char nodename[128];
- sprintf(nodename, "%s", device_get_nameunit(sc->sc_dev));
- if ((err = ng_name_node(sc->node, nodename))) {
- NG_NODE_UNREF(sc->node);
- sc->node = NULL;
- goto bad;
- } else {
- NG_NODE_SET_PRIVATE(sc->node, sc);
- sc->xmitq.ifq_maxlen = IFQ_MAXLEN;
- sc->xmitq_hipri.ifq_maxlen = IFQ_MAXLEN;
- mtx_init(&sc->xmitq.ifq_mtx, "usb_xmitq", NULL,
- MTX_DEF);
- mtx_init(&sc->xmitq_hipri.ifq_mtx,
- "usb_xmitq_hipri", NULL, MTX_DEF);
- }
- }
- sc->flags = NETGRAPH_INITIALISED;
- /* sc->flags &= ~DISCONNECTED; */ /* XXX */
-
-
- /* the device is now operational */
-
-
- /* schedule the first incoming xfer */
- err = udbp_setup_in_transfer(sc);
- if (err) {
- goto bad;
- }
- return 0;
-bad:
-#if 0 /* probably done in udbp_detach() */
- if (sc->sc_bulkout_buffer) {
- free(sc->sc_bulkout_buffer, M_USBDEV);
- }
- if (sc->sc_bulkin_buffer) {
- free(sc->sc_bulkin_buffer, M_USBDEV);
- }
- if (sc->sc_bulkout_xfer) {
- usbd_free_xfer(sc->sc_bulkout_xfer);
- }
- if (sc->sc_bulkin_xfer) {
- usbd_free_xfer(sc->sc_bulkin_xfer);
- }
-#endif
- udbp_detach(self);
- return ENXIO;
-}
-
-
-static int
-udbp_detach(device_t self)
-{
- struct udbp_softc *sc = device_get_softc(self);
-
- sc->flags |= DISCONNECTED;
-
- DPRINTF(("%s: disconnected\n", device_get_nameunit(self)));
-
- if (sc->sc_bulkin_pipe) {
- usbd_abort_pipe(sc->sc_bulkin_pipe);
- usbd_close_pipe(sc->sc_bulkin_pipe);
- }
- if (sc->sc_bulkout_pipe) {
- usbd_abort_pipe(sc->sc_bulkout_pipe);
- usbd_close_pipe(sc->sc_bulkout_pipe);
- }
-
- if (sc->flags & NETGRAPH_INITIALISED) {
- ng_rmnode_self(sc->node);
- NG_NODE_SET_PRIVATE(sc->node, NULL);
- NG_NODE_UNREF(sc->node);
- sc->node = NULL; /* Paranoid */
- }
-
- if (sc->sc_bulkin_xfer)
- usbd_free_xfer(sc->sc_bulkin_xfer);
- if (sc->sc_bulkout_xfer)
- usbd_free_xfer(sc->sc_bulkout_xfer);
-
- if (sc->sc_bulkin_buffer)
- free(sc->sc_bulkin_buffer, M_USBDEV);
- if (sc->sc_bulkout_buffer)
- free(sc->sc_bulkout_buffer, M_USBDEV);
- return 0;
-}
-
-
-static int
-udbp_setup_in_transfer(udbp_p sc)
-{
- void *priv = sc; /* XXX this should probably be some pointer to
- * struct describing the transfer (mbuf?)
- * See also below.
- */
- usbd_status err;
-
- /* XXX
- * How should we arrange for 2 extra bytes at the start of the
- * packet?
- */
-
- /* Initialise a USB transfer and then schedule it */
-
- (void) usbd_setup_xfer( sc->sc_bulkin_xfer,
- sc->sc_bulkin_pipe,
- priv,
- sc->sc_bulkin_buffer,
- sc->sc_bulkin_bufferlen,
- USBD_SHORT_XFER_OK,
- USBD_NO_TIMEOUT,
- udbp_in_transfer_cb);
-
- err = usbd_transfer(sc->sc_bulkin_xfer);
- if (err && err != USBD_IN_PROGRESS) {
- DPRINTF(("%s: failed to setup in-transfer, %s\n",
- device_get_nameunit(sc->sc_dev), usbd_errstr(err)));
- return(err);
- }
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-static void
-udbp_in_transfer_cb(usbd_xfer_handle xfer, usbd_private_handle priv,
- usbd_status err)
-{
- udbp_p sc = priv; /* XXX see priv above */
- int s;
- int len;
- struct mbuf *m;
-
- if (err) {
- if (err != USBD_CANCELLED) {
- DPRINTF(("%s: bulk-out transfer failed: %s\n",
- device_get_nameunit(sc->sc_dev), usbd_errstr(err)));
- } else {
- /* USBD_CANCELLED happens at unload of the driver */
- return;
- }
-
- /* Transfer has failed, packet is not received */
- } else {
-
- len = xfer->actlen;
-
- s = splimp(); /* block network stuff too */
- if (sc->hook) {
- /* get packet from device and send on */
- m = m_devget(sc->sc_bulkin_buffer, len, 0, NULL, NULL);
- NG_SEND_DATA_ONLY(err, sc->hook, m);
- }
- splx(s);
-
- }
- /* schedule the next in transfer */
- udbp_setup_in_transfer(sc);
-}
-
-
-static int
-udbp_setup_out_transfer(udbp_p sc)
-{
- void *priv = sc; /* XXX this should probably be some pointer to
- * struct describing the transfer (mbuf?)
- * See also below.
- */
- int pktlen;
- usbd_status err;
- int s, s1;
- struct mbuf *m;
-
-
- s = splusb();
- if (sc->flags & OUT_BUSY)
- panic("out transfer already in use, we should add queuing");
- sc->flags |= OUT_BUSY;
- splx(s);
- s1 = splimp(); /* Queueing happens at splnet */
- IF_DEQUEUE(&sc->xmitq_hipri, m);
- if (m == NULL) {
- IF_DEQUEUE(&sc->xmitq, m);
- }
- splx(s1);
-
- if (!m) {
- sc->flags &= ~OUT_BUSY;
- return (USBD_NORMAL_COMPLETION);
- }
-
- pktlen = m->m_pkthdr.len;
- if (pktlen > sc->sc_bulkout_bufferlen) {
- device_printf(sc->sc_dev, "Packet too large, %d > %d\n",
- pktlen, sc->sc_bulkout_bufferlen);
- return (USBD_IOERROR);
- }
-
- m_copydata(m, 0, pktlen, sc->sc_bulkout_buffer);
- m_freem(m);
-
- /* Initialise a USB transfer and then schedule it */
-
- (void) usbd_setup_xfer( sc->sc_bulkout_xfer,
- sc->sc_bulkout_pipe,
- priv,
- sc->sc_bulkout_buffer,
- pktlen,
- USBD_SHORT_XFER_OK,
- UDBP_TIMEOUT,
- udbp_out_transfer_cb);
-
- err = usbd_transfer(sc->sc_bulkout_xfer);
- if (err && err != USBD_IN_PROGRESS) {
- DPRINTF(("%s: failed to setup out-transfer, %s\n",
- device_get_nameunit(sc->sc_dev), usbd_errstr(err)));
- return(err);
- }
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-static void
-udbp_out_transfer_cb(usbd_xfer_handle xfer, usbd_private_handle priv,
- usbd_status err)
-{
- udbp_p sc = priv; /* XXX see priv above */
- int s;
-
- if (err) {
- DPRINTF(("%s: bulk-out transfer failed: %s\n",
- device_get_nameunit(sc->sc_dev), usbd_errstr(err)));
- /* Transfer has failed, packet is not transmitted */
- /* XXX Invalidate packet */
- return;
- }
-
- /* packet has been transmitted */
-
- s = splusb(); /* mark the buffer available */
- sc->flags &= ~OUT_BUSY;
- udbp_setup_out_transfer(sc);
- splx(s);
-}
-
-DRIVER_MODULE(udbp, uhub, udbp_driver, udbp_devclass, usbd_driver_load, 0);
-MODULE_DEPEND(udbp, netgraph, NG_ABI_VERSION, NG_ABI_VERSION, NG_ABI_VERSION);
-MODULE_DEPEND(udbp, usb, 1, 1, 1);
-
-
-/***********************************************************************
- * Start of Netgraph methods
- **********************************************************************/
-
-/*
- * If this is a device node so this work is done in the attach()
- * routine and the constructor will return EINVAL as you should not be able
- * to create nodes that depend on hardware (unless you can add the hardware :)
- */
-static int
-ng_udbp_constructor(node_p node)
-{
- return (EINVAL);
-}
-
-/*
- * Give our ok for a hook to be added...
- * If we are not running this might kick a device into life.
- * Possibly decode information out of the hook name.
- * Add the hook's private info to the hook structure.
- * (if we had some). In this example, we assume that there is a
- * an array of structs, called 'channel' in the private info,
- * one for each active channel. The private
- * pointer of each hook points to the appropriate UDBP_hookinfo struct
- * so that the source of an input packet is easily identified.
- */
-static int
-ng_udbp_newhook(node_p node, hook_p hook, const char *name)
-{
- const udbp_p sc = NG_NODE_PRIVATE(node);
-
-#if 0
- /* Possibly start up the device if it's not already going */
- if ((sc->flags & SCF_RUNNING) == 0) {
- ng_udbp_start_hardware(sc);
- }
-#endif
-
- if (strcmp(name, NG_UDBP_HOOK_NAME) == 0) {
- sc->hook = hook;
- NG_HOOK_SET_PRIVATE(hook, NULL);
- } else {
- return (EINVAL); /* not a hook we know about */
- }
- return(0);
-}
-
-/*
- * Get a netgraph control message.
- * Check it is one we understand. If needed, send a response.
- * We could save the address for an async action later, but don't here.
- * Always free the message.
- * The response should be in a malloc'd region that the caller can 'free'.
- * A response is not required.
- * Theoretically you could respond defferently to old message types if
- * the cookie in the header didn't match what we consider to be current
- * (so that old userland programs could continue to work).
- */
-static int
-ng_udbp_rcvmsg(node_p node, item_p item, hook_p lasthook)
-{
- const udbp_p sc = NG_NODE_PRIVATE(node);
- struct ng_mesg *resp = NULL;
- int error = 0;
- struct ng_mesg *msg;
-
- NGI_GET_MSG(item, msg);
- /* Deal with message according to cookie and command */
- switch (msg->header.typecookie) {
- case NGM_UDBP_COOKIE:
- switch (msg->header.cmd) {
- case NGM_UDBP_GET_STATUS:
- {
- struct ngudbpstat *stats;
-
- NG_MKRESPONSE(resp, msg, sizeof(*stats), M_NOWAIT);
- if (!resp) {
- error = ENOMEM;
- break;
- }
- stats = (struct ngudbpstat *) resp->data;
- stats->packets_in = sc->packets_in;
- stats->packets_out = sc->packets_out;
- break;
- }
- case NGM_UDBP_SET_FLAG:
- if (msg->header.arglen != sizeof(u_int32_t)) {
- error = EINVAL;
- break;
- }
- sc->flags = *((u_int32_t *) msg->data);
- break;
- default:
- error = EINVAL; /* unknown command */
- break;
- }
- break;
- default:
- error = EINVAL; /* unknown cookie type */
- break;
- }
-
- /* Take care of synchronous response, if any */
- NG_RESPOND_MSG(error, node, item, resp);
- NG_FREE_MSG(msg);
- return(error);
-}
-
-/*
- * Accept data from the hook and queue it for output.
- */
-static int
-ng_udbp_rcvdata(hook_p hook, item_p item)
-{
- const udbp_p sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
- int error;
- struct ifqueue *xmitq_p;
- int s;
- struct mbuf *m;
- struct ng_tag_prio *ptag;
-
- NGI_GET_M(item, m);
- NG_FREE_ITEM(item);
-
- /*
- * Now queue the data for when it can be sent
- */
- if ((ptag = (struct ng_tag_prio *)m_tag_locate(m, NGM_GENERIC_COOKIE,
- NG_TAG_PRIO, NULL)) != NULL && (ptag->priority > NG_PRIO_CUTOFF) )
- xmitq_p = (&sc->xmitq_hipri);
- else
- xmitq_p = (&sc->xmitq);
-
- s = splusb();
- IF_LOCK(xmitq_p);
- if (_IF_QFULL(xmitq_p)) {
- _IF_DROP(xmitq_p);
- IF_UNLOCK(xmitq_p);
- splx(s);
- error = ENOBUFS;
- goto bad;
- }
- _IF_ENQUEUE(xmitq_p, m);
- IF_UNLOCK(xmitq_p);
- if (!(sc->flags & OUT_BUSY))
- udbp_setup_out_transfer(sc);
- splx(s);
- return (0);
-
-bad: /*
- * It was an error case.
- * check if we need to free the mbuf, and then return the error
- */
- NG_FREE_M(m);
- return (error);
-}
-
-/*
- * Do local shutdown processing..
- * We are a persistant device, we refuse to go away, and
- * only remove our links and reset ourself.
- */
-static int
-ng_udbp_rmnode(node_p node)
-{
- const udbp_p sc = NG_NODE_PRIVATE(node);
- int err;
-
- if (sc->flags & DISCONNECTED) {
- /*
- * WE are really going away.. hardware must have gone.
- * Assume that the hardware drive part will clear up the
- * sc, in fact it may already have done so..
- * In which case we may have just segfaulted..XXX
- */
- return (0);
- }
-
- /* stolen from attach routine */
- /* Drain the queues */
- IF_DRAIN(&sc->xmitq_hipri);
- IF_DRAIN(&sc->xmitq);
-
- sc->packets_in = 0; /* reset stats */
- sc->packets_out = 0;
- NG_NODE_UNREF(node); /* forget it ever existed */
-
- if ((err = ng_make_node_common(&ng_udbp_typestruct, &sc->node)) == 0) {
- char nodename[128];
- sprintf(nodename, "%s", device_get_nameunit(sc->sc_dev));
- if ((err = ng_name_node(sc->node, nodename))) {
- NG_NODE_UNREF(sc->node); /* out damned spot! */
- sc->flags &= ~NETGRAPH_INITIALISED;
- sc->node = NULL;
- } else {
- NG_NODE_SET_PRIVATE(sc->node, sc);
- }
- }
- return (err);
-}
-
-/*
- * This is called once we've already connected a new hook to the other node.
- * It gives us a chance to balk at the last minute.
- */
-static int
-ng_udbp_connect(hook_p hook)
-{
- /* probably not at splnet, force outward queueing */
- NG_HOOK_FORCE_QUEUE(NG_HOOK_PEER(hook));
- /* be really amiable and just say "YUP that's OK by me! " */
- return (0);
-}
-
-/*
- * Dook disconnection
- *
- * For this type, removal of the last link destroys the node
- */
-static int
-ng_udbp_disconnect(hook_p hook)
-{
- const udbp_p sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
- sc->hook = NULL;
-
- if ((NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0)
- && (NG_NODE_IS_VALID(NG_HOOK_NODE(hook))))
- ng_rmnode_self(NG_HOOK_NODE(hook));
- return (0);
-}
-
diff --git a/sys/dev/usb/udbp.h b/sys/dev/usb/udbp.h
deleted file mode 100644
index 97ef945..0000000
--- a/sys/dev/usb/udbp.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*-
- * Copyright (c) 1996-2000 Whistle Communications, Inc.
- * All rights reserved.
- *
- * Subject to the following obligations and disclaimer of warranty, use and
- * redistribution of this software, in source or object code forms, with or
- * without modifications are expressly permitted by Whistle Communications;
- * provided, however, that:
- * 1. Any and all reproductions of the source or object code must include the
- * copyright notice above and the following disclaimer of warranties; and
- * 2. No rights are granted, in any manner or form, to use Whistle
- * Communications, Inc. trademarks, including the mark "WHISTLE
- * COMMUNICATIONS" on advertising, endorsements, or otherwise except as
- * such appears in the above copyright notice or in the software.
- *
- * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
- * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
- * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
- * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
- * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
- * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
- * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
- * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
- * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
- * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER 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 WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * This file was derived from src/sys/netgraph/ng_sample.h, revision 1.1
- * written by Julian Elischer, Whistle Communications.
- *
- * $FreeBSD$
- */
-
-#ifndef _NETGRAPH_UDBP_H_
-#define _NETGRAPH_UDBP_H_
-
-/* Node type name. This should be unique among all netgraph node types */
-#define NG_UDBP_NODE_TYPE "udbp"
-
-/* Node type cookie. Should also be unique. This value MUST change whenever
- an incompatible change is made to this header file, to insure consistency.
- The de facto method for generating cookies is to take the output of the
- date command: date -u +'%s' */
-#define NGM_UDBP_COOKIE 944609300
-
-
-#define NG_UDBP_HOOK_NAME "data"
-
-/* Netgraph commands understood by this node type */
-enum {
- NGM_UDBP_SET_FLAG = 1,
- NGM_UDBP_GET_STATUS,
-};
-
-/* This structure is returned by the NGM_UDBP_GET_STATUS command */
-struct ngudbpstat {
- u_int packets_in; /* packets in from downstream */
- u_int packets_out; /* packets out towards downstream */
-};
-
-/*
- * This is used to define the 'parse type' for a struct ngudbpstat, which
- * is bascially a description of how to convert a binary struct ngudbpstat
- * to an ASCII string and back. See ng_parse.h for more info.
- *
- * This needs to be kept in sync with the above structure definition
- */
-#define NG_UDBP_STATS_TYPE_INFO { \
- { "packets_in", &ng_parse_int32_type }, \
- { "packets_out", &ng_parse_int32_type }, \
- { NULL }, \
-}
-
-#endif /* _NETGRAPH_UDBP_H_ */
diff --git a/sys/dev/usb/ufm.c b/sys/dev/usb/ufm.c
deleted file mode 100644
index 2635827..0000000
--- a/sys/dev/usb/ufm.c
+++ /dev/null
@@ -1,376 +0,0 @@
-/*-
- * Copyright (c) 2001-2007 M. Warner Losh
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- * This code is based on ugen.c and ulpt.c developed by Lennart Augustsson.
- * This code includes software developed by the NetBSD Foundation, Inc. and
- * its contributors.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/ioccom.h>
-#include <sys/fcntl.h>
-#include <sys/filio.h>
-#include <sys/conf.h>
-#include <sys/uio.h>
-#include <sys/tty.h>
-#include <sys/file.h>
-#include <sys/selinfo.h>
-#include <sys/poll.h>
-#include <sys/sysctl.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-
-#include "usbdevs.h"
-#include <dev/usb/dsbr100io.h>
-
-#ifdef USB_DEBUG
-#define DPRINTF(x) if (ufmdebug) printf x
-#define DPRINTFN(n,x) if (ufmdebug>(n)) printf x
-int ufmdebug = 0;
-SYSCTL_NODE(_hw_usb, OID_AUTO, ufm, CTLFLAG_RW, 0, "USB ufm");
-SYSCTL_INT(_hw_usb_ufm, OID_AUTO, debug, CTLFLAG_RW,
- &ufmdebug, 0, "ufm debug level");
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-d_open_t ufmopen;
-d_close_t ufmclose;
-d_ioctl_t ufmioctl;
-
-static struct cdevsw ufm_cdevsw = {
- .d_version = D_VERSION,
- .d_flags = D_NEEDGIANT,
- .d_open = ufmopen,
- .d_close = ufmclose,
- .d_ioctl = ufmioctl,
- .d_name = "ufm",
-};
-
-#define FM_CMD0 0x00
-#define FM_CMD_SET_FREQ 0x01
-#define FM_CMD2 0x02
-
-struct ufm_softc {
- device_t sc_dev;
- usbd_device_handle sc_udev;
- usbd_interface_handle sc_iface;
-
- int sc_opened;
- int sc_epaddr;
- int sc_freq;
-
- int sc_refcnt;
-};
-
-#define UFMUNIT(n) (dev2unit(n))
-
-static device_probe_t ufm_match;
-static device_attach_t ufm_attach;
-static device_detach_t ufm_detach;
-
-static device_method_t ufm_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, ufm_match),
- DEVMETHOD(device_attach, ufm_attach),
- DEVMETHOD(device_detach, ufm_detach),
-
- { 0, 0 }
-};
-
-static driver_t ufm_driver = {
- "ufm",
- ufm_methods,
- sizeof(struct ufm_softc)
-};
-
-static devclass_t ufm_devclass;
-
-static int
-ufm_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usb_device_descriptor_t *dd;
-
- DPRINTFN(10,("ufm_match\n"));
- if (!uaa->iface)
- return UMATCH_NONE;
-
- dd = usbd_get_device_descriptor(uaa->device);
-
- if (dd &&
- ((UGETW(dd->idVendor) == USB_VENDOR_CYPRESS &&
- UGETW(dd->idProduct) == USB_PRODUCT_CYPRESS_FMRADIO)))
- return UMATCH_VENDOR_PRODUCT;
- else
- return UMATCH_NONE;
-}
-
-static int
-ufm_attach(device_t self)
-{
- struct ufm_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usb_endpoint_descriptor_t *edesc;
- usbd_device_handle udev;
- usbd_interface_handle iface;
- u_int8_t epcount;
- usbd_status r;
- char * ermsg = "<none>";
-
- DPRINTFN(10,("ufm_attach: sc=%p\n", sc));
- sc->sc_dev = self;
- sc->sc_udev = udev = uaa->device;
-
- if ((!uaa->device) || (!uaa->iface)) {
- ermsg = "device or iface";
- goto nobulk;
- }
- sc->sc_iface = iface = uaa->iface;
- sc->sc_opened = 0;
- sc->sc_refcnt = 0;
-
- r = usbd_endpoint_count(iface, &epcount);
- if (r != USBD_NORMAL_COMPLETION) {
- ermsg = "endpoints";
- goto nobulk;
- }
-
- edesc = usbd_interface2endpoint_descriptor(iface, 0);
- if (!edesc) {
- ermsg = "interface endpoint";
- goto nobulk;
- }
- sc->sc_epaddr = edesc->bEndpointAddress;
-
- /* XXX no error trapping, no storing of struct cdev **/
- (void) make_dev(&ufm_cdevsw, device_get_unit(self),
- UID_ROOT, GID_OPERATOR,
- 0644, "ufm%d", device_get_unit(self));
- DPRINTFN(10, ("ufm_attach: %p\n", sc->sc_udev));
- return 0;
-
- nobulk:
- device_printf(sc->sc_dev, "could not find %s\n", ermsg);
- return ENXIO;
-}
-
-
-int
-ufmopen(struct cdev *dev, int flag, int mode, struct thread *td)
-{
- struct ufm_softc *sc;
-
- int unit = UFMUNIT(dev);
- sc = devclass_get_softc(ufm_devclass, unit);
- if (sc == NULL)
- return (ENXIO);
-
- DPRINTFN(5, ("ufmopen: flag=%d, mode=%d, unit=%d\n",
- flag, mode, unit));
-
- if (sc->sc_opened)
- return (EBUSY);
-
- if ((flag & (FWRITE|FREAD)) != (FWRITE|FREAD))
- return (EACCES);
-
- sc->sc_opened = 1;
- return (0);
-}
-
-int
-ufmclose(struct cdev *dev, int flag, int mode, struct thread *td)
-{
- struct ufm_softc *sc;
-
- int unit = UFMUNIT(dev);
- sc = devclass_get_softc(ufm_devclass, unit);
-
- DPRINTFN(5, ("ufmclose: flag=%d, mode=%d, unit=%d\n", flag, mode, unit));
- sc->sc_opened = 0;
- sc->sc_refcnt = 0;
- return 0;
-}
-
-static int
-ufm_do_req(struct ufm_softc *sc, u_int8_t reqtype, u_int8_t request,
- u_int16_t value, u_int16_t index, u_int8_t len, void *retbuf)
-{
- int s;
- usb_device_request_t req;
- usbd_status err;
-
- s = splusb();
- req.bmRequestType = reqtype;
- req.bRequest = request;
- USETW(req.wValue, value);
- USETW(req.wIndex, index);
- USETW(req.wLength, len);
- err = usbd_do_request_flags(sc->sc_udev, &req, retbuf, 0, NULL,
- USBD_DEFAULT_TIMEOUT);
- splx(s);
- if (err)
- return (EIO);
- return (0);
-}
-
-static int
-ufm_set_freq(struct ufm_softc *sc, caddr_t addr)
-{
- int freq = *(int *)addr;
- u_int8_t ret;
-
- /*
- * Freq now is in Hz. We need to convert it to the frequency
- * that the radio wants. This frequency is 10.7MHz above
- * the actual frequency. We then need to convert to
- * units of 12.5kHz. We add one to the IFM to make rounding
- * easier.
- */
- sc->sc_freq = freq;
- freq = (freq + 10700001) / 12500;
- /* This appears to set the frequency */
- if (ufm_do_req(sc, UT_READ_VENDOR_DEVICE, FM_CMD_SET_FREQ, freq >> 8,
- freq, 1, &ret) != 0)
- return (EIO);
- /* Not sure what this does */
- if (ufm_do_req(sc, UT_READ_VENDOR_DEVICE, FM_CMD0, 0x96, 0xb7, 1,
- &ret) != 0)
- return (EIO);
- return (0);
-}
-
-static int
-ufm_get_freq(struct ufm_softc *sc, caddr_t addr)
-{
- int *valp = (int *)addr;
- *valp = sc->sc_freq;
- return (0);
-}
-
-static int
-ufm_start(struct ufm_softc *sc, caddr_t addr)
-{
- u_int8_t ret;
-
- if (ufm_do_req(sc, UT_READ_VENDOR_DEVICE, FM_CMD0, 0x00, 0xc7,
- 1, &ret))
- return (EIO);
- if (ufm_do_req(sc, UT_READ_VENDOR_DEVICE, FM_CMD2, 0x01, 0x00,
- 1, &ret))
- return (EIO);
- if (ret & 0x1)
- return (EIO);
- return (0);
-}
-
-static int
-ufm_stop(struct ufm_softc *sc, caddr_t addr)
-{
- u_int8_t ret;
-
- if (ufm_do_req(sc, UT_READ_VENDOR_DEVICE, FM_CMD0, 0x16, 0x1C,
- 1, &ret))
- return (EIO);
- if (ufm_do_req(sc, UT_READ_VENDOR_DEVICE, FM_CMD2, 0x00, 0x00,
- 1, &ret))
- return (EIO);
- return (0);
-}
-
-static int
-ufm_get_stat(struct ufm_softc *sc, caddr_t addr)
-{
- u_int8_t ret;
-
- /*
- * Note, there's a 240ms settle time before the status
- * will be valid, so tsleep that amount. hz/4 is a good
- * approximation of that. Since this is a short sleep
- * we don't try to catch any signals to keep things
- * simple.
- */
- tsleep(sc, 0, "ufmwait", hz/4);
- if (ufm_do_req(sc, UT_READ_VENDOR_DEVICE, FM_CMD0, 0x00, 0x24,
- 1, &ret))
- return (EIO);
- *(int *)addr = ret;
-
- return (0);
-}
-
-int
-ufmioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td)
-{
- struct ufm_softc *sc;
-
- int unit = UFMUNIT(dev);
- int error = 0;
-
- sc = devclass_get_softc(ufm_devclass, unit);
-
- switch (cmd) {
- case FM_SET_FREQ:
- error = ufm_set_freq(sc, addr);
- break;
- case FM_GET_FREQ:
- error = ufm_get_freq(sc, addr);
- break;
- case FM_START:
- error = ufm_start(sc, addr);
- break;
- case FM_STOP:
- error = ufm_stop(sc, addr);
- break;
- case FM_GET_STAT:
- error = ufm_get_stat(sc, addr);
- break;
- default:
- return ENOTTY;
- break;
- }
- return error;
-}
-
-static int
-ufm_detach(device_t self)
-{
- return 0;
-}
-
-MODULE_DEPEND(ufm, usb, 1, 1, 1);
-DRIVER_MODULE(ufm, uhub, ufm_driver, ufm_devclass, usbd_driver_load, 0);
diff --git a/sys/dev/usb/ufoma.c b/sys/dev/usb/ufoma.c
deleted file mode 100644
index e5704a7..0000000
--- a/sys/dev/usb/ufoma.c
+++ /dev/null
@@ -1,1192 +0,0 @@
-/* $NetBSD: umodem.c,v 1.45 2002/09/23 05:51:23 simonb Exp $ */
-#define UFOMA_HANDSFREE
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*-
- * Copyright (c) 2005, Takanori Watanabe
- * Copyright (c) 2003, M. Warner Losh <imp@freebsd.org>.
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- */
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) 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.
- */
-
-/*
- * Comm Class spec: http://www.usb.org/developers/devclass_docs/usbccs10.pdf
- * http://www.usb.org/developers/devclass_docs/usbcdc11.pdf
- */
-
-/*
- * TODO:
- * - Add error recovery in various places; the big problem is what
- * to do in a callback if there is an error.
- * - Implement a Call Device for modems without multiplexed commands.
- *
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/ioccom.h>
-#include <sys/conf.h>
-#include <sys/serial.h>
-#include <sys/tty.h>
-#include <sys/file.h>
-#include <sys/select.h>
-#include <sys/sysctl.h>
-#include <sys/proc.h>
-#include <sys/bus.h>
-#include <sys/sbuf.h>
-#include <sys/poll.h>
-#include <sys/uio.h>
-#include <sys/taskqueue.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbcdc.h>
-
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include <dev/usb/usb_quirks.h>
-
-#include <dev/usb/ucomvar.h>
-
-#include "usbdevs.h"
-
-typedef struct ufoma_mobile_acm_descriptor{
- uByte bFunctionLength;
- uByte bDescriptorType;
- uByte bDescriptorSubtype;
- uByte bType;
- uByte bMode[1];
-}usb_mcpc_acm_descriptor;
-
-#define UISUBCLASS_MCPC 0x88
-
-#define UDESC_VS_INTERFACE 0x44
-#define UDESCSUB_MCPC_ACM 0x11
-
-#define UMCPC_ACM_TYPE_AB1 0x1
-#define UMCPC_ACM_TYPE_AB2 0x2
-#define UMCPC_ACM_TYPE_AB5 0x5
-#define UMCPC_ACM_TYPE_AB6 0x6
-
-#define UMCPC_ACM_MODE_DEACTIVATED 0x0
-#define UMCPC_ACM_MODE_MODEM 0x1
-#define UMCPC_ACM_MODE_ATCOMMAND 0x2
-#define UMCPC_ACM_MODE_OBEX 0x60
-#define UMCPC_ACM_MODE_VENDOR1 0xc0
-#define UMCPC_ACM_MODE_VENDOR2 0xfe
-#define UMCPC_ACM_MODE_UNLINKED 0xff
-
-#define UMCPC_CM_MOBILE_ACM 0x0
-
-#define UMCPC_ACTIVATE_MODE 0x60
-#define UMCPC_GET_MODETABLE 0x61
-#define UMCPC_SET_LINK 0x62
-#define UMCPC_CLEAR_LINK 0x63
-
-#define UMCPC_REQUEST_ACKNOLEDGE 0x31
-
-#define UFOMA_MAX_TIMEOUT 15 /*Standard says 10(sec)*/
-#define UFOMA_CMD_BUF_SIZE 64
-
-#define UMODEMIBUFSIZE 1024
-#define UMODEMOBUFSIZE 1024
-#define DPRINTF(a)
-
-struct ufoma_softc{
- struct ucom_softc sc_ucom;
- int sc_is_ucom;
- int sc_isopen;
-
- struct mtx sc_mtx;
- int sc_ctl_iface_no;
- usbd_interface_handle sc_ctl_iface;
- usbd_interface_handle sc_data_iface;
- int sc_data_iface_no;
- int sc_cm_cap;
- int sc_acm_cap;
- usb_cdc_line_state_t sc_line_state; /* current line state */
- usb_cdc_line_state_t sc_line_state_init; /* pre open line state*/
- u_char sc_dtr; /* current DTR state */
- u_char sc_rts; /* current RTS state */
-
- usbd_pipe_handle sc_notify_pipe;
- usb_cdc_notification_t sc_notify_buf;
- u_char sc_lsr;
- u_char sc_msr;
-
- struct task sc_task;
- uByte *sc_modetable;
- uByte sc_modetoactivate;
- uByte sc_currentmode;
- char sc_resbuffer[UFOMA_CMD_BUF_SIZE+1];
- int sc_cmdbp;
- int sc_nummsg;
- usbd_xfer_handle sc_msgxf;
-};
-static usbd_status
-ufoma_set_line_coding(struct ufoma_softc *sc, usb_cdc_line_state_t *state);
-static device_probe_t ufoma_match;
-static device_attach_t ufoma_attach;
-static device_detach_t ufoma_detach;
-static void *ufoma_get_intconf(usb_config_descriptor_t *cd, usb_interface_descriptor_t *id,int type, int subtype);
-static void ufoma_notify(void * ,int count);
-static void ufoma_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
-static char *ufoma_mode_to_str(int);
-static int ufoma_str_to_mode(char *);
-
-#ifdef UFOMA_HANDSFREE
-/*Pseudo ucom stuff(for Handsfree interface)*/
-static int ufoma_init_pseudo_ucom(struct ufoma_softc *);
-static tsw_open_t ufoma_open;
-static tsw_close_t ufoma_close;
-static tsw_outwakeup_t ufoma_outwakeup;
-static tsw_free_t ufoma_free;
-#endif
-
-/*umodem like stuff*/
-static int ufoma_init_modem(struct ufoma_softc *, struct usb_attach_arg *);
-static void ufoma_get_status(void *, int portno, u_char *lst, u_char *msr);
-static void ufoma_set(void *, int portno, int reg, int onoff);
-static int ufoma_param(void *, int portno, struct termios *);
-static int ufoma_ucom_open(void *, int portno);
-static void ufoma_ucom_close(void *, int portno);
-static void ufoma_break(struct ufoma_softc *sc, int onoff);
-static void ufoma_dtr(struct ufoma_softc *sc, int onoff);
-static void ufoma_rts(struct ufoma_softc *sc, int onoff);
-
-/*sysctl stuff*/
-static int ufoma_sysctl_support(SYSCTL_HANDLER_ARGS);
-static int ufoma_sysctl_current(SYSCTL_HANDLER_ARGS);
-static int ufoma_sysctl_open(SYSCTL_HANDLER_ARGS);
-static void ufoma_set_line_state(struct ufoma_softc *sc);
-
-static struct ucom_callback ufoma_callback = {
- .ucom_get_status = ufoma_get_status,
- .ucom_set = ufoma_set,
- .ucom_param = ufoma_param,
- .ucom_open = ufoma_ucom_open,
- .ucom_close = ufoma_ucom_close,
-};
-
-
-static device_method_t ufoma_methods[] = {
- /**/
- DEVMETHOD(device_probe, ufoma_match),
- DEVMETHOD(device_attach, ufoma_attach),
- DEVMETHOD(device_detach, ufoma_detach),
- {0, 0}
-};
-struct umcpc_modetostr_tab{
- int mode;
- char *str;
-}umcpc_modetostr_tab[]={
- {UMCPC_ACM_MODE_DEACTIVATED, "deactivated"},
- {UMCPC_ACM_MODE_MODEM, "modem"},
- {UMCPC_ACM_MODE_ATCOMMAND, "handsfree"},
- {UMCPC_ACM_MODE_OBEX, "obex"},
- {UMCPC_ACM_MODE_VENDOR1, "vendor1"},
- {UMCPC_ACM_MODE_VENDOR2, "vendor2"},
- {UMCPC_ACM_MODE_UNLINKED, "unlinked"},
- {0, NULL}
-};
-
-static driver_t ufoma_driver = {
- "ucom",
- ufoma_methods,
- sizeof(struct ufoma_softc)
-};
-
-
-DRIVER_MODULE(ufoma, uhub, ufoma_driver, ucom_devclass, usbd_driver_load, 0);
-MODULE_DEPEND(ufoma, usb, 1, 1, 1);
-MODULE_DEPEND(ufoma, ucom, UCOM_MINVER, UCOM_PREFVER, UCOM_MAXVER);
-
-static int
-ufoma_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usb_interface_descriptor_t *id;
- usb_config_descriptor_t *cd;
- usb_mcpc_acm_descriptor *mad;
- int ret;
-
- ret = UMATCH_NONE;
-
- if(uaa->iface == NULL)
- return(UMATCH_NONE);
- id = usbd_get_interface_descriptor(uaa->iface);
- cd = usbd_get_config_descriptor(uaa->device);
-
- if(id == NULL || cd == NULL)
- return (UMATCH_NONE);
-
- if( id->bInterfaceClass == UICLASS_CDC &&
- id->bInterfaceSubClass == UISUBCLASS_MCPC){
- ret = (UMATCH_IFACECLASS_IFACESUBCLASS);
- }else{
- return UMATCH_NONE;
- }
-
- mad = ufoma_get_intconf(cd, id , UDESC_VS_INTERFACE, UDESCSUB_MCPC_ACM);
- if(mad == NULL){
- return (UMATCH_NONE);
- }
-
-#ifndef UFOMA_HANDSFREE
- if((mad->bType == UMCPC_ACM_TYPE_AB5)||
- (mad->bType == UMCPC_ACM_TYPE_AB6)){
- return UMATCH_NONE;
- }
-#endif
- return ret;
-}
-
-static int
-ufoma_attach(device_t self)
-{
- struct ufoma_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usbd_device_handle dev = uaa->device;
- usb_config_descriptor_t *cd;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
- usb_mcpc_acm_descriptor *mad;
- struct ucom_softc *ucom = &sc->sc_ucom;
- const char *devname,*modename;
- int ctl_notify;
- int i,err;
- int elements;
- uByte *mode;
- struct sysctl_ctx_list *sctx;
- struct sysctl_oid *soid;
-
- ucom->sc_dev = self;
- ucom->sc_udev = dev;
- sc->sc_ctl_iface = uaa->iface;
- mtx_init(&sc->sc_mtx, "ufoma", NULL, MTX_DEF);
-
- cd = usbd_get_config_descriptor(ucom->sc_udev);
- id = usbd_get_interface_descriptor(sc->sc_ctl_iface);
- sc->sc_ctl_iface_no = id->bInterfaceNumber;
-
- devname = device_get_nameunit(self);
- device_printf(self, "iclass %d/%d ifno:%d\n",
- id->bInterfaceClass, id->bInterfaceSubClass, sc->sc_ctl_iface_no);
-
- ctl_notify = -1;
- for (i = 0; i < id->bNumEndpoints; i++) {
- ed = usbd_interface2endpoint_descriptor(sc->sc_ctl_iface, i);
- if (ed == NULL)
- continue;
-
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- (ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT) {
- ctl_notify = ed->bEndpointAddress;
- }
- }
-
- if(ctl_notify== -1){
- /*NOTIFY is mandatory.*/
- printf("NOTIFY interface not found\n");
- goto error;
- }
-
- err = usbd_open_pipe_intr(sc->sc_ctl_iface, ctl_notify,
- USBD_SHORT_XFER_OK, &sc->sc_notify_pipe, sc, &sc->sc_notify_buf,
- sizeof(sc->sc_notify_buf), ufoma_intr, USBD_DEFAULT_INTERVAL);
- if(err){
- printf("PIPE open error %d\n", err);
- goto error;
- }
- mad = ufoma_get_intconf(cd, id , UDESC_VS_INTERFACE, UDESCSUB_MCPC_ACM);
- if(mad ==NULL){
- goto error;
- }
-
- printf("%s:Supported Mode:", devname);
- for(mode = mad->bMode;
- mode < ((uByte *)mad + mad->bFunctionLength); mode++){
- modename = ufoma_mode_to_str(*mode);
- if(modename){
- printf("%s", ufoma_mode_to_str(*mode));
- }else{
- printf("(%x)", *mode);
- }
- if(mode != ((uByte*)mad + mad->bFunctionLength-1)){
- printf(",");
- }
- }
- printf("\n");
- if((mad->bType == UMCPC_ACM_TYPE_AB5)
- ||(mad->bType == UMCPC_ACM_TYPE_AB6)){
-#ifdef UFOMA_HANDSFREE
- /*These does not have data interface*/
- sc->sc_is_ucom = 0;
- ufoma_init_pseudo_ucom(sc);
-#else
- /*Should not happen*/
- goto error;
-#endif
-
- }else{
- if(ufoma_init_modem(sc, uaa)){
- goto error;
- }
- }
- elements = mad->bFunctionLength - sizeof(*mad)+1;
- sc->sc_msgxf = usbd_alloc_xfer(ucom->sc_udev);
- sc->sc_nummsg = 0;
-
- /*Initialize Mode vars.*/
- sc->sc_modetable = malloc(elements + 1, M_USBDEV, M_WAITOK);
- sc->sc_modetable[0] = elements + 1;
- bcopy(mad->bMode, &sc->sc_modetable[1], elements);
- sc->sc_currentmode = UMCPC_ACM_MODE_UNLINKED;
- sc->sc_modetoactivate = mad->bMode[0];
-
- /*Sysctls*/
- sctx = device_get_sysctl_ctx(self);
- soid = device_get_sysctl_tree(self);
-
- SYSCTL_ADD_PROC(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "supportmode",
- CTLFLAG_RD|CTLTYPE_STRING, sc, 0, ufoma_sysctl_support,
- "A", "Supporting port role");
-
- SYSCTL_ADD_PROC(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "currentmode",
- CTLFLAG_RD|CTLTYPE_STRING, sc, 0, ufoma_sysctl_current,
- "A", "Current port role");
-
- SYSCTL_ADD_PROC(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "openmode",
- CTLFLAG_RW|CTLTYPE_STRING, sc, 0, ufoma_sysctl_open,
- "A", "Mode to transit when port is opened");
-
- return 0;
- error:
- if(sc->sc_modetable)
- free(sc->sc_modetable, M_USBDEV);
- return EIO;
-}
-
-static int
-ufoma_detach(device_t self)
-{
- struct ufoma_softc *sc = device_get_softc(self);
- int rv = 0;
-
- usbd_free_xfer(sc->sc_msgxf);
- sc->sc_ucom.sc_dying = 1;
- usbd_abort_pipe(sc->sc_notify_pipe);
- usbd_close_pipe(sc->sc_notify_pipe);
- if(sc->sc_is_ucom){
- ucom_detach(&sc->sc_ucom);
- }
-#ifdef UFOMA_HANDSFREE
- else{
- tty_lock(sc->sc_ucom.sc_tty);
- tty_rel_gone(sc->sc_ucom.sc_tty);
- }
-
-#endif
- free(sc->sc_modetable, M_USBDEV);
- return rv;
-}
-
-
-static char *ufoma_mode_to_str(int mode)
-{
- int i;
- for(i = 0 ;umcpc_modetostr_tab[i].str != NULL; i++){
- if(umcpc_modetostr_tab[i].mode == mode){
- return umcpc_modetostr_tab[i].str;
- }
- }
- return NULL;
-}
-
-static int ufoma_str_to_mode(char *str)
-{
- int i;
- for(i = 0 ;umcpc_modetostr_tab[i].str != NULL; i++){
- if(strcmp(str, umcpc_modetostr_tab[i].str)==0){
- return umcpc_modetostr_tab[i].mode;
- }
- }
- return -1;
-}
-
-static void *ufoma_get_intconf( usb_config_descriptor_t *cd,
- usb_interface_descriptor_t *id, int type, int subtype)
-{
- uByte *p, *end;
- usb_descriptor_t *ud=NULL;
- int flag=0;
-
-
- for(p = (uByte *)cd,end = p + UGETW(cd->wTotalLength); p < end;
- p += ud->bLength){
- ud = (usb_descriptor_t *)p;
- if(flag && ud->bDescriptorType==UDESC_INTERFACE){
- return NULL;
- }
- /*Read through this interface desc.*/
- if(bcmp(p, id, sizeof(*id))==0){
- flag=1;
- continue;
- }
- if(flag==0)
- continue;
- if(ud->bDescriptorType == type
- && ud->bDescriptorSubtype == subtype){
- break;
- }
- }
- return ud;
-}
-
-
-
-static int ufoma_link_state(struct ufoma_softc *sc)
-{
- usb_device_request_t req;
- struct ucom_softc *ucom = &sc->sc_ucom;
- int err;
-
- req.bmRequestType = UT_WRITE_VENDOR_INTERFACE;
- req.bRequest = UMCPC_SET_LINK;
- USETW(req.wValue, UMCPC_CM_MOBILE_ACM);
- USETW(req.wIndex, sc->sc_ctl_iface_no);
- USETW(req.wLength, sc->sc_modetable[0]);
-
- err = usbd_do_request(ucom->sc_udev, &req, sc->sc_modetable);
- if(err){
- printf("SET_LINK:%s\n",usbd_errstr(err));
- return EIO;
- }
- err = tsleep(&sc->sc_currentmode, PZERO|PCATCH, "fmalnk", hz);
- if(err){
- printf("NO response");
- return EIO;
- }
- if(sc->sc_currentmode != UMCPC_ACM_MODE_DEACTIVATED){
- return EIO;
- }
- return 0;
-}
-
-static int ufoma_activate_state(struct ufoma_softc *sc, int state)
-{
- usb_device_request_t req;
- int err;
- struct ucom_softc *ucom = &sc->sc_ucom;
-
- req.bmRequestType = UT_WRITE_VENDOR_INTERFACE;
- req.bRequest = UMCPC_ACTIVATE_MODE;
- USETW(req.wValue, state);
- USETW(req.wIndex, sc->sc_ctl_iface_no);
- USETW(req.wLength, 0);
-
- err = usbd_do_request(ucom->sc_udev, &req, NULL);
- if(err){
- printf("%s:ACTIVATE(%x):%s\n",
- device_get_nameunit(ucom->sc_dev), state,
- usbd_errstr(err));
- return EIO;
- }
-
- err = tsleep(&sc->sc_currentmode, PZERO|PCATCH, "fmaact", UFOMA_MAX_TIMEOUT*hz);
- if(err){
- printf("%s:NO response", device_get_nameunit(ucom->sc_dev));
- return EIO;
- }
- if(sc->sc_currentmode != state){
- return EIO;
- }
- return 0;
-}
-
-#ifdef UFOMA_HANDSFREE
-static inline void ufoma_setup_msg_req(struct ufoma_softc *sc, usb_device_request_t *req)
-{
- req->bmRequestType = UT_READ_CLASS_INTERFACE;
- req->bRequest = UCDC_GET_ENCAPSULATED_RESPONSE;
- USETW(req->wIndex, sc->sc_ctl_iface_no);
- USETW(req->wValue, 0);
- USETW(req->wLength, UFOMA_CMD_BUF_SIZE);
-}
-
-
-static void ufoma_msg(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- usb_device_request_t req;
- struct ufoma_softc *sc = priv;
- int actlen,i;
- struct ucom_softc *ucom= &sc->sc_ucom;
- usbd_get_xfer_status(xfer, NULL, NULL, &actlen ,NULL);
- ufoma_setup_msg_req(sc, &req);
- mtx_lock(&sc->sc_mtx);
- for(i = 0;i < actlen; i++){
-
- if(ttydisc_rint(sc->sc_ucom.sc_tty, sc->sc_resbuffer[i], 0)
- == -1){
- break;
- }
- }
-
- ttydisc_rint_done(sc->sc_ucom.sc_tty);
-
- sc->sc_nummsg--;
- if(sc->sc_nummsg){
- usbd_setup_default_xfer(sc->sc_msgxf, ucom->sc_udev,
- priv, USBD_DEFAULT_TIMEOUT, &req,
- sc->sc_resbuffer,
- UFOMA_CMD_BUF_SIZE,
- 0, ufoma_msg);
- usbd_transfer(sc->sc_msgxf);
- }
- mtx_unlock(&sc->sc_mtx);
-
-}
-#endif
-static void ufoma_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- struct ufoma_softc *sc = priv;
- unsigned int a;
- struct ucom_softc *ucom =&sc->sc_ucom;
- u_char mstatus;
-
-#ifdef UFOMA_HANDSFREE
- usb_device_request_t req;
-
- ufoma_setup_msg_req(sc, &req);
-#endif
-
- if (sc->sc_ucom.sc_dying)
- return;
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
- return;
- printf("%s: abnormal status: %s\n", device_get_nameunit(ucom->sc_dev),
- usbd_errstr(status));
- return;
- }
- if((sc->sc_notify_buf.bmRequestType == UT_READ_VENDOR_INTERFACE)&&
- (sc->sc_notify_buf.bNotification == UMCPC_REQUEST_ACKNOLEDGE)){
- a = UGETW(sc->sc_notify_buf.wValue);
- sc->sc_currentmode = a>>8;
- if(!(a&0xff)){
- printf("%s:Mode change Failed\n", device_get_nameunit(ucom->sc_dev));
- }
- wakeup(&sc->sc_currentmode);
- }
- if(sc->sc_notify_buf.bmRequestType != UCDC_NOTIFICATION){
- return;
- }
- switch(sc->sc_notify_buf.bNotification){
-#ifdef UFOMA_HANDSFREE
- case UCDC_N_RESPONSE_AVAILABLE:
- if(sc->sc_is_ucom){
- printf("%s:wrong response request?\n", device_get_nameunit(ucom->sc_dev));
- break;
- }
- mtx_lock(&sc->sc_mtx);
- if(!sc->sc_nummsg){
- usbd_setup_default_xfer(sc->sc_msgxf, ucom->sc_udev,
- priv, USBD_DEFAULT_TIMEOUT, &req, sc->sc_resbuffer,
- UFOMA_CMD_BUF_SIZE,
- 0, ufoma_msg);
- usbd_transfer(sc->sc_msgxf);
- }
- sc->sc_nummsg++;
- mtx_unlock(&sc->sc_mtx);
- break;
-#endif
- case UCDC_N_SERIAL_STATE:
- if(!sc->sc_is_ucom){
- printf("%s:wrong sereal request?\n",device_get_nameunit(ucom->sc_dev));
- break;
- }
-
- /*
- * Set the serial state in ucom driver based on
- * the bits from the notify message
- */
- if (UGETW(sc->sc_notify_buf.wLength) != 2) {
- printf("%s: Invalid notification length! (%d)\n",
- device_get_nameunit(ucom->sc_dev),
- UGETW(sc->sc_notify_buf.wLength));
- break;
- }
- DPRINTF(("%s: notify bytes = %02x%02x\n",
- device_get_nameunit(ucom->sc_dev),
- sc->sc_notify_buf.data[0],
- sc->sc_notify_buf.data[1]));
- /* Currently, lsr is always zero. */
- sc->sc_lsr = sc->sc_msr = 0;
- mstatus = sc->sc_notify_buf.data[0];
-
- if (ISSET(mstatus, UCDC_N_SERIAL_RI))
- sc->sc_msr |= SER_RI;
- if (ISSET(mstatus, UCDC_N_SERIAL_DSR))
- sc->sc_msr |= SER_DSR;
- if (ISSET(mstatus, UCDC_N_SERIAL_DCD))
- sc->sc_msr |= SER_DCD;
- /* Deferred notifying to the ucom layer */
- taskqueue_enqueue(taskqueue_swi_giant, &sc->sc_task);
- break;
- default:
- break;
- }
-}
-
-#ifdef UFOMA_HANDSFREE
-struct ttydevsw ufomatty_class ={
- .tsw_flags = TF_INITLOCK|TF_CALLOUT,
- .tsw_open = ufoma_open,
- .tsw_close = ufoma_close,
- .tsw_outwakeup = ufoma_outwakeup,
- .tsw_free = ufoma_free
-};
-static void ufoma_free(void *sc)
-{
-
-}
-static int ufoma_init_pseudo_ucom(struct ufoma_softc *sc)
-{
- struct tty *tp;
- struct ucom_softc *ucom = &sc->sc_ucom;
- tp = ucom->sc_tty = tty_alloc(&ufomatty_class, sc, &Giant);
- tty_makedev(tp, NULL, "U%d", device_get_unit(ucom->sc_dev));
-
- return 0;
-}
-
-
-static int ufoma_open(struct tty * tty)
-{
-
- struct ufoma_softc *sc = tty_softc(tty);
-
- if(sc->sc_ucom.sc_dying)
- return (ENXIO);
-
- mtx_lock(&sc->sc_mtx);
- if(sc->sc_isopen){
- mtx_unlock(&sc->sc_mtx);
- return EBUSY;
- }
- mtx_unlock(&sc->sc_mtx);
-
- return ufoma_ucom_open(sc, 0);
-}
-
-static void ufoma_close(struct tty *tty)
-{
- struct ufoma_softc *sc = tty_softc(tty);
-
- ufoma_ucom_close(sc, 0);
-}
-
-static void ufoma_outwakeup(struct tty *tp)
-{
- struct ufoma_softc *sc = tty_softc(tp);
- struct ucom_softc *ucom = &sc->sc_ucom;
- usb_device_request_t req;
- int len,i;
- unsigned char buf[128];
-
- uByte c;
- if(ucom->sc_dying)
- return;
- if(ucom->sc_state &UCS_TXBUSY)
- return;
-
- ucom->sc_state |= UCS_TXBUSY;
- for(;;){
- len = ttydisc_getc(tp, buf, sizeof(buf));
- if(len == 0){
- break;
- }
-
- for(i=0; i < len; i++){
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- c = buf[i];
- req.bRequest = UCDC_SEND_ENCAPSULATED_COMMAND;
- USETW(req.wIndex, sc->sc_ctl_iface_no);
- USETW(req.wValue, 0);
- USETW(req.wLength, 1);
- usbd_do_request(ucom->sc_udev, &req, &c);
- }
- }
- ucom->sc_state &= ~(UCS_TXBUSY);
-
-}
-#endif
-
-
-static int ufoma_ucom_open(void *p, int portno)
-{
- struct ufoma_softc *sc = p;
- int res;
-
- if(sc->sc_currentmode == UMCPC_ACM_MODE_UNLINKED){
- if((res = ufoma_link_state(sc))){
- return res;
- }
- }
-
- sc->sc_cmdbp = 0;
- if(sc->sc_currentmode == UMCPC_ACM_MODE_DEACTIVATED){
- if((res = ufoma_activate_state(sc, sc->sc_modetoactivate))){
- return res;
- }
- }
- mtx_lock(&sc->sc_mtx);
- sc->sc_isopen = 1;
- mtx_unlock(&sc->sc_mtx);
- /*Now line coding should be set.*/
- if(sc->sc_is_ucom){
- ufoma_set_line_state(sc);
- ufoma_set_line_coding(sc, NULL);
- }
- return 0;
-}
-
-static void ufoma_ucom_close(void *p, int portno)
-{
- struct ufoma_softc *sc = p;
- ufoma_activate_state(sc, UMCPC_ACM_MODE_DEACTIVATED);
- mtx_lock(&sc->sc_mtx);
- sc->sc_isopen = 0;
- mtx_unlock(&sc->sc_mtx);
- return ;
-}
-
-void
-ufoma_break(struct ufoma_softc *sc, int onoff)
-{
- usb_device_request_t req;
- struct ucom_softc *ucom = &sc->sc_ucom;
- DPRINTF(("ufoma_break: onoff=%d\n", onoff));
-
- if (!(sc->sc_acm_cap & USB_CDC_ACM_HAS_BREAK))
- return;
-
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UCDC_SEND_BREAK;
- USETW(req.wValue, onoff ? UCDC_BREAK_ON : UCDC_BREAK_OFF);
- USETW(req.wIndex, sc->sc_ctl_iface_no);
- USETW(req.wLength, 0);
-
- (void)usbd_do_request(ucom->sc_udev, &req, 0);
-}
-
-void
-ufoma_get_status(void *addr, int portno, u_char *lsr, u_char *msr)
-{
- struct ufoma_softc *sc = addr;
-
- if (lsr != NULL)
- *lsr = sc->sc_lsr;
- if (msr != NULL)
- *msr = sc->sc_msr;
-}
-
-static void ufoma_set(void * addr, int portno, int reg, int onoff)
-{
- struct ufoma_softc *sc = addr;
-
- switch (reg) {
- case UCOM_SET_DTR:
- ufoma_dtr(sc, onoff);
- break;
- case UCOM_SET_RTS:
- ufoma_rts(sc, onoff);
- break;
- case UCOM_SET_BREAK:
- ufoma_break(sc, onoff);
- break;
- default:
- break;
- }
-
-}
-
-static void
-ufoma_set_line_state(struct ufoma_softc *sc)
-{
- usb_device_request_t req;
- struct ucom_softc *ucom = &sc->sc_ucom;
- int ls;
- int err;
-
- if(!sc->sc_isopen){
- return ; /*Set it later*/
- }
-
- /*Don't send line state emulation request for OBEX port*/
- if(sc->sc_currentmode == UMCPC_ACM_MODE_OBEX){
- return;
- }
-
- ls = (sc->sc_dtr ? UCDC_LINE_DTR : 0) |
- (sc->sc_rts ? UCDC_LINE_RTS : 0);
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UCDC_SET_CONTROL_LINE_STATE;
- USETW(req.wValue, ls);
- USETW(req.wIndex, sc->sc_ctl_iface_no);
- USETW(req.wLength, 0);
-
- err = usbd_do_request(ucom->sc_udev, &req, 0);
- if(err){
- printf("LINE_STATE:%s\n", usbd_errstr(err));
- }
-
-
-}
-
-void
-ufoma_dtr(struct ufoma_softc *sc, int onoff)
-{
- DPRINTF(("ufoma_foma: onoff=%d\n", onoff));
-
- if (sc->sc_dtr == onoff)
- return;
- sc->sc_dtr = onoff;
-
- ufoma_set_line_state(sc);
-}
-
-void
-ufoma_rts(struct ufoma_softc *sc, int onoff)
-{
- DPRINTF(("ufoma_foma: onoff=%d\n", onoff));
-
- if (sc->sc_rts == onoff)
- return;
- sc->sc_rts = onoff;
-
- ufoma_set_line_state(sc);
-}
-
-usbd_status
-ufoma_set_line_coding(struct ufoma_softc *sc, usb_cdc_line_state_t *state)
-{
-
- usbd_status err;
- usb_device_request_t req;
- struct ucom_softc *ucom = &sc->sc_ucom;
- if(!sc->sc_isopen){
- sc->sc_line_state_init = *state;
- return (USBD_NORMAL_COMPLETION);
- }
-
- DPRINTF(("ufoma_set_line_coding: rate=%d fmt=%d parity=%d bits=%d\n",
- UGETDW(state->dwDTERate), state->bCharFormat,
- state->bParityType, state->bDataBits));
- if(state == NULL){
- state = &sc->sc_line_state_init;
- }else if (memcmp(state, &sc->sc_line_state,
- UCDC_LINE_STATE_LENGTH) == 0) {
- DPRINTF(("ufoma_set_line_coding: already set\n"));
- return (USBD_NORMAL_COMPLETION);
- }
-
- /*Don't send line state emulation request for OBEX port*/
- if(sc->sc_currentmode == UMCPC_ACM_MODE_OBEX){
- sc->sc_line_state = *state;
- return (USBD_NORMAL_COMPLETION);
- }
-
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UCDC_SET_LINE_CODING;
- USETW(req.wValue, 0);
- USETW(req.wIndex, sc->sc_ctl_iface_no);
- USETW(req.wLength, UCDC_LINE_STATE_LENGTH);
-
- err = usbd_do_request(ucom->sc_udev, &req, state);
- if (err) {
- DPRINTF(("ufoma_set_line_coding: failed, err=%s\n",
- usbd_errstr(err)));
- return (err);
- }
-
- sc->sc_line_state = *state;
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-static int
-ufoma_param(void *addr, int portno, struct termios *t)
-{
-
- struct ufoma_softc *sc = addr;
- usbd_status err;
- usb_cdc_line_state_t ls;
-
- DPRINTF(("ufoma_param: sc=%p\n", sc));
-
- USETDW(ls.dwDTERate, t->c_ospeed);
- if (ISSET(t->c_cflag, CSTOPB))
- ls.bCharFormat = UCDC_STOP_BIT_2;
- else
- ls.bCharFormat = UCDC_STOP_BIT_1;
- if (ISSET(t->c_cflag, PARENB)) {
- if (ISSET(t->c_cflag, PARODD))
- ls.bParityType = UCDC_PARITY_ODD;
- else
- ls.bParityType = UCDC_PARITY_EVEN;
- } else
- ls.bParityType = UCDC_PARITY_NONE;
- switch (ISSET(t->c_cflag, CSIZE)) {
- case CS5:
- ls.bDataBits = 5;
- break;
- case CS6:
- ls.bDataBits = 6;
- break;
- case CS7:
- ls.bDataBits = 7;
- break;
- case CS8:
- ls.bDataBits = 8;
- break;
- }
-
- err = ufoma_set_line_coding(sc, &ls);
- if (err) {
- DPRINTF(("ufoma_param: err=%s\n", usbd_errstr(err)));
- return (EIO);
- }
-
- return (0);
-}
-
-static int ufoma_init_modem(struct ufoma_softc *sc,struct usb_attach_arg *uaa)
-{
- struct ucom_softc *ucom = &sc->sc_ucom;
- usb_config_descriptor_t *cd;
- usb_cdc_acm_descriptor_t *acm;
- usb_cdc_cm_descriptor_t *cmd;
- usb_endpoint_descriptor_t *ed;
- usb_interface_descriptor_t *id;
- const char *devname = device_get_nameunit(ucom->sc_dev);
- int i;
- cd = usbd_get_config_descriptor(ucom->sc_udev);
- id = usbd_get_interface_descriptor(sc->sc_ctl_iface);
-
- sc->sc_is_ucom = 1;
-
- cmd = ufoma_get_intconf(cd, id, UDESC_CS_INTERFACE, UDESCSUB_CDC_CM);
- if(cmd == NULL)
- return -1;
- sc->sc_cm_cap = cmd->bmCapabilities;
-
- acm = ufoma_get_intconf(cd, id, UDESC_CS_INTERFACE, UDESCSUB_CDC_ACM);
- if(acm == NULL)
- return -1;
- sc->sc_acm_cap = acm->bmCapabilities;
-
- sc->sc_data_iface_no = cmd->bDataInterface;
- printf("%s: data interface %d, has %sCM over data, has %sbreak\n",
- devname, sc->sc_data_iface_no,
- sc->sc_cm_cap & USB_CDC_CM_OVER_DATA ? "" : "no ",
- sc->sc_acm_cap & USB_CDC_ACM_HAS_BREAK ? "" : "no ");
-
- for(i = 0; i < uaa->nifaces; i++){
- if(!uaa->ifaces[i])
- continue;
- id = usbd_get_interface_descriptor(uaa->ifaces[i]);
- if(id != NULL &&
- id->bInterfaceNumber == sc->sc_data_iface_no){
- sc->sc_data_iface = uaa->ifaces[i];
- //uaa->ifaces[i] = NULL;
- }
- }
-
- ucom->sc_iface = sc->sc_data_iface;
- ucom->sc_bulkin_no = ucom->sc_bulkout_no = -1;
- id = usbd_get_interface_descriptor(sc->sc_data_iface);
- for(i = 0 ; i < id->bNumEndpoints; i++){
- ed = usbd_interface2endpoint_descriptor(sc->sc_data_iface, i);
- if(ed == NULL){
- printf("%s: endpoint descriptor for %d\n",
- devname,i);
- return -1;
- }
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
- ucom->sc_bulkin_no = ed->bEndpointAddress;
- } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
- ucom->sc_bulkout_no = ed->bEndpointAddress;
- }
- }
-
- if (ucom->sc_bulkin_no == -1) {
- printf("%s: Could not find data bulk in\n", devname);
- return -1;
- }
- if (ucom->sc_bulkout_no == -1) {
- printf("%s: Could not find data bulk out\n", devname);
- return -1;
- }
-
- sc->sc_dtr = -1;
-
- ucom->sc_parent = sc;
- ucom->sc_portno = UCOM_UNK_PORTNO;
- /* bulkin, bulkout set above */
- ucom->sc_ibufsize = UMODEMIBUFSIZE;
- ucom->sc_obufsize = UMODEMOBUFSIZE;
- ucom->sc_ibufsizepad = UMODEMIBUFSIZE;
- ucom->sc_opkthdrlen = 0;
- ucom->sc_callback = &ufoma_callback;
- TASK_INIT(&sc->sc_task, 0, ufoma_notify, sc);
- ucom_attach(&sc->sc_ucom);
-
- return 0;
-}
-
-static void
-ufoma_notify(void *arg, int count)
-{
- struct ufoma_softc *sc;
-
- sc = (struct ufoma_softc *)arg;
- if (sc->sc_ucom.sc_dying)
- return;
- ucom_status_change(&sc->sc_ucom);
-}
-static int ufoma_sysctl_support(SYSCTL_HANDLER_ARGS)
-{
- struct ufoma_softc *sc = (struct ufoma_softc *)oidp->oid_arg1;
- struct sbuf sb;
- int i;
- char *mode;
-
- sbuf_new(&sb, NULL, 1, SBUF_AUTOEXTEND);
- for(i = 1; i < sc->sc_modetable[0]; i++){
- mode = ufoma_mode_to_str(sc->sc_modetable[i]);
- if(mode !=NULL){
- sbuf_cat(&sb, mode);
- }else{
- sbuf_printf(&sb, "(%02x)", sc->sc_modetable[i]);
- }
- if(i < (sc->sc_modetable[0]-1))
- sbuf_cat(&sb, ",");
- }
- sbuf_trim(&sb);
- sbuf_finish(&sb);
- sysctl_handle_string(oidp, sbuf_data(&sb), sbuf_len(&sb), req);
- sbuf_delete(&sb);
-
- return 0;
-}
-static int ufoma_sysctl_current(SYSCTL_HANDLER_ARGS)
-{
- struct ufoma_softc *sc = (struct ufoma_softc *)oidp->oid_arg1;
- char *mode;
- char subbuf[]="(XXX)";
- mode = ufoma_mode_to_str(sc->sc_currentmode);
- if(!mode){
- mode = subbuf;
- snprintf(subbuf, sizeof(subbuf), "(%02x)", sc->sc_currentmode);
- }
- sysctl_handle_string(oidp, mode, strlen(mode), req);
-
- return 0;
-
-}
-static int ufoma_sysctl_open(SYSCTL_HANDLER_ARGS)
-{
- struct ufoma_softc *sc = (struct ufoma_softc *)oidp->oid_arg1;
- char *mode;
- char subbuf[40];
- int newmode;
- int error;
- int i;
-
- mode = ufoma_mode_to_str(sc->sc_modetoactivate);
- if(mode){
- strncpy(subbuf, mode, sizeof(subbuf));
- }else{
- snprintf(subbuf, sizeof(subbuf), "(%02x)", sc->sc_modetoactivate);
- }
- error = sysctl_handle_string(oidp, subbuf, sizeof(subbuf), req);
- if(error != 0 || req->newptr == NULL){
- return error;
- }
-
- if((newmode = ufoma_str_to_mode(subbuf)) == -1){
- return EINVAL;
- }
-
- for(i = 1 ; i < sc->sc_modetable[0] ; i++){
- if(sc->sc_modetable[i] == newmode){
- sc->sc_modetoactivate = newmode;
- return 0;
- }
- }
-
- return EINVAL;
-}
diff --git a/sys/dev/usb/uftdi.c b/sys/dev/usb/uftdi.c
deleted file mode 100644
index c652977..0000000
--- a/sys/dev/usb/uftdi.c
+++ /dev/null
@@ -1,793 +0,0 @@
-/* $NetBSD: uftdi.c,v 1.13 2002/09/23 05:51:23 simonb Exp $ */
-
-/*-
- * Copyright (c) 2000 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net).
- *
- * 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * FTDI FT8U100AX serial adapter driver
- */
-
-#include <sys/cdefs.h>
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/ioccom.h>
-#include <sys/fcntl.h>
-#include <sys/conf.h>
-#include <sys/tty.h>
-#include <sys/file.h>
-
-#include <sys/selinfo.h>
-
-#include <sys/sysctl.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbhid.h>
-
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include "usbdevs.h"
-
-#include <dev/usb/ucomvar.h>
-
-#include <dev/usb/uftdireg.h>
-
-#ifdef USB_DEBUG
-static int uftdidebug = 0;
-SYSCTL_NODE(_hw_usb, OID_AUTO, uftdi, CTLFLAG_RW, 0, "USB uftdi");
-SYSCTL_INT(_hw_usb_uftdi, OID_AUTO, debug, CTLFLAG_RW,
- &uftdidebug, 0, "uftdi debug level");
-#define DPRINTF(x) do { \
- if (uftdidebug) \
- printf x; \
- } while (0)
-
-#define DPRINTFN(n, x) do { \
- if (uftdidebug > (n)) \
- printf x; \
- } while (0)
-
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-#define UFTDI_CONFIG_INDEX 0
-#define UFTDI_IFACE_INDEX 0
-
-
-/*
- * These are the maximum number of bytes transferred per frame.
- * The output buffer size cannot be increased due to the size encoding.
- */
-#define UFTDIIBUFSIZE 256
-#define UFTDIOBUFSIZE 64
-
-struct uftdi_softc {
- struct ucom_softc sc_ucom;
- usbd_interface_handle sc_iface; /* interface */
- enum uftdi_type sc_type;
- u_int sc_hdrlen;
- u_char sc_msr;
- u_char sc_lsr;
- u_int last_lcr;
-};
-
-static void uftdi_get_status(void *, int portno, u_char *lsr, u_char *msr);
-static void uftdi_set(void *, int, int, int);
-static int uftdi_param(void *, int, struct termios *);
-static int uftdi_open(void *sc, int portno);
-static void uftdi_read(void *sc, int portno, u_char **ptr,u_int32_t *count);
-static size_t uftdi_write(void *sc, int portno, struct tty *,
- u_char *to, u_int32_t count);
-static void uftdi_break(void *sc, int portno, int onoff);
-static int uftdi_8u232am_getrate(speed_t speed, int *rate);
-
-struct ucom_callback uftdi_callback = {
- uftdi_get_status,
- uftdi_set,
- uftdi_param,
- NULL,
- uftdi_open,
- NULL,
- uftdi_read,
- uftdi_write,
-};
-
-static int
-uftdi_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
-
- if (uaa->iface != NULL) {
- if (uaa->vendor == USB_VENDOR_FTDI &&
- (uaa->product == USB_PRODUCT_FTDI_SERIAL_2232C))
- return (UMATCH_VENDOR_IFACESUBCLASS);
- return (UMATCH_NONE);
- }
-
- DPRINTFN(20,("uftdi: vendor=0x%x, product=0x%x\n",
- uaa->vendor, uaa->product));
-
- if (uaa->vendor == USB_VENDOR_FTDI &&
- (uaa->product == USB_PRODUCT_FTDI_SERIAL_8U100AX ||
- uaa->product == USB_PRODUCT_FTDI_SERIAL_8U232AM ||
- uaa->product == USB_PRODUCT_FTDI_SEMC_DSS20 ||
- uaa->product == USB_PRODUCT_FTDI_CFA_631 ||
- uaa->product == USB_PRODUCT_FTDI_CFA_632 ||
- uaa->product == USB_PRODUCT_FTDI_CFA_633 ||
- uaa->product == USB_PRODUCT_FTDI_CFA_634 ||
- uaa->product == USB_PRODUCT_FTDI_CFA_635 ||
- uaa->product == USB_PRODUCT_FTDI_USBSERIAL ||
- uaa->product == USB_PRODUCT_FTDI_MX2_3 ||
- uaa->product == USB_PRODUCT_FTDI_MX4_5 ||
- uaa->product == USB_PRODUCT_FTDI_LK202 ||
- uaa->product == USB_PRODUCT_FTDI_LK204 ||
- uaa->product == USB_PRODUCT_FTDI_TACTRIX_OPENPORT_13M ||
- uaa->product == USB_PRODUCT_FTDI_TACTRIX_OPENPORT_13S ||
- uaa->product == USB_PRODUCT_FTDI_TACTRIX_OPENPORT_13U ||
- uaa->product == USB_PRODUCT_FTDI_EISCOU ||
- uaa->product == USB_PRODUCT_FTDI_UOPTBR ||
- uaa->product == USB_PRODUCT_FTDI_EMCU2D ||
- uaa->product == USB_PRODUCT_FTDI_PCMSFU ||
- uaa->product == USB_PRODUCT_FTDI_EMCU2H ||
- uaa->product == USB_PRODUCT_FTDI_MAXSTREAM ))
- return (UMATCH_VENDOR_PRODUCT);
- if (uaa->vendor == USB_VENDOR_SIIG2 &&
- (uaa->product == USB_PRODUCT_SIIG2_US2308))
- return (UMATCH_VENDOR_PRODUCT);
- if (uaa->vendor == USB_VENDOR_INTREPIDCS &&
- (uaa->product == USB_PRODUCT_INTREPIDCS_VALUECAN ||
- uaa->product == USB_PRODUCT_INTREPIDCS_NEOVI))
- return (UMATCH_VENDOR_PRODUCT);
- if (uaa->vendor == USB_VENDOR_BBELECTRONICS &&
- (uaa->product == USB_PRODUCT_BBELECTRONICS_USOTL4))
- return (UMATCH_VENDOR_PRODUCT);
- if (uaa->vendor == USB_VENDOR_MELCO &&
- (uaa->product == USB_PRODUCT_MELCO_PCOPRS1))
- return (UMATCH_VENDOR_PRODUCT);
- if (uaa->vendor == USB_VENDOR_DRESDENELEKTRONIK &&
- (uaa->product == USB_PRODUCT_DRESDENELEKTRONIK_SENSORTERMINALBOARD))
- return (UMATCH_VENDOR_PRODUCT);
-
- return (UMATCH_NONE);
-}
-
-static int
-uftdi_attach(device_t self)
-{
- struct uftdi_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usbd_device_handle dev = uaa->device;
- usbd_interface_handle iface;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
- int i;
- usbd_status err;
- struct ucom_softc *ucom = &sc->sc_ucom;
- DPRINTFN(10,("\nuftdi_attach: sc=%p\n", sc));
-
- ucom->sc_dev = self;
- ucom->sc_udev = dev;
-
- if (uaa->iface == NULL) {
- /* Move the device into the configured state. */
- err = usbd_set_config_index(dev, UFTDI_CONFIG_INDEX, 1);
- if (err) {
- device_printf(ucom->sc_dev,
- "failed to set configuration, err=%s\n",
- usbd_errstr(err));
- goto bad;
- }
-
- err = usbd_device2interface_handle(dev, UFTDI_IFACE_INDEX, &iface);
- if (err) {
- device_printf(ucom->sc_dev,
- "failed to get interface, err=%s\n", usbd_errstr(err));
- goto bad;
- }
- } else {
- iface = uaa->iface;
- }
-
- id = usbd_get_interface_descriptor(iface);
- ucom->sc_iface = iface;
- switch( uaa->vendor ){
- case USB_VENDOR_FTDI:
- switch( uaa->product ){
- case USB_PRODUCT_FTDI_SERIAL_8U100AX:
- sc->sc_type = UFTDI_TYPE_SIO;
- sc->sc_hdrlen = 1;
- break;
- case USB_PRODUCT_FTDI_SEMC_DSS20:
- case USB_PRODUCT_FTDI_SERIAL_8U232AM:
- case USB_PRODUCT_FTDI_SERIAL_2232C:
- case USB_PRODUCT_FTDI_CFA_631:
- case USB_PRODUCT_FTDI_CFA_632:
- case USB_PRODUCT_FTDI_CFA_633:
- case USB_PRODUCT_FTDI_CFA_634:
- case USB_PRODUCT_FTDI_CFA_635:
- case USB_PRODUCT_FTDI_USBSERIAL:
- case USB_PRODUCT_FTDI_MX2_3:
- case USB_PRODUCT_FTDI_MX4_5:
- case USB_PRODUCT_FTDI_LK202:
- case USB_PRODUCT_FTDI_LK204:
- case USB_PRODUCT_FTDI_TACTRIX_OPENPORT_13M:
- case USB_PRODUCT_FTDI_TACTRIX_OPENPORT_13S:
- case USB_PRODUCT_FTDI_TACTRIX_OPENPORT_13U:
- case USB_PRODUCT_FTDI_EISCOU:
- case USB_PRODUCT_FTDI_UOPTBR:
- case USB_PRODUCT_FTDI_EMCU2D:
- case USB_PRODUCT_FTDI_PCMSFU:
- case USB_PRODUCT_FTDI_EMCU2H:
- case USB_PRODUCT_FTDI_MAXSTREAM:
- sc->sc_type = UFTDI_TYPE_8U232AM;
- sc->sc_hdrlen = 0;
- break;
-
- default: /* Can't happen */
- goto bad;
- }
- break;
-
- case USB_VENDOR_INTREPIDCS:
- switch( uaa->product ){
- case USB_PRODUCT_INTREPIDCS_VALUECAN:
- case USB_PRODUCT_INTREPIDCS_NEOVI:
- sc->sc_type = UFTDI_TYPE_8U232AM;
- sc->sc_hdrlen = 0;
- break;
-
- default: /* Can't happen */
- goto bad;
- }
- break;
-
- case USB_VENDOR_SIIG2:
- switch( uaa->product ){
- case USB_PRODUCT_SIIG2_US2308:
- sc->sc_type = UFTDI_TYPE_8U232AM;
- sc->sc_hdrlen = 0;
- break;
-
- default: /* Can't happen */
- goto bad;
- }
- break;
-
- case USB_VENDOR_BBELECTRONICS:
- switch( uaa->product ){
- case USB_PRODUCT_BBELECTRONICS_USOTL4:
- sc->sc_type = UFTDI_TYPE_8U232AM;
- sc->sc_hdrlen = 0;
- break;
-
- default: /* Can't happen */
- goto bad;
- }
- break;
-
- case USB_VENDOR_MELCO:
- switch( uaa->product ){
- case USB_PRODUCT_MELCO_PCOPRS1:
- sc->sc_type = UFTDI_TYPE_8U232AM;
- sc->sc_hdrlen = 0;
- break;
-
- default: /* Can't happen */
- goto bad;
- }
- break;
-
- case USB_VENDOR_DRESDENELEKTRONIK:
- switch( uaa->product ){
- case USB_PRODUCT_DRESDENELEKTRONIK_SENSORTERMINALBOARD:
- sc->sc_type = UFTDI_TYPE_8U232AM;
- sc->sc_hdrlen = 0;
- break;
-
- default: /* Can't happen */
- goto bad;
- }
- break;
-
- default: /* Can't happen */
- goto bad;
- }
-
- ucom->sc_bulkin_no = ucom->sc_bulkout_no = -1;
-
- for (i = 0; i < id->bNumEndpoints; i++) {
- int addr, dir, attr;
- ed = usbd_interface2endpoint_descriptor(iface, i);
- if (ed == NULL) {
- device_printf(ucom->sc_dev,
- "could not read endpoint descriptor\n");
- goto bad;
- }
-
- addr = ed->bEndpointAddress;
- dir = UE_GET_DIR(ed->bEndpointAddress);
- attr = ed->bmAttributes & UE_XFERTYPE;
- if (dir == UE_DIR_IN && attr == UE_BULK)
- ucom->sc_bulkin_no = addr;
- else if (dir == UE_DIR_OUT && attr == UE_BULK)
- ucom->sc_bulkout_no = addr;
- else {
- device_printf(ucom->sc_dev, "unexpected endpoint\n");
- goto bad;
- }
- }
- if (ucom->sc_bulkin_no == -1) {
- device_printf(ucom->sc_dev, "Could not find data bulk in\n");
- goto bad;
- }
- if (ucom->sc_bulkout_no == -1) {
- device_printf(ucom->sc_dev, "Could not find data bulk out\n");
- goto bad;
- }
- ucom->sc_parent = sc;
- if (uaa->iface == NULL)
- ucom->sc_portno = FTDI_PIT_SIOA;
- else
- ucom->sc_portno = FTDI_PIT_SIOA + id->bInterfaceNumber;
- /* bulkin, bulkout set above */
-
- ucom->sc_ibufsize = UFTDIIBUFSIZE;
- ucom->sc_obufsize = UFTDIOBUFSIZE - sc->sc_hdrlen;
- ucom->sc_ibufsizepad = UFTDIIBUFSIZE;
- ucom->sc_opkthdrlen = sc->sc_hdrlen;
-
-
- ucom->sc_callback = &uftdi_callback;
-#if 0
- usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, ucom->sc_udev,
- ucom->sc_dev);
-#endif
- DPRINTF(("uftdi: in=0x%x out=0x%x\n", ucom->sc_bulkin_no, ucom->sc_bulkout_no));
- ucom_attach(&sc->sc_ucom);
- return 0;
-
-bad:
- DPRINTF(("uftdi_attach: ATTACH ERROR\n"));
- ucom->sc_dying = 1;
- return ENXIO;
-}
-#if 0
-int
-uftdi_activate(device_t self, enum devact act)
-{
- struct uftdi_softc *sc = (struct uftdi_softc *)self;
- int rv = 0;
-
- switch (act) {
- case DVACT_ACTIVATE:
- return (EOPNOTSUPP);
-
- case DVACT_DEACTIVATE:
- if (sc->sc_subdev != NULL)
- rv = config_deactivate(sc->sc_subdev);
- sc->sc_ucom.sc_dying = 1;
- break;
- }
- return (rv);
-}
-#endif
-
-static int
-uftdi_detach(device_t self)
-{
- struct uftdi_softc *sc = device_get_softc(self);
-
- int rv = 0;
-
- DPRINTF(("uftdi_detach: sc=%p\n", sc));
- sc->sc_ucom.sc_dying = 1;
- rv = ucom_detach(&sc->sc_ucom);
-
- return rv;
-}
-
-static int
-uftdi_open(void *vsc, int portno)
-{
- struct uftdi_softc *sc = vsc;
- struct ucom_softc *ucom = &sc->sc_ucom;
- usb_device_request_t req;
- usbd_status err;
- struct termios t;
-
- DPRINTF(("uftdi_open: sc=%p\n", sc));
-
- if (ucom->sc_dying)
- return (EIO);
-
- /* Perform a full reset on the device */
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = FTDI_SIO_RESET;
- USETW(req.wValue, FTDI_SIO_RESET_SIO);
- USETW(req.wIndex, portno);
- USETW(req.wLength, 0);
- err = usbd_do_request(ucom->sc_udev, &req, NULL);
- if (err)
- return (EIO);
-
- /* Set 9600 baud, 2 stop bits, no parity, 8 bits */
- t.c_ospeed = 9600;
- t.c_cflag = CSTOPB | CS8;
- (void)uftdi_param(sc, portno, &t);
-
- /* Turn on RTS/CTS flow control */
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = FTDI_SIO_SET_FLOW_CTRL;
- USETW(req.wValue, 0);
- USETW2(req.wIndex, FTDI_SIO_RTS_CTS_HS, portno);
- USETW(req.wLength, 0);
- err = usbd_do_request(ucom->sc_udev, &req, NULL);
- if (err)
- return (EIO);
-
- return (0);
-}
-
-static void
-uftdi_read(void *vsc, int portno, u_char **ptr, u_int32_t *count)
-{
- struct uftdi_softc *sc = vsc;
- u_char msr, lsr;
- unsigned l;
-
- DPRINTFN(15,("uftdi_read: sc=%p, port=%d count=%d\n",
- sc, portno, *count));
- while (*count > 0) {
- l = *count;
- if (l > 64)
- l = 64;
-
- msr = FTDI_GET_MSR(*ptr);
- lsr = FTDI_GET_LSR(*ptr);
-
- if (sc->sc_msr != msr ||
- (sc->sc_lsr & FTDI_LSR_MASK) != (lsr & FTDI_LSR_MASK)) {
- DPRINTF(("uftdi_read: status change msr=0x%02x(0x%02x) "
- "lsr=0x%02x(0x%02x)\n", msr, sc->sc_msr,
- lsr, sc->sc_lsr));
- sc->sc_msr = msr;
- sc->sc_lsr = lsr;
- ucom_status_change(&sc->sc_ucom);
- }
-
- if (l > 2)
- ucomrxchars(&sc->sc_ucom, (*ptr) + 2, l - 2);
- *ptr += l;
- *count -= l;
- }
-}
-
-static size_t
-uftdi_write(void *vsc, int portno, struct tty *tp, u_char *to, u_int32_t count)
-{
- struct uftdi_softc *sc = vsc;
- size_t l;
-
- DPRINTFN(10,("uftdi_write: sc=%p, port=%d tp=%p, count=%u\n",
- vsc, portno, tp, count));
-
- /* Leave space for the length tag. */
- l = ttydisc_getc(tp, to + sc->sc_hdrlen, count - sc->sc_hdrlen);
- if (l == 0)
- return (0);
-
- /* Make length tag. */
- if (sc->sc_hdrlen > 0)
- *to = FTDI_OUT_TAG(l, portno);
-
- return (l + sc->sc_hdrlen);
-}
-
-static void
-uftdi_set(void *vsc, int portno, int reg, int onoff)
-{
- struct uftdi_softc *sc = vsc;
- struct ucom_softc *ucom = vsc;
- usb_device_request_t req;
- int ctl;
-
- DPRINTF(("uftdi_set: sc=%p, port=%d reg=%d onoff=%d\n", vsc, portno,
- reg, onoff));
-
- switch (reg) {
- case UCOM_SET_DTR:
- ctl = onoff ? FTDI_SIO_SET_DTR_HIGH : FTDI_SIO_SET_DTR_LOW;
- break;
- case UCOM_SET_RTS:
- ctl = onoff ? FTDI_SIO_SET_RTS_HIGH : FTDI_SIO_SET_RTS_LOW;
- break;
- case UCOM_SET_BREAK:
- uftdi_break(sc, portno, onoff);
- return;
- default:
- return;
- }
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = FTDI_SIO_MODEM_CTRL;
- USETW(req.wValue, ctl);
- USETW(req.wIndex, portno);
- USETW(req.wLength, 0);
- DPRINTFN(2,("uftdi_set: reqtype=0x%02x req=0x%02x value=0x%04x "
- "index=0x%04x len=%d\n", req.bmRequestType, req.bRequest,
- UGETW(req.wValue), UGETW(req.wIndex), UGETW(req.wLength)));
- (void)usbd_do_request(ucom->sc_udev, &req, NULL);
-}
-
-static int
-uftdi_param(void *vsc, int portno, struct termios *t)
-{
- struct uftdi_softc *sc = vsc;
- struct ucom_softc *ucom = &sc->sc_ucom;
- usb_device_request_t req;
- usbd_status err;
- int rate=0, data, flow;
-
- DPRINTF(("uftdi_param: sc=%p\n", sc));
-
- if (ucom->sc_dying)
- return (EIO);
-
- switch (sc->sc_type) {
- case UFTDI_TYPE_SIO:
- switch (t->c_ospeed) {
- case 300: rate = ftdi_sio_b300; break;
- case 600: rate = ftdi_sio_b600; break;
- case 1200: rate = ftdi_sio_b1200; break;
- case 2400: rate = ftdi_sio_b2400; break;
- case 4800: rate = ftdi_sio_b4800; break;
- case 9600: rate = ftdi_sio_b9600; break;
- case 19200: rate = ftdi_sio_b19200; break;
- case 38400: rate = ftdi_sio_b38400; break;
- case 57600: rate = ftdi_sio_b57600; break;
- case 115200: rate = ftdi_sio_b115200; break;
- default:
- return (EINVAL);
- }
- break;
-
- case UFTDI_TYPE_8U232AM:
- if (uftdi_8u232am_getrate(t->c_ospeed, &rate) == -1)
- return (EINVAL);
- break;
- }
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = FTDI_SIO_SET_BAUD_RATE;
- USETW(req.wValue, rate);
- USETW(req.wIndex, portno);
- USETW(req.wLength, 0);
- DPRINTFN(2,("uftdi_param: reqtype=0x%02x req=0x%02x value=0x%04x "
- "index=0x%04x len=%d\n", req.bmRequestType, req.bRequest,
- UGETW(req.wValue), UGETW(req.wIndex), UGETW(req.wLength)));
- err = usbd_do_request(ucom->sc_udev, &req, NULL);
- if (err)
- return (EIO);
-
- if (ISSET(t->c_cflag, CSTOPB))
- data = FTDI_SIO_SET_DATA_STOP_BITS_2;
- else
- data = FTDI_SIO_SET_DATA_STOP_BITS_1;
- if (ISSET(t->c_cflag, PARENB)) {
- if (ISSET(t->c_cflag, PARODD))
- data |= FTDI_SIO_SET_DATA_PARITY_ODD;
- else
- data |= FTDI_SIO_SET_DATA_PARITY_EVEN;
- } else
- data |= FTDI_SIO_SET_DATA_PARITY_NONE;
- switch (ISSET(t->c_cflag, CSIZE)) {
- case CS5:
- data |= FTDI_SIO_SET_DATA_BITS(5);
- break;
- case CS6:
- data |= FTDI_SIO_SET_DATA_BITS(6);
- break;
- case CS7:
- data |= FTDI_SIO_SET_DATA_BITS(7);
- break;
- case CS8:
- data |= FTDI_SIO_SET_DATA_BITS(8);
- break;
- }
- sc->last_lcr = data;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = FTDI_SIO_SET_DATA;
- USETW(req.wValue, data);
- USETW(req.wIndex, portno);
- USETW(req.wLength, 0);
- DPRINTFN(2,("uftdi_param: reqtype=0x%02x req=0x%02x value=0x%04x "
- "index=0x%04x len=%d\n", req.bmRequestType, req.bRequest,
- UGETW(req.wValue), UGETW(req.wIndex), UGETW(req.wLength)));
- err = usbd_do_request(ucom->sc_udev, &req, NULL);
- if (err)
- return (EIO);
-
- if (ISSET(t->c_cflag, CRTSCTS)) {
- flow = FTDI_SIO_RTS_CTS_HS;
- USETW(req.wValue, 0);
- } else if (ISSET(t->c_iflag, IXON|IXOFF)) {
- flow = FTDI_SIO_XON_XOFF_HS;
- USETW2(req.wValue, t->c_cc[VSTOP], t->c_cc[VSTART]);
- } else {
- flow = FTDI_SIO_DISABLE_FLOW_CTRL;
- USETW(req.wValue, 0);
- }
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = FTDI_SIO_SET_FLOW_CTRL;
- USETW2(req.wIndex, flow, portno);
- USETW(req.wLength, 0);
- err = usbd_do_request(ucom->sc_udev, &req, NULL);
- if (err)
- return (EIO);
-
- return (0);
-}
-
-void
-uftdi_get_status(void *vsc, int portno, u_char *lsr, u_char *msr)
-{
- struct uftdi_softc *sc = vsc;
-
- DPRINTF(("uftdi_status: msr=0x%02x lsr=0x%02x\n",
- sc->sc_msr, sc->sc_lsr));
-
- if (msr != NULL)
- *msr = sc->sc_msr;
- if (lsr != NULL)
- *lsr = sc->sc_lsr;
-}
-
-void
-uftdi_break(void *vsc, int portno, int onoff)
-{
- struct uftdi_softc *sc = vsc;
- struct ucom_softc *ucom = vsc;
-
- usb_device_request_t req;
- int data;
-
- DPRINTF(("uftdi_break: sc=%p, port=%d onoff=%d\n", vsc, portno,
- onoff));
-
- if (onoff) {
- data = sc->last_lcr | FTDI_SIO_SET_BREAK;
- } else {
- data = sc->last_lcr;
- }
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = FTDI_SIO_SET_DATA;
- USETW(req.wValue, data);
- USETW(req.wIndex, portno);
- USETW(req.wLength, 0);
- (void)usbd_do_request(ucom->sc_udev, &req, NULL);
-}
-
-static int
-uftdi_8u232am_getrate(speed_t speed, int *rate)
-{
- /* Table of the nearest even powers-of-2 for values 0..15. */
- static const unsigned char roundoff[16] = {
- 0, 2, 2, 4, 4, 4, 8, 8,
- 8, 8, 8, 8, 16, 16, 16, 16,
- };
-
- unsigned int d, freq;
- int result;
-
- if (speed <= 0)
- return (-1);
-
- /* Special cases for 2M and 3M. */
- if (speed >= 3000000 * 100 / 103 &&
- speed <= 3000000 * 100 / 97) {
- result = 0;
- goto done;
- }
- if (speed >= 2000000 * 100 / 103 &&
- speed <= 2000000 * 100 / 97) {
- result = 1;
- goto done;
- }
-
- d = (FTDI_8U232AM_FREQ << 4) / speed;
- d = (d & ~15) + roundoff[d & 15];
-
- if (d < FTDI_8U232AM_MIN_DIV)
- d = FTDI_8U232AM_MIN_DIV;
- else if (d > FTDI_8U232AM_MAX_DIV)
- d = FTDI_8U232AM_MAX_DIV;
-
- /*
- * Calculate the frequency needed for d to exactly divide down
- * to our target speed, and check that the actual frequency is
- * within 3% of this.
- */
- freq = speed * d;
- if (freq < (quad_t)(FTDI_8U232AM_FREQ << 4) * 100 / 103 ||
- freq > (quad_t)(FTDI_8U232AM_FREQ << 4) * 100 / 97)
- return (-1);
-
- /*
- * Pack the divisor into the resultant value. The lower
- * 14-bits hold the integral part, while the upper 2 bits
- * encode the fractional component: either 0, 0.5, 0.25, or
- * 0.125.
- */
- result = d >> 4;
- if (d & 8)
- result |= 0x4000;
- else if (d & 4)
- result |= 0x8000;
- else if (d & 2)
- result |= 0xc000;
-
-done:
- *rate = result;
- return (0);
-}
-
-static device_method_t uftdi_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, uftdi_match),
- DEVMETHOD(device_attach, uftdi_attach),
- DEVMETHOD(device_detach, uftdi_detach),
-
- { 0, 0 }
-};
-
-static driver_t uftdi_driver = {
- "ucom",
- uftdi_methods,
- sizeof (struct uftdi_softc)
-};
-
-DRIVER_MODULE(uftdi, uhub, uftdi_driver, ucom_devclass, usbd_driver_load, 0);
-MODULE_DEPEND(uftdi, usb, 1, 1, 1);
-MODULE_DEPEND(uftdi, ucom,UCOM_MINVER, UCOM_PREFVER, UCOM_MAXVER);
diff --git a/sys/dev/usb/uftdireg.h b/sys/dev/usb/uftdireg.h
deleted file mode 100644
index 78c9349..0000000
--- a/sys/dev/usb/uftdireg.h
+++ /dev/null
@@ -1,338 +0,0 @@
-/* $NetBSD: uftdireg.h,v 1.6 2002/07/11 21:14:28 augustss Exp $ */
-/* $FreeBSD$ */
-
-/*
- * Definitions for the FTDI USB Single Port Serial Converter -
- * known as FTDI_SIO (Serial Input/Output application of the chipset)
- *
- * The device is based on the FTDI FT8U100AX chip. It has a DB25 on one side,
- * USB on the other.
- *
- * Thanx to FTDI (http://www.ftdi.co.uk) for so kindly providing details
- * of the protocol required to talk to the device and ongoing assistence
- * during development.
- *
- * Bill Ryder - bryder@sgi.com of Silicon Graphics, Inc. is the original
- * author of this file.
- */
-/* Modified by Lennart Augustsson */
-
-/* Vendor Request Interface */
-#define FTDI_SIO_RESET 0 /* Reset the port */
-#define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */
-#define FTDI_SIO_SET_FLOW_CTRL 2 /* Set flow control register */
-#define FTDI_SIO_SET_BAUD_RATE 3 /* Set baud rate */
-#define FTDI_SIO_SET_DATA 4 /* Set the data characteristics of the port */
-#define FTDI_SIO_GET_STATUS 5 /* Retrieve current value of status reg */
-#define FTDI_SIO_SET_EVENT_CHAR 6 /* Set the event character */
-#define FTDI_SIO_SET_ERROR_CHAR 7 /* Set the error character */
-
-/* Port Identifier Table */
-#define FTDI_PIT_DEFAULT 0 /* SIOA */
-#define FTDI_PIT_SIOA 1 /* SIOA */
-#define FTDI_PIT_SIOB 2 /* SIOB */
-#define FTDI_PIT_PARALLEL 3 /* Parallel */
-
-enum uftdi_type {
- UFTDI_TYPE_SIO,
- UFTDI_TYPE_8U232AM
-};
-
-/*
- * BmRequestType: 0100 0000B
- * bRequest: FTDI_SIO_RESET
- * wValue: Control Value
- * 0 = Reset SIO
- * 1 = Purge RX buffer
- * 2 = Purge TX buffer
- * wIndex: Port
- * wLength: 0
- * Data: None
- *
- * The Reset SIO command has this effect:
- *
- * Sets flow control set to 'none'
- * Event char = 0x0d
- * Event trigger = disabled
- * Purge RX buffer
- * Purge TX buffer
- * Clear DTR
- * Clear RTS
- * baud and data format not reset
- *
- * The Purge RX and TX buffer commands affect nothing except the buffers
- *
- */
-/* FTDI_SIO_RESET */
-#define FTDI_SIO_RESET_SIO 0
-#define FTDI_SIO_RESET_PURGE_RX 1
-#define FTDI_SIO_RESET_PURGE_TX 2
-
-
-/*
- * BmRequestType: 0100 0000B
- * bRequest: FTDI_SIO_SET_BAUDRATE
- * wValue: BaudRate value - see below
- * wIndex: Port
- * wLength: 0
- * Data: None
- */
-/* FTDI_SIO_SET_BAUDRATE */
-enum {
- ftdi_sio_b300 = 0,
- ftdi_sio_b600 = 1,
- ftdi_sio_b1200 = 2,
- ftdi_sio_b2400 = 3,
- ftdi_sio_b4800 = 4,
- ftdi_sio_b9600 = 5,
- ftdi_sio_b19200 = 6,
- ftdi_sio_b38400 = 7,
- ftdi_sio_b57600 = 8,
- ftdi_sio_b115200 = 9
-};
-
-#define FTDI_8U232AM_FREQ 3000000
-
-/* Bounds for normal divisors as 4-bit fixed precision ints. */
-#define FTDI_8U232AM_MIN_DIV 0x20
-#define FTDI_8U232AM_MAX_DIV 0x3fff8
-
-/*
- * BmRequestType: 0100 0000B
- * bRequest: FTDI_SIO_SET_DATA
- * wValue: Data characteristics (see below)
- * wIndex: Port
- * wLength: 0
- * Data: No
- *
- * Data characteristics
- *
- * B0..7 Number of data bits
- * B8..10 Parity
- * 0 = None
- * 1 = Odd
- * 2 = Even
- * 3 = Mark
- * 4 = Space
- * B11..13 Stop Bits
- * 0 = 1
- * 1 = 1.5
- * 2 = 2
- * B14..15 Reserved
- *
- */
-/* FTDI_SIO_SET_DATA */
-#define FTDI_SIO_SET_DATA_BITS(n) (n)
-#define FTDI_SIO_SET_DATA_PARITY_NONE (0x0 << 8)
-#define FTDI_SIO_SET_DATA_PARITY_ODD (0x1 << 8)
-#define FTDI_SIO_SET_DATA_PARITY_EVEN (0x2 << 8)
-#define FTDI_SIO_SET_DATA_PARITY_MARK (0x3 << 8)
-#define FTDI_SIO_SET_DATA_PARITY_SPACE (0x4 << 8)
-#define FTDI_SIO_SET_DATA_STOP_BITS_1 (0x0 << 11)
-#define FTDI_SIO_SET_DATA_STOP_BITS_15 (0x1 << 11)
-#define FTDI_SIO_SET_DATA_STOP_BITS_2 (0x2 << 11)
-#define FTDI_SIO_SET_BREAK (0x1 << 14)
-
-
-/*
- * BmRequestType: 0100 0000B
- * bRequest: FTDI_SIO_MODEM_CTRL
- * wValue: ControlValue (see below)
- * wIndex: Port
- * wLength: 0
- * Data: None
- *
- * NOTE: If the device is in RTS/CTS flow control, the RTS set by this
- * command will be IGNORED without an error being returned
- * Also - you can not set DTR and RTS with one control message
- *
- * ControlValue
- * B0 DTR state
- * 0 = reset
- * 1 = set
- * B1 RTS state
- * 0 = reset
- * 1 = set
- * B2..7 Reserved
- * B8 DTR state enable
- * 0 = ignore
- * 1 = use DTR state
- * B9 RTS state enable
- * 0 = ignore
- * 1 = use RTS state
- * B10..15 Reserved
- */
-/* FTDI_SIO_MODEM_CTRL */
-#define FTDI_SIO_SET_DTR_MASK 0x1
-#define FTDI_SIO_SET_DTR_HIGH (1 | ( FTDI_SIO_SET_DTR_MASK << 8))
-#define FTDI_SIO_SET_DTR_LOW (0 | ( FTDI_SIO_SET_DTR_MASK << 8))
-#define FTDI_SIO_SET_RTS_MASK 0x2
-#define FTDI_SIO_SET_RTS_HIGH (2 | ( FTDI_SIO_SET_RTS_MASK << 8))
-#define FTDI_SIO_SET_RTS_LOW (0 | ( FTDI_SIO_SET_RTS_MASK << 8))
-
-
-/*
- * BmRequestType: 0100 0000b
- * bRequest: FTDI_SIO_SET_FLOW_CTRL
- * wValue: Xoff/Xon
- * wIndex: Protocol/Port - hIndex is protocl / lIndex is port
- * wLength: 0
- * Data: None
- *
- * hIndex protocol is:
- * B0 Output handshaking using RTS/CTS
- * 0 = disabled
- * 1 = enabled
- * B1 Output handshaking using DTR/DSR
- * 0 = disabled
- * 1 = enabled
- * B2 Xon/Xoff handshaking
- * 0 = disabled
- * 1 = enabled
- *
- * A value of zero in the hIndex field disables handshaking
- *
- * If Xon/Xoff handshaking is specified, the hValue field should contain the
- * XOFF character and the lValue field contains the XON character.
- */
-/* FTDI_SIO_SET_FLOW_CTRL */
-#define FTDI_SIO_DISABLE_FLOW_CTRL 0x0
-#define FTDI_SIO_RTS_CTS_HS 0x1
-#define FTDI_SIO_DTR_DSR_HS 0x2
-#define FTDI_SIO_XON_XOFF_HS 0x4
-
-
-/*
- * BmRequestType: 0100 0000b
- * bRequest: FTDI_SIO_SET_EVENT_CHAR
- * wValue: Event Char
- * wIndex: Port
- * wLength: 0
- * Data: None
- *
- * wValue:
- * B0..7 Event Character
- * B8 Event Character Processing
- * 0 = disabled
- * 1 = enabled
- * B9..15 Reserved
- *
- * FTDI_SIO_SET_EVENT_CHAR
- *
- * Set the special event character for the specified communications port.
- * If the device sees this character it will immediately return the
- * data read so far - rather than wait 40ms or until 62 bytes are read
- * which is what normally happens.
- */
-
-
-
-/*
- * BmRequestType: 0100 0000b
- * bRequest: FTDI_SIO_SET_ERROR_CHAR
- * wValue: Error Char
- * wIndex: Port
- * wLength: 0
- * Data: None
- *
- * Error Char
- * B0..7 Error Character
- * B8 Error Character Processing
- * 0 = disabled
- * 1 = enabled
- * B9..15 Reserved
- *
- *
- * FTDI_SIO_SET_ERROR_CHAR
- * Set the parity error replacement character for the specified communications
- * port.
- */
-
-
-/*
- * BmRequestType: 1100 0000b
- * bRequest: FTDI_SIO_GET_MODEM_STATUS
- * wValue: zero
- * wIndex: Port
- * wLength: 1
- * Data: Status
- *
- * One byte of data is returned
- * B0..3 0
- * B4 CTS
- * 0 = inactive
- * 1 = active
- * B5 DSR
- * 0 = inactive
- * 1 = active
- * B6 Ring Indicator (RI)
- * 0 = inactive
- * 1 = active
- * B7 Receive Line Signal Detect (RLSD)
- * 0 = inactive
- * 1 = active
- *
- * FTDI_SIO_GET_MODEM_STATUS
- * Retrieve the current value of the modem status register.
- */
-#define FTDI_SIO_CTS_MASK 0x10
-#define FTDI_SIO_DSR_MASK 0x20
-#define FTDI_SIO_RI_MASK 0x40
-#define FTDI_SIO_RLSD_MASK 0x80
-
-
-
-/*
- *
- * DATA FORMAT
- *
- * IN Endpoint
- *
- * The device reserves the first two bytes of data on this endpoint to contain
- * the current values of the modem and line status registers. In the absence of
- * data, the device generates a message consisting of these two status bytes
- * every 40 ms.
- *
- * Byte 0: Modem Status
- * NOTE: 4 upper bits have same layout as the MSR register in a 16550
- *
- * Offset Description
- * B0..3 Port
- * B4 Clear to Send (CTS)
- * B5 Data Set Ready (DSR)
- * B6 Ring Indicator (RI)
- * B7 Receive Line Signal Detect (RLSD)
- *
- * Byte 1: Line Status
- * NOTE: same layout as the LSR register in a 16550
- *
- * Offset Description
- * B0 Data Ready (DR)
- * B1 Overrun Error (OE)
- * B2 Parity Error (PE)
- * B3 Framing Error (FE)
- * B4 Break Interrupt (BI)
- * B5 Transmitter Holding Register (THRE)
- * B6 Transmitter Empty (TEMT)
- * B7 Error in RCVR FIFO
- *
- *
- * OUT Endpoint
- *
- * This device reserves the first bytes of data on this endpoint contain the
- * length and port identifier of the message. For the FTDI USB Serial converter
- * the port identifier is always 1.
- *
- * Byte 0: Port & length
- *
- * Offset Description
- * B0..1 Port
- * B2..7 Length of message - (not including Byte 0)
- *
- */
-#define FTDI_PORT_MASK 0x0f
-#define FTDI_MSR_MASK 0xf0
-#define FTDI_GET_MSR(p) (((p)[0]) & FTDI_MSR_MASK)
-#define FTDI_GET_LSR(p) ((p)[1])
-#define FTDI_LSR_MASK (~0x60) /* interesting bits */
-#define FTDI_OUT_TAG(len, port) (((len) << 2) | (port))
diff --git a/sys/dev/usb/ugen.c b/sys/dev/usb/ugen.c
deleted file mode 100644
index 4f03cfb..0000000
--- a/sys/dev/usb/ugen.c
+++ /dev/null
@@ -1,1590 +0,0 @@
-/* $NetBSD: ugen.c,v 1.79 2006/03/01 12:38:13 yamt Exp $ */
-
-/* Also already merged from NetBSD:
- * $NetBSD: ugen.c,v 1.61 2002/09/23 05:51:20 simonb Exp $
- * $NetBSD: ugen.c,v 1.64 2003/06/28 14:21:46 darrenr Exp $
- * $NetBSD: ugen.c,v 1.65 2003/06/29 22:30:56 fvdl Exp $
- * $NetBSD: ugen.c,v 1.68 2004/06/23 02:30:52 mycroft Exp $
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) 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.
- */
-
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/clist.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/ioccom.h>
-#include <sys/conf.h>
-#include <sys/fcntl.h>
-#include <sys/filio.h>
-#include <sys/file.h>
-#include <sys/selinfo.h>
-#include <sys/poll.h>
-#include <sys/sysctl.h>
-#include <sys/uio.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-
-#ifdef USB_DEBUG
-#define DPRINTF(x) if (ugendebug) printf x
-#define DPRINTFN(n,x) if (ugendebug>(n)) printf x
-int ugendebug = 0;
-SYSCTL_NODE(_hw_usb, OID_AUTO, ugen, CTLFLAG_RW, 0, "USB ugen");
-SYSCTL_INT(_hw_usb_ugen, OID_AUTO, debug, CTLFLAG_RW,
- &ugendebug, 0, "ugen debug level");
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-#define UGEN_CHUNK 128 /* chunk size for read */
-#define UGEN_IBSIZE 1020 /* buffer size */
-#define UGEN_BBSIZE 1024
-
-#define UGEN_NISOFRAMES 500 /* 0.5 seconds worth */
-#define UGEN_NISOREQS 6 /* number of outstanding xfer requests */
-#define UGEN_NISORFRMS 4 /* number of frames (miliseconds) per req */
-
-struct ugen_endpoint {
- struct ugen_softc *sc;
- struct cdev *dev;
- usb_endpoint_descriptor_t *edesc;
- usbd_interface_handle iface;
- int state;
-#define UGEN_ASLP 0x02 /* waiting for data */
-#define UGEN_SHORT_OK 0x04 /* short xfers are OK */
- usbd_pipe_handle pipeh;
- struct clist q;
- struct selinfo rsel;
- u_char *ibuf; /* start of buffer (circular for isoc) */
- u_char *fill; /* location for input (isoc) */
- u_char *limit; /* end of circular buffer (isoc) */
- u_char *cur; /* current read location (isoc) */
- u_int32_t timeout;
- struct isoreq {
- struct ugen_endpoint *sce;
- usbd_xfer_handle xfer;
- void *dmabuf;
- u_int16_t sizes[UGEN_NISORFRMS];
- } isoreqs[UGEN_NISOREQS];
-};
-
-struct ugen_softc {
- device_t sc_dev; /* base device */
- usbd_device_handle sc_udev;
- struct cdev *dev;
-
- char sc_is_open[USB_MAX_ENDPOINTS];
- struct ugen_endpoint sc_endpoints[USB_MAX_ENDPOINTS][2];
-#define OUT 0
-#define IN 1
-
-#define UGEN_DEV_REF(dev, sc) \
- if ((sc)->sc_dying || dev_refthread(dev) == NULL) \
- return (ENXIO)
-#define UGEN_DEV_RELE(dev, sc) \
- dev_relthread(dev)
-#define UGEN_DEV_OPEN(dev, sc) \
- /* handled by dev layer */
-#define UGEN_DEV_CLOSE(dev, sc) \
- /* handled by dev layer */
- u_char sc_dying;
-};
-
-d_open_t ugenopen;
-d_close_t ugenclose;
-d_read_t ugenread;
-d_write_t ugenwrite;
-d_ioctl_t ugenioctl;
-d_poll_t ugenpoll;
-d_purge_t ugenpurge;
-
-static struct cdevsw ugenctl_cdevsw = {
- .d_version = D_VERSION,
- .d_flags = D_NEEDGIANT,
- .d_open = ugenopen,
- .d_close = ugenclose,
- .d_ioctl = ugenioctl,
- .d_purge = ugenpurge,
- .d_name = "ugenctl",
-};
-
-static struct cdevsw ugen_cdevsw = {
- .d_version = D_VERSION,
- .d_flags = D_NEEDGIANT,
- .d_open = ugenopen,
- .d_close = ugenclose,
- .d_read = ugenread,
- .d_write = ugenwrite,
- .d_ioctl = ugenioctl,
- .d_poll = ugenpoll,
- .d_purge = ugenpurge,
- .d_name = "ugen",
-};
-
-static void ugenintr(usbd_xfer_handle xfer, usbd_private_handle addr,
- usbd_status status);
-static void ugen_isoc_rintr(usbd_xfer_handle xfer, usbd_private_handle addr,
- usbd_status status);
-static int ugen_do_read(struct ugen_softc *, int, struct uio *, int);
-static int ugen_do_write(struct ugen_softc *, int, struct uio *, int);
-static int ugen_do_ioctl(struct ugen_softc *, int, u_long,
- caddr_t, int, struct thread *);
-static void ugen_make_devnodes(struct ugen_softc *sc);
-static void ugen_destroy_devnodes(struct ugen_softc *sc);
-static int ugen_set_config(struct ugen_softc *sc, int configno);
-static usb_config_descriptor_t *ugen_get_cdesc(struct ugen_softc *sc,
- int index, int *lenp);
-static usbd_status ugen_set_interface(struct ugen_softc *, int, int);
-static int ugen_get_alt_index(struct ugen_softc *sc, int ifaceidx);
-
-#define UGENUNIT(n) ((dev2unit(n) >> 4) & 0xf)
-#define UGENENDPOINT(n) (dev2unit(n) & 0xf)
-#define UGENMINOR(u, e) (((u) << 4) | (e))
-
-static device_probe_t ugen_match;
-static device_attach_t ugen_attach;
-static device_detach_t ugen_detach;
-
-static devclass_t ugen_devclass;
-
-static device_method_t ugen_methods[] = {
- DEVMETHOD(device_probe, ugen_match),
- DEVMETHOD(device_attach, ugen_attach),
- DEVMETHOD(device_detach, ugen_detach),
- {0,0},
- {0,0}
-};
-
-static driver_t ugen_driver = {
- "ugen",
- ugen_methods,
- sizeof(struct ugen_softc)
-};
-
-MODULE_DEPEND(ugen, usb, 1, 1, 1);
-
-static int
-ugen_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
-
-#if 0
- if (uaa->matchlvl)
- return (uaa->matchlvl);
-#endif
- if (uaa->usegeneric)
- return (UMATCH_GENERIC);
- else
- return (UMATCH_NONE);
-}
-
-static int
-ugen_attach(device_t self)
-{
- struct ugen_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usbd_device_handle udev;
- usbd_status err;
- int conf;
-
- sc->sc_dev = self;
- sc->sc_udev = udev = uaa->device;
-
- memset(sc->sc_endpoints, 0, sizeof sc->sc_endpoints);
-
- /* 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",
- device_get_nameunit(sc->sc_dev));
- sc->sc_dying = 1;
- return (ENXIO);
- }
- conf = usbd_get_config_descriptor(udev)->bConfigurationValue;
-
- /* Set up all the local state for this configuration. */
- err = ugen_set_config(sc, conf);
- if (err) {
- printf("%s: setting configuration %d failed\n",
- device_get_nameunit(sc->sc_dev), conf);
- sc->sc_dying = 1;
- return (ENXIO);
- }
-
- /* the main device, ctrl endpoint */
- sc->dev = make_dev(&ugenctl_cdevsw,
- UGENMINOR(device_get_unit(sc->sc_dev), 0), UID_ROOT, GID_OPERATOR, 0644,
- "%s", device_get_nameunit(sc->sc_dev));
- ugen_make_devnodes(sc);
- usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev);
- return (0);
-}
-
-static void
-ugen_make_devnodes(struct ugen_softc *sc)
-{
- int endptno;
- struct cdev *dev;
-
- for (endptno = 1; endptno < USB_MAX_ENDPOINTS; endptno++) {
- if (sc->sc_endpoints[endptno][IN].sc != NULL ||
- sc->sc_endpoints[endptno][OUT].sc != NULL ) {
- /* endpt can be 0x81 and 0x01, representing
- * endpoint address 0x01 and IN/OUT directions.
- * We map both endpts to the same device,
- * IN is reading from it, OUT is writing to it.
- *
- * In the if clause above we check whether one
- * of the structs is populated.
- */
- dev = make_dev(&ugen_cdevsw,
- UGENMINOR(device_get_unit(sc->sc_dev), endptno),
- UID_ROOT, GID_OPERATOR, 0644,
- "%s.%d",
- device_get_nameunit(sc->sc_dev), endptno);
- dev_depends(sc->dev, dev);
- if (sc->sc_endpoints[endptno][IN].sc != NULL)
- sc->sc_endpoints[endptno][IN].dev = dev;
- if (sc->sc_endpoints[endptno][OUT].sc != NULL)
- sc->sc_endpoints[endptno][OUT].dev = dev;
- }
- }
-}
-
-static void
-ugen_destroy_devnodes(struct ugen_softc *sc)
-{
- int endptno, prev_sc_dying;
- struct cdev *dev;
-
- prev_sc_dying = sc->sc_dying;
- sc->sc_dying = 1;
- /* destroy all devices for the other (existing) endpoints as well */
- for (endptno = 1; endptno < USB_MAX_ENDPOINTS; endptno++) {
- if (sc->sc_endpoints[endptno][IN].sc != NULL ||
- sc->sc_endpoints[endptno][OUT].sc != NULL ) {
- /* endpt can be 0x81 and 0x01, representing
- * endpoint address 0x01 and IN/OUT directions.
- * We map both endpoint addresses to the same device,
- * IN is reading from it, OUT is writing to it.
- *
- * In the if clause above we check whether one
- * of the structs is populated.
- */
- if (sc->sc_endpoints[endptno][IN].sc != NULL)
- dev = sc->sc_endpoints[endptno][IN].dev;
- else
- dev = sc->sc_endpoints[endptno][OUT].dev;
-
- KASSERT(dev != NULL,
- ("ugen_destroy_devnodes: NULL dev"));
- if(dev != NULL)
- destroy_dev(dev);
-
- sc->sc_endpoints[endptno][IN].sc = NULL;
- sc->sc_endpoints[endptno][OUT].sc = NULL;
- }
- }
- sc->sc_dying = prev_sc_dying;
-}
-
-static int
-ugen_set_config(struct ugen_softc *sc, int configno)
-{
- usbd_device_handle dev = sc->sc_udev;
- usbd_interface_handle iface;
- usb_endpoint_descriptor_t *ed;
- struct ugen_endpoint *sce, **sce_cache, ***sce_cache_arr;
- u_int8_t niface, niface_cache, nendpt, *nendpt_cache;
- int ifaceno, endptno, endpt;
- usbd_status err;
- int dir;
-
- DPRINTFN(1,("ugen_set_config: %s to configno %d, sc=%p\n",
- device_get_nameunit(sc->sc_dev), configno, sc));
-
- /* We start at 1, not 0, because we don't care whether the
- * control endpoint is open or not. It is always present.
- */
- for (endptno = 1; endptno < USB_MAX_ENDPOINTS; endptno++)
- if (sc->sc_is_open[endptno]) {
- DPRINTFN(1,
- ("ugen_set_config: %s - endpoint %d is open\n",
- device_get_nameunit(sc->sc_dev), endptno));
- return (USBD_IN_USE);
- }
-
- err = usbd_interface_count(dev, &niface);
- if (err)
- return (err);
- /* store an array of endpoint descriptors to clear if the configuration
- * change succeeds - these aren't available afterwards */
- nendpt_cache = malloc(sizeof(u_int8_t) * niface, M_TEMP, M_WAITOK |
- M_ZERO);
- sce_cache_arr = malloc(sizeof(struct ugen_endpoint **) * niface, M_TEMP,
- M_WAITOK | M_ZERO);
- niface_cache = niface;
-
- for (ifaceno = 0; ifaceno < niface; ifaceno++) {
- DPRINTFN(1,("ugen_set_config: ifaceno %d\n", ifaceno));
- err = usbd_device2interface_handle(dev, ifaceno, &iface);
- if (err)
- panic("ugen_set_config: can't obtain interface handle");
- err = usbd_endpoint_count(iface, &nendpt);
- if (err)
- panic("ugen_set_config: endpoint count failed");
-
- /* store endpoint descriptors for each interface */
- nendpt_cache[ifaceno] = nendpt;
- sce_cache = malloc(sizeof(struct ugen_endpoint *) * nendpt, M_TEMP,
- M_WAITOK);
- sce_cache_arr[ifaceno] = sce_cache;
-
- for (endptno = 0; endptno < nendpt; endptno++) {
- ed = usbd_interface2endpoint_descriptor(iface,endptno);
- endpt = ed->bEndpointAddress;
- dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT;
- sce_cache[endptno] = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir];
- }
- }
-
- /* Avoid setting the current value. */
- if (usbd_get_config_descriptor(dev)->bConfigurationValue != configno) {
- /* attempt to perform the configuration change */
- err = usbd_set_config_no(dev, configno, 1);
- if (err) {
- for(ifaceno = 0; ifaceno < niface_cache; ifaceno++)
- free(sce_cache_arr[ifaceno], M_TEMP);
- free(sce_cache_arr, M_TEMP);
- free(nendpt_cache, M_TEMP);
- return (err);
- }
- }
-
- ugen_destroy_devnodes(sc);
-
- /* now we can clear the old interface's ugen_endpoints */
- for(ifaceno = 0; ifaceno < niface_cache; ifaceno++) {
- sce_cache = sce_cache_arr[ifaceno];
- for(endptno = 0; endptno < nendpt_cache[ifaceno]; endptno++) {
- sce = sce_cache[endptno];
- sce->sc = 0;
- sce->edesc = 0;
- sce->iface = 0;
- }
- }
-
- /* and free the cache storing them */
- for(ifaceno = 0; ifaceno < niface_cache; ifaceno++)
- free(sce_cache_arr[ifaceno], M_TEMP);
- free(sce_cache_arr, M_TEMP);
- free(nendpt_cache, M_TEMP);
-
- /* no endpoints if the device is in the unconfigured state */
- if (configno != USB_UNCONFIG_NO)
- {
- /* set the new configuration's ugen_endpoints */
- err = usbd_interface_count(dev, &niface);
- if (err)
- panic("ugen_set_config: interface count failed");
-
- memset(sc->sc_endpoints, 0, sizeof sc->sc_endpoints);
- for (ifaceno = 0; ifaceno < niface; ifaceno++) {
- DPRINTFN(1,("ugen_set_config: ifaceno %d\n", ifaceno));
- err = usbd_device2interface_handle(dev, ifaceno, &iface);
- if (err)
- panic("ugen_set_config: can't obtain interface handle");
- err = usbd_endpoint_count(iface, &nendpt);
- if (err)
- panic("ugen_set_config: endpoint count failed");
- for (endptno = 0; endptno < nendpt; endptno++) {
- ed = usbd_interface2endpoint_descriptor(iface,endptno);
- endpt = ed->bEndpointAddress;
- dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT;
- sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir];
- DPRINTFN(1,("ugen_set_config: endptno %d, endpt=0x%02x"
- "(%d,%d), sce=%p\n",
- endptno, endpt, UE_GET_ADDR(endpt),
- UE_GET_DIR(endpt), sce));
- sce->sc = sc;
- sce->edesc = ed;
- sce->iface = iface;
- }
- }
- }
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-int
-ugenopen(struct cdev *dev, int flag, int mode, struct thread *p)
-{
- struct ugen_softc *sc;
- int unit = UGENUNIT(dev);
- int endpt = UGENENDPOINT(dev);
- usb_endpoint_descriptor_t *edesc;
- struct ugen_endpoint *sce;
- int dir, isize;
- usbd_status err;
- usbd_xfer_handle xfer;
- void *buf;
- int i, j;
-
- sc = devclass_get_softc(ugen_devclass, unit);
- if (sc == NULL)
- return (ENXIO);
-
- DPRINTFN(5, ("ugenopen: flag=%d, mode=%d, unit=%d endpt=%d\n",
- flag, mode, unit, endpt));
-
- if (sc == NULL || sc->sc_dying)
- return (ENXIO);
-
- if (sc->sc_is_open[endpt])
- return (EBUSY);
-
- if (endpt == USB_CONTROL_ENDPOINT) {
- sc->sc_is_open[USB_CONTROL_ENDPOINT] = 1;
- UGEN_DEV_OPEN(dev, sc);
- return (0);
- }
-
- /* Make sure there are pipes for all directions. */
- for (dir = OUT; dir <= IN; dir++) {
- if (flag & (dir == OUT ? FWRITE : FREAD)) {
- sce = &sc->sc_endpoints[endpt][dir];
- if (sce->edesc == 0)
- return (ENXIO);
- }
- }
-
- /* Actually open the pipes. */
- /* XXX Should back out properly if it fails. */
- for (dir = OUT; dir <= IN; dir++) {
- if (!(flag & (dir == OUT ? FWRITE : FREAD)))
- continue;
- sce = &sc->sc_endpoints[endpt][dir];
- sce->state = 0;
- sce->timeout = USBD_NO_TIMEOUT;
- DPRINTFN(5, ("ugenopen: sc=%p, endpt=%d, dir=%d, sce=%p\n",
- sc, endpt, dir, sce));
- edesc = sce->edesc;
- switch (edesc->bmAttributes & UE_XFERTYPE) {
- case UE_INTERRUPT:
- if (dir == OUT) {
- err = usbd_open_pipe(sce->iface,
- edesc->bEndpointAddress, 0, &sce->pipeh);
- if (err)
- return (EIO);
- break;
- }
- isize = UGETW(edesc->wMaxPacketSize);
- if (isize == 0) /* shouldn't happen */
- return (EINVAL);
- sce->ibuf = malloc(isize, M_USBDEV, M_WAITOK);
- DPRINTFN(5, ("ugenopen: intr endpt=%d,isize=%d\n",
- endpt, isize));
- if ((clist_alloc_cblocks(&sce->q, UGEN_IBSIZE,
- 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);
- if (err) {
- free(sce->ibuf, M_USBDEV);
- clist_free_cblocks(&sce->q);
- return (EIO);
- }
- DPRINTFN(5, ("ugenopen: interrupt open done\n"));
- break;
- case UE_BULK:
- err = usbd_open_pipe(sce->iface,
- edesc->bEndpointAddress, 0, &sce->pipeh);
- if (err)
- return (EIO);
- break;
- case UE_ISOCHRONOUS:
- if (dir == OUT)
- return (EINVAL);
- isize = UGETW(edesc->wMaxPacketSize);
- if (isize == 0) /* shouldn't happen */
- return (EINVAL);
- sce->ibuf = malloc(isize * UGEN_NISOFRAMES,
- M_USBDEV, M_WAITOK);
- sce->cur = sce->fill = sce->ibuf;
- sce->limit = sce->ibuf + isize * UGEN_NISOFRAMES;
- DPRINTFN(5, ("ugenopen: isoc endpt=%d, isize=%d\n",
- endpt, isize));
- err = usbd_open_pipe(sce->iface,
- edesc->bEndpointAddress, 0, &sce->pipeh);
- if (err) {
- free(sce->ibuf, M_USBDEV);
- return (EIO);
- }
- for(i = 0; i < UGEN_NISOREQS; ++i) {
- sce->isoreqs[i].sce = sce;
- xfer = usbd_alloc_xfer(sc->sc_udev);
- if (xfer == 0)
- goto bad;
- sce->isoreqs[i].xfer = xfer;
- buf = usbd_alloc_buffer
- (xfer, isize * UGEN_NISORFRMS);
- if (buf == 0) {
- i++;
- goto bad;
- }
- sce->isoreqs[i].dmabuf = buf;
- for(j = 0; j < UGEN_NISORFRMS; ++j)
- sce->isoreqs[i].sizes[j] = isize;
- usbd_setup_isoc_xfer
- (xfer, sce->pipeh, &sce->isoreqs[i],
- sce->isoreqs[i].sizes,
- UGEN_NISORFRMS, USBD_NO_COPY,
- ugen_isoc_rintr);
- (void)usbd_transfer(xfer);
- }
- DPRINTFN(5, ("ugenopen: isoc open done\n"));
- break;
- bad:
- while (--i >= 0) /* implicit buffer free */
- usbd_free_xfer(sce->isoreqs[i].xfer);
- return (ENOMEM);
- case UE_CONTROL:
- sce->timeout = USBD_DEFAULT_TIMEOUT;
- return (EINVAL);
- }
- }
- sc->sc_is_open[endpt] = 1;
- UGEN_DEV_OPEN(dev, sc);
- return (0);
-}
-
-int
-ugenclose(struct cdev *dev, int flag, int mode, struct thread *p)
-{
- int endpt = UGENENDPOINT(dev);
- struct ugen_softc *sc;
- struct ugen_endpoint *sce;
- int dir;
- int i;
-
- sc = devclass_get_softc(ugen_devclass, UGENUNIT(dev));
-
- DPRINTFN(5, ("ugenclose: flag=%d, mode=%d, unit=%d, endpt=%d\n",
- flag, mode, UGENUNIT(dev), endpt));
-
-#ifdef DIAGNOSTIC
- if (!sc->sc_is_open[endpt]) {
- printf("ugenclose: not open\n");
- return (EINVAL);
- }
-#endif
-
- if (endpt == USB_CONTROL_ENDPOINT) {
- DPRINTFN(5, ("ugenclose: close control\n"));
- sc->sc_is_open[endpt] = 0;
- UGEN_DEV_CLOSE(dev, sc);
- return (0);
- }
-
- for (dir = OUT; dir <= IN; dir++) {
- if (!(flag & (dir == OUT ? FWRITE : FREAD)))
- continue;
- sce = &sc->sc_endpoints[endpt][dir];
- if (sce->pipeh == NULL)
- continue;
- DPRINTFN(5, ("ugenclose: endpt=%d dir=%d sce=%p\n",
- endpt, dir, sce));
-
- usbd_abort_pipe(sce->pipeh);
- usbd_close_pipe(sce->pipeh);
- sce->pipeh = NULL;
-
- switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
- case UE_INTERRUPT:
- ndflush(&sce->q, sce->q.c_cc);
- clist_free_cblocks(&sce->q);
- break;
- case UE_ISOCHRONOUS:
- for (i = 0; i < UGEN_NISOREQS; ++i)
- usbd_free_xfer(sce->isoreqs[i].xfer);
-
- default:
- break;
- }
-
- if (sce->ibuf != NULL) {
- free(sce->ibuf, M_USBDEV);
- sce->ibuf = NULL;
- clist_free_cblocks(&sce->q);
- }
- }
- sc->sc_is_open[endpt] = 0;
- UGEN_DEV_CLOSE(dev, sc);
-
- return (0);
-}
-
-static int
-ugen_do_read(struct ugen_softc *sc, int endpt, struct uio *uio, int flag)
-{
- struct ugen_endpoint *sce = &sc->sc_endpoints[endpt][IN];
- u_int32_t n, tn;
- char buf[UGEN_BBSIZE];
- usbd_xfer_handle xfer;
- usbd_status err;
- int s;
- int error = 0, doneone = 0;
- u_char buffer[UGEN_CHUNK];
-
- DPRINTFN(5, ("%s: ugenread: %d\n", device_get_nameunit(sc->sc_dev), endpt));
-
- if (sc->sc_dying)
- return (EIO);
-
- if (endpt == USB_CONTROL_ENDPOINT)
- return (ENODEV);
-
-#ifdef DIAGNOSTIC
- if (sce->edesc == NULL) {
- printf("ugenread: no edesc\n");
- return (EIO);
- }
- if (sce->pipeh == NULL) {
- printf("ugenread: no pipe\n");
- return (EIO);
- }
-#endif
-
- switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
- case UE_INTERRUPT:
- /* Block until activity occurred. */
- s = splusb();
- while (sce->q.c_cc == 0) {
- if (flag & O_NONBLOCK) {
- splx(s);
- return (EWOULDBLOCK);
- }
- sce->state |= UGEN_ASLP;
- DPRINTFN(5, ("ugenread: sleep on %p\n", sce));
- error = tsleep(sce, PZERO | PCATCH, "ugenri",
- (sce->timeout * hz + 999) / 1000);
- sce->state &= ~UGEN_ASLP;
- DPRINTFN(5, ("ugenread: woke, error=%d\n", error));
- if (sc->sc_dying)
- error = EIO;
- if (error == EAGAIN) {
- error = 0; /* timeout, return 0 bytes */
- break;
- }
- if (error)
- break;
- }
- splx(s);
-
- /* Transfer as many chunks as possible. */
- while (sce->q.c_cc > 0 && uio->uio_resid > 0 && !error) {
- n = min(sce->q.c_cc, uio->uio_resid);
- if (n > sizeof(buffer))
- n = sizeof(buffer);
-
- /* Remove a small chunk from the input queue. */
- q_to_b(&sce->q, buffer, n);
- DPRINTFN(5, ("ugenread: got %d chars\n", n));
-
- /* Copy the data to the user process. */
- error = uiomove(buffer, n, uio);
- if (error)
- break;
- }
- break;
- case UE_BULK:
- xfer = usbd_alloc_xfer(sc->sc_udev);
- if (xfer == 0)
- return (ENOMEM);
- while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0 ||
- !doneone) {
- DPRINTFN(1, ("ugenread: start transfer %d bytes\n",n));
- tn = n;
- doneone = 1;
- err = usbd_bulk_transfer(
- 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;
- else if (err == USBD_TIMEOUT)
- error = ETIMEDOUT;
- else
- error = EIO;
- break;
- }
- DPRINTFN(1, ("ugenread: got %d bytes\n", tn));
- error = uiomove(buf, tn, uio);
- if (error || tn < n)
- break;
- }
- usbd_free_xfer(xfer);
- break;
- case UE_ISOCHRONOUS:
- s = splusb();
- while (sce->cur == sce->fill) {
- if (flag & O_NONBLOCK) {
- splx(s);
- return (EWOULDBLOCK);
- }
- sce->state |= UGEN_ASLP;
- DPRINTFN(5, ("ugenread: sleep on %p\n", sce));
- error = tsleep(sce, PZERO | PCATCH, "ugenri",
- (sce->timeout * hz + 999) / 1000);
- sce->state &= ~UGEN_ASLP;
- DPRINTFN(5, ("ugenread: woke, error=%d\n", error));
- if (sc->sc_dying)
- error = EIO;
- if (error == EAGAIN) {
- error = 0; /* timeout, return 0 bytes */
- break;
- }
- if (error)
- break;
- }
-
- while (sce->cur != sce->fill && uio->uio_resid > 0 && !error) {
- if (sce->fill > sce->cur)
- n = min(sce->fill - sce->cur, uio->uio_resid);
- else
- n = min(sce->limit - sce->cur, uio->uio_resid);
-
- DPRINTFN(5, ("ugenread: isoc got %d chars\n", n));
-
- /* Copy the data to the user process. */
- error = uiomove(sce->cur, n, uio);
- if (error)
- break;
- sce->cur += n;
- if(sce->cur >= sce->limit)
- sce->cur = sce->ibuf;
- }
- splx(s);
- break;
-
-
- default:
- return (ENXIO);
- }
- return (error);
-}
-
-int
-ugenread(struct cdev *dev, struct uio *uio, int flag)
-{
- int endpt = UGENENDPOINT(dev);
- struct ugen_softc *sc;
- int error;
-
- sc = devclass_get_softc(ugen_devclass, UGENUNIT(dev));
-
- if (sc->sc_dying)
- return (EIO);
-
- UGEN_DEV_REF(dev, sc);
- error = ugen_do_read(sc, endpt, uio, flag);
- UGEN_DEV_RELE(dev, sc);
- return (error);
-}
-
-static int
-ugen_do_write(struct ugen_softc *sc, int endpt, struct uio *uio, int flag)
-{
- struct ugen_endpoint *sce = &sc->sc_endpoints[endpt][OUT];
- u_int32_t n;
- int error = 0, doneone = 0;
- char buf[UGEN_BBSIZE];
- usbd_xfer_handle xfer;
- usbd_status err;
-
- DPRINTFN(5, ("%s: ugenwrite: %d\n", device_get_nameunit(sc->sc_dev), endpt));
-
- if (sc->sc_dying)
- return (EIO);
-
- if (endpt == USB_CONTROL_ENDPOINT)
- return (ENODEV);
-
-#ifdef DIAGNOSTIC
- if (sce->edesc == NULL) {
- printf("ugenwrite: no edesc\n");
- return (EIO);
- }
- if (sce->pipeh == NULL) {
- printf("ugenwrite: no pipe\n");
- return (EIO);
- }
-#endif
-
- switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
- case UE_BULK:
- xfer = usbd_alloc_xfer(sc->sc_udev);
- if (xfer == 0)
- return (EIO);
- while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0 ||
- !doneone) {
- doneone = 1;
- error = uiomove(buf, n, uio);
- if (error)
- break;
- DPRINTFN(1, ("ugenwrite: transfer %d bytes\n", n));
- err = usbd_bulk_transfer(xfer, sce->pipeh, 0,
- sce->timeout, buf, &n,"ugenwb");
- if (err) {
- if (err == USBD_INTERRUPTED)
- error = EINTR;
- else if (err == USBD_TIMEOUT)
- error = ETIMEDOUT;
- else
- error = EIO;
- break;
- }
- }
- usbd_free_xfer(xfer);
- break;
- case UE_INTERRUPT:
- xfer = usbd_alloc_xfer(sc->sc_udev);
- if (xfer == 0)
- return (EIO);
- while ((n = min(UGETW(sce->edesc->wMaxPacketSize),
- uio->uio_resid)) != 0 || !doneone) {
- doneone = 1;
- error = uiomove(buf, n, uio);
- if (error)
- break;
- DPRINTFN(1, ("ugenwrite: transfer %d bytes\n", n));
- err = usbd_intr_transfer(xfer, sce->pipeh, 0,
- sce->timeout, buf, &n, "ugenwi");
- if (err) {
- if (err == USBD_INTERRUPTED)
- error = EINTR;
- else if (err == USBD_TIMEOUT)
- error = ETIMEDOUT;
- else
- error = EIO;
- break;
- }
- }
- usbd_free_xfer(xfer);
- break;
- default:
- return (ENXIO);
- }
- return (error);
-}
-
-int
-ugenwrite(struct cdev *dev, struct uio *uio, int flag)
-{
- int endpt = UGENENDPOINT(dev);
- struct ugen_softc *sc;
- int error;
-
- sc = devclass_get_softc(ugen_devclass, UGENUNIT(dev));
-
- if (sc->sc_dying)
- return (EIO);
-
- UGEN_DEV_REF(dev, sc);
- error = ugen_do_write(sc, endpt, uio, flag);
- UGEN_DEV_RELE(dev, sc);
- return (error);
-}
-
-void
-ugenpurge(struct cdev *dev)
-{
- int endpt = UGENENDPOINT(dev);
- struct ugen_endpoint *sce;
- struct ugen_softc *sc;
-
- if (endpt == USB_CONTROL_ENDPOINT)
- return;
- sc = devclass_get_softc(ugen_devclass, UGENUNIT(dev));
- sce = &sc->sc_endpoints[endpt][IN];
- if (sce->pipeh)
- usbd_abort_pipe(sce->pipeh);
- if (sce->state & UGEN_ASLP) {
- DPRINTFN(5, ("ugenpurge: waking %p\n", sce));
- wakeup(sce);
- }
- selwakeuppri(&sce->rsel, PZERO);
-
- sce = &sc->sc_endpoints[endpt][OUT];
- if (sce->pipeh)
- usbd_abort_pipe(sce->pipeh);
- if (sce->state & UGEN_ASLP) {
- DPRINTFN(5, ("ugenpurge: waking %p\n", sce));
- wakeup(sce);
- }
- selwakeuppri(&sce->rsel, PZERO);
-}
-
-static int
-ugen_detach(device_t self)
-{
- struct ugen_softc *sc = device_get_softc(self);
- struct ugen_endpoint *sce;
- int i, dir;
-
- DPRINTF(("ugen_detach: sc=%p\n", sc));
-
- sc->sc_dying = 1;
- /* Abort all pipes. Causes processes waiting for transfer to wake. */
- for (i = 0; i < USB_MAX_ENDPOINTS; i++) {
- for (dir = OUT; dir <= IN; dir++) {
- sce = &sc->sc_endpoints[i][dir];
- if (sce->pipeh)
- usbd_abort_pipe(sce->pipeh);
- selwakeuppri(&sce->rsel, PZERO);
- }
- }
-
- /* destroy the device for the control endpoint */
- destroy_dev(sc->dev);
- usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev);
- return (0);
-}
-
-static void
-ugenintr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status)
-{
- struct ugen_endpoint *sce = addr;
- /*struct ugen_softc *sc = sce->sc;*/
- u_int32_t count;
- u_char *ibuf;
-
- if (status == USBD_CANCELLED)
- return;
-
- if (status != USBD_NORMAL_COMPLETION) {
- DPRINTF(("ugenintr: status=%d\n", status));
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall_async(sce->pipeh);
- return;
- }
-
- usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
- ibuf = sce->ibuf;
-
- DPRINTFN(5, ("ugenintr: xfer=%p status=%d count=%d\n",
- xfer, status, count));
- DPRINTFN(5, (" data = %02x %02x %02x\n",
- ibuf[0], ibuf[1], ibuf[2]));
-
- (void)b_to_q(ibuf, count, &sce->q);
-
- if (sce->state & UGEN_ASLP) {
- sce->state &= ~UGEN_ASLP;
- DPRINTFN(5, ("ugen_intr: waking %p\n", sce));
- wakeup(sce);
- }
- selwakeuppri(&sce->rsel, PZERO);
-}
-
-static void
-ugen_isoc_rintr(usbd_xfer_handle xfer, usbd_private_handle addr,
- usbd_status status)
-{
- struct isoreq *req = addr;
- struct ugen_endpoint *sce = req->sce;
- u_int32_t count, n;
- int i, isize;
-
- /* Return if we are aborting. */
- if (status == USBD_CANCELLED)
- return;
-
- usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
- DPRINTFN(5,("ugen_isoc_rintr: xfer %td, count=%d\n", req - sce->isoreqs,
- count));
-
- /* throw away oldest input if the buffer is full */
- if(sce->fill < sce->cur && sce->cur <= sce->fill + count) {
- sce->cur += count;
- if(sce->cur >= sce->limit)
- sce->cur = sce->ibuf + (sce->limit - sce->cur);
- DPRINTF(("ugen_isoc_rintr: throwing away %d bytes\n",
- count));
- }
-
- isize = UGETW(sce->edesc->wMaxPacketSize);
- for (i = 0; i < UGEN_NISORFRMS; i++) {
- u_int32_t actlen = req->sizes[i];
- char const *buf = (char const *)req->dmabuf + isize * i;
-
- /* copy data to buffer */
- while (actlen > 0) {
- n = min(actlen, sce->limit - sce->fill);
- memcpy(sce->fill, buf, n);
-
- buf += n;
- actlen -= n;
- sce->fill += n;
- if(sce->fill == sce->limit)
- sce->fill = sce->ibuf;
- }
-
- /* setup size for next transfer */
- req->sizes[i] = isize;
- }
-
- usbd_setup_isoc_xfer(xfer, sce->pipeh, req, req->sizes, UGEN_NISORFRMS,
- USBD_NO_COPY, ugen_isoc_rintr);
- (void)usbd_transfer(xfer);
-
- if (sce->state & UGEN_ASLP) {
- sce->state &= ~UGEN_ASLP;
- DPRINTFN(5, ("ugen_isoc_rintr: waking %p\n", sce));
- wakeup(sce);
- }
- selwakeuppri(&sce->rsel, PZERO);
-}
-
-static usbd_status
-ugen_set_interface(struct ugen_softc *sc, int ifaceidx, int altno)
-{
- usbd_interface_handle iface;
- usb_endpoint_descriptor_t *ed;
- usbd_status err;
- struct ugen_endpoint *sce, **sce_cache;
- u_int8_t niface, nendpt, nendpt_cache, endptno, endpt;
- int dir;
-
- DPRINTFN(15, ("ugen_set_interface %d %d\n", ifaceidx, altno));
-
- err = usbd_interface_count(sc->sc_udev, &niface);
- if (err)
- return (err);
- if (ifaceidx < 0 || ifaceidx >= niface)
- return (USBD_INVAL);
-
- err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface);
- if (err)
- return (err);
- err = usbd_endpoint_count(iface, &nendpt);
- if (err)
- return (err);
-
- /* store an array of endpoint descriptors to clear if the interface
- * change succeeds - these aren't available afterwards */
- sce_cache = malloc(sizeof(struct ugen_endpoint *) * nendpt, M_TEMP,
- M_WAITOK);
- nendpt_cache = nendpt;
-
- for (endptno = 0; endptno < nendpt; endptno++) {
- ed = usbd_interface2endpoint_descriptor(iface,endptno);
- endpt = ed->bEndpointAddress;
- dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT;
- sce_cache[endptno] = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir];
- }
-
- /* change setting */
- err = usbd_set_interface(iface, altno);
- if (err) {
- free(sce_cache, M_TEMP);
- return (err);
- }
- err = usbd_endpoint_count(iface, &nendpt);
- if (err)
- panic("ugen_set_interface: endpoint count failed");
-
- /* destroy the existing devices, we remake the new ones in a moment */
- ugen_destroy_devnodes(sc);
-
- /* now we can clear the old interface's ugen_endpoints */
- for (endptno = 0; endptno < nendpt_cache; endptno++) {
- sce = sce_cache[endptno];
- sce->sc = 0;
- sce->edesc = 0;
- sce->iface = 0;
- }
- free(sce_cache, M_TEMP);
-
- /* set the new interface's ugen_endpoints */
- for (endptno = 0; endptno < nendpt; endptno++) {
- ed = usbd_interface2endpoint_descriptor(iface,endptno);
- endpt = ed->bEndpointAddress;
- dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT;
- sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir];
- sce->sc = sc;
- sce->edesc = ed;
- sce->iface = iface;
- }
-
- /* make the new devices */
- ugen_make_devnodes(sc);
-
- return (0);
-}
-
-/* Retrieve a complete descriptor for a certain device and index. */
-static usb_config_descriptor_t *
-ugen_get_cdesc(struct ugen_softc *sc, int index, int *lenp)
-{
- usb_config_descriptor_t *cdesc, *tdesc, cdescr;
- int len;
- usbd_status err;
-
- if (index == USB_CURRENT_CONFIG_INDEX) {
- tdesc = usbd_get_config_descriptor(sc->sc_udev);
- len = UGETW(tdesc->wTotalLength);
- if (lenp)
- *lenp = len;
- cdesc = malloc(len, M_TEMP, M_WAITOK);
- memcpy(cdesc, tdesc, len);
- DPRINTFN(5,("ugen_get_cdesc: current, len=%d\n", len));
- } else {
- err = usbd_get_config_desc(sc->sc_udev, index, &cdescr);
- if (err)
- return (0);
- len = UGETW(cdescr.wTotalLength);
- DPRINTFN(5,("ugen_get_cdesc: index=%d, len=%d\n", index, len));
- if (lenp)
- *lenp = len;
- cdesc = malloc(len, M_TEMP, M_WAITOK);
- err = usbd_get_config_desc_full(sc->sc_udev, index, cdesc, len);
- if (err) {
- free(cdesc, M_TEMP);
- return (0);
- }
- }
- return (cdesc);
-}
-
-static int
-ugen_get_alt_index(struct ugen_softc *sc, int ifaceidx)
-{
- usbd_interface_handle iface;
- usbd_status err;
-
- err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface);
- if (err)
- return (-1);
- return (usbd_get_interface_altindex(iface));
-}
-
-static int
-ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd,
- caddr_t addr, int flag, struct thread *p)
-{
- struct ugen_endpoint *sce;
- usbd_status err;
- usbd_interface_handle iface;
- struct usb_config_desc *cd;
- usb_config_descriptor_t *cdesc;
- struct usb_interface_desc *id;
- usb_interface_descriptor_t *idesc;
- struct usb_endpoint_desc *ed;
- usb_endpoint_descriptor_t *edesc;
- struct usb_alt_interface *ai;
- struct usb_string_desc *si;
- u_int8_t conf, alt;
-
- DPRINTFN(5, ("ugenioctl: cmd=%08lx\n", cmd));
- if (sc->sc_dying)
- return (EIO);
-
- switch (cmd) {
- case FIONBIO:
- case FIOASYNC:
- /* All handled in the upper FS layer. */
- return (0);
- case USB_SET_SHORT_XFER:
- if (endpt == USB_CONTROL_ENDPOINT)
- return (EINVAL);
- /* This flag only affects read */
- sce = &sc->sc_endpoints[endpt][IN];
-
- if (sce->pipeh == NULL) {
- printf("ugenioctl: USB_SET_SHORT_XFER, no pipe\n");
- return (EIO);
- }
-
- if (*(int *)addr)
- sce->state |= UGEN_SHORT_OK;
- else
- sce->state &= ~UGEN_SHORT_OK;
- return (0);
- case USB_SET_TIMEOUT:
- sce = &sc->sc_endpoints[endpt][IN];
- sce->timeout = *(int *)addr;
- sce = &sc->sc_endpoints[endpt][OUT];
- sce->timeout = *(int *)addr;
- return (0);
- default:
- break;
- }
-
- if (endpt != USB_CONTROL_ENDPOINT)
- return (EINVAL);
-
- switch (cmd) {
-#ifdef USB_DEBUG
- case USB_SETDEBUG:
- ugendebug = *(int *)addr;
- break;
-#endif
- case USB_GET_CONFIG:
- err = usbd_get_config(sc->sc_udev, &conf);
- if (err)
- return (EIO);
- *(int *)addr = conf;
- break;
- case USB_SET_CONFIG:
- if (!(flag & FWRITE))
- return (EPERM);
- err = ugen_set_config(sc, *(int *)addr);
- switch (err) {
- case USBD_NORMAL_COMPLETION:
- ugen_make_devnodes(sc);
- break;
- case USBD_IN_USE:
- return (EBUSY);
- default:
- return (EIO);
- }
- break;
- case USB_GET_ALTINTERFACE:
- ai = (struct usb_alt_interface *)addr;
- err = usbd_device2interface_handle(sc->sc_udev,
- ai->uai_interface_index, &iface);
- if (err)
- return (EINVAL);
- idesc = usbd_get_interface_descriptor(iface);
- if (idesc == NULL)
- return (EIO);
- ai->uai_alt_no = idesc->bAlternateSetting;
- break;
- case USB_SET_ALTINTERFACE:
- if (!(flag & FWRITE))
- return (EPERM);
- ai = (struct usb_alt_interface *)addr;
- err = usbd_device2interface_handle(sc->sc_udev,
- ai->uai_interface_index, &iface);
- if (err)
- return (EINVAL);
- err = ugen_set_interface(sc, ai->uai_interface_index,
- ai->uai_alt_no);
- if (err)
- return (EINVAL);
- break;
- case USB_GET_NO_ALT:
- ai = (struct usb_alt_interface *)addr;
- cdesc = ugen_get_cdesc(sc, ai->uai_config_index, 0);
- if (cdesc == NULL)
- return (EINVAL);
- idesc = usbd_find_idesc(cdesc, ai->uai_interface_index, 0);
- if (idesc == NULL) {
- free(cdesc, M_TEMP);
- return (EINVAL);
- }
- ai->uai_alt_no = usbd_get_no_alts(cdesc,
- idesc->bInterfaceNumber);
- free(cdesc, M_TEMP);
- break;
- case USB_GET_DEVICE_DESC:
- *(usb_device_descriptor_t *)addr =
- *usbd_get_device_descriptor(sc->sc_udev);
- break;
- case USB_GET_CONFIG_DESC:
- cd = (struct usb_config_desc *)addr;
- cdesc = ugen_get_cdesc(sc, cd->ucd_config_index, 0);
- if (cdesc == NULL)
- return (EINVAL);
- cd->ucd_desc = *cdesc;
- free(cdesc, M_TEMP);
- break;
- case USB_GET_INTERFACE_DESC:
- id = (struct usb_interface_desc *)addr;
- cdesc = ugen_get_cdesc(sc, id->uid_config_index, 0);
- if (cdesc == NULL)
- return (EINVAL);
- if (id->uid_config_index == USB_CURRENT_CONFIG_INDEX &&
- id->uid_alt_index == USB_CURRENT_ALT_INDEX)
- alt = ugen_get_alt_index(sc, id->uid_interface_index);
- else
- alt = id->uid_alt_index;
- idesc = usbd_find_idesc(cdesc, id->uid_interface_index, alt);
- if (idesc == NULL) {
- free(cdesc, M_TEMP);
- return (EINVAL);
- }
- id->uid_desc = *idesc;
- free(cdesc, M_TEMP);
- break;
- case USB_GET_ENDPOINT_DESC:
- ed = (struct usb_endpoint_desc *)addr;
- cdesc = ugen_get_cdesc(sc, ed->ued_config_index, 0);
- if (cdesc == NULL)
- return (EINVAL);
- if (ed->ued_config_index == USB_CURRENT_CONFIG_INDEX &&
- ed->ued_alt_index == USB_CURRENT_ALT_INDEX)
- alt = ugen_get_alt_index(sc, ed->ued_interface_index);
- else
- alt = ed->ued_alt_index;
- edesc = usbd_find_edesc(cdesc, ed->ued_interface_index,
- alt, ed->ued_endpoint_index);
- if (edesc == NULL) {
- free(cdesc, M_TEMP);
- return (EINVAL);
- }
- ed->ued_desc = *edesc;
- free(cdesc, M_TEMP);
- break;
- case USB_GET_FULL_DESC:
- {
- int len;
- struct iovec iov;
- struct uio uio;
- struct usb_full_desc *fd = (struct usb_full_desc *)addr;
- int error;
-
- cdesc = ugen_get_cdesc(sc, fd->ufd_config_index, &len);
- if (len > fd->ufd_size)
- len = fd->ufd_size;
- iov.iov_base = (caddr_t)fd->ufd_data;
- iov.iov_len = len;
- uio.uio_iov = &iov;
- uio.uio_iovcnt = 1;
- uio.uio_resid = len;
- uio.uio_offset = 0;
- uio.uio_segflg = UIO_USERSPACE;
- uio.uio_rw = UIO_READ;
- uio.uio_td = p;
- error = uiomove((void *)cdesc, len, &uio);
- free(cdesc, M_TEMP);
- return (error);
- }
- case USB_GET_STRING_DESC: {
- int len;
- si = (struct usb_string_desc *)addr;
- err = usbd_get_string_desc(sc->sc_udev, si->usd_string_index,
- si->usd_language_id, &si->usd_desc, &len);
- if (err)
- return (EINVAL);
- break;
- }
- case USB_DO_REQUEST:
- {
- struct usb_ctl_request *ur = (void *)addr;
- int len = UGETW(ur->ucr_request.wLength);
- struct iovec iov;
- struct uio uio;
- void *ptr = 0;
- int error = 0;
-
- if (!(flag & FWRITE))
- return (EPERM);
- /* Avoid requests that would damage the bus integrity. */
- if ((ur->ucr_request.bmRequestType == UT_WRITE_DEVICE &&
- ur->ucr_request.bRequest == UR_SET_ADDRESS) ||
- (ur->ucr_request.bmRequestType == UT_WRITE_DEVICE &&
- ur->ucr_request.bRequest == UR_SET_CONFIG) ||
- (ur->ucr_request.bmRequestType == UT_WRITE_INTERFACE &&
- ur->ucr_request.bRequest == UR_SET_INTERFACE))
- return (EINVAL);
-
- if (len < 0 || len > 32767)
- return (EINVAL);
- if (len != 0) {
- iov.iov_base = (caddr_t)ur->ucr_data;
- iov.iov_len = len;
- uio.uio_iov = &iov;
- uio.uio_iovcnt = 1;
- uio.uio_resid = len;
- uio.uio_offset = 0;
- uio.uio_segflg = UIO_USERSPACE;
- uio.uio_rw =
- ur->ucr_request.bmRequestType & UT_READ ?
- UIO_READ : UIO_WRITE;
- uio.uio_td = p;
- ptr = malloc(len, M_TEMP, M_WAITOK);
- if (uio.uio_rw == UIO_WRITE) {
- error = uiomove(ptr, len, &uio);
- if (error)
- goto ret;
- }
- }
- sce = &sc->sc_endpoints[endpt][IN];
- err = usbd_do_request_flags(sc->sc_udev, &ur->ucr_request,
- ptr, ur->ucr_flags, &ur->ucr_actlen, sce->timeout);
- if (err) {
- error = EIO;
- goto ret;
- }
- if (len != 0) {
- if (uio.uio_rw == UIO_READ) {
- error = uiomove(ptr, len, &uio);
- if (error)
- goto ret;
- }
- }
- ret:
- if (ptr)
- free(ptr, M_TEMP);
- return (error);
- }
- case USB_GET_DEVICEINFO:
- usbd_fill_deviceinfo(sc->sc_udev,
- (struct usb_device_info *)addr, 1);
- break;
- case USB_RESET_DEVICE:
- err = usbd_reset_device(sc->sc_udev);
- if (err)
- return EIO;
- break;
- default:
- return (EINVAL);
- }
- return (0);
-}
-
-int
-ugenioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
- struct thread *p)
-{
- int endpt = UGENENDPOINT(dev);
- struct ugen_softc *sc;
- int error;
-
- sc = devclass_get_softc(ugen_devclass, UGENUNIT(dev));
-
- if (sc->sc_dying)
- return (EIO);
-
- UGEN_DEV_REF(dev, sc);
- error = ugen_do_ioctl(sc, endpt, cmd, addr, flag, p);
- UGEN_DEV_RELE(dev, sc);
- return (error);
-}
-
-int
-ugenpoll(struct cdev *dev, int events, struct thread *p)
-{
- struct ugen_softc *sc;
- struct ugen_endpoint *sce_in, *sce_out;
- usb_endpoint_descriptor_t *edesc;
- int revents = 0;
- int s;
-
- sc = devclass_get_softc(ugen_devclass, UGENUNIT(dev));
-
- if (sc->sc_dying)
- return ((events & (POLLIN | POLLOUT | POLLRDNORM |
- POLLWRNORM)) | POLLHUP);
- /* Do not allow to poll a control endpoint */
- if (UGENENDPOINT(dev) == USB_CONTROL_ENDPOINT)
- return (events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM));
-
- sce_in = &sc->sc_endpoints[UGENENDPOINT(dev)][IN];
- sce_out = &sc->sc_endpoints[UGENENDPOINT(dev)][OUT];
- edesc = (sce_in->edesc != NULL) ? sce_in->edesc : sce_out->edesc;
- KASSERT(edesc != NULL, ("ugenpoll: NULL edesc"));
- if (sce_in->edesc == NULL || sce_in->pipeh == NULL)
- sce_in = NULL;
- if (sce_out->edesc == NULL || sce_out->pipeh == NULL)
- sce_out = NULL;
-
- s = splusb();
- switch (edesc->bmAttributes & UE_XFERTYPE) {
- case UE_INTERRUPT:
- if (sce_in != NULL && (events & (POLLIN | POLLRDNORM))) {
- if (sce_in->q.c_cc > 0)
- revents |= events & (POLLIN | POLLRDNORM);
- else
- selrecord(p, &sce_in->rsel);
- }
- if (sce_out != NULL && (events & (POLLOUT | POLLWRNORM))) {
- if (sce_out->q.c_cc > 0)
- revents |= events & (POLLOUT | POLLWRNORM);
- else
- selrecord(p, &sce_out->rsel);
- }
- break;
- case UE_ISOCHRONOUS:
- if (sce_in != NULL && (events & (POLLIN | POLLRDNORM))) {
- if (sce_in->cur != sce_in->fill)
- revents |= events & (POLLIN | POLLRDNORM);
- else
- selrecord(p, &sce_in->rsel);
- }
- if (sce_out != NULL && (events & (POLLOUT | POLLWRNORM))) {
- if (sce_out->cur != sce_out->fill)
- revents |= events & (POLLOUT | POLLWRNORM);
- else
- selrecord(p, &sce_out->rsel);
- }
- break;
- case UE_BULK:
- /*
- * We have no easy way of determining if a read will
- * yield any data or a write will happen.
- * Pretend they will.
- */
- revents |= events &
- (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM);
- break;
- default:
- break;
- }
- splx(s);
- return (revents);
-}
-
-DRIVER_MODULE(ugen, uhub, ugen_driver, ugen_devclass, usbd_driver_load, 0);
diff --git a/sys/dev/usb/ugraphire_rdesc.h b/sys/dev/usb/ugraphire_rdesc.h
deleted file mode 100644
index 9c5a0c1..0000000
--- a/sys/dev/usb/ugraphire_rdesc.h
+++ /dev/null
@@ -1,176 +0,0 @@
-/* $NetBSD: usb/ugraphire_rdesc.h,v 1.1 2000/12/29 01:47:49 augustss Exp $ */
-/* $FreeBSD$ */
-/*-
- * Copyright (c) 2000 Nick Hibma <n_hibma@freebsd.org>
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- */
-
-static const uByte uhid_graphire_report_descr[] = {
- 0x05, 0x0d, /* USAGE_PAGE (Digitizers) */
- 0x09, 0x01, /* USAGE (Digitizer) */
- 0xa1, 0x01, /* COLLECTION (Application) */
- 0x85, 0x02, /* REPORT_ID (2) */
- 0x05, 0x0d, /* USAGE_PAGE (Digitizers) */
- 0x09, 0x01, /* USAGE (Digitizer) */
- 0xa1, 0x00, /* COLLECTION (Physical) */
- 0x15, 0x00, /* LOGICAL_MINIMUM (0) */
- 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
- 0x09, 0x33, /* USAGE (Touch) */
- 0x95, 0x01, /* REPORT_COUNT (1) */
- 0x75, 0x01, /* REPORT_SIZE (1) */
- 0x81, 0x02, /* INPUT (Data,Var,Abs) */
- 0x09, 0x44, /* USAGE (Barrel Switch) */
- 0x95, 0x02, /* REPORT_COUNT (2) */
- 0x75, 0x01, /* REPORT_SIZE (1) */
- 0x81, 0x02, /* INPUT (Data,Var,Abs) */
- 0x09, 0x00, /* USAGE (Undefined) */
- 0x95, 0x02, /* REPORT_COUNT (2) */
- 0x75, 0x01, /* REPORT_SIZE (1) */
- 0x81, 0x03, /* INPUT (Cnst,Var,Abs) */
- 0x09, 0x3c, /* USAGE (Invert) */
- 0x95, 0x01, /* REPORT_COUNT (1) */
- 0x75, 0x01, /* REPORT_SIZE (1) */
- 0x81, 0x02, /* INPUT (Data,Var,Abs) */
- 0x09, 0x38, /* USAGE (Transducer Index) */
- 0x95, 0x01, /* REPORT_COUNT (1) */
- 0x75, 0x01, /* REPORT_SIZE (1) */
- 0x81, 0x02, /* INPUT (Data,Var,Abs) */
- 0x09, 0x32, /* USAGE (In Range) */
- 0x95, 0x01, /* REPORT_COUNT (1) */
- 0x75, 0x01, /* REPORT_SIZE (1) */
- 0x81, 0x02, /* INPUT (Data,Var,Abs) */
- 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */
- 0x09, 0x30, /* USAGE (X) */
- 0x15, 0x00, /* LOGICAL_MINIMUM (0) */
- 0x26, 0xde, 0x27, /* LOGICAL_MAXIMUM (10206) */
- 0x95, 0x01, /* REPORT_COUNT (1) */
- 0x75, 0x10, /* REPORT_SIZE (16) */
- 0x81, 0x02, /* INPUT (Data,Var,Abs) */
- 0x09, 0x31, /* USAGE (Y) */
- 0x26, 0xfe, 0x1c, /* LOGICAL_MAXIMUM (7422) */
- 0x95, 0x01, /* REPORT_COUNT (1) */
- 0x75, 0x10, /* REPORT_SIZE (16) */
- 0x81, 0x02, /* INPUT (Data,Var,Abs) */
- 0x05, 0x0d, /* USAGE_PAGE (Digitizers) */
- 0x09, 0x30, /* USAGE (Tip Pressure) */
- 0x26, 0xff, 0x01, /* LOGICAL_MAXIMUM (511) */
- 0x95, 0x01, /* REPORT_COUNT (1) */
- 0x75, 0x10, /* REPORT_SIZE (16) */
- 0x81, 0x02, /* INPUT (Data,Var,Abs) */
- 0xc0, /* END_COLLECTION */
- 0x05, 0x0d, /* USAGE_PAGE (Digitizers) */
- 0x09, 0x00, /* USAGE (Undefined) */
- 0x85, 0x02, /* REPORT_ID (2) */
- 0x95, 0x01, /* REPORT_COUNT (1) */
- 0xb1, 0x02, /* FEATURE (Data,Var,Abs) */
- 0x09, 0x00, /* USAGE (Undefined) */
- 0x85, 0x03, /* REPORT_ID (3) */
- 0x95, 0x01, /* REPORT_COUNT (1) */
- 0xb1, 0x02, /* FEATURE (Data,Var,Abs) */
- 0xc0, /* END_COLLECTION */
-};
-
-static const uByte uhid_graphire3_4x5_report_descr[] = {
- 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */
- 0x09, 0x02, /* USAGE (Mouse) */
- 0xa1, 0x01, /* COLLECTION (Application) */
- 0x85, 0x01, /* REPORT_ID (1) */
- 0x09, 0x01, /* USAGE (Pointer) */
- 0xa1, 0x00, /* COLLECTION (Physical) */
- 0x05, 0x09, /* USAGE_PAGE (Button) */
- 0x19, 0x01, /* USAGE_MINIMUM (Button 1) */
- 0x29, 0x03, /* USAGE_MAXIMUM (Button 3) */
- 0x15, 0x00, /* LOGICAL_MINIMUM (0) */
- 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
- 0x95, 0x03, /* REPORT_COUNT (3) */
- 0x75, 0x01, /* REPORT_SIZE (1) */
- 0x81, 0x02, /* INPUT (Data,Var,Abs) */
- 0x95, 0x01, /* REPORT_COUNT (1) */
- 0x75, 0x05, /* REPORT_SIZE (5) */
- 0x81, 0x01, /* INPUT (Cnst,Ary,Abs) */
- 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */
- 0x09, 0x30, /* USAGE (X) */
- 0x09, 0x31, /* USAGE (Y) */
- 0x09, 0x38, /* USAGE (Wheel) */
- 0x15, 0x81, /* LOGICAL_MINIMUM (-127) */
- 0x25, 0x7f, /* LOGICAL_MAXIMUM (127) */
- 0x75, 0x08, /* REPORT_SIZE (8) */
- 0x95, 0x03, /* REPORT_COUNT (3) */
- 0x81, 0x06, /* INPUT (Data,Var,Rel) */
- 0xc0, /* END_COLLECTION */
- 0xc0, /* END_COLLECTION */
- 0x05, 0x0d, /* USAGE_PAGE (Digitizers) */
- 0x09, 0x01, /* USAGE (Pointer) */
- 0xa1, 0x01, /* COLLECTION (Applicaption) */
- 0x85, 0x02, /* REPORT_ID (2) */
- 0x05, 0x0d, /* USAGE_PAGE (Digitizers) */
- 0x09, 0x01, /* USAGE (Digitizer) */
- 0xa1, 0x00, /* COLLECTION (Physical) */
- 0x09, 0x33, /* USAGE (Touch) */
- 0x09, 0x44, /* USAGE (Barrel Switch) */
- 0x09, 0x44, /* USAGE (Barrel Switch) */
- 0x15, 0x00, /* LOGICAL_MINIMUM (0) */
- 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
- 0x75, 0x01, /* REPORT_SIZE (1) */
- 0x95, 0x03, /* REPORT_COUNT (3) */
- 0x81, 0x02, /* INPUT (Data,Var,Abs) */
- 0x75, 0x01, /* REPORT_SIZE (1) */
- 0x95, 0x02, /* REPORT_COUNT (2) */
- 0x81, 0x01, /* INPUT (Cnst,Ary,Abs) */
- 0x09, 0x3c, /* USAGE (Invert) */
- 0x09, 0x38, /* USAGE (Transducer Index) */
- 0x09, 0x32, /* USAGE (In Range) */
- 0x75, 0x01, /* REPORT_SIZE (1) */
- 0x95, 0x03, /* REPORT_COUNT (3) */
- 0x81, 0x02, /* INPUT (Data,Var,Abs) */
- 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */
- 0x09, 0x30, /* USAGE (X) */
- 0x15, 0x00, /* LOGICAL_MINIMUM (0) */
- 0x26, 0xde, 0x27, /* LOGICAL_MAXIMUM (10206) */
- 0x75, 0x10, /* REPORT_SIZE (16) */
- 0x95, 0x01, /* REPORT_COUNT (1) */
- 0x81, 0x02, /* INPUT (Data,Var,Abs) */
- 0x09, 0x31, /* USAGE (Y) */
- 0x26, 0xfe, 0x1c, /* LOGICAL_MAXIMUM (7422) */
- 0x75, 0x10, /* REPORT_SIZE (16) */
- 0x95, 0x01, /* REPORT_COUNT (1) */
- 0x81, 0x02, /* INPUT (Data,Var,Abs) */
- 0x05, 0x0d, /* USAGE_PAGE (Digitizers) */
- 0x09, 0x30, /* USAGE (Tip Pressure) */
- 0x26, 0xff, 0x01, /* LOGICAL_MAXIMUM (511) */
- 0x75, 0x10, /* REPORT_SIZE (16) */
- 0x95, 0x01, /* REPORT_COUNT (1) */
- 0x81, 0x02, /* INPUT (Data,Var,Abs) */
- 0xc0, /* END_COLLECTION */
- 0x05, 0x0d, /* USAGE_PAGE (Digitizers) */
- 0x09, 0x00, /* USAGE (Undefined) */
- 0x85, 0x02, /* REPORT_ID (2) */
- 0x95, 0x01, /* REPORT_COUNT (1) */
- 0xb1, 0x02, /* FEATURE (Data,Var,Abs) */
- 0x09, 0x00, /* USAGE (Undefined) */
- 0x85, 0x03, /* REPORT_ID (3) */
- 0x95, 0x01, /* REPORT_COUNT (1) */
- 0xb1, 0x02, /* FEATURE (Data,Var,Abs) */
- 0xc0 /* END_COLLECTION */
-};
diff --git a/sys/dev/usb/uhci.c b/sys/dev/usb/uhci.c
deleted file mode 100644
index 4d4c61b..0000000
--- a/sys/dev/usb/uhci.c
+++ /dev/null
@@ -1,3704 +0,0 @@
-/* $NetBSD: uhci.c,v 1.170 2003/02/19 01:35:04 augustss Exp $ */
-
-/* Also already incorporated from NetBSD:
- * $NetBSD: uhci.c,v 1.172 2003/02/23 04:19:26 simonb Exp $
- * $NetBSD: uhci.c,v 1.173 2003/05/13 04:41:59 gson Exp $
- * $NetBSD: uhci.c,v 1.175 2003/09/12 16:18:08 mycroft Exp $
- * $NetBSD: uhci.c,v 1.176 2003/11/04 19:11:21 mycroft Exp $
- * $NetBSD: uhci.c,v 1.177 2003/12/29 08:17:10 toshii Exp $
- * $NetBSD: uhci.c,v 1.178 2004/03/02 16:32:05 martin Exp $
- * $NetBSD: uhci.c,v 1.180 2004/07/17 20:12:03 mycroft Exp $
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) 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.
- */
-
-/*
- * USB Universal Host Controller driver.
- * Handles e.g. PIIX3 and PIIX4.
- *
- * UHCI spec: http://developer.intel.com/design/USB/UHCI11D.htm
- * USB spec: http://www.usb.org/developers/docs/usbspec.zip
- * PIIXn spec: ftp://download.intel.com/design/intarch/datashts/29055002.pdf
- * ftp://download.intel.com/design/intarch/datashts/29056201.pdf
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/endian.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#if defined(DIAGNOSTIC) && defined(__i386__)
-#include <machine/cpu.h>
-#endif
-#include <sys/proc.h>
-#include <sys/queue.h>
-#include <sys/sysctl.h>
-
-#include <machine/bus.h>
-#include <machine/endian.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdivar.h>
-#include <dev/usb/usb_mem.h>
-#include <dev/usb/usb_quirks.h>
-
-#include <dev/usb/uhcireg.h>
-#include <dev/usb/uhcivar.h>
-
-/* Use bandwidth reclamation for control transfers. Some devices choke on it. */
-/*#define UHCI_CTL_LOOP */
-
-#define delay(d) DELAY(d)
-
-#define MS_TO_TICKS(ms) ((ms) * hz / 1000)
-
-#ifdef USB_DEBUG
-uhci_softc_t *thesc;
-#define DPRINTF(x) if (uhcidebug) printf x
-#define DPRINTFN(n,x) if (uhcidebug>(n)) printf x
-int uhcidebug = 0;
-int uhcinoloop = 0;
-SYSCTL_NODE(_hw_usb, OID_AUTO, uhci, CTLFLAG_RW, 0, "USB uhci");
-SYSCTL_INT(_hw_usb_uhci, OID_AUTO, debug, CTLFLAG_RW,
- &uhcidebug, 0, "uhci debug level");
-SYSCTL_INT(_hw_usb_uhci, OID_AUTO, loop, CTLFLAG_RW,
- &uhcinoloop, 0, "uhci noloop");
-#define bitmask_snprintf(q,f,b,l) snprintf((b), (l), "%b", (q), (f))
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-struct uhci_pipe {
- struct usbd_pipe pipe;
- int nexttoggle;
-
- u_char aborting;
- usbd_xfer_handle abortstart, abortend;
-
- /* Info needed for different pipe kinds. */
- union {
- /* Control pipe */
- struct {
- uhci_soft_qh_t *sqh;
- usb_dma_t reqdma;
- uhci_soft_td_t *setup, *stat;
- u_int length;
- } ctl;
- /* Interrupt pipe */
- struct {
- int npoll;
- int isread;
- uhci_soft_qh_t **qhs;
- } intr;
- /* Bulk pipe */
- struct {
- uhci_soft_qh_t *sqh;
- u_int length;
- int isread;
- } bulk;
- /* Iso pipe */
- struct iso {
- uhci_soft_td_t **stds;
- int next, inuse;
- } iso;
- } u;
-};
-
-static void uhci_globalreset(uhci_softc_t *);
-static usbd_status uhci_portreset(uhci_softc_t*, int);
-static void uhci_reset(uhci_softc_t *);
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-static void uhci_shutdown(void *v);
-static void uhci_power(int, void *);
-#endif
-static usbd_status uhci_run(uhci_softc_t *, int run);
-static uhci_soft_td_t *uhci_alloc_std(uhci_softc_t *);
-static void uhci_free_std(uhci_softc_t *, uhci_soft_td_t *);
-static uhci_soft_qh_t *uhci_alloc_sqh(uhci_softc_t *);
-static void uhci_free_sqh(uhci_softc_t *, uhci_soft_qh_t *);
-static usbd_status uhci_aux_dma_alloc(uhci_softc_t *, uhci_soft_td_t *,
- void *data, int len);
-static uhci_physaddr_t uhci_aux_dma_prepare(uhci_soft_td_t *, int);
-static void uhci_aux_dma_complete(uhci_soft_td_t *, int);
-#if 0
-static void uhci_enter_ctl_q(uhci_softc_t *, uhci_soft_qh_t *,
- uhci_intr_info_t *);
-static void uhci_exit_ctl_q(uhci_softc_t *, uhci_soft_qh_t *);
-#endif
-
-static void uhci_free_std_chain(uhci_softc_t *,
- uhci_soft_td_t *, uhci_soft_td_t *);
-static usbd_status uhci_alloc_std_chain(struct uhci_pipe *,
- uhci_softc_t *, int, int, u_int16_t,
- usbd_xfer_handle xfer,
- uhci_soft_td_t **, uhci_soft_td_t **);
-static void uhci_poll_hub(void *);
-static void uhci_waitintr(uhci_softc_t *, usbd_xfer_handle);
-static void uhci_check_intr(uhci_softc_t *, uhci_intr_info_t *);
-static void uhci_idone(uhci_intr_info_t *);
-
-static void uhci_abort_xfer(usbd_xfer_handle, usbd_status status);
-static void uhci_transfer_complete(usbd_xfer_handle xfer);
-
-static void uhci_timeout(void *);
-static void uhci_timeout_task(void *);
-static void uhci_add_ls_ctrl(uhci_softc_t *, uhci_soft_qh_t *);
-static void uhci_add_hs_ctrl(uhci_softc_t *, uhci_soft_qh_t *);
-static void uhci_add_bulk(uhci_softc_t *, uhci_soft_qh_t *);
-static void uhci_remove_ls_ctrl(uhci_softc_t *,uhci_soft_qh_t *);
-static void uhci_remove_hs_ctrl(uhci_softc_t *,uhci_soft_qh_t *);
-static void uhci_remove_bulk(uhci_softc_t *,uhci_soft_qh_t *);
-static int uhci_str(usb_string_descriptor_t *, int, char *);
-static void uhci_add_loop(uhci_softc_t *sc);
-static void uhci_rem_loop(uhci_softc_t *sc);
-
-static usbd_status uhci_setup_isoc(usbd_pipe_handle pipe);
-static void uhci_device_isoc_enter(usbd_xfer_handle);
-
-static usbd_status uhci_allocm(struct usbd_bus *, usb_dma_t *, u_int32_t);
-static void uhci_freem(struct usbd_bus *, usb_dma_t *);
-
-static usbd_xfer_handle uhci_allocx(struct usbd_bus *);
-static void uhci_freex(struct usbd_bus *, usbd_xfer_handle);
-
-static usbd_status uhci_device_ctrl_transfer(usbd_xfer_handle);
-static usbd_status uhci_device_ctrl_start(usbd_xfer_handle);
-static void uhci_device_ctrl_abort(usbd_xfer_handle);
-static void uhci_device_ctrl_close(usbd_pipe_handle);
-static void uhci_device_ctrl_done(usbd_xfer_handle);
-
-static usbd_status uhci_device_intr_transfer(usbd_xfer_handle);
-static usbd_status uhci_device_intr_start(usbd_xfer_handle);
-static void uhci_device_intr_abort(usbd_xfer_handle);
-static void uhci_device_intr_close(usbd_pipe_handle);
-static void uhci_device_intr_done(usbd_xfer_handle);
-
-static usbd_status uhci_device_bulk_transfer(usbd_xfer_handle);
-static usbd_status uhci_device_bulk_start(usbd_xfer_handle);
-static void uhci_device_bulk_abort(usbd_xfer_handle);
-static void uhci_device_bulk_close(usbd_pipe_handle);
-static void uhci_device_bulk_done(usbd_xfer_handle);
-
-static usbd_status uhci_device_isoc_transfer(usbd_xfer_handle);
-static usbd_status uhci_device_isoc_start(usbd_xfer_handle);
-static void uhci_device_isoc_abort(usbd_xfer_handle);
-static void uhci_device_isoc_close(usbd_pipe_handle);
-static void uhci_device_isoc_done(usbd_xfer_handle);
-
-static usbd_status uhci_root_ctrl_transfer(usbd_xfer_handle);
-static usbd_status uhci_root_ctrl_start(usbd_xfer_handle);
-static void uhci_root_ctrl_abort(usbd_xfer_handle);
-static void uhci_root_ctrl_close(usbd_pipe_handle);
-static void uhci_root_ctrl_done(usbd_xfer_handle);
-
-static usbd_status uhci_root_intr_transfer(usbd_xfer_handle);
-static usbd_status uhci_root_intr_start(usbd_xfer_handle);
-static void uhci_root_intr_abort(usbd_xfer_handle);
-static void uhci_root_intr_close(usbd_pipe_handle);
-static void uhci_root_intr_done(usbd_xfer_handle);
-
-static usbd_status uhci_open(usbd_pipe_handle);
-static void uhci_poll(struct usbd_bus *);
-static void uhci_softintr(void *);
-
-static usbd_status uhci_device_request(usbd_xfer_handle xfer);
-
-static void uhci_add_intr(uhci_softc_t *, uhci_soft_qh_t *);
-static void uhci_remove_intr(uhci_softc_t *, uhci_soft_qh_t *);
-static usbd_status uhci_device_setintr(uhci_softc_t *sc,
- struct uhci_pipe *pipe, int ival);
-
-static void uhci_device_clear_toggle(usbd_pipe_handle pipe);
-static void uhci_noop(usbd_pipe_handle pipe);
-
-static __inline uhci_soft_qh_t *uhci_find_prev_qh(uhci_soft_qh_t *,
- uhci_soft_qh_t *);
-
-#ifdef USB_DEBUG
-static void uhci_dump_all(uhci_softc_t *);
-static void uhci_dumpregs(uhci_softc_t *);
-static void uhci_dump_qhs(uhci_soft_qh_t *);
-static void uhci_dump_qh(uhci_soft_qh_t *);
-static void uhci_dump_tds(uhci_soft_td_t *);
-static void uhci_dump_td(uhci_soft_td_t *);
-static void uhci_dump_ii(uhci_intr_info_t *ii);
-void uhci_dump(void);
-#endif
-
-#define UBARR(sc) bus_space_barrier((sc)->iot, (sc)->ioh, 0, (sc)->sc_size, \
- BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE)
-#define UWRITE1(sc, r, x) \
- do { UBARR(sc); bus_space_write_1((sc)->iot, (sc)->ioh, (r), (x)); \
- } while (/*CONSTCOND*/0)
-#define UWRITE2(sc, r, x) \
- do { UBARR(sc); bus_space_write_2((sc)->iot, (sc)->ioh, (r), (x)); \
- } while (/*CONSTCOND*/0)
-#define UWRITE4(sc, r, x) \
- do { UBARR(sc); bus_space_write_4((sc)->iot, (sc)->ioh, (r), (x)); \
- } while (/*CONSTCOND*/0)
-#define UREAD1(sc, r) (UBARR(sc), bus_space_read_1((sc)->iot, (sc)->ioh, (r)))
-#define UREAD2(sc, r) (UBARR(sc), bus_space_read_2((sc)->iot, (sc)->ioh, (r)))
-#define UREAD4(sc, r) (UBARR(sc), bus_space_read_4((sc)->iot, (sc)->ioh, (r)))
-
-#define UHCICMD(sc, cmd) UWRITE2(sc, UHCI_CMD, cmd)
-#define UHCISTS(sc) UREAD2(sc, UHCI_STS)
-
-#define UHCI_RESET_TIMEOUT 100 /* ms, reset timeout */
-
-#define UHCI_CURFRAME(sc) (UREAD2(sc, UHCI_FRNUM) & UHCI_FRNUM_MASK)
-
-#define UHCI_INTR_ENDPT 1
-
-struct usbd_bus_methods uhci_bus_methods = {
- uhci_open,
- uhci_softintr,
- uhci_poll,
- uhci_allocm,
- uhci_freem,
- uhci_allocx,
- uhci_freex,
-};
-
-struct usbd_pipe_methods uhci_root_ctrl_methods = {
- uhci_root_ctrl_transfer,
- uhci_root_ctrl_start,
- uhci_root_ctrl_abort,
- uhci_root_ctrl_close,
- uhci_noop,
- uhci_root_ctrl_done,
-};
-
-struct usbd_pipe_methods uhci_root_intr_methods = {
- uhci_root_intr_transfer,
- uhci_root_intr_start,
- uhci_root_intr_abort,
- uhci_root_intr_close,
- uhci_noop,
- uhci_root_intr_done,
-};
-
-struct usbd_pipe_methods uhci_device_ctrl_methods = {
- uhci_device_ctrl_transfer,
- uhci_device_ctrl_start,
- uhci_device_ctrl_abort,
- uhci_device_ctrl_close,
- uhci_noop,
- uhci_device_ctrl_done,
-};
-
-struct usbd_pipe_methods uhci_device_intr_methods = {
- uhci_device_intr_transfer,
- uhci_device_intr_start,
- uhci_device_intr_abort,
- uhci_device_intr_close,
- uhci_device_clear_toggle,
- uhci_device_intr_done,
-};
-
-struct usbd_pipe_methods uhci_device_bulk_methods = {
- uhci_device_bulk_transfer,
- uhci_device_bulk_start,
- uhci_device_bulk_abort,
- uhci_device_bulk_close,
- uhci_device_clear_toggle,
- uhci_device_bulk_done,
-};
-
-struct usbd_pipe_methods uhci_device_isoc_methods = {
- uhci_device_isoc_transfer,
- uhci_device_isoc_start,
- uhci_device_isoc_abort,
- uhci_device_isoc_close,
- uhci_noop,
- 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) \
- do { \
- LIST_REMOVE((ii), list); \
- (ii)->list.le_prev = NULL; \
- } while (0)
-#define uhci_active_intr_info(ii) ((ii)->list.le_prev != NULL)
-
-static __inline uhci_soft_qh_t *
-uhci_find_prev_qh(uhci_soft_qh_t *pqh, uhci_soft_qh_t *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(USB_DEBUG)
- if (le32toh(pqh->qh.qh_hlink) & UHCI_PTR_T) {
- printf("uhci_find_prev_qh: QH not found\n");
- return (NULL);
- }
-#endif
- }
- return (pqh);
-}
-
-void
-uhci_globalreset(uhci_softc_t *sc)
-{
- UHCICMD(sc, UHCI_CMD_GRESET); /* global reset */
- usb_delay_ms(&sc->sc_bus, USB_BUS_RESET_DELAY); /* wait a little */
- UHCICMD(sc, 0); /* do nothing */
-}
-
-usbd_status
-uhci_init(uhci_softc_t *sc)
-{
- usbd_status err;
- int i, j;
- uhci_soft_qh_t *clsqh, *chsqh, *bsqh, *sqh, *lsqh;
- uhci_soft_td_t *std;
-
- DPRINTFN(1,("uhci_init: start\n"));
-
-#ifdef USB_DEBUG
- thesc = sc;
-
- if (uhcidebug > 2)
- uhci_dumpregs(sc);
-#endif
-
- UWRITE2(sc, UHCI_INTR, 0); /* disable interrupts */
- uhci_globalreset(sc); /* reset the controller */
- uhci_reset(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);
- if (err)
- return (err);
- sc->sc_pframes = KERNADDR(&sc->sc_dma, 0);
- UWRITE2(sc, UHCI_FRNUM, 0); /* set frame number to 0 */
- UWRITE4(sc, UHCI_FLBASEADDR, DMAADDR(&sc->sc_dma, 0)); /* set frame list*/
-
- /*
- * Allocate a TD, inactive, that hangs from the last QH.
- * This is to avoid a bug in the PIIX that makes it run berserk
- * otherwise.
- */
- std = uhci_alloc_std(sc);
- if (std == NULL)
- return (USBD_NOMEM);
- std->link.std = NULL;
- std->td.td_link = htole32(UHCI_PTR_T);
- std->td.td_status = htole32(0); /* inactive */
- std->td.td_token = htole32(0);
- std->td.td_buffer = htole32(0);
-
- /* Allocate the dummy QH marking the end and used for looping the QHs.*/
- lsqh = uhci_alloc_sqh(sc);
- if (lsqh == NULL)
- return (USBD_NOMEM);
- lsqh->hlink = NULL;
- lsqh->qh.qh_hlink = htole32(UHCI_PTR_T); /* end of QH chain */
- lsqh->elink = std;
- lsqh->qh.qh_elink = htole32(std->physaddr | UHCI_PTR_TD);
- sc->sc_last_qh = lsqh;
-
- /* Allocate the dummy QH where bulk traffic will be queued. */
- bsqh = uhci_alloc_sqh(sc);
- if (bsqh == NULL)
- return (USBD_NOMEM);
- bsqh->hlink = lsqh;
- bsqh->qh.qh_hlink = htole32(lsqh->physaddr | UHCI_PTR_QH);
- bsqh->elink = NULL;
- bsqh->qh.qh_elink = htole32(UHCI_PTR_T);
- sc->sc_bulk_start = sc->sc_bulk_end = bsqh;
-
- /* Allocate dummy QH where high speed control traffic will be queued. */
- chsqh = uhci_alloc_sqh(sc);
- if (chsqh == NULL)
- return (USBD_NOMEM);
- chsqh->hlink = bsqh;
- chsqh->qh.qh_hlink = htole32(bsqh->physaddr | UHCI_PTR_QH);
- chsqh->elink = NULL;
- chsqh->qh.qh_elink = htole32(UHCI_PTR_T);
- sc->sc_hctl_start = sc->sc_hctl_end = chsqh;
-
- /* Allocate dummy QH where control traffic will be queued. */
- clsqh = uhci_alloc_sqh(sc);
- if (clsqh == NULL)
- return (USBD_NOMEM);
- clsqh->hlink = chsqh;
- clsqh->qh.qh_hlink = htole32(chsqh->physaddr | UHCI_PTR_QH);
- clsqh->elink = NULL;
- clsqh->qh.qh_elink = htole32(UHCI_PTR_T);
- sc->sc_lctl_start = sc->sc_lctl_end = clsqh;
-
- /*
- * Make all (virtual) frame list pointers point to the interrupt
- * queue heads and the interrupt queue heads at the control
- * queue head and point the physical frame list to the virtual.
- */
- for(i = 0; i < UHCI_VFRAMELIST_COUNT; i++) {
- std = uhci_alloc_std(sc);
- sqh = uhci_alloc_sqh(sc);
- if (std == NULL || sqh == NULL)
- return (USBD_NOMEM);
- std->link.sqh = sqh;
- std->td.td_link = htole32(sqh->physaddr | UHCI_PTR_QH);
- std->td.td_status = htole32(UHCI_TD_IOS); /* iso, inactive */
- std->td.td_token = htole32(0);
- std->td.td_buffer = htole32(0);
- sqh->hlink = clsqh;
- sqh->qh.qh_hlink = htole32(clsqh->physaddr | UHCI_PTR_QH);
- sqh->elink = NULL;
- 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;
- sc->sc_vframes[i].eqh = sqh;
- for (j = i;
- j < UHCI_FRAMELIST_COUNT;
- j += UHCI_VFRAMELIST_COUNT)
- sc->sc_pframes[j] = htole32(std->physaddr);
- }
-
- LIST_INIT(&sc->sc_intrhead);
-
- STAILQ_INIT(&sc->sc_free_xfers);
-
- callout_init(&sc->sc_poll_handle, 0);
-
- /* 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 |
- UHCI_INTR_IOCE | UHCI_INTR_SPIE); /* enable interrupts */
-
- UHCICMD(sc, UHCI_CMD_MAXP); /* Assume 64 byte packets at frame end */
-
- return (uhci_run(sc, 1)); /* and here we go... */
-}
-
-int
-uhci_detach(struct uhci_softc *sc, int flags)
-{
- usbd_xfer_handle xfer;
- int rv = 0;
-
- sc->sc_dying = 1;
-
- UWRITE2(sc, UHCI_INTR, 0); /* disable interrupts */
- uhci_run(sc, 0);
-
-#if defined(__NetBSD__) || defined(__OpenBSD__)
- powerhook_disestablish(sc->sc_powerhook);
- shutdownhook_disestablish(sc->sc_shutdownhook);
-#endif
-
- /* Free all xfers associated with this HC. */
- for (;;) {
- xfer = STAILQ_FIRST(&sc->sc_free_xfers);
- if (xfer == NULL)
- break;
- STAILQ_REMOVE_HEAD(&sc->sc_free_xfers, next);
- free(xfer, M_USB);
- }
-
- /* XXX free other data structures XXX */
- usb_freemem(&sc->sc_bus, &sc->sc_dma);
-
- return (rv);
-}
-
-usbd_status
-uhci_allocm(struct usbd_bus *bus, usb_dma_t *dma, u_int32_t size)
-{
- return (usb_allocmem(bus, size, 0, dma));
-}
-
-void
-uhci_freem(struct usbd_bus *bus, usb_dma_t *dma)
-{
- usb_freemem(bus, dma);
-}
-
-usbd_xfer_handle
-uhci_allocx(struct usbd_bus *bus)
-{
- struct uhci_softc *sc = (struct uhci_softc *)bus;
- usbd_xfer_handle xfer;
-
- xfer = STAILQ_FIRST(&sc->sc_free_xfers);
- if (xfer != NULL) {
- STAILQ_REMOVE_HEAD(&sc->sc_free_xfers, next);
-#ifdef DIAGNOSTIC
- if (xfer->busy_free != XFER_FREE) {
- printf("uhci_allocx: 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;
- usb_init_task(&UXFER(xfer)->abort_task, uhci_timeout_task,
- xfer);
- UXFER(xfer)->uhci_xfer_flags = 0;
-#ifdef DIAGNOSTIC
- UXFER(xfer)->iinfo.isdone = 1;
- xfer->busy_free = XFER_BUSY;
-#endif
- }
- return (xfer);
-}
-
-void
-uhci_freex(struct usbd_bus *bus, usbd_xfer_handle 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");
- return;
- }
-#endif
- STAILQ_INSERT_HEAD(&sc->sc_free_xfers, xfer, next);
-}
-
-/*
- * Shut down the controller when the system is going down.
- */
-void
-uhci_shutdown(void *v)
-{
- uhci_softc_t *sc = v;
-
- DPRINTF(("uhci_shutdown: stopping the HC\n"));
- uhci_run(sc, 0); /* stop the controller */
-}
-
-/*
- * 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
- * are almost suspended anyway.
- */
-void
-uhci_power(int why, void *v)
-{
- uhci_softc_t *sc = v;
- int cmd;
- int s;
-
- s = splhardusb();
- cmd = UREAD2(sc, UHCI_CMD);
-
- DPRINTF(("uhci_power: sc=%p, why=%d (was %d), cmd=0x%x\n",
- sc, why, sc->sc_suspend, cmd));
-
- if (why != PWR_RESUME) {
-#ifdef USB_DEBUG
- if (uhcidebug > 2)
- uhci_dumpregs(sc);
-#endif
- if (sc->sc_intr_xfer != NULL)
- callout_stop(&sc->sc_poll_handle);
- sc->sc_bus.use_polling++;
- uhci_run(sc, 0); /* stop the controller */
- cmd &= ~UHCI_CMD_RS;
-
- /* save some state if BIOS doesn't */
- sc->sc_saved_frnum = UREAD2(sc, UHCI_FRNUM);
- sc->sc_saved_sof = UREAD1(sc, UHCI_SOF);
-
- UWRITE2(sc, UHCI_INTR, 0); /* disable intrs */
-
- UHCICMD(sc, cmd | UHCI_CMD_EGSM); /* enter global suspend */
- usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT);
- sc->sc_suspend = why;
- sc->sc_bus.use_polling--;
- DPRINTF(("uhci_power: cmd=0x%x\n", UREAD2(sc, UHCI_CMD)));
- } else {
-#ifdef DIAGNOSTIC
- if (sc->sc_suspend == PWR_RESUME)
- printf("uhci_power: weird, resume without suspend.\n");
-#endif
- sc->sc_bus.use_polling++;
- sc->sc_suspend = why;
- UWRITE2(sc, UHCI_INTR, 0); /* disable interrupts */
- uhci_globalreset(sc); /* reset the controller */
- uhci_reset(sc);
- if (cmd & UHCI_CMD_RS)
- uhci_run(sc, 0); /* in case BIOS has started it */
-
- uhci_globalreset(sc);
- uhci_reset(sc);
-
- /* restore saved state */
- UWRITE4(sc, UHCI_FLBASEADDR, DMAADDR(&sc->sc_dma, 0));
- UWRITE2(sc, UHCI_FRNUM, sc->sc_saved_frnum);
- UWRITE1(sc, UHCI_SOF, sc->sc_saved_sof);
-
- UHCICMD(sc, cmd | UHCI_CMD_FGR); /* force global resume */
- usb_delay_ms(&sc->sc_bus, USB_RESUME_DELAY);
- UHCICMD(sc, cmd & ~UHCI_CMD_EGSM); /* back to normal */
- UWRITE2(sc, UHCI_INTR, UHCI_INTR_TOCRCIE | UHCI_INTR_RIE |
- UHCI_INTR_IOCE | UHCI_INTR_SPIE); /* re-enable intrs */
- UHCICMD(sc, UHCI_CMD_MAXP);
- 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_intr_xfer != NULL)
- callout_reset(&sc->sc_poll_handle, sc->sc_ival,
- uhci_poll_hub, sc->sc_intr_xfer);
-#ifdef USB_DEBUG
- if (uhcidebug > 2)
- uhci_dumpregs(sc);
-#endif
- }
- splx(s);
-}
-
-#ifdef USB_DEBUG
-static void
-uhci_dumpregs(uhci_softc_t *sc)
-{
- DPRINTFN(-1,("%s regs: cmd=%04x, sts=%04x, intr=%04x, frnum=%04x, "
- "flbase=%08x, sof=%04x, portsc1=%04x, portsc2=%04x\n",
- device_get_nameunit(sc->sc_bus.bdev),
- UREAD2(sc, UHCI_CMD),
- UREAD2(sc, UHCI_STS),
- UREAD2(sc, UHCI_INTR),
- UREAD2(sc, UHCI_FRNUM),
- UREAD4(sc, UHCI_FLBASEADDR),
- UREAD1(sc, UHCI_SOF),
- UREAD2(sc, UHCI_PORTSC1),
- UREAD2(sc, UHCI_PORTSC2)));
-}
-
-void
-uhci_dump_td(uhci_soft_td_t *p)
-{
- char sbuf[128], sbuf2[128];
-
- DPRINTFN(-1,("TD(%p) at %08lx = link=0x%08lx status=0x%08lx "
- "token=0x%08lx buffer=0x%08lx\n",
- p, (long)p->physaddr,
- (long)le32toh(p->td.td_link),
- (long)le32toh(p->td.td_status),
- (long)le32toh(p->td.td_token),
- (long)le32toh(p->td.td_buffer)));
-
- bitmask_snprintf((u_int32_t)le32toh(p->td.td_link), "\20\1T\2Q\3VF",
- sbuf, sizeof(sbuf));
- bitmask_snprintf((u_int32_t)le32toh(p->td.td_status),
- "\20\22BITSTUFF\23CRCTO\24NAK\25BABBLE\26DBUFFER\27"
- "STALLED\30ACTIVE\31IOC\32ISO\33LS\36SPD",
- sbuf2, sizeof(sbuf2));
-
- DPRINTFN(-1,(" %s %s,errcnt=%d,actlen=%d pid=%02x,addr=%d,endpt=%d,"
- "D=%d,maxlen=%d\n", sbuf, sbuf2,
- 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
-uhci_dump_qh(uhci_soft_qh_t *sqh)
-{
- DPRINTFN(-1,("QH(%p) at %08x: hlink=%08x elink=%08x\n", sqh,
- (int)sqh->physaddr, le32toh(sqh->qh.qh_hlink),
- le32toh(sqh->qh.qh_elink)));
-}
-
-
-#if 1
-void
-uhci_dump(void)
-{
- uhci_dump_all(thesc);
-}
-#endif
-
-void
-uhci_dump_all(uhci_softc_t *sc)
-{
- uhci_dumpregs(sc);
- printf("intrs=%d\n", sc->sc_bus.no_intrs);
- /*printf("framelist[i].link = %08x\n", sc->sc_framelist[0].link);*/
- uhci_dump_qh(sc->sc_lctl_start);
-}
-
-
-void
-uhci_dump_qhs(uhci_soft_qh_t *sqh)
-{
- uhci_dump_qh(sqh);
-
- /* uhci_dump_qhs displays all the QHs and TDs from the given QH onwards
- * Traverses sideways first, then down.
- *
- * QH1
- * QH2
- * No QH
- * TD2.1
- * TD2.2
- * TD1.1
- * etc.
- *
- * TD2.x being the TDs queued at QH2 and QH1 being referenced from QH1.
- */
-
-
- 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 && !(le32toh(sqh->qh.qh_elink) & UHCI_PTR_T))
- uhci_dump_tds(sqh->elink);
- else
- DPRINTF(("No TD\n"));
-}
-
-void
-uhci_dump_tds(uhci_soft_td_t *std)
-{
- uhci_soft_td_t *td;
-
- for(td = std; td != NULL; td = td->link.std) {
- uhci_dump_td(td);
-
- /* Check whether the link pointer in this TD marks
- * the link pointer as end of queue. This avoids
- * printing the free list in case the queue/TD has
- * already been moved there (seatbelt).
- */
- if (le32toh(td->td.td_link) & UHCI_PTR_T ||
- le32toh(td->td.td_link) == 0)
- break;
- }
-}
-
-static void
-uhci_dump_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;
- }
- if (pipe->endpoint == NULL) {
- printf("ii %p: done=%d xfer=%p pipe=%p pipe->endpoint=NULL\n",
- ii, DONE, ii->xfer, pipe);
- return;
- }
- if (pipe->device == NULL) {
- printf("ii %p: done=%d xfer=%p pipe=%p pipe->device=NULL\n",
- ii, DONE, ii->xfer, pipe);
- 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 *sc);
-void
-uhci_dump_iis(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(void) { uhci_dump_iis(thesc); }
-
-#endif
-
-/*
- * This routine is executed periodically and simulates interrupts
- * from the root controller interrupt pipe for port status change.
- */
-void
-uhci_poll_hub(void *addr)
-{
- usbd_xfer_handle xfer = addr;
- usbd_pipe_handle pipe = xfer->pipe;
- usbd_device_handle dev = pipe->device;
- uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
- int s;
- u_char *p;
-
- DPRINTFN(20, ("uhci_poll_hub\n"));
-
- callout_reset(&sc->sc_poll_handle, sc->sc_ival, uhci_poll_hub, xfer);
-
- p = xfer->buffer;
- p[0] = 0;
- if (UREAD2(sc, UHCI_PORTSC1) & (UHCI_PORTSC_CSC|UHCI_PORTSC_OCIC))
- p[0] |= 1<<1;
- if (UREAD2(sc, UHCI_PORTSC2) & (UHCI_PORTSC_CSC|UHCI_PORTSC_OCIC))
- p[0] |= 1<<2;
- if (p[0] == 0)
- /* No change, try again in a while */
- return;
-
- xfer->actlen = 1;
- xfer->status = USBD_NORMAL_COMPLETION;
- s = splusb();
- dev->bus->intr_context++;
- uhci_transfer_complete(xfer);
- dev->bus->intr_context--;
- splx(s);
-}
-
-void
-uhci_root_intr_done(usbd_xfer_handle xfer)
-{
-}
-
-void
-uhci_root_ctrl_done(usbd_xfer_handle xfer)
-{
-}
-
-/*
- * Let the last QH loop back to the high speed control transfer QH.
- * This is what intel calls "bandwidth reclamation" and improves
- * USB performance a lot for some devices.
- * If we are already looping, just count it.
- */
-void
-uhci_add_loop(uhci_softc_t *sc) {
-#ifdef USB_DEBUG
- if (uhcinoloop)
- return;
-#endif
- if (++sc->sc_loops == 1) {
- DPRINTFN(5,("uhci_start_loop: add\n"));
- /* Note, we don't loop back the soft pointer. */
- sc->sc_last_qh->qh.qh_hlink =
- htole32(sc->sc_hctl_start->physaddr | UHCI_PTR_QH);
- }
-}
-
-void
-uhci_rem_loop(uhci_softc_t *sc) {
-#ifdef USB_DEBUG
- if (uhcinoloop)
- return;
-#endif
- if (--sc->sc_loops == 0) {
- DPRINTFN(5,("uhci_end_loop: remove\n"));
- sc->sc_last_qh->qh.qh_hlink = htole32(UHCI_PTR_T);
- }
-}
-
-/* Add high speed control QH, called at splusb(). */
-void
-uhci_add_hs_ctrl(uhci_softc_t *sc, uhci_soft_qh_t *sqh)
-{
- uhci_soft_qh_t *eqh;
-
- SPLUSBCHECK;
-
- DPRINTFN(10, ("uhci_add_ctrl: sqh=%p\n", sqh));
- eqh = sc->sc_hctl_end;
- sqh->hlink = eqh->hlink;
- sqh->qh.qh_hlink = eqh->qh.qh_hlink;
- eqh->hlink = sqh;
- eqh->qh.qh_hlink = htole32(sqh->physaddr | UHCI_PTR_QH);
- sc->sc_hctl_end = sqh;
-#ifdef UHCI_CTL_LOOP
- uhci_add_loop(sc);
-#endif
-}
-
-/* Remove high speed control QH, called at splusb(). */
-void
-uhci_remove_hs_ctrl(uhci_softc_t *sc, uhci_soft_qh_t *sqh)
-{
- uhci_soft_qh_t *pqh;
-
- SPLUSBCHECK;
-
- DPRINTFN(10, ("uhci_remove_hs_ctrl: sqh=%p\n", sqh));
-#ifdef UHCI_CTL_LOOP
- uhci_rem_loop(sc);
-#endif
- /*
- * The T bit should be set in the elink of the QH so that the HC
- * doesn't follow the pointer. This condition may fail if the
- * the transferred packet was short so that the QH still points
- * at the last used TD.
- * In this case we set the T bit and wait a little for the HC
- * to stop looking at the TD.
- */
- if (!(sqh->qh.qh_elink & htole32(UHCI_PTR_T))) {
- sqh->qh.qh_elink = htole32(UHCI_PTR_T);
- delay(UHCI_QH_REMOVE_DELAY);
- }
-
- pqh = uhci_find_prev_qh(sc->sc_hctl_start, sqh);
- pqh->hlink = sqh->hlink;
- pqh->qh.qh_hlink = sqh->qh.qh_hlink;
- delay(UHCI_QH_REMOVE_DELAY);
- if (sc->sc_hctl_end == sqh)
- sc->sc_hctl_end = pqh;
-}
-
-/* Add low speed control QH, called at splusb(). */
-void
-uhci_add_ls_ctrl(uhci_softc_t *sc, uhci_soft_qh_t *sqh)
-{
- uhci_soft_qh_t *eqh;
-
- SPLUSBCHECK;
-
- DPRINTFN(10, ("uhci_add_ls_ctrl: sqh=%p\n", sqh));
- eqh = sc->sc_lctl_end;
- sqh->hlink = eqh->hlink;
- sqh->qh.qh_hlink = eqh->qh.qh_hlink;
- eqh->hlink = sqh;
- eqh->qh.qh_hlink = htole32(sqh->physaddr | UHCI_PTR_QH);
- sc->sc_lctl_end = sqh;
-}
-
-/* Remove low speed control QH, called at splusb(). */
-void
-uhci_remove_ls_ctrl(uhci_softc_t *sc, uhci_soft_qh_t *sqh)
-{
- uhci_soft_qh_t *pqh;
-
- SPLUSBCHECK;
-
- DPRINTFN(10, ("uhci_remove_ls_ctrl: sqh=%p\n", sqh));
- /* See comment in uhci_remove_hs_ctrl() */
- if (!(sqh->qh.qh_elink & htole32(UHCI_PTR_T))) {
- sqh->qh.qh_elink = htole32(UHCI_PTR_T);
- delay(UHCI_QH_REMOVE_DELAY);
- }
- pqh = uhci_find_prev_qh(sc->sc_lctl_start, sqh);
- pqh->hlink = sqh->hlink;
- pqh->qh.qh_hlink = sqh->qh.qh_hlink;
- delay(UHCI_QH_REMOVE_DELAY);
- if (sc->sc_lctl_end == sqh)
- sc->sc_lctl_end = pqh;
-}
-
-/* Add bulk QH, called at splusb(). */
-void
-uhci_add_bulk(uhci_softc_t *sc, uhci_soft_qh_t *sqh)
-{
- uhci_soft_qh_t *eqh;
-
- SPLUSBCHECK;
-
- DPRINTFN(10, ("uhci_add_bulk: sqh=%p\n", sqh));
- eqh = sc->sc_bulk_end;
- sqh->hlink = eqh->hlink;
- sqh->qh.qh_hlink = eqh->qh.qh_hlink;
- eqh->hlink = sqh;
- eqh->qh.qh_hlink = htole32(sqh->physaddr | UHCI_PTR_QH);
- sc->sc_bulk_end = sqh;
- uhci_add_loop(sc);
-}
-
-/* Remove bulk QH, called at splusb(). */
-void
-uhci_remove_bulk(uhci_softc_t *sc, uhci_soft_qh_t *sqh)
-{
- uhci_soft_qh_t *pqh;
-
- SPLUSBCHECK;
-
- DPRINTFN(10, ("uhci_remove_bulk: sqh=%p\n", sqh));
- uhci_rem_loop(sc);
- /* See comment in uhci_remove_hs_ctrl() */
- if (!(sqh->qh.qh_elink & htole32(UHCI_PTR_T))) {
- sqh->qh.qh_elink = htole32(UHCI_PTR_T);
- delay(UHCI_QH_REMOVE_DELAY);
- }
- pqh = uhci_find_prev_qh(sc->sc_bulk_start, sqh);
- pqh->hlink = sqh->hlink;
- pqh->qh.qh_hlink = sqh->qh.qh_hlink;
- delay(UHCI_QH_REMOVE_DELAY);
- if (sc->sc_bulk_end == sqh)
- sc->sc_bulk_end = pqh;
-}
-
-static int uhci_intr1(uhci_softc_t *);
-
-int
-uhci_intr(void *arg)
-{
- uhci_softc_t *sc = arg;
-
- if (sc->sc_dying)
- return (0);
-
- DPRINTFN(15,("uhci_intr: real interrupt\n"));
- if (sc->sc_bus.use_polling) {
-#ifdef DIAGNOSTIC
- printf("uhci_intr: ignored interrupt while polling\n");
-#endif
- return (0);
- }
- return (uhci_intr1(sc));
-}
-
-int
-uhci_intr1(uhci_softc_t *sc)
-{
-
- int status;
- int ack;
-
- /*
- * It can happen that an interrupt will be delivered to
- * us before the device has been fully attached and the
- * softc struct has been configured. Usually this happens
- * when kldloading the USB support as a module after the
- * system has been booted. If we detect this condition,
- * we need to squelch the unwanted interrupts until we're
- * ready for them.
- */
- if (sc->sc_bus.bdev == NULL) {
- UWRITE2(sc, UHCI_STS, 0xFFFF); /* ack pending interrupts */
- uhci_run(sc, 0); /* stop the controller */
- UWRITE2(sc, UHCI_INTR, 0); /* disable interrupts */
- return(0);
- }
-
-#ifdef USB_DEBUG
- if (uhcidebug > 15) {
- DPRINTF(("%s: uhci_intr1\n", device_get_nameunit(sc->sc_bus.bdev)));
- uhci_dumpregs(sc);
- }
-#endif
- status = UREAD2(sc, UHCI_STS) & UHCI_STS_ALLINTRS;
- if (status == 0) /* The interrupt was not for us. */
- return (0);
-
-#if defined(DIAGNOSTIC) && defined(__NetBSD__)
- if (sc->sc_suspend != PWR_RESUME)
- printf("uhci_intr: suspended sts=0x%x\n", status);
-#endif
-
- if (sc->sc_suspend != PWR_RESUME) {
- printf("%s: interrupt while not operating ignored\n",
- device_get_nameunit(sc->sc_bus.bdev));
- UWRITE2(sc, UHCI_STS, status); /* acknowledge the ints */
- return (0);
- }
-
- ack = 0;
- if (status & UHCI_STS_USBINT)
- ack |= UHCI_STS_USBINT;
- if (status & UHCI_STS_USBEI)
- ack |= UHCI_STS_USBEI;
- if (status & UHCI_STS_RD) {
- ack |= UHCI_STS_RD;
-#ifdef USB_DEBUG
- printf("%s: resume detect\n", device_get_nameunit(sc->sc_bus.bdev));
-#endif
- }
- if (status & UHCI_STS_HSE) {
- ack |= UHCI_STS_HSE;
- printf("%s: host system error\n", device_get_nameunit(sc->sc_bus.bdev));
- }
- if (status & UHCI_STS_HCPE) {
- ack |= UHCI_STS_HCPE;
- printf("%s: host controller process error\n",
- device_get_nameunit(sc->sc_bus.bdev));
- }
- if (status & UHCI_STS_HCH) {
- /* no acknowledge needed */
- if (!sc->sc_dying) {
- printf("%s: host controller halted\n",
- device_get_nameunit(sc->sc_bus.bdev));
-#ifdef USB_DEBUG
- uhci_dump_all(sc);
-#endif
- }
- sc->sc_dying = 1;
- }
-
- if (!ack)
- return (0); /* nothing to acknowledge */
- UWRITE2(sc, UHCI_STS, ack); /* acknowledge the ints */
-
- sc->sc_bus.no_intrs++;
- usb_schedsoftintr(&sc->sc_bus);
-
- DPRINTFN(15, ("%s: uhci_intr: exit\n", device_get_nameunit(sc->sc_bus.bdev)));
-
- return (1);
-}
-
-void
-uhci_softintr(void *v)
-{
- uhci_softc_t *sc = v;
- uhci_intr_info_t *ii, *nextii;
-
- DPRINTFN(10,("%s: uhci_softintr (%d)\n", device_get_nameunit(sc->sc_bus.bdev),
- sc->sc_bus.intr_context));
-
- sc->sc_bus.intr_context++;
-
- /*
- * Interrupts on UHCI really suck. When the host controller
- * interrupts because a transfer is completed there is no
- * way of knowing which transfer it was. You can scan down
- * the TDs and QHs of the previous frame to limit the search,
- * but that assumes that the interrupt was not delayed by more
- * than 1 ms, which may not always be true (e.g. after debug
- * output on a slow console).
- * We scan all interrupt descriptors to see if any have
- * completed.
- */
- LIST_FOREACH_SAFE(ii, &sc->sc_intrhead, list, nextii)
- uhci_check_intr(sc, ii);
-
-#ifdef USB_USE_SOFTINTR
- if (sc->sc_softwake) {
- sc->sc_softwake = 0;
- wakeup(&sc->sc_softwake);
- }
-#endif /* USB_USE_SOFTINTR */
-
- sc->sc_bus.intr_context--;
-}
-
-/* Check for an interrupt. */
-void
-uhci_check_intr(uhci_softc_t *sc, uhci_intr_info_t *ii)
-{
- uhci_soft_td_t *std, *lstd;
- u_int32_t status;
-
- DPRINTFN(15, ("uhci_check_intr: ii=%p\n", ii));
-#ifdef DIAGNOSTIC
- if (ii == NULL) {
- printf("uhci_check_intr: no ii? %p\n", ii);
- return;
- }
-#endif
- if (ii->xfer->status == USBD_CANCELLED ||
- ii->xfer->status == USBD_TIMEOUT) {
- DPRINTF(("uhci_check_intr: aborted xfer=%p\n", ii->xfer));
- return;
- }
-
- if (ii->stdstart == NULL)
- return;
- lstd = ii->stdend;
-#ifdef DIAGNOSTIC
- if (lstd == NULL) {
- printf("uhci_check_intr: std==0\n");
- return;
- }
-#endif
- /*
- * If the last TD is still active we need to check whether there
- * is an error somewhere in the middle, or whether there was a
- * short packet (SPD and not ACTIVE).
- */
- 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 = le32toh(std->td.td_status);
- /* If there's an active TD the xfer isn't done. */
- if (status & UHCI_TD_ACTIVE)
- break;
- /* Any kind of error makes the xfer done. */
- if (status & UHCI_TD_STALLED)
- 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(le32toh(std->td.td_token)))
- goto done;
- }
- DPRINTFN(12, ("uhci_check_intr: ii=%p std=%p still active\n",
- ii, ii->stdstart));
- return;
- }
- done:
- DPRINTFN(12, ("uhci_check_intr: ii=%p done\n", ii));
- callout_stop(&ii->xfer->timeout_handle);
- usb_rem_task(ii->xfer->pipe->device, &UXFER(ii->xfer)->abort_task);
- uhci_idone(ii);
-}
-
-/* Called at splusb() */
-void
-uhci_idone(uhci_intr_info_t *ii)
-{
- usbd_xfer_handle xfer = ii->xfer;
- struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
- uhci_soft_td_t *std;
- u_int32_t status = 0, nstatus;
- int actlen;
-
- DPRINTFN(12, ("uhci_idone: ii=%p\n", ii));
-#ifdef DIAGNOSTIC
- {
- int s = splhigh();
- if (ii->isdone) {
- splx(s);
-#ifdef USB_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;
- splx(s);
- }
-#endif
-
- if (xfer->nframes != 0) {
- /* Isoc transfer, do things differently. */
- uhci_soft_td_t **stds = upipe->u.iso.stds;
- int i, n, nframes, len;
-
- DPRINTFN(5,("uhci_idone: ii=%p isoc ready\n", ii));
-
- nframes = xfer->nframes;
- actlen = 0;
- n = UXFER(xfer)->curframe;
- for (i = 0; i < nframes; i++) {
- std = stds[n];
-#ifdef USB_DEBUG
- if (uhcidebug > 5) {
- DPRINTFN(-1,("uhci_idone: isoc TD %d\n", i));
- uhci_dump_td(std);
- }
-#endif
- if (++n >= UHCI_VFRAMELIST_COUNT)
- n = 0;
- status = le32toh(std->td.td_status);
- len = UHCI_TD_GET_ACTLEN(status);
- xfer->frlengths[i] = len;
- actlen += len;
- }
- upipe->u.iso.inuse -= nframes;
- xfer->actlen = actlen;
- xfer->status = USBD_NORMAL_COMPLETION;
- goto end;
- }
-
-#ifdef USB_DEBUG
- DPRINTFN(10, ("uhci_idone: ii=%p, xfer=%p, pipe=%p ready\n",
- ii, xfer, upipe));
- if (uhcidebug > 10)
- uhci_dump_tds(ii->stdstart);
-#endif
-
- /* The transfer is done, compute actual length and status. */
- actlen = 0;
- for (std = ii->stdstart; std != NULL; std = std->link.std) {
- nstatus = le32toh(std->td.td_status);
- if (nstatus & UHCI_TD_ACTIVE)
- break;
-
- status = nstatus;
- if (UHCI_TD_GET_PID(le32toh(std->td.td_token)) !=
- UHCI_TD_PID_SETUP)
- actlen += UHCI_TD_GET_ACTLEN(status);
- else {
- /*
- * UHCI will report CRCTO in addition to a STALL or NAK
- * for a SETUP transaction. See section 3.2.2, "TD
- * CONTROL AND STATUS".
- */
- if (status & (UHCI_TD_STALLED | UHCI_TD_NAK))
- status &= ~UHCI_TD_CRCTO;
- }
- }
- /* If there are left over TDs we need to update the toggle. */
- if (std != NULL)
- upipe->nexttoggle = UHCI_TD_GET_DT(le32toh(std->td.td_token));
-
- status &= UHCI_TD_ERROR;
- DPRINTFN(10, ("uhci_idone: actlen=%d, status=0x%x\n",
- actlen, status));
- xfer->actlen = actlen;
- if (status != 0) {
-#ifdef USB_DEBUG
- char sbuf[128];
-
- bitmask_snprintf((u_int32_t)status,
- "\20\22BITSTUFF\23CRCTO\24NAK\25"
- "BABBLE\26DBUFFER\27STALLED\30ACTIVE",
- sbuf, sizeof(sbuf));
-
- DPRINTFN((status == UHCI_TD_STALLED)*10,
- ("uhci_idone: error, addr=%d, endpt=0x%02x, "
- "status 0x%s\n",
- xfer->pipe->device->address,
- xfer->pipe->endpoint->edesc->bEndpointAddress,
- sbuf));
-#endif
-
- if (status == UHCI_TD_STALLED)
- xfer->status = USBD_STALLED;
- else
- xfer->status = USBD_IOERROR; /* more info XXX */
- } else {
- xfer->status = USBD_NORMAL_COMPLETION;
- }
-
- end:
- uhci_transfer_complete(xfer);
- DPRINTFN(12, ("uhci_idone: ii=%p done\n", ii));
-}
-
-/*
- * Called when a request does not complete.
- */
-void
-uhci_timeout(void *addr)
-{
- uhci_intr_info_t *ii = addr;
- struct uhci_xfer *uxfer = UXFER(ii->xfer);
- struct uhci_pipe *upipe = (struct uhci_pipe *)uxfer->xfer.pipe;
- uhci_softc_t *sc = (uhci_softc_t *)upipe->pipe.device->bus;
-
- DPRINTF(("uhci_timeout: uxfer=%p\n", uxfer));
-
- if (sc->sc_dying) {
- uhci_abort_xfer(&uxfer->xfer, USBD_TIMEOUT);
- return;
- }
-
- /* Execute the abort in a process context. */
- usb_add_task(uxfer->xfer.pipe->device, &uxfer->abort_task,
- USB_TASKQ_HC);
-}
-
-void
-uhci_timeout_task(void *addr)
-{
- usbd_xfer_handle xfer = addr;
- int s;
-
- DPRINTF(("uhci_timeout_task: xfer=%p\n", xfer));
-
- s = splusb();
- uhci_abort_xfer(xfer, USBD_TIMEOUT);
- splx(s);
-}
-
-/*
- * Wait here until controller claims to have an interrupt.
- * Then call uhci_intr and return. Use timeout to avoid waiting
- * too long.
- * Only used during boot when interrupts are not enabled yet.
- */
-void
-uhci_waitintr(uhci_softc_t *sc, usbd_xfer_handle xfer)
-{
- int timo = xfer->timeout;
- uhci_intr_info_t *ii;
-
- DPRINTFN(10,("uhci_waitintr: timeout = %dms\n", timo));
-
- xfer->status = USBD_IN_PROGRESS;
- for (; timo >= 0; timo--) {
- usb_delay_ms(&sc->sc_bus, 1);
- DPRINTFN(20,("uhci_waitintr: 0x%04x\n", UREAD2(sc, UHCI_STS)));
- if (UREAD2(sc, UHCI_STS) & UHCI_STS_ALLINTRS)
- uhci_intr1(sc);
- if (xfer->status != USBD_IN_PROGRESS)
- return;
- }
-
- /* Timeout */
- DPRINTF(("uhci_waitintr: timeout\n"));
- for (ii = LIST_FIRST(&sc->sc_intrhead);
- ii != NULL && ii->xfer != xfer;
- ii = LIST_NEXT(ii, list))
- ;
-#ifdef DIAGNOSTIC
- if (ii == NULL)
- panic("uhci_waitintr: lost intr_info");
-#endif
- uhci_idone(ii);
-}
-
-void
-uhci_poll(struct usbd_bus *bus)
-{
- uhci_softc_t *sc = (uhci_softc_t *)bus;
-
- if (UREAD2(sc, UHCI_STS) & UHCI_STS_ALLINTRS)
- uhci_intr1(sc);
-}
-
-void
-uhci_reset(uhci_softc_t *sc)
-{
- 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++)
- usb_delay_ms(&sc->sc_bus, 1);
- if (n >= UHCI_RESET_TIMEOUT)
- printf("%s: controller did not reset\n",
- device_get_nameunit(sc->sc_bus.bdev));
-}
-
-usbd_status
-uhci_run(uhci_softc_t *sc, int run)
-{
- int s, n, running;
- u_int16_t cmd;
-
- run = run != 0;
- s = splhardusb();
- DPRINTF(("uhci_run: setting run=%d\n", run));
- cmd = UREAD2(sc, UHCI_CMD);
- if (run)
- cmd |= UHCI_CMD_RS;
- else
- cmd &= ~UHCI_CMD_RS;
- UHCICMD(sc, cmd);
- for(n = 0; n < 10; n++) {
- running = !(UREAD2(sc, UHCI_STS) & UHCI_STS_HCH);
- /* return when we've entered the state we want */
- if (run == running) {
- splx(s);
- DPRINTF(("uhci_run: done cmd=0x%x sts=0x%x\n",
- UREAD2(sc, UHCI_CMD), UREAD2(sc, UHCI_STS)));
- return (USBD_NORMAL_COMPLETION);
- }
- usb_delay_ms(&sc->sc_bus, 1);
- }
- splx(s);
- printf("%s: cannot %s\n", device_get_nameunit(sc->sc_bus.bdev),
- run ? "start" : "stop");
- return (USBD_IOERROR);
-}
-
-/*
- * Memory management routines.
- * uhci_alloc_std allocates TDs
- * uhci_alloc_sqh allocates QHs
- * These two routines do their own free list management,
- * partly for speed, partly because allocating DMAable memory
- * has page size granularaity so much memory would be wasted if
- * only one TD/QH (32 bytes) was placed in each allocated chunk.
- */
-
-uhci_soft_td_t *
-uhci_alloc_std(uhci_softc_t *sc)
-{
- uhci_soft_td_t *std;
- usbd_status err;
- int i, offs;
- usb_dma_t dma;
-
- 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);
- if (err)
- return (0);
- for(i = 0; i < UHCI_STD_CHUNK; i++) {
- offs = i * UHCI_STD_SIZE;
- std = KERNADDR(&dma, offs);
- std->physaddr = DMAADDR(&dma, offs);
- std->link.std = sc->sc_freetds;
- std->aux_dma.block = NULL;
- std->aux_data = NULL;
- std->aux_len = 0;
- sc->sc_freetds = std;
- }
- }
- std = sc->sc_freetds;
- sc->sc_freetds = std->link.std;
- memset(&std->td, 0, sizeof(uhci_td_t));
- return std;
-}
-
-void
-uhci_free_std(uhci_softc_t *sc, uhci_soft_td_t *std)
-{
-#ifdef DIAGNOSTIC
-#define TD_IS_FREE 0x12345678
- if (le32toh(std->td.td_token) == TD_IS_FREE) {
- printf("uhci_free_std: freeing free TD %p\n", std);
- return;
- }
- std->td.td_token = htole32(TD_IS_FREE);
-#endif
- if (std->aux_dma.block != NULL) {
- usb_freemem(&sc->sc_bus, &std->aux_dma);
- std->aux_dma.block = NULL;
- std->aux_data = NULL;
- std->aux_len = 0;
- }
- std->link.std = sc->sc_freetds;
- sc->sc_freetds = std;
-}
-
-uhci_soft_qh_t *
-uhci_alloc_sqh(uhci_softc_t *sc)
-{
- uhci_soft_qh_t *sqh;
- usbd_status err;
- int i, offs;
- usb_dma_t dma;
-
- 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);
- if (err)
- return (0);
- for(i = 0; i < UHCI_SQH_CHUNK; i++) {
- offs = i * UHCI_SQH_SIZE;
- sqh = KERNADDR(&dma, offs);
- sqh->physaddr = DMAADDR(&dma, offs);
- sqh->hlink = sc->sc_freeqhs;
- sc->sc_freeqhs = sqh;
- }
- }
- sqh = sc->sc_freeqhs;
- sc->sc_freeqhs = sqh->hlink;
- memset(&sqh->qh, 0, sizeof(uhci_qh_t));
- return (sqh);
-}
-
-void
-uhci_free_sqh(uhci_softc_t *sc, uhci_soft_qh_t *sqh)
-{
- sqh->hlink = sc->sc_freeqhs;
- sc->sc_freeqhs = sqh;
-}
-
-void
-uhci_free_std_chain(uhci_softc_t *sc, uhci_soft_td_t *std,
- uhci_soft_td_t *stdend)
-{
- uhci_soft_td_t *p;
-
- for (; std != stdend; std = p) {
- p = std->link.std;
- uhci_free_std(sc, std);
- }
-}
-
-usbd_status
-uhci_alloc_std_chain(struct uhci_pipe *upipe, uhci_softc_t *sc, int len,
- int rd, u_int16_t flags, usbd_xfer_handle xfer,
- uhci_soft_td_t **sp, uhci_soft_td_t **ep)
-{
- struct usb_dma_mapping *dma = &xfer->dmamap;
- uhci_soft_td_t *p, *prevp, *startp;
- int err, i, ntd, l, tog, maxp, seg, segoff;
- u_int32_t status;
- int addr = upipe->pipe.device->address;
- int endpt = upipe->pipe.endpoint->edesc->bEndpointAddress;
-
- DPRINTFN(8, ("uhci_alloc_std_chain: addr=%d endpt=%d len=%d speed=%d "
- "flags=0x%x\n", addr, UE_GET_ADDR(endpt), len,
- upipe->pipe.device->speed, flags));
- maxp = UGETW(upipe->pipe.endpoint->edesc->wMaxPacketSize);
- if (maxp == 0) {
- printf("uhci_alloc_std_chain: maxp=0\n");
- return (USBD_INVAL);
- }
- ntd = (len + maxp - 1) / maxp;
- if (len == 0)
- flags |= USBD_FORCE_SHORT_XFER;
- if ((flags & USBD_FORCE_SHORT_XFER) && len % maxp == 0)
- ntd++;
- DPRINTFN(10, ("uhci_alloc_std_chain: maxp=%d ntd=%d\n", maxp, ntd));
- KASSERT(ntd > 0, ("uhci_alloc_std_chain: ntd=0"));
- tog = upipe->nexttoggle;
- prevp = NULL;
- startp = NULL;
- status = UHCI_TD_ZERO_ACTLEN(UHCI_TD_SET_ERRCNT(3) | UHCI_TD_ACTIVE);
- if (upipe->pipe.device->speed == USB_SPEED_LOW)
- status |= UHCI_TD_LS;
- if (flags & USBD_SHORT_XFER_OK)
- status |= UHCI_TD_SPD;
- seg = 0;
- segoff = 0;
- for (i = 0; i < ntd; i++) {
- p = uhci_alloc_std(sc);
- if (p == NULL) {
- uhci_free_std_chain(sc, startp, NULL);
- return (USBD_NOMEM);
- }
- p->link.std = NULL;
- if (prevp != NULL) {
- prevp->link.std = p;
- prevp->td.td_link = htole32(p->physaddr | UHCI_PTR_VF |
- UHCI_PTR_TD);
- } else {
- startp = p;
- }
- p->td.td_status = htole32(status);
- if (i == ntd - 1) {
- /* last TD */
- l = len % maxp;
- if (l == 0 && !(flags & USBD_FORCE_SHORT_XFER))
- l = maxp;
- *ep = p;
- } else
- l = maxp;
- p->td.td_token =
- htole32(rd ? UHCI_TD_IN (l, endpt, addr, tog) :
- UHCI_TD_OUT(l, endpt, addr, tog));
-
- KASSERT(seg < dma->nsegs || l == 0,
- ("uhci_alloc_std_chain: too few segments"));
- if (l == 0) {
- p->td.td_buffer = 0;
- } else if (l > dma->segs[seg].ds_len - segoff) {
- /* UHCI can't handle non-contiguous data. */
- err = uhci_aux_dma_alloc(sc, p, (char *)xfer->buffer +
- i * maxp, l);
- if (err) {
- uhci_free_std_chain(sc, startp, NULL);
- return (err);
- }
- p->td.td_buffer = htole32(uhci_aux_dma_prepare(p, rd));
- l -= dma->segs[seg].ds_len - segoff;
- seg++;
- KASSERT(seg < dma->nsegs,
- ("uhci_alloc_std_chain: too few segments 2"));
- segoff = 0;
- } else {
- p->td.td_buffer = htole32(dma->segs[seg].ds_addr +
- segoff);
- }
- segoff += l;
- if (l > 0 && segoff >= dma->segs[seg].ds_len) {
- KASSERT(segoff == dma->segs[seg].ds_len,
- ("uhci_alloc_std_chain: overlap"));
- if (i * maxp + l != len) {
- seg++;
- segoff = 0;
- }
- }
- prevp = p;
- tog ^= 1;
- }
- prevp->td.td_link = htole32(UHCI_PTR_T | UHCI_PTR_VF | UHCI_PTR_TD);
- upipe->nexttoggle = tog;
- *sp = startp;
- DPRINTFN(10, ("uhci_alloc_std_chain: nexttog=%d\n",
- upipe->nexttoggle));
- return (USBD_NORMAL_COMPLETION);
-}
-
-/*
- * Allocate a physically contiguous buffer to handle cases where UHCI
- * cannot handle a packet because it is not physically contiguous.
- * If the usb_dma_t was already allocated this just ensures it is
- * large enough for the specified size.
- */
-static usbd_status
-uhci_aux_dma_alloc(uhci_softc_t *sc, uhci_soft_td_t *std, void *data, int len)
-{
- int err, align;
-
- if (std->aux_dma.block == NULL || std->aux_dma.block->size < len) {
- /* Align to avoid crossing a page boundary. */
- if (powerof2(len))
- align = len;
- else
- align = 1 << fls(len);
-
- if (std->aux_dma.block != NULL)
- usb_freemem(&sc->sc_bus, &std->aux_dma);
- std->aux_dma.block = NULL;
- err = usb_allocmem(&sc->sc_bus, len, align, &std->aux_dma);
- if (err)
- return (err);
- }
- std->aux_data = data;
- std->aux_len = len;
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-static uhci_physaddr_t
-uhci_aux_dma_prepare(uhci_soft_td_t *std, int isread)
-{
- if (!isread) {
- bcopy(std->aux_data, KERNADDR(&std->aux_dma, 0), std->aux_len);
- bus_dmamap_sync(std->aux_dma.block->tag,
- std->aux_dma.block->map, BUS_DMASYNC_PREWRITE);
- }
-
- return (DMAADDR(&std->aux_dma, 0));
-}
-
-static void
-uhci_aux_dma_complete(uhci_soft_td_t *std, int isread)
-{
- if (isread) {
- bus_dmamap_sync(std->aux_dma.block->tag,
- std->aux_dma.block->map, BUS_DMASYNC_POSTREAD);
- bcopy(KERNADDR(&std->aux_dma, 0), std->aux_data, std->aux_len);
- }
-}
-
-void
-uhci_device_clear_toggle(usbd_pipe_handle pipe)
-{
- struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
- upipe->nexttoggle = 0;
-}
-
-void
-uhci_noop(usbd_pipe_handle pipe)
-{
-}
-
-usbd_status
-uhci_device_bulk_transfer(usbd_xfer_handle xfer)
-{
- usbd_status err;
-
- /* Insert last in queue. */
- err = usb_insert_transfer(xfer);
- if (err)
- return (err);
-
- /*
- * Pipe isn't running (otherwise err would be USBD_INPROG),
- * so start it first.
- */
- return (uhci_device_bulk_start(STAILQ_FIRST(&xfer->pipe->queue)));
-}
-
-usbd_status
-uhci_device_bulk_start(usbd_xfer_handle 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 = &UXFER(xfer)->iinfo;
- uhci_soft_td_t *data, *dataend;
- uhci_soft_qh_t *sqh;
- usbd_status err;
- int len, isread, endpt;
- int s;
-
- DPRINTFN(3, ("uhci_device_bulk_start: xfer=%p len=%d flags=%d ii=%p\n",
- xfer, xfer->length, xfer->flags, ii));
-
- if (sc->sc_dying)
- return (USBD_IOERROR);
-
-#ifdef DIAGNOSTIC
- if (xfer->rqflags & URQ_REQUEST)
- panic("uhci_device_bulk_transfer: a request");
-#endif
-
- len = xfer->length;
- endpt = upipe->pipe.endpoint->edesc->bEndpointAddress;
- isread = UE_GET_DIR(endpt) == UE_DIR_IN;
- sqh = upipe->u.bulk.sqh;
-
- upipe->u.bulk.isread = isread;
- upipe->u.bulk.length = len;
-
- err = uhci_alloc_std_chain(upipe, sc, len, isread, xfer->flags, xfer,
- &data, &dataend);
- if (err)
- return (err);
- dataend->td.td_status |= htole32(UHCI_TD_IOC);
-
-#ifdef USB_DEBUG
- if (uhcidebug > 8) {
- DPRINTF(("uhci_device_bulk_transfer: data(1)\n"));
- uhci_dump_tds(data);
- }
-#endif
-
- /* Set up interrupt info. */
- ii->xfer = xfer;
- ii->stdstart = data;
- ii->stdend = dataend;
-#ifdef DIAGNOSTIC
- if (!ii->isdone) {
- printf("uhci_device_bulk_transfer: not done, ii=%p\n", ii);
- }
- ii->isdone = 0;
-#endif
-
- sqh->elink = data;
- sqh->qh.qh_elink = htole32(data->physaddr | UHCI_PTR_TD);
-
- s = splusb();
- uhci_add_bulk(sc, sqh);
- uhci_add_intr_info(sc, ii);
-
- if (xfer->timeout && !sc->sc_bus.use_polling) {
- callout_reset(&xfer->timeout_handle, MS_TO_TICKS(xfer->timeout),
- uhci_timeout, ii);
- }
- xfer->status = USBD_IN_PROGRESS;
- splx(s);
-
-#ifdef USB_DEBUG
- if (uhcidebug > 10) {
- DPRINTF(("uhci_device_bulk_transfer: data(2)\n"));
- uhci_dump_tds(data);
- }
-#endif
-
- if (sc->sc_bus.use_polling)
- uhci_waitintr(sc, xfer);
-
- return (USBD_IN_PROGRESS);
-}
-
-/* Abort a device bulk request. */
-void
-uhci_device_bulk_abort(usbd_xfer_handle xfer)
-{
- DPRINTF(("uhci_device_bulk_abort:\n"));
- uhci_abort_xfer(xfer, USBD_CANCELLED);
-}
-
-/*
- * Abort a device request.
- * If this routine is called at splusb() it guarantees that the request
- * will be removed from the hardware scheduling and that the callback
- * for it will be called with USBD_CANCELLED status.
- * It's impossible to guarantee that the requested transfer will not
- * have happened since the hardware runs concurrently.
- * If the transaction has already happened we rely on the ordinary
- * interrupt processing to process it.
- */
-void
-uhci_abort_xfer(usbd_xfer_handle xfer, usbd_status status)
-{
- struct uhci_xfer *uxfer = UXFER(xfer);
- uhci_intr_info_t *ii = &uxfer->iinfo;
- struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
- uhci_softc_t *sc = (uhci_softc_t *)upipe->pipe.device->bus;
- uhci_soft_td_t *std;
- int s;
-
- DPRINTFN(1,("uhci_abort_xfer: xfer=%p, status=%d\n", xfer, status));
-
- if (sc->sc_dying) {
- /* If we're dying, just do the software part. */
- s = splusb();
- xfer->status = status; /* make software ignore it */
- callout_stop(&xfer->timeout_handle);
- usb_rem_task(xfer->pipe->device, &UXFER(xfer)->abort_task);
- uhci_transfer_complete(xfer);
- splx(s);
- return;
- }
-
- if (xfer->device->bus->intr_context || !curproc)
- panic("uhci_abort_xfer: not in process context");
-
- /*
- * If an abort is already in progress then just wait for it to
- * complete and return.
- */
- if (uxfer->uhci_xfer_flags & UHCI_XFER_ABORTING) {
- DPRINTFN(2, ("uhci_abort_xfer: already aborting\n"));
- /* No need to wait if we're aborting from a timeout. */
- if (status == USBD_TIMEOUT)
- return;
- /* Override the status which might be USBD_TIMEOUT. */
- xfer->status = status;
- DPRINTFN(2, ("uhci_abort_xfer: waiting for abort to finish\n"));
- uxfer->uhci_xfer_flags |= UHCI_XFER_ABORTWAIT;
- while (uxfer->uhci_xfer_flags & UHCI_XFER_ABORTING)
- tsleep(&uxfer->uhci_xfer_flags, PZERO, "uhciaw", 0);
- return;
- }
-
- /*
- * Step 1: Make interrupt routine and hardware ignore xfer.
- */
- s = splusb();
- uxfer->uhci_xfer_flags |= UHCI_XFER_ABORTING;
- xfer->status = status; /* make software ignore it */
- callout_stop(&xfer->timeout_handle);
- usb_rem_task(xfer->pipe->device, &UXFER(xfer)->abort_task);
- DPRINTFN(1,("uhci_abort_xfer: stop ii=%p\n", ii));
- for (std = ii->stdstart; std != NULL; std = std->link.std)
- std->td.td_status &= htole32(~(UHCI_TD_ACTIVE | UHCI_TD_IOC));
- splx(s);
-
- /*
- * Step 2: Wait until we know hardware has finished any possible
- * use of the xfer. Also make sure the soft interrupt routine
- * has run.
- */
- usb_delay_ms(upipe->pipe.device->bus, 2); /* Hardware finishes in 1ms */
- s = splusb();
-#ifdef USB_USE_SOFTINTR
- sc->sc_softwake = 1;
-#endif /* USB_USE_SOFTINTR */
- usb_schedsoftintr(&sc->sc_bus);
-#ifdef USB_USE_SOFTINTR
- DPRINTFN(1,("uhci_abort_xfer: tsleep\n"));
- tsleep(&sc->sc_softwake, PZERO, "uhciab", 0);
-#endif /* USB_USE_SOFTINTR */
- splx(s);
-
- /*
- * Step 3: Execute callback.
- */
- DPRINTFN(1,("uhci_abort_xfer: callback\n"));
- s = splusb();
-#ifdef DIAGNOSTIC
- ii->isdone = 1;
-#endif
- /* Do the wakeup first to avoid touching the xfer after the callback. */
- uxfer->uhci_xfer_flags &= ~UHCI_XFER_ABORTING;
- if (uxfer->uhci_xfer_flags & UHCI_XFER_ABORTWAIT) {
- uxfer->uhci_xfer_flags &= ~UHCI_XFER_ABORTWAIT;
- wakeup(&uxfer->uhci_xfer_flags);
- }
- uhci_transfer_complete(xfer);
- splx(s);
-}
-
-/*
- * Perform any UHCI-specific transfer completion operations, then
- * call usb_transfer_complete().
- */
-static void
-uhci_transfer_complete(usbd_xfer_handle xfer)
-{
- uhci_intr_info_t *ii = &UXFER(xfer)->iinfo;
- struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
- uhci_soft_td_t *p;
- int i, isread, n;
-
- /* XXX, must be an easier way to detect reads... */
- isread = ((xfer->rqflags & URQ_REQUEST) &&
- (xfer->request.bmRequestType & UT_READ)) ||
- (xfer->pipe->endpoint->edesc->bEndpointAddress & UE_DIR_IN);
-
- /* Copy back from any auxillary buffers after a read operation. */
- if (xfer->nframes == 0) {
- for (p = ii->stdstart; p != NULL; p = p->link.std) {
- if (p->aux_data != NULL)
- uhci_aux_dma_complete(p, isread);
- }
- } else {
- if (xfer->nframes != 0) {
- /* Isoc transfer, do things differently. */
- n = UXFER(xfer)->curframe;
- for (i = 0; i < xfer->nframes; i++) {
- p = upipe->u.iso.stds[n];
- if (p->aux_data != NULL)
- uhci_aux_dma_complete(p, isread);
- if (++n >= UHCI_VFRAMELIST_COUNT)
- n = 0;
- }
- }
- }
-
- usb_transfer_complete(xfer);
-}
-
-/* Close a device bulk pipe. */
-void
-uhci_device_bulk_close(usbd_pipe_handle pipe)
-{
- struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
- usbd_device_handle dev = upipe->pipe.device;
- uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
-
- uhci_free_sqh(sc, upipe->u.bulk.sqh);
- pipe->endpoint->savedtoggle = upipe->nexttoggle;
-}
-
-usbd_status
-uhci_device_ctrl_transfer(usbd_xfer_handle xfer)
-{
- usbd_status err;
-
- /* Insert last in queue. */
- err = usb_insert_transfer(xfer);
- if (err)
- return (err);
-
- /*
- * Pipe isn't running (otherwise err would be USBD_INPROG),
- * so start it first.
- */
- return (uhci_device_ctrl_start(STAILQ_FIRST(&xfer->pipe->queue)));
-}
-
-usbd_status
-uhci_device_ctrl_start(usbd_xfer_handle xfer)
-{
- uhci_softc_t *sc = (uhci_softc_t *)xfer->pipe->device->bus;
- usbd_status err;
-
- if (sc->sc_dying)
- return (USBD_IOERROR);
-
-#ifdef DIAGNOSTIC
- if (!(xfer->rqflags & URQ_REQUEST))
- panic("uhci_device_ctrl_transfer: not a request");
-#endif
-
- err = uhci_device_request(xfer);
- if (err)
- return (err);
-
- if (sc->sc_bus.use_polling)
- uhci_waitintr(sc, xfer);
- return (USBD_IN_PROGRESS);
-}
-
-usbd_status
-uhci_device_intr_transfer(usbd_xfer_handle xfer)
-{
- usbd_status err;
-
- /* Insert last in queue. */
- err = usb_insert_transfer(xfer);
- if (err)
- return (err);
-
- /*
- * Pipe isn't running (otherwise err would be USBD_INPROG),
- * so start it first.
- */
- return (uhci_device_intr_start(STAILQ_FIRST(&xfer->pipe->queue)));
-}
-
-usbd_status
-uhci_device_intr_start(usbd_xfer_handle 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 = &UXFER(xfer)->iinfo;
- uhci_soft_td_t *data, *dataend;
- uhci_soft_qh_t *sqh;
- usbd_status err;
- int isread, endpt;
- int i, s;
-
- if (sc->sc_dying)
- return (USBD_IOERROR);
-
- DPRINTFN(3,("uhci_device_intr_transfer: xfer=%p len=%d flags=%d\n",
- xfer, xfer->length, xfer->flags));
-
-#ifdef DIAGNOSTIC
- if (xfer->rqflags & URQ_REQUEST)
- panic("uhci_device_intr_transfer: a request");
-#endif
-
- endpt = upipe->pipe.endpoint->edesc->bEndpointAddress;
- isread = UE_GET_DIR(endpt) == UE_DIR_IN;
- sqh = upipe->u.bulk.sqh;
-
- upipe->u.intr.isread = isread;
-
- err = uhci_alloc_std_chain(upipe, sc, xfer->length, isread, xfer->flags,
- xfer, &data, &dataend);
- if (err)
- return (err);
- dataend->td.td_status |= htole32(UHCI_TD_IOC);
-
-#ifdef USB_DEBUG
- if (uhcidebug > 10) {
- DPRINTF(("uhci_device_intr_transfer: data(1)\n"));
- uhci_dump_tds(data);
- uhci_dump_qh(upipe->u.intr.qhs[0]);
- }
-#endif
-
- s = splusb();
- /* Set up interrupt info. */
- ii->xfer = xfer;
- ii->stdstart = data;
- ii->stdend = dataend;
-#ifdef DIAGNOSTIC
- if (!ii->isdone) {
- printf("uhci_device_intr_transfer: not done, ii=%p\n", ii);
- }
- ii->isdone = 0;
-#endif
-
- DPRINTFN(10,("uhci_device_intr_transfer: qhs[0]=%p\n",
- upipe->u.intr.qhs[0]));
- for (i = 0; i < upipe->u.intr.npoll; i++) {
- sqh = upipe->u.intr.qhs[i];
- sqh->elink = data;
- sqh->qh.qh_elink = htole32(data->physaddr | UHCI_PTR_TD);
- }
- uhci_add_intr_info(sc, ii);
- xfer->status = USBD_IN_PROGRESS;
- splx(s);
-
-#ifdef USB_DEBUG
- if (uhcidebug > 10) {
- DPRINTF(("uhci_device_intr_transfer: data(2)\n"));
- uhci_dump_tds(data);
- uhci_dump_qh(upipe->u.intr.qhs[0]);
- }
-#endif
-
- return (USBD_IN_PROGRESS);
-}
-
-/* Abort a device control request. */
-void
-uhci_device_ctrl_abort(usbd_xfer_handle xfer)
-{
- DPRINTF(("uhci_device_ctrl_abort:\n"));
- uhci_abort_xfer(xfer, USBD_CANCELLED);
-}
-
-/* Close a device control pipe. */
-void
-uhci_device_ctrl_close(usbd_pipe_handle pipe)
-{
-}
-
-/* Abort a device interrupt request. */
-void
-uhci_device_intr_abort(usbd_xfer_handle xfer)
-{
- DPRINTFN(1,("uhci_device_intr_abort: xfer=%p\n", xfer));
- if (xfer->pipe->intrxfer == xfer) {
- DPRINTFN(1,("uhci_device_intr_abort: remove\n"));
- xfer->pipe->intrxfer = NULL;
- }
- uhci_abort_xfer(xfer, USBD_CANCELLED);
-}
-
-/* Close a device interrupt pipe. */
-void
-uhci_device_intr_close(usbd_pipe_handle pipe)
-{
- struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
- uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus;
- int i, npoll;
- int s;
-
- /* Unlink descriptors from controller data structures. */
- npoll = upipe->u.intr.npoll;
- s = splusb();
- for (i = 0; i < npoll; i++)
- uhci_remove_intr(sc, upipe->u.intr.qhs[i]);
- splx(s);
-
- /*
- * We now have to wait for any activity on the physical
- * descriptors to stop.
- */
- usb_delay_ms(&sc->sc_bus, 2);
-
- for(i = 0; i < npoll; i++)
- uhci_free_sqh(sc, upipe->u.intr.qhs[i]);
- free(upipe->u.intr.qhs, M_USBHC);
-
- /* XXX free other resources */
-}
-
-usbd_status
-uhci_device_request(usbd_xfer_handle xfer)
-{
- struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
- usb_device_request_t *req = &xfer->request;
- usbd_device_handle dev = upipe->pipe.device;
- 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 = &UXFER(xfer)->iinfo;
- uhci_soft_td_t *setup, *data, *stat, *next, *dataend;
- uhci_soft_qh_t *sqh;
- int len;
- u_int32_t ls;
- usbd_status err;
- int isread;
- int s;
-
- DPRINTFN(3,("uhci_device_control type=0x%02x, request=0x%02x, "
- "wValue=0x%04x, wIndex=0x%04x len=%d, addr=%d, endpt=%d\n",
- req->bmRequestType, req->bRequest, UGETW(req->wValue),
- UGETW(req->wIndex), UGETW(req->wLength),
- addr, endpt));
-
- ls = dev->speed == USB_SPEED_LOW ? UHCI_TD_LS : 0;
- isread = req->bmRequestType & UT_READ;
- len = UGETW(req->wLength);
-
- setup = upipe->u.ctl.setup;
- stat = upipe->u.ctl.stat;
- sqh = upipe->u.ctl.sqh;
-
- /* Set up data transaction */
- if (len != 0) {
- upipe->nexttoggle = 1;
- err = uhci_alloc_std_chain(upipe, sc, len, isread, xfer->flags,
- xfer, &data, &dataend);
- if (err)
- return (err);
- next = data;
- dataend->link.std = stat;
- dataend->td.td_link = htole32(stat->physaddr | UHCI_PTR_VF | UHCI_PTR_TD);
- } else {
- next = stat;
- }
- upipe->u.ctl.length = len;
-
- memcpy(KERNADDR(&upipe->u.ctl.reqdma, 0), req, sizeof *req);
-
- setup->link.std = next;
- setup->td.td_link = htole32(next->physaddr | UHCI_PTR_VF | UHCI_PTR_TD);
- 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, 0));
-
- 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 =
- htole32(isread ? UHCI_TD_OUT(0, endpt, addr, 1) :
- UHCI_TD_IN (0, endpt, addr, 1));
- stat->td.td_buffer = htole32(0);
-
-#ifdef USB_DEBUG
- if (uhcidebug > 10) {
- DPRINTF(("uhci_device_request: before transfer\n"));
- uhci_dump_tds(setup);
- }
-#endif
-
- /* Set up interrupt info. */
- ii->xfer = xfer;
- ii->stdstart = setup;
- ii->stdend = stat;
-#ifdef DIAGNOSTIC
- if (!ii->isdone) {
- printf("uhci_device_request: not done, ii=%p\n", ii);
- }
- ii->isdone = 0;
-#endif
-
- sqh->elink = setup;
- sqh->qh.qh_elink = htole32(setup->physaddr | UHCI_PTR_TD);
-
- s = splusb();
- if (dev->speed == USB_SPEED_LOW)
- uhci_add_ls_ctrl(sc, sqh);
- else
- uhci_add_hs_ctrl(sc, sqh);
- uhci_add_intr_info(sc, ii);
-#ifdef USB_DEBUG
- if (uhcidebug > 12) {
- uhci_soft_td_t *std;
- uhci_soft_qh_t *xqh;
- uhci_soft_qh_t *sxqh;
- int maxqh = 0;
- uhci_physaddr_t link;
- DPRINTF(("uhci_enter_ctl_q: follow from [0]\n"));
- for (std = sc->sc_vframes[0].htd, link = 0;
- (link & UHCI_PTR_QH) == 0;
- std = std->link.std) {
- link = le32toh(std->td.td_link);
- uhci_dump_td(std);
- }
- sxqh = (uhci_soft_qh_t *)std;
- uhci_dump_qh(sxqh);
- for (xqh = sxqh;
- xqh != NULL;
- xqh = (maxqh++ == 5 || xqh->hlink == sxqh ||
- xqh->hlink == xqh ? NULL : xqh->hlink)) {
- uhci_dump_qh(xqh);
- }
- DPRINTF(("Enqueued QH:\n"));
- uhci_dump_qh(sqh);
- uhci_dump_tds(sqh->elink);
- }
-#endif
- if (xfer->timeout && !sc->sc_bus.use_polling) {
- callout_reset(&xfer->timeout_handle, MS_TO_TICKS(xfer->timeout),
- uhci_timeout, ii);
- }
- xfer->status = USBD_IN_PROGRESS;
- splx(s);
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-usbd_status
-uhci_device_isoc_transfer(usbd_xfer_handle xfer)
-{
- usbd_status err;
-
- DPRINTFN(5,("uhci_device_isoc_transfer: xfer=%p\n", xfer));
-
- /* Put it on our queue, */
- err = usb_insert_transfer(xfer);
-
- /* bail out on error, */
- if (err && err != USBD_IN_PROGRESS)
- return (err);
-
- /* XXX should check inuse here */
-
- /* insert into schedule, */
- uhci_device_isoc_enter(xfer);
-
- /* and start if the pipe wasn't running */
- if (!err)
- uhci_device_isoc_start(STAILQ_FIRST(&xfer->pipe->queue));
-
- return (err);
-}
-
-void
-uhci_device_isoc_enter(usbd_xfer_handle 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;
- struct iso *iso = &upipe->u.iso;
- uhci_soft_td_t *std;
- void *dataptr;
- u_int32_t len, status;
- int err, s, i, isread, next, nframes, seg, segoff;
-
- DPRINTFN(5,("uhci_device_isoc_enter: used=%d next=%d xfer=%p "
- "nframes=%d\n",
- iso->inuse, iso->next, xfer, xfer->nframes));
-
- if (sc->sc_dying)
- return;
-
- 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 */
- }
-
-#ifdef DIAGNOSTIC
- if (iso->inuse >= UHCI_VFRAMELIST_COUNT)
- printf("uhci_device_isoc_enter: overflow!\n");
-#endif
-
- next = iso->next;
- if (next == -1) {
- /* Not in use yet, schedule it a few frames ahead. */
- next = (UREAD2(sc, UHCI_FRNUM) + 3) % UHCI_VFRAMELIST_COUNT;
- DPRINTFN(2,("uhci_device_isoc_enter: start next=%d\n", next));
- }
-
- xfer->status = USBD_IN_PROGRESS;
- UXFER(xfer)->curframe = next;
-
- seg = 0;
- segoff = 0;
- dataptr = xfer->allocbuf; /* Normal buffers not possible for isoc? */
- isread = xfer->pipe->endpoint->edesc->bEndpointAddress & UE_DIR_IN;
- 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++) {
- std = iso->stds[next];
- if (++next >= UHCI_VFRAMELIST_COUNT)
- next = 0;
- len = xfer->frlengths[i];
- KASSERT(seg < xfer->dmamap.nsegs,
- ("uhci_device_isoc_enter: too few segments"));
- if (len + segoff > xfer->dmamap.segs[seg].ds_len) {
- /* UHCI can't handle non-contiguous data. */
- err = uhci_aux_dma_alloc(sc, std, dataptr, len);
- /* XXX */
- if (err)
- printf("uhci_device_isoc_enter: aux alloc\n");
- std->td.td_buffer = htole32(uhci_aux_dma_prepare(std,
- isread));
- segoff += len;
- while (segoff >= xfer->dmamap.segs[seg].ds_len) {
- KASSERT(seg < xfer->dmamap.nsegs - 1 ||
- segoff == xfer->dmamap.segs[seg].ds_len,
- ("uhci_device_isoc_enter: overlap2"));
- segoff -= xfer->dmamap.segs[seg].ds_len;
- seg++;
- }
- } else {
- std->td.td_buffer =
- htole32(xfer->dmamap.segs[seg].ds_addr + segoff);
- segoff += len;
- if (segoff >= xfer->dmamap.segs[seg].ds_len) {
- KASSERT(segoff == xfer->dmamap.segs[seg].ds_len,
- ("uhci_device_isoc_enter: overlap"));
- segoff = 0;
- seg++;
- }
- }
- if (i == nframes - 1)
- 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 USB_DEBUG
- if (uhcidebug > 5) {
- DPRINTFN(5,("uhci_device_isoc_enter: TD %d\n", i));
- uhci_dump_td(std);
- }
-#endif
- dataptr = (char *)dataptr + len;
- }
- iso->next = next;
- iso->inuse += xfer->nframes;
-
- splx(s);
-}
-
-usbd_status
-uhci_device_isoc_start(usbd_xfer_handle 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 = &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);
-
-#ifdef DIAGNOSTIC
- if (xfer->status != USBD_IN_PROGRESS)
- printf("uhci_device_isoc_start: not in progress %p\n", xfer);
-#endif
-
- /* Find the last TD */
- 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;
-#ifdef DIAGNOSTIC
- if (!ii->isdone)
- printf("uhci_device_isoc_start: not done, ii=%p\n", ii);
- ii->isdone = 0;
-#endif
- uhci_add_intr_info(sc, ii);
-
- splx(s);
-
- return (USBD_IN_PROGRESS);
-}
-
-void
-uhci_device_isoc_abort(usbd_xfer_handle xfer)
-{
- struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
- uhci_soft_td_t **stds = upipe->u.iso.stds;
- uhci_soft_td_t *std;
- 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;
- }
-
- /* Give xfer the requested abort code. */
- xfer->status = USBD_CANCELLED;
-
- /* make hardware ignore it, */
- nframes = xfer->nframes;
- n = UXFER(xfer)->curframe;
- maxlen = 0;
- for (i = 0; i < nframes; i++) {
- std = stds[n];
- std->td.td_status &= htole32(~(UHCI_TD_ACTIVE | UHCI_TD_IOC));
- len = UHCI_TD_GET_MAXLEN(le32toh(std->td.td_token));
- if (len > maxlen)
- maxlen = len;
- if (++n >= UHCI_VFRAMELIST_COUNT)
- n = 0;
- }
-
- /* and wait until we are sure the hardware has finished. */
- delay(maxlen);
-
-#ifdef DIAGNOSTIC
- UXFER(xfer)->iinfo.isdone = 1;
-#endif
- /* Run callback and remove from interrupt list. */
- uhci_transfer_complete(xfer);
-
- splx(s);
-}
-
-void
-uhci_device_isoc_close(usbd_pipe_handle pipe)
-{
- struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
- usbd_device_handle dev = upipe->pipe.device;
- uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
- uhci_soft_td_t *std, *vstd;
- struct iso *iso;
- int i, s;
-
- /*
- * Make sure all TDs are marked as inactive.
- * Wait for completion.
- * Unschedule.
- * Deallocate.
- */
- iso = &upipe->u.iso;
-
- for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++)
- iso->stds[i]->td.td_status &= htole32(~UHCI_TD_ACTIVE);
- usb_delay_ms(&sc->sc_bus, 2); /* wait for completion */
-
- s = splusb();
- for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++) {
- std = iso->stds[i];
- for (vstd = sc->sc_vframes[i].htd;
- vstd != NULL && vstd->link.std != std;
- vstd = vstd->link.std)
- ;
- if (vstd == NULL) {
- /*panic*/
- printf("uhci_device_isoc_close: %p not found\n", std);
- splx(s);
- return;
- }
- vstd->link = std->link;
- vstd->td.td_link = std->td.td_link;
- uhci_free_std(sc, std);
- }
- splx(s);
-
- free(iso->stds, M_USBHC);
-}
-
-usbd_status
-uhci_setup_isoc(usbd_pipe_handle pipe)
-{
- struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
- usbd_device_handle dev = upipe->pipe.device;
- uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
- int addr = upipe->pipe.device->address;
- int endpt = upipe->pipe.endpoint->edesc->bEndpointAddress;
- int rd = UE_GET_DIR(endpt) == UE_DIR_IN;
- uhci_soft_td_t *std, *vstd;
- u_int32_t token;
- struct iso *iso;
- int i, s;
-
- iso = &upipe->u.iso;
- iso->stds = malloc(UHCI_VFRAMELIST_COUNT * sizeof (uhci_soft_td_t *),
- M_USBHC, M_WAITOK);
-
- 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 = htole32(UHCI_TD_IOS); /* iso, inactive */
- std->td.td_token = htole32(token);
- iso->stds[i] = std;
- }
-
- /* Insert TDs into schedule. */
- 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 = htole32(std->physaddr | UHCI_PTR_TD);
- }
- splx(s);
-
- iso->next = -1;
- iso->inuse = 0;
-
- return (USBD_NORMAL_COMPLETION);
-
- bad:
- while (--i >= 0)
- uhci_free_std(sc, iso->stds[i]);
- free(iso->stds, M_USBHC);
- return (USBD_NOMEM);
-}
-
-void
-uhci_device_isoc_done(usbd_xfer_handle xfer)
-{
- 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;
-
- if (!uhci_active_intr_info(ii))
- 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 USB_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 &= htole32(~UHCI_TD_IOC);
-
- uhci_del_intr_info(ii); /* remove from active list */
-
-#ifdef DIAGNOSTIC
- if (ii->stdend == NULL) {
- printf("uhci_device_isoc_done: xfer=%p stdend==NULL\n", xfer);
-#ifdef USB_DEBUG
- uhci_dump_ii(ii);
-#endif
- return;
- }
-#endif
- ii->stdstart = NULL;
- ii->stdend = NULL;
-}
-
-void
-uhci_device_intr_done(usbd_xfer_handle xfer)
-{
- 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;
- int i, npoll;
-
- DPRINTFN(5, ("uhci_device_intr_done: length=%d\n", xfer->actlen));
-
- npoll = upipe->u.intr.npoll;
- for(i = 0; i < npoll; i++) {
- sqh = upipe->u.intr.qhs[i];
- sqh->elink = NULL;
- sqh->qh.qh_elink = htole32(UHCI_PTR_T);
- }
- uhci_free_std_chain(sc, ii->stdstart, NULL);
-
- /* XXX Wasteful. */
- 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,
- upipe->u.intr.isread, xfer->flags, xfer,
- &data, &dataend);
- dataend->td.td_status |= htole32(UHCI_TD_IOC);
-
-#ifdef USB_DEBUG
- if (uhcidebug > 10) {
- DPRINTF(("uhci_device_intr_done: data(1)\n"));
- uhci_dump_tds(data);
- uhci_dump_qh(upipe->u.intr.qhs[0]);
- }
-#endif
-
- ii->stdstart = data;
- ii->stdend = dataend;
-#ifdef DIAGNOSTIC
- if (!ii->isdone) {
- printf("uhci_device_intr_done: not done, ii=%p\n", ii);
- }
- ii->isdone = 0;
-#endif
- for (i = 0; i < npoll; i++) {
- sqh = upipe->u.intr.qhs[i];
- sqh->elink = data;
- sqh->qh.qh_elink = htole32(data->physaddr | UHCI_PTR_TD);
- }
- xfer->status = USBD_IN_PROGRESS;
- /* The ii is already on the examined list, just leave it. */
- } else {
- DPRINTFN(5,("uhci_device_intr_done: removing\n"));
- if (uhci_active_intr_info(ii)) {
- uhci_del_intr_info(ii);
- ii->stdstart = NULL;
- ii->stdend = NULL;
- }
- }
-}
-
-/* Deallocate request data structures */
-void
-uhci_device_ctrl_done(usbd_xfer_handle xfer)
-{
- uhci_intr_info_t *ii = &UXFER(xfer)->iinfo;
- uhci_softc_t *sc = ii->sc;
- struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
-
-#ifdef DIAGNOSTIC
- if (!(xfer->rqflags & URQ_REQUEST))
- panic("uhci_device_ctrl_done: not a request");
-#endif
-
- if (!uhci_active_intr_info(ii))
- return;
-
- uhci_del_intr_info(ii); /* remove from active list */
-
- if (upipe->pipe.device->speed == USB_SPEED_LOW)
- uhci_remove_ls_ctrl(sc, upipe->u.ctl.sqh);
- else
- uhci_remove_hs_ctrl(sc, upipe->u.ctl.sqh);
-
- if (upipe->u.ctl.length != 0)
- uhci_free_std_chain(sc, ii->stdstart->link.std, ii->stdend);
- ii->stdstart = NULL;
- ii->stdend = NULL;
-
- DPRINTFN(5, ("uhci_device_ctrl_done: length=%d\n", xfer->actlen));
-}
-
-/* Deallocate request data structures */
-void
-uhci_device_bulk_done(usbd_xfer_handle xfer)
-{
- uhci_intr_info_t *ii = &UXFER(xfer)->iinfo;
- uhci_softc_t *sc = ii->sc;
- struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
-
- DPRINTFN(5,("uhci_device_bulk_done: xfer=%p ii=%p sc=%p upipe=%p\n",
- xfer, ii, sc, upipe));
-
- if (!uhci_active_intr_info(ii))
- return;
-
- uhci_del_intr_info(ii); /* remove from active list */
-
- uhci_remove_bulk(sc, upipe->u.bulk.sqh);
-
- uhci_free_std_chain(sc, ii->stdstart, NULL);
- ii->stdstart = NULL;
- ii->stdend = NULL;
-
- DPRINTFN(5, ("uhci_device_bulk_done: length=%d\n", xfer->actlen));
-}
-
-/* Add interrupt QH, called with vflock. */
-void
-uhci_add_intr(uhci_softc_t *sc, uhci_soft_qh_t *sqh)
-{
- struct uhci_vframe *vf = &sc->sc_vframes[sqh->pos];
- uhci_soft_qh_t *eqh;
-
- 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 = htole32(sqh->physaddr | UHCI_PTR_QH);
- vf->eqh = sqh;
- vf->bandwidth++;
-}
-
-/* Remove interrupt QH. */
-void
-uhci_remove_intr(uhci_softc_t *sc, uhci_soft_qh_t *sqh)
-{
- struct uhci_vframe *vf = &sc->sc_vframes[sqh->pos];
- uhci_soft_qh_t *pqh;
-
- DPRINTFN(4, ("uhci_remove_intr: n=%d sqh=%p\n", sqh->pos, sqh));
-
- /* See comment in uhci_remove_ctrl() */
- if (!(sqh->qh.qh_elink & htole32(UHCI_PTR_T))) {
- sqh->qh.qh_elink = htole32(UHCI_PTR_T);
- delay(UHCI_QH_REMOVE_DELAY);
- }
-
- pqh = uhci_find_prev_qh(vf->hqh, sqh);
- pqh->hlink = sqh->hlink;
- pqh->qh.qh_hlink = sqh->qh.qh_hlink;
- delay(UHCI_QH_REMOVE_DELAY);
- if (vf->eqh == sqh)
- vf->eqh = pqh;
- vf->bandwidth--;
-}
-
-usbd_status
-uhci_device_setintr(uhci_softc_t *sc, struct uhci_pipe *upipe, int ival)
-{
- uhci_soft_qh_t *sqh;
- int i, npoll, s;
- u_int bestbw, bw, bestoffs, offs;
-
- DPRINTFN(2, ("uhci_device_setintr: pipe=%p\n", upipe));
- if (ival == 0) {
- printf("uhci_setintr: 0 interval\n");
- return (USBD_INVAL);
- }
-
- if (ival > UHCI_VFRAMELIST_COUNT)
- ival = UHCI_VFRAMELIST_COUNT;
- npoll = (UHCI_VFRAMELIST_COUNT + ival - 1) / ival;
- DPRINTFN(2, ("uhci_device_setintr: ival=%d npoll=%d\n", ival, npoll));
-
- upipe->u.intr.npoll = npoll;
- upipe->u.intr.qhs =
- malloc(npoll * sizeof(uhci_soft_qh_t *), M_USBHC, M_WAITOK);
-
- /*
- * Figure out which offset in the schedule that has most
- * bandwidth left over.
- */
-#define MOD(i) ((i) & (UHCI_VFRAMELIST_COUNT-1))
- for (bestoffs = offs = 0, bestbw = ~0; offs < ival; offs++) {
- for (bw = i = 0; i < npoll; i++)
- bw += sc->sc_vframes[MOD(i * ival + offs)].bandwidth;
- if (bw < bestbw) {
- bestbw = bw;
- bestoffs = offs;
- }
- }
- DPRINTFN(1, ("uhci_device_setintr: bw=%d offs=%d\n", bestbw, bestoffs));
-
- for(i = 0; i < npoll; i++) {
- upipe->u.intr.qhs[i] = sqh = uhci_alloc_sqh(sc);
- sqh->elink = NULL;
- sqh->qh.qh_elink = htole32(UHCI_PTR_T);
- sqh->pos = MOD(i * ival + bestoffs);
- }
-#undef MOD
-
- s = splusb();
- /* Enter QHs into the controller data structures. */
- for(i = 0; i < npoll; i++)
- uhci_add_intr(sc, upipe->u.intr.qhs[i]);
- splx(s);
-
- DPRINTFN(5, ("uhci_device_setintr: returns %p\n", upipe));
- return (USBD_NORMAL_COMPLETION);
-}
-
-/* Open a new pipe. */
-usbd_status
-uhci_open(usbd_pipe_handle pipe)
-{
- uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus;
- struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
- usb_endpoint_descriptor_t *ed = pipe->endpoint->edesc;
- usbd_status err;
- int ival;
-
- 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 = pipe->endpoint->savedtoggle;
-
- if (pipe->device->address == sc->sc_addr) {
- switch (ed->bEndpointAddress) {
- case USB_CONTROL_ENDPOINT:
- pipe->methods = &uhci_root_ctrl_methods;
- break;
- case UE_DIR_IN | UHCI_INTR_ENDPT:
- pipe->methods = &uhci_root_intr_methods;
- break;
- default:
- return (USBD_INVAL);
- }
- } else {
- switch (ed->bmAttributes & UE_XFERTYPE) {
- case UE_CONTROL:
- pipe->methods = &uhci_device_ctrl_methods;
- upipe->u.ctl.sqh = uhci_alloc_sqh(sc);
- if (upipe->u.ctl.sqh == NULL)
- goto bad;
- upipe->u.ctl.setup = uhci_alloc_std(sc);
- if (upipe->u.ctl.setup == NULL) {
- uhci_free_sqh(sc, upipe->u.ctl.sqh);
- goto bad;
- }
- upipe->u.ctl.stat = uhci_alloc_std(sc);
- if (upipe->u.ctl.stat == NULL) {
- uhci_free_sqh(sc, upipe->u.ctl.sqh);
- uhci_free_std(sc, upipe->u.ctl.setup);
- goto bad;
- }
- err = usb_allocmem(&sc->sc_bus,
- 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);
- uhci_free_std(sc, upipe->u.ctl.stat);
- goto bad;
- }
- break;
- case UE_INTERRUPT:
- pipe->methods = &uhci_device_intr_methods;
- ival = pipe->interval;
- if (ival == USBD_DEFAULT_INTERVAL)
- ival = ed->bInterval;
- return (uhci_device_setintr(sc, upipe, ival));
- case UE_ISOCHRONOUS:
- pipe->methods = &uhci_device_isoc_methods;
- return (uhci_setup_isoc(pipe));
- case UE_BULK:
- pipe->methods = &uhci_device_bulk_methods;
- upipe->u.bulk.sqh = uhci_alloc_sqh(sc);
- if (upipe->u.bulk.sqh == NULL)
- goto bad;
- break;
- }
- }
- return (USBD_NORMAL_COMPLETION);
-
- bad:
- return (USBD_NOMEM);
-}
-
-/*
- * Data structures and routines to emulate the root hub.
- */
-usb_device_descriptor_t uhci_devd = {
- USB_DEVICE_DESCRIPTOR_SIZE,
- UDESC_DEVICE, /* type */
- {0x00, 0x01}, /* USB version */
- UDCLASS_HUB, /* class */
- UDSUBCLASS_HUB, /* subclass */
- UDPROTO_FSHUB, /* protocol */
- 64, /* max packet */
- {0},{0},{0x00,0x01}, /* device id */
- 1,2,0, /* string indicies */
- 1 /* # of configurations */
-};
-
-usb_config_descriptor_t uhci_confd = {
- USB_CONFIG_DESCRIPTOR_SIZE,
- UDESC_CONFIG,
- {USB_CONFIG_DESCRIPTOR_SIZE +
- USB_INTERFACE_DESCRIPTOR_SIZE +
- USB_ENDPOINT_DESCRIPTOR_SIZE},
- 1,
- 1,
- 0,
- UC_SELF_POWERED,
- 0 /* max power */
-};
-
-usb_interface_descriptor_t uhci_ifcd = {
- USB_INTERFACE_DESCRIPTOR_SIZE,
- UDESC_INTERFACE,
- 0,
- 0,
- 1,
- UICLASS_HUB,
- UISUBCLASS_HUB,
- UIPROTO_FSHUB,
- 0
-};
-
-usb_endpoint_descriptor_t uhci_endpd = {
- USB_ENDPOINT_DESCRIPTOR_SIZE,
- UDESC_ENDPOINT,
- UE_DIR_IN | UHCI_INTR_ENDPT,
- UE_INTERRUPT,
- {8},
- 255
-};
-
-usb_hub_descriptor_t uhci_hubd_piix = {
- USB_HUB_DESCRIPTOR_SIZE,
- UDESC_HUB,
- 2,
- { UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL, 0 },
- 50, /* power on to power good */
- 0,
- { 0x00 }, /* both ports are removable */
-};
-
-int
-uhci_str(usb_string_descriptor_t *p, int l, char *s)
-{
- int i;
-
- if (l == 0)
- return (0);
- p->bLength = 2 * strlen(s) + 2;
- if (l == 1)
- return (1);
- p->bDescriptorType = UDESC_STRING;
- l -= 2;
- for (i = 0; s[i] && l > 1; i++, l -= 2)
- USETW2(p->bString[i], 0, s[i]);
- return (2*i+2);
-}
-
-/*
- * The USB hub protocol requires that SET_FEATURE(PORT_RESET) also
- * enables the port, and also states that SET_FEATURE(PORT_ENABLE)
- * should not be used by the USB subsystem. As we cannot issue a
- * SET_FEATURE(PORT_ENABLE) externally, we must ensure that the port
- * will be enabled as part of the reset.
- *
- * On the VT83C572, the port cannot be successfully enabled until the
- * outstanding "port enable change" and "connection status change"
- * events have been reset.
- */
-static usbd_status
-uhci_portreset(uhci_softc_t *sc, int index)
-{
- int lim, port, x;
-
- if (index == 1)
- port = UHCI_PORTSC1;
- else if (index == 2)
- port = UHCI_PORTSC2;
- else
- return (USBD_IOERROR);
-
- x = URWMASK(UREAD2(sc, port));
- UWRITE2(sc, port, x | UHCI_PORTSC_PR);
-
- usb_delay_ms(&sc->sc_bus, USB_PORT_ROOT_RESET_DELAY);
-
- DPRINTFN(3,("uhci port %d reset, status0 = 0x%04x\n",
- index, UREAD2(sc, port)));
-
- x = URWMASK(UREAD2(sc, port));
- UWRITE2(sc, port, x & ~UHCI_PORTSC_PR);
-
- delay(100);
-
- DPRINTFN(3,("uhci port %d reset, status1 = 0x%04x\n",
- index, UREAD2(sc, port)));
-
- x = URWMASK(UREAD2(sc, port));
- UWRITE2(sc, port, x | UHCI_PORTSC_PE);
-
- for (lim = 10; --lim > 0;) {
- usb_delay_ms(&sc->sc_bus, USB_PORT_RESET_DELAY);
-
- x = UREAD2(sc, port);
-
- DPRINTFN(3,("uhci port %d iteration %u, status = 0x%04x\n",
- index, lim, x));
-
- if (!(x & UHCI_PORTSC_CCS)) {
- /*
- * No device is connected (or was disconnected
- * during reset). Consider the port reset.
- * The delay must be long enough to ensure on
- * the initial iteration that the device
- * connection will have been registered. 50ms
- * appears to be sufficient, but 20ms is not.
- */
- DPRINTFN(3,("uhci port %d loop %u, device detached\n",
- index, lim));
- break;
- }
-
- if (x & (UHCI_PORTSC_POEDC | UHCI_PORTSC_CSC)) {
- /*
- * Port enabled changed and/or connection
- * status changed were set. Reset either or
- * both raised flags (by writing a 1 to that
- * bit), and wait again for state to settle.
- */
- UWRITE2(sc, port, URWMASK(x) |
- (x & (UHCI_PORTSC_POEDC | UHCI_PORTSC_CSC)));
- continue;
- }
-
- if (x & UHCI_PORTSC_PE)
- /* Port is enabled */
- break;
-
- UWRITE2(sc, port, URWMASK(x) | UHCI_PORTSC_PE);
- }
-
- DPRINTFN(3,("uhci port %d reset, status2 = 0x%04x\n",
- index, UREAD2(sc, port)));
-
- if (lim <= 0) {
- DPRINTFN(1,("uhci port %d reset timed out\n", index));
- return (USBD_TIMEOUT);
- }
-
- sc->sc_isreset = 1;
- return (USBD_NORMAL_COMPLETION);
-}
-
-/*
- * Simulate a hardware hub by handling all the necessary requests.
- */
-usbd_status
-uhci_root_ctrl_transfer(usbd_xfer_handle xfer)
-{
- usbd_status err;
-
- /* Insert last in queue. */
- err = usb_insert_transfer(xfer);
- if (err)
- return (err);
-
- /*
- * Pipe isn't running (otherwise err would be USBD_INPROG),
- * so start it first.
- */
- return (uhci_root_ctrl_start(STAILQ_FIRST(&xfer->pipe->queue)));
-}
-
-usbd_status
-uhci_root_ctrl_start(usbd_xfer_handle xfer)
-{
- uhci_softc_t *sc = (uhci_softc_t *)xfer->pipe->device->bus;
- usb_device_request_t *req;
- void *buf = NULL;
- int port, x;
- int s, len, value, index, status, change, l, totlen = 0;
- usb_port_status_t ps;
- usbd_status err;
-
- if (sc->sc_dying)
- return (USBD_IOERROR);
-
-#ifdef DIAGNOSTIC
- if (!(xfer->rqflags & URQ_REQUEST))
- panic("uhci_root_ctrl_transfer: not a request");
-#endif
- req = &xfer->request;
-
- DPRINTFN(2,("uhci_root_ctrl_control type=0x%02x request=%02x\n",
- req->bmRequestType, req->bRequest));
-
- len = UGETW(req->wLength);
- value = UGETW(req->wValue);
- index = UGETW(req->wIndex);
-
- if (len != 0)
- buf = xfer->buffer;
-
-#define C(x,y) ((x) | ((y) << 8))
- switch(C(req->bRequest, req->bmRequestType)) {
- case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE):
- case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE):
- case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT):
- /*
- * DEVICE_REMOTE_WAKEUP and ENDPOINT_HALT are no-ops
- * for the integrated root hub.
- */
- break;
- case C(UR_GET_CONFIG, UT_READ_DEVICE):
- if (len > 0) {
- *(u_int8_t *)buf = sc->sc_conf;
- totlen = 1;
- }
- break;
- case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
- DPRINTFN(2,("uhci_root_ctrl_control wValue=0x%04x\n", value));
- switch(value >> 8) {
- case UDESC_DEVICE:
- if ((value & 0xff) != 0) {
- err = USBD_IOERROR;
- goto ret;
- }
- totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE);
- USETW(uhci_devd.idVendor, sc->sc_id_vendor);
- memcpy(buf, &uhci_devd, l);
- break;
- case UDESC_CONFIG:
- if ((value & 0xff) != 0) {
- err = USBD_IOERROR;
- goto ret;
- }
- totlen = l = min(len, USB_CONFIG_DESCRIPTOR_SIZE);
- memcpy(buf, &uhci_confd, l);
- buf = (char *)buf + l;
- len -= l;
- l = min(len, USB_INTERFACE_DESCRIPTOR_SIZE);
- totlen += l;
- memcpy(buf, &uhci_ifcd, l);
- buf = (char *)buf + l;
- len -= l;
- l = min(len, USB_ENDPOINT_DESCRIPTOR_SIZE);
- totlen += l;
- memcpy(buf, &uhci_endpd, l);
- break;
- case UDESC_STRING:
- if (len == 0)
- break;
- *(u_int8_t *)buf = 0;
- totlen = 1;
- switch (value & 0xff) {
- case 1: /* Vendor */
- totlen = uhci_str(buf, len, sc->sc_vendor);
- break;
- case 2: /* Product */
- totlen = uhci_str(buf, len, "UHCI root hub");
- break;
- }
- break;
- default:
- err = USBD_IOERROR;
- goto ret;
- }
- break;
- case C(UR_GET_INTERFACE, UT_READ_INTERFACE):
- if (len > 0) {
- *(u_int8_t *)buf = 0;
- totlen = 1;
- }
- break;
- case C(UR_GET_STATUS, UT_READ_DEVICE):
- if (len > 1) {
- USETW(((usb_status_t *)buf)->wStatus,UDS_SELF_POWERED);
- totlen = 2;
- }
- break;
- case C(UR_GET_STATUS, UT_READ_INTERFACE):
- case C(UR_GET_STATUS, UT_READ_ENDPOINT):
- if (len > 1) {
- USETW(((usb_status_t *)buf)->wStatus, 0);
- totlen = 2;
- }
- break;
- case C(UR_SET_ADDRESS, UT_WRITE_DEVICE):
- if (value >= USB_MAX_DEVICES) {
- err = USBD_IOERROR;
- goto ret;
- }
- sc->sc_addr = value;
- break;
- case C(UR_SET_CONFIG, UT_WRITE_DEVICE):
- if (value != 0 && value != 1) {
- err = USBD_IOERROR;
- goto ret;
- }
- sc->sc_conf = value;
- break;
- case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE):
- break;
- case C(UR_SET_FEATURE, UT_WRITE_DEVICE):
- case C(UR_SET_FEATURE, UT_WRITE_INTERFACE):
- case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT):
- err = USBD_IOERROR;
- goto ret;
- case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE):
- break;
- case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT):
- break;
- /* Hub requests */
- case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE):
- break;
- case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER):
- DPRINTFN(3, ("uhci_root_ctrl_control: UR_CLEAR_PORT_FEATURE "
- "port=%d feature=%d\n",
- index, value));
- if (index == 1)
- port = UHCI_PORTSC1;
- else if (index == 2)
- port = UHCI_PORTSC2;
- else {
- err = USBD_IOERROR;
- goto ret;
- }
- switch(value) {
- case UHF_PORT_ENABLE:
- x = URWMASK(UREAD2(sc, port));
- UWRITE2(sc, port, x & ~UHCI_PORTSC_PE);
- break;
- case UHF_PORT_SUSPEND:
- x = URWMASK(UREAD2(sc, port));
- UWRITE2(sc, port, x & ~UHCI_PORTSC_SUSP);
- break;
- case UHF_PORT_RESET:
- x = URWMASK(UREAD2(sc, port));
- UWRITE2(sc, port, x & ~UHCI_PORTSC_PR);
- break;
- case UHF_C_PORT_CONNECTION:
- x = URWMASK(UREAD2(sc, port));
- UWRITE2(sc, port, x | UHCI_PORTSC_CSC);
- break;
- case UHF_C_PORT_ENABLE:
- x = URWMASK(UREAD2(sc, port));
- UWRITE2(sc, port, x | UHCI_PORTSC_POEDC);
- break;
- case UHF_C_PORT_OVER_CURRENT:
- x = URWMASK(UREAD2(sc, port));
- UWRITE2(sc, port, x | UHCI_PORTSC_OCIC);
- break;
- case UHF_C_PORT_RESET:
- sc->sc_isreset = 0;
- err = USBD_NORMAL_COMPLETION;
- goto ret;
- case UHF_PORT_CONNECTION:
- case UHF_PORT_OVER_CURRENT:
- case UHF_PORT_POWER:
- case UHF_PORT_LOW_SPEED:
- case UHF_C_PORT_SUSPEND:
- default:
- err = USBD_IOERROR;
- goto ret;
- }
- break;
- case C(UR_GET_BUS_STATE, UT_READ_CLASS_OTHER):
- if (index == 1)
- port = UHCI_PORTSC1;
- else if (index == 2)
- port = UHCI_PORTSC2;
- else {
- err = USBD_IOERROR;
- goto ret;
- }
- if (len > 0) {
- *(u_int8_t *)buf =
- (UREAD2(sc, port) & UHCI_PORTSC_LS) >>
- UHCI_PORTSC_LS_SHIFT;
- totlen = 1;
- }
- break;
- case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE):
- if ((value & 0xff) != 0) {
- err = USBD_IOERROR;
- goto ret;
- }
- l = min(len, USB_HUB_DESCRIPTOR_SIZE);
- totlen = l;
- memcpy(buf, &uhci_hubd_piix, l);
- break;
- case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
- if (len != 4) {
- err = USBD_IOERROR;
- goto ret;
- }
- memset(buf, 0, len);
- totlen = len;
- break;
- case C(UR_GET_STATUS, UT_READ_CLASS_OTHER):
- if (index == 1)
- port = UHCI_PORTSC1;
- else if (index == 2)
- port = UHCI_PORTSC2;
- else {
- err = USBD_IOERROR;
- goto ret;
- }
- if (len != 4) {
- err = USBD_IOERROR;
- goto ret;
- }
- x = UREAD2(sc, port);
- status = change = 0;
- if (x & UHCI_PORTSC_CCS)
- status |= UPS_CURRENT_CONNECT_STATUS;
- if (x & UHCI_PORTSC_CSC)
- change |= UPS_C_CONNECT_STATUS;
- if (x & UHCI_PORTSC_PE)
- status |= UPS_PORT_ENABLED;
- if (x & UHCI_PORTSC_POEDC)
- change |= UPS_C_PORT_ENABLED;
- if (x & UHCI_PORTSC_OCI)
- status |= UPS_OVERCURRENT_INDICATOR;
- if (x & UHCI_PORTSC_OCIC)
- change |= UPS_C_OVERCURRENT_INDICATOR;
- if (x & UHCI_PORTSC_SUSP)
- status |= UPS_SUSPEND;
- if (x & UHCI_PORTSC_LSDA)
- status |= UPS_LOW_SPEED;
- status |= UPS_PORT_POWER;
- if (sc->sc_isreset)
- change |= UPS_C_PORT_RESET;
- USETW(ps.wPortStatus, status);
- USETW(ps.wPortChange, change);
- l = min(len, sizeof ps);
- memcpy(buf, &ps, l);
- totlen = l;
- break;
- case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE):
- err = USBD_IOERROR;
- goto ret;
- case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE):
- break;
- case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER):
- if (index == 1)
- port = UHCI_PORTSC1;
- else if (index == 2)
- port = UHCI_PORTSC2;
- else {
- err = USBD_IOERROR;
- goto ret;
- }
- switch(value) {
- case UHF_PORT_ENABLE:
- x = URWMASK(UREAD2(sc, port));
- UWRITE2(sc, port, x | UHCI_PORTSC_PE);
- break;
- case UHF_PORT_SUSPEND:
- x = URWMASK(UREAD2(sc, port));
- UWRITE2(sc, port, x | UHCI_PORTSC_SUSP);
- break;
- case UHF_PORT_RESET:
- err = uhci_portreset(sc, index);
- goto ret;
- case UHF_PORT_POWER:
- /* Pretend we turned on power */
- err = USBD_NORMAL_COMPLETION;
- goto ret;
- case UHF_C_PORT_CONNECTION:
- case UHF_C_PORT_ENABLE:
- case UHF_C_PORT_OVER_CURRENT:
- case UHF_PORT_CONNECTION:
- case UHF_PORT_OVER_CURRENT:
- case UHF_PORT_LOW_SPEED:
- case UHF_C_PORT_SUSPEND:
- case UHF_C_PORT_RESET:
- default:
- err = USBD_IOERROR;
- goto ret;
- }
- break;
- default:
- err = USBD_IOERROR;
- goto ret;
- }
- xfer->actlen = totlen;
- err = USBD_NORMAL_COMPLETION;
- ret:
- xfer->status = err;
- s = splusb();
- uhci_transfer_complete(xfer);
- splx(s);
- return (USBD_IN_PROGRESS);
-}
-
-/* Abort a root control request. */
-void
-uhci_root_ctrl_abort(usbd_xfer_handle xfer)
-{
- /* Nothing to do, all transfers are synchronous. */
-}
-
-/* Close the root pipe. */
-void
-uhci_root_ctrl_close(usbd_pipe_handle pipe)
-{
- DPRINTF(("uhci_root_ctrl_close\n"));
-}
-
-/* Abort a root interrupt request. */
-void
-uhci_root_intr_abort(usbd_xfer_handle xfer)
-{
- uhci_softc_t *sc = (uhci_softc_t *)xfer->pipe->device->bus;
-
- callout_stop(&sc->sc_poll_handle);
- 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
- uhci_transfer_complete(xfer);
-}
-
-usbd_status
-uhci_root_intr_transfer(usbd_xfer_handle xfer)
-{
- usbd_status err;
-
- /* Insert last in queue. */
- err = usb_insert_transfer(xfer);
- if (err)
- return (err);
-
- /*
- * Pipe isn't running (otherwise err would be USBD_INPROG),
- * so start it first.
- */
- return (uhci_root_intr_start(STAILQ_FIRST(&xfer->pipe->queue)));
-}
-
-/* Start a transfer on the root interrupt pipe */
-usbd_status
-uhci_root_intr_start(usbd_xfer_handle xfer)
-{
- usbd_pipe_handle pipe = xfer->pipe;
- uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus;
-
- DPRINTFN(3, ("uhci_root_intr_start: xfer=%p len=%d flags=%d\n",
- xfer, xfer->length, xfer->flags));
-
- if (sc->sc_dying)
- return (USBD_IOERROR);
-
- sc->sc_ival = MS_TO_TICKS(xfer->pipe->endpoint->edesc->bInterval);
- callout_reset(&sc->sc_poll_handle, sc->sc_ival, uhci_poll_hub, xfer);
- sc->sc_intr_xfer = xfer;
- return (USBD_IN_PROGRESS);
-}
-
-/* Close the root interrupt pipe. */
-void
-uhci_root_intr_close(usbd_pipe_handle pipe)
-{
- uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus;
-
- callout_stop(&sc->sc_poll_handle);
- sc->sc_intr_xfer = NULL;
- DPRINTF(("uhci_root_intr_close\n"));
-}
diff --git a/sys/dev/usb/uhci_pci.c b/sys/dev/usb/uhci_pci.c
deleted file mode 100644
index 4ee19d6..0000000
--- a/sys/dev/usb/uhci_pci.c
+++ /dev/null
@@ -1,524 +0,0 @@
-/*-
- * 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/* Universal Host Controller Interface
- *
- * UHCI spec: http://www.intel.com/
- */
-
-/* The low level controller code for UHCI has been split into
- * PCI probes and UHCI specific code. This was done to facilitate the
- * sharing of code between *BSD's
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/bus.h>
-#include <sys/queue.h>
-#include <sys/bus.h>
-
-#include <machine/bus.h>
-#include <machine/resource.h>
-#include <sys/rman.h>
-
-#include <dev/pci/pcivar.h>
-#include <dev/pci/pcireg.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdivar.h>
-#include <dev/usb/usb_mem.h>
-
-#include <dev/usb/uhcireg.h>
-#include <dev/usb/uhcivar.h>
-
-#define PCI_UHCI_VENDORID_INTEL 0x8086
-#define PCI_UHCI_VENDORID_VIA 0x1106
-
-#define PCI_UHCI_DEVICEID_PIIX3 0x70208086
-static const char *uhci_device_piix3 = "Intel 82371SB (PIIX3) USB controller";
-
-#define PCI_UHCI_DEVICEID_PIIX4 0x71128086
-#define PCI_UHCI_DEVICEID_PIIX4E 0x71128086 /* no separate stepping */
-static const char *uhci_device_piix4 = "Intel 82371AB/EB (PIIX4) USB controller";
-
-#define PCI_UHCI_DEVICEID_ICH 0x24128086
-static const char *uhci_device_ich = "Intel 82801AA (ICH) USB controller";
-
-#define PCI_UHCI_DEVICEID_ICH0 0x24228086
-static const char *uhci_device_ich0 = "Intel 82801AB (ICH0) USB controller";
-
-#define PCI_UHCI_DEVICEID_ICH2_A 0x24428086
-static const char *uhci_device_ich2_a = "Intel 82801BA/BAM (ICH2) USB controller USB-A";
-
-#define PCI_UHCI_DEVICEID_ICH2_B 0x24448086
-static const char *uhci_device_ich2_b = "Intel 82801BA/BAM (ICH2) USB controller USB-B";
-
-#define PCI_UHCI_DEVICEID_ICH3_A 0x24828086
-static const char *uhci_device_ich3_a = "Intel 82801CA/CAM (ICH3) USB controller USB-A";
-
-#define PCI_UHCI_DEVICEID_ICH3_B 0x24848086
-static const char *uhci_device_ich3_b = "Intel 82801CA/CAM (ICH3) USB controller USB-B";
-
-#define PCI_UHCI_DEVICEID_ICH3_C 0x24878086
-static const char *uhci_device_ich3_c = "Intel 82801CA/CAM (ICH3) USB controller USB-C";
-
-#define PCI_UHCI_DEVICEID_ICH4_A 0x24c28086
-static const char *uhci_device_ich4_a = "Intel 82801DB (ICH4) USB controller USB-A";
-
-#define PCI_UHCI_DEVICEID_ICH4_B 0x24c48086
-static const char *uhci_device_ich4_b = "Intel 82801DB (ICH4) USB controller USB-B";
-
-#define PCI_UHCI_DEVICEID_ICH4_C 0x24c78086
-static const char *uhci_device_ich4_c = "Intel 82801DB (ICH4) USB controller USB-C";
-
-#define PCI_UHCI_DEVICEID_ICH5_A 0x24d28086
-static const char *uhci_device_ich5_a = "Intel 82801EB (ICH5) USB controller USB-A";
-
-#define PCI_UHCI_DEVICEID_ICH5_B 0x24d48086
-static const char *uhci_device_ich5_b = "Intel 82801EB (ICH5) USB controller USB-B";
-
-#define PCI_UHCI_DEVICEID_ICH5_C 0x24d78086
-static const char *uhci_device_ich5_c = "Intel 82801EB (ICH5) USB controller USB-C";
-
-#define PCI_UHCI_DEVICEID_ICH5_D 0x24de8086
-static const char *uhci_device_ich5_d = "Intel 82801EB (ICH5) USB controller USB-D";
-
-#define PCI_UHCI_DEVICEID_ICH6_A 0x26588086
-static const char *uhci_device_ich6_a = "Intel 82801FB/FR/FW/FRW (ICH6) USB controller USB-A";
-
-#define PCI_UHCI_DEVICEID_ICH6_B 0x26598086
-static const char *uhci_device_ich6_b = "Intel 82801FB/FR/FW/FRW (ICH6) USB controller USB-B";
-
-#define PCI_UHCI_DEVICEID_ICH6_C 0x265a8086
-static const char *uhci_device_ich6_c = "Intel 82801FB/FR/FW/FRW (ICH6) USB controller USB-C";
-
-#define PCI_UHCI_DEVICEID_ICH6_D 0x265b8086
-static const char *uhci_device_ich6_d = "Intel 82801FB/FR/FW/FRW (ICH6) USB controller USB-D";
-
-#define PCI_UHCI_DEVICEID_63XXESB_1 0x26888086
-static const char *uhci_device_esb_1 = "Intel 631XESB/632XESB/3100 USB controller USB-1";
-
-#define PCI_UHCI_DEVICEID_63XXESB_2 0x26898086
-static const char *uhci_device_esb_2 = "Intel 631XESB/632XESB/3100 USB controller USB-2";
-
-#define PCI_UHCI_DEVICEID_63XXESB_3 0x268a8086
-static const char *uhci_device_esb_3 = "Intel 631XESB/632XESB/3100 USB controller USB-3";
-
-#define PCI_UHCI_DEVICEID_63XXESB_4 0x268b8086
-static const char *uhci_device_esb_4 = "Intel 631XESB/632XESB/3100 USB controller USB-4";
-
-#define PCI_UHCI_DEVICEID_ICH8_A 0x28308086
-static const char *uhci_device_ich8_a = "Intel 82801H (ICH8) USB controller USB-A";
-
-#define PCI_UHCI_DEVICEID_ICH8_B 0x28318086
-static const char *uhci_device_ich8_b = "Intel 82801H (ICH8) USB controller USB-B";
-
-#define PCI_UHCI_DEVICEID_ICH8_C 0x28328086
-static const char *uhci_device_ich8_c = "Intel 82801H (ICH8) USB controller USB-C";
-
-#define PCI_UHCI_DEVICEID_ICH8_D 0x28348086
-static const char *uhci_device_ich8_d = "Intel 82801H (ICH8) USB controller USB-D";
-
-#define PCI_UHCI_DEVICEID_ICH8_E 0x28358086
-static const char *uhci_device_ich8_e = "Intel 82801H (ICH8) USB controller USB-E";
-
-#define PCI_UHCI_DEVICEID_ICH9_A 0x29348086
-#define PCI_UHCI_DEVICEID_ICH9_B 0x29358086
-#define PCI_UHCI_DEVICEID_ICH9_C 0x29368086
-#define PCI_UHCI_DEVICEID_ICH9_D 0x29378086
-#define PCI_UHCI_DEVICEID_ICH9_E 0x29388086
-#define PCI_UHCI_DEVICEID_ICH9_F 0x29398086
-static const char *uhci_device_ich9 = "Intel 82801I (ICH9) USB controller";
-
-#define PCI_UHCI_DEVICEID_440MX 0x719a8086
-static const char *uhci_device_440mx = "Intel 82443MX USB controller";
-
-#define PCI_UHCI_DEVICEID_460GX 0x76028086
-static const char *uhci_device_460gx = "Intel 82372FB/82468GX USB controller";
-
-#define PCI_UHCI_DEVICEID_VT83C572 0x30381106
-static const char *uhci_device_vt83c572 = "VIA 83C572 USB controller";
-
-static const char *uhci_device_generic = "UHCI (generic) USB controller";
-
-#define PCI_UHCI_BASE_REG 0x20
-
-
-static device_attach_t uhci_pci_attach;
-static device_detach_t uhci_pci_detach;
-static device_suspend_t uhci_pci_suspend;
-static device_resume_t uhci_pci_resume;
-
-static int
-uhci_pci_suspend(device_t self)
-{
- uhci_softc_t *sc = device_get_softc(self);
- int err;
-
- err = bus_generic_suspend(self);
- if (err)
- return err;
- uhci_power(PWR_SUSPEND, sc);
-
- return 0;
-}
-
-static int
-uhci_pci_resume(device_t self)
-{
- uhci_softc_t *sc = device_get_softc(self);
-
- pci_write_config(self, PCI_LEGSUP, PCI_LEGSUP_USBPIRQDEN, 2);
-
- uhci_power(PWR_RESUME, sc);
- bus_generic_resume(self);
-
- return 0;
-}
-
-static const char *
-uhci_pci_match(device_t self)
-{
- u_int32_t device_id = pci_get_devid(self);
-
- if (device_id == PCI_UHCI_DEVICEID_PIIX3) {
- return (uhci_device_piix3);
- } else if (device_id == PCI_UHCI_DEVICEID_PIIX4) {
- return (uhci_device_piix4);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH) {
- return (uhci_device_ich);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH0) {
- return (uhci_device_ich0);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH2_A) {
- return (uhci_device_ich2_a);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH2_B) {
- return (uhci_device_ich2_b);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH3_A) {
- return (uhci_device_ich3_a);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH3_B) {
- return (uhci_device_ich3_b);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH3_C) {
- return (uhci_device_ich3_c);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH4_A) {
- return (uhci_device_ich4_a);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH4_B) {
- return (uhci_device_ich4_b);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH4_C) {
- return (uhci_device_ich4_c);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH5_A) {
- return (uhci_device_ich5_a);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH5_B) {
- return (uhci_device_ich5_b);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH5_C) {
- return (uhci_device_ich5_c);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH5_D) {
- return (uhci_device_ich5_d);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH6_A) {
- return (uhci_device_ich6_a);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH6_B) {
- return (uhci_device_ich6_b);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH6_C) {
- return (uhci_device_ich6_c);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH6_D) {
- return (uhci_device_ich6_d);
- } else if (device_id == PCI_UHCI_DEVICEID_63XXESB_1) {
- return (uhci_device_esb_1);
- } else if (device_id == PCI_UHCI_DEVICEID_63XXESB_2) {
- return (uhci_device_esb_2);
- } else if (device_id == PCI_UHCI_DEVICEID_63XXESB_3) {
- return (uhci_device_esb_3);
- } else if (device_id == PCI_UHCI_DEVICEID_63XXESB_4) {
- return (uhci_device_esb_4);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH8_A) {
- return (uhci_device_ich8_a);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH8_B) {
- return (uhci_device_ich8_b);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH8_C) {
- return (uhci_device_ich8_c);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH8_D) {
- return (uhci_device_ich8_d);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH8_E) {
- return (uhci_device_ich8_e);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH9_A) {
- return (uhci_device_ich9);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH9_B) {
- return (uhci_device_ich9);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH9_C) {
- return (uhci_device_ich9);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH9_D) {
- return (uhci_device_ich9);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH9_E) {
- return (uhci_device_ich9);
- } else if (device_id == PCI_UHCI_DEVICEID_ICH9_F) {
- return (uhci_device_ich9);
- } else if (device_id == PCI_UHCI_DEVICEID_440MX) {
- return (uhci_device_440mx);
- } else if (device_id == PCI_UHCI_DEVICEID_460GX) {
- return (uhci_device_460gx);
- } else if (device_id == PCI_UHCI_DEVICEID_VT83C572) {
- return (uhci_device_vt83c572);
- } else {
- if (pci_get_class(self) == PCIC_SERIALBUS
- && pci_get_subclass(self) == PCIS_SERIALBUS_USB
- && pci_get_progif(self) == PCI_INTERFACE_UHCI) {
- return (uhci_device_generic);
- }
- }
-
- return NULL; /* dunno... */
-}
-
-static int
-uhci_pci_probe(device_t self)
-{
- const char *desc = uhci_pci_match(self);
-
- if (desc) {
- device_set_desc(self, desc);
- return BUS_PROBE_DEFAULT;
- } else {
- return ENXIO;
- }
-}
-
-static int
-uhci_pci_attach(device_t self)
-{
- uhci_softc_t *sc = device_get_softc(self);
- int rid;
- int err;
-
- pci_enable_busmaster(self);
-
- rid = PCI_UHCI_BASE_REG;
- sc->io_res = bus_alloc_resource_any(self, SYS_RES_IOPORT, &rid,
- RF_ACTIVE);
- if (!sc->io_res) {
- device_printf(self, "Could not map ports\n");
- return ENXIO;
- }
- sc->iot = rman_get_bustag(sc->io_res);
- sc->ioh = rman_get_bushandle(sc->io_res);
-
- /* disable interrupts */
- bus_space_write_2(sc->iot, sc->ioh, UHCI_INTR, 0);
-
- rid = 0;
- sc->irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid,
- RF_SHAREABLE | RF_ACTIVE);
- if (sc->irq_res == NULL) {
- device_printf(self, "Could not allocate irq\n");
- uhci_pci_detach(self);
- return ENXIO;
- }
- sc->sc_bus.bdev = device_add_child(self, "usb", -1);
- if (!sc->sc_bus.bdev) {
- device_printf(self, "Could not add USB device\n");
- uhci_pci_detach(self);
- return ENOMEM;
- }
- device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
-
- /* uhci_pci_match must never return NULL if uhci_pci_probe succeeded */
- device_set_desc(sc->sc_bus.bdev, uhci_pci_match(self));
- switch (pci_get_vendor(self)) {
- case PCI_UHCI_VENDORID_INTEL:
- sprintf(sc->sc_vendor, "Intel");
- break;
- case PCI_UHCI_VENDORID_VIA:
- sprintf(sc->sc_vendor, "VIA");
- break;
- default:
- if (bootverbose)
- device_printf(self, "(New UHCI DeviceId=0x%08x)\n",
- pci_get_devid(self));
- sprintf(sc->sc_vendor, "(0x%04x)", pci_get_vendor(self));
- }
-
- switch (pci_read_config(self, PCI_USBREV, 1) & PCI_USBREV_MASK) {
- case PCI_USBREV_PRE_1_0:
- sc->sc_bus.usbrev = USBREV_PRE_1_0;
- break;
- case PCI_USBREV_1_0:
- sc->sc_bus.usbrev = USBREV_1_0;
- break;
- default:
- sc->sc_bus.usbrev = USBREV_UNKNOWN;
- break;
- }
-
- /*
- * Quirk for Parallels Desktop 4.0.
- */
- if (pci_get_devid(self) == PCI_UHCI_DEVICEID_ICH6_A)
- sc->sc_bus.usbrev = USBREV_2_0;
-
- err = bus_setup_intr(self, sc->irq_res, INTR_TYPE_BIO,
- NULL, (driver_intr_t *) uhci_intr, sc, &sc->ih);
- if (err) {
- device_printf(self, "Could not setup irq, %d\n", err);
- sc->ih = NULL;
- uhci_pci_detach(self);
- return ENXIO;
- }
- /*
- * Set the PIRQD enable bit and switch off all the others. We don't
- * want legacy support to interfere with us XXX Does this also mean
- * that the BIOS won't touch the keyboard anymore if it is connected
- * to the ports of the root hub?
- */
-#ifdef USB_DEBUG
- if (pci_read_config(self, PCI_LEGSUP, 2) != PCI_LEGSUP_USBPIRQDEN)
- device_printf(self, "LegSup = 0x%04x\n",
- pci_read_config(self, PCI_LEGSUP, 2));
-#endif
- pci_write_config(self, PCI_LEGSUP, PCI_LEGSUP_USBPIRQDEN, 2);
-
- /* Allocate a parent dma tag for DMA maps */
- err = bus_dma_tag_create(bus_get_dma_tag(self), 1, 0,
- BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
- BUS_SPACE_MAXSIZE_32BIT, USB_DMA_NSEG, BUS_SPACE_MAXSIZE_32BIT, 0,
- NULL, NULL, &sc->sc_bus.parent_dmatag);
- if (err) {
- device_printf(self, "Could not allocate parent DMA tag (%d)\n",
- err);
- uhci_pci_detach(self);
- return ENXIO;
- }
- /* Allocate a dma tag for transfer buffers */
- err = bus_dma_tag_create(sc->sc_bus.parent_dmatag, 1, 0,
- BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
- BUS_SPACE_MAXSIZE_32BIT, USB_DMA_NSEG, BUS_SPACE_MAXSIZE_32BIT, 0,
- busdma_lock_mutex, &Giant, &sc->sc_bus.buffer_dmatag);
- if (err) {
- device_printf(self, "Could not allocate transfer tag (%d)\n",
- err);
- uhci_pci_detach(self);
- return ENXIO;
- }
-
- err = uhci_init(sc);
- if (!err) {
- sc->sc_flags |= UHCI_SCFLG_DONEINIT;
- err = device_probe_and_attach(sc->sc_bus.bdev);
- }
-
- if (err) {
- device_printf(self, "USB init failed\n");
- uhci_pci_detach(self);
- return EIO;
- }
- return 0; /* success */
-}
-
-int
-uhci_pci_detach(device_t self)
-{
- uhci_softc_t *sc = device_get_softc(self);
-
- if (sc->sc_flags & UHCI_SCFLG_DONEINIT) {
- uhci_detach(sc, 0);
- sc->sc_flags &= ~UHCI_SCFLG_DONEINIT;
- }
-
- if (sc->sc_bus.parent_dmatag != NULL)
- bus_dma_tag_destroy(sc->sc_bus.parent_dmatag);
- if (sc->sc_bus.buffer_dmatag != NULL)
- bus_dma_tag_destroy(sc->sc_bus.buffer_dmatag);
-
- if (sc->irq_res && sc->ih) {
- int err = bus_teardown_intr(self, sc->irq_res, sc->ih);
-
- if (err)
- /* XXX or should we panic? */
- device_printf(self, "Could not tear down irq, %d\n",
- err);
- sc->ih = NULL;
- }
- if (sc->sc_bus.bdev) {
- device_delete_child(self, sc->sc_bus.bdev);
- sc->sc_bus.bdev = NULL;
- }
- if (sc->irq_res) {
- bus_release_resource(self, SYS_RES_IRQ, 0, sc->irq_res);
- sc->irq_res = NULL;
- }
- if (sc->io_res) {
- bus_release_resource(self, SYS_RES_IOPORT, PCI_UHCI_BASE_REG,
- sc->io_res);
- sc->io_res = NULL;
- sc->iot = 0;
- sc->ioh = 0;
- }
- return 0;
-}
-
-
-static device_method_t uhci_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, uhci_pci_probe),
- DEVMETHOD(device_attach, uhci_pci_attach),
- DEVMETHOD(device_detach, uhci_pci_detach),
- DEVMETHOD(device_suspend, uhci_pci_suspend),
- DEVMETHOD(device_resume, uhci_pci_resume),
- DEVMETHOD(device_shutdown, bus_generic_shutdown),
-
- /* Bus interface */
- DEVMETHOD(bus_print_child, bus_generic_print_child),
-
- {0, 0}
-};
-
-static driver_t uhci_driver = {
- "uhci",
- uhci_methods,
- sizeof(uhci_softc_t),
-};
-
-static devclass_t uhci_devclass;
-
-DRIVER_MODULE(uhci, pci, uhci_driver, uhci_devclass, 0, 0);
-DRIVER_MODULE(uhci, cardbus, uhci_driver, uhci_devclass, 0, 0);
-MODULE_DEPEND(uhci, usb, 1, 1, 1);
diff --git a/sys/dev/usb/uhcireg.h b/sys/dev/usb/uhcireg.h
deleted file mode 100644
index 512dd2d..0000000
--- a/sys/dev/usb/uhcireg.h
+++ /dev/null
@@ -1,193 +0,0 @@
-/* $NetBSD: uhcireg.h,v 1.15 2002/02/11 11:41:30 augustss Exp $ */
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) 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.
- */
-
-#ifndef _DEV_PCI_UHCIREG_H_
-#define _DEV_PCI_UHCIREG_H_
-
-/*** PCI config registers ***/
-
-#define PCI_USBREV 0x60 /* USB protocol revision */
-#define PCI_USBREV_MASK 0xff
-#define PCI_USBREV_PRE_1_0 0x00
-#define PCI_USBREV_1_0 0x10
-#define PCI_USBREV_1_1 0x11
-
-#define PCI_LEGSUP 0xc0 /* Legacy Support register */
-#define PCI_LEGSUP_USBPIRQDEN 0x2000 /* USB PIRQ D Enable */
-
-#define PCI_CBIO 0x20 /* configuration base IO */
-
-#define PCI_INTERFACE_UHCI 0x00
-
-/*** UHCI registers ***/
-
-#define UHCI_CMD 0x00
-#define UHCI_CMD_RS 0x0001
-#define UHCI_CMD_HCRESET 0x0002
-#define UHCI_CMD_GRESET 0x0004
-#define UHCI_CMD_EGSM 0x0008
-#define UHCI_CMD_FGR 0x0010
-#define UHCI_CMD_SWDBG 0x0020
-#define UHCI_CMD_CF 0x0040
-#define UHCI_CMD_MAXP 0x0080
-
-#define UHCI_STS 0x02
-#define UHCI_STS_USBINT 0x0001
-#define UHCI_STS_USBEI 0x0002
-#define UHCI_STS_RD 0x0004
-#define UHCI_STS_HSE 0x0008
-#define UHCI_STS_HCPE 0x0010
-#define UHCI_STS_HCH 0x0020
-#define UHCI_STS_ALLINTRS 0x003f
-
-#define UHCI_INTR 0x04
-#define UHCI_INTR_TOCRCIE 0x0001
-#define UHCI_INTR_RIE 0x0002
-#define UHCI_INTR_IOCE 0x0004
-#define UHCI_INTR_SPIE 0x0008
-
-#define UHCI_FRNUM 0x06
-#define UHCI_FRNUM_MASK 0x03ff
-
-#define UHCI_FLBASEADDR 0x08
-
-#define UHCI_SOF 0x0c
-#define UHCI_SOF_MASK 0x7f
-
-#define UHCI_PORTSC1 0x010
-#define UHCI_PORTSC2 0x012
-#define UHCI_PORTSC_CCS 0x0001
-#define UHCI_PORTSC_CSC 0x0002
-#define UHCI_PORTSC_PE 0x0004
-#define UHCI_PORTSC_POEDC 0x0008
-#define UHCI_PORTSC_LS 0x0030
-#define UHCI_PORTSC_LS_SHIFT 4
-#define UHCI_PORTSC_RD 0x0040
-#define UHCI_PORTSC_LSDA 0x0100
-#define UHCI_PORTSC_PR 0x0200
-#define UHCI_PORTSC_OCI 0x0400
-#define UHCI_PORTSC_OCIC 0x0800
-#define UHCI_PORTSC_SUSP 0x1000
-
-#define URWMASK(x) \
- ((x) & (UHCI_PORTSC_SUSP | UHCI_PORTSC_PR | UHCI_PORTSC_RD | UHCI_PORTSC_PE))
-
-#define UHCI_FRAMELIST_COUNT 1024
-#define UHCI_FRAMELIST_ALIGN 4096
-
-#define UHCI_TD_ALIGN 16
-#define UHCI_QH_ALIGN 16
-
-typedef u_int32_t uhci_physaddr_t;
-#define UHCI_PTR_T 0x00000001
-#define UHCI_PTR_TD 0x00000000
-#define UHCI_PTR_QH 0x00000002
-#define UHCI_PTR_VF 0x00000004
-
-/*
- * Wait this long after a QH has been removed. This gives that HC a
- * chance to stop looking at it before it's recycled.
- */
-#define UHCI_QH_REMOVE_DELAY 5
-
-/*
- * The Queue Heads and Transfer Descriptors are accessed
- * by both the CPU and the USB controller which run
- * concurrently. This means that they have to be accessed
- * with great care. As long as the data structures are
- * not linked into the controller's frame list they cannot
- * be accessed by it and anything goes. As soon as a
- * TD is accessible by the controller it "owns" the td_status
- * field; it will not be written by the CPU. Similarly
- * the controller "owns" the qh_elink field.
- */
-
-typedef struct {
- uhci_physaddr_t td_link;
- u_int32_t td_status;
-#define UHCI_TD_GET_ACTLEN(s) (((s) + 1) & 0x3ff)
-#define UHCI_TD_ZERO_ACTLEN(t) ((t) | 0x3ff)
-#define UHCI_TD_BITSTUFF 0x00020000
-#define UHCI_TD_CRCTO 0x00040000
-#define UHCI_TD_NAK 0x00080000
-#define UHCI_TD_BABBLE 0x00100000
-#define UHCI_TD_DBUFFER 0x00200000
-#define UHCI_TD_STALLED 0x00400000
-#define UHCI_TD_ACTIVE 0x00800000
-#define UHCI_TD_IOC 0x01000000
-#define UHCI_TD_IOS 0x02000000
-#define UHCI_TD_LS 0x04000000
-#define UHCI_TD_GET_ERRCNT(s) (((s) >> 27) & 3)
-#define UHCI_TD_SET_ERRCNT(n) ((n) << 27)
-#define UHCI_TD_SPD 0x20000000
- u_int32_t td_token;
-#define UHCI_TD_PID_IN 0x00000069
-#define UHCI_TD_PID_OUT 0x000000e1
-#define UHCI_TD_PID_SETUP 0x0000002d
-#define UHCI_TD_GET_PID(s) ((s) & 0xff)
-#define UHCI_TD_SET_DEVADDR(a) ((a) << 8)
-#define UHCI_TD_GET_DEVADDR(s) (((s) >> 8) & 0x7f)
-#define UHCI_TD_SET_ENDPT(e) (((e)&0xf) << 15)
-#define UHCI_TD_GET_ENDPT(s) (((s) >> 15) & 0xf)
-#define UHCI_TD_SET_DT(t) ((t) << 19)
-#define UHCI_TD_GET_DT(s) (((s) >> 19) & 1)
-#define UHCI_TD_SET_MAXLEN(l) (((l)-1) << 21)
-#define UHCI_TD_GET_MAXLEN(s) ((((s) >> 21) + 1) & 0x7ff)
-#define UHCI_TD_MAXLEN_MASK 0xffe00000
- u_int32_t td_buffer;
-} uhci_td_t;
-
-#define UHCI_TD_ERROR (UHCI_TD_BITSTUFF|UHCI_TD_CRCTO|UHCI_TD_BABBLE|UHCI_TD_DBUFFER|UHCI_TD_STALLED)
-
-#define UHCI_TD_SETUP(len, endp, dev) (UHCI_TD_SET_MAXLEN(len) | \
- UHCI_TD_SET_ENDPT(endp) | UHCI_TD_SET_DEVADDR(dev) | UHCI_TD_PID_SETUP)
-#define UHCI_TD_OUT(len, endp, dev, dt) (UHCI_TD_SET_MAXLEN(len) | \
- UHCI_TD_SET_ENDPT(endp) | UHCI_TD_SET_DEVADDR(dev) | \
- UHCI_TD_PID_OUT | UHCI_TD_SET_DT(dt))
-#define UHCI_TD_IN(len, endp, dev, dt) (UHCI_TD_SET_MAXLEN(len) | \
- UHCI_TD_SET_ENDPT(endp) | UHCI_TD_SET_DEVADDR(dev) | UHCI_TD_PID_IN | \
- UHCI_TD_SET_DT(dt))
-
-typedef struct {
- uhci_physaddr_t qh_hlink;
- uhci_physaddr_t qh_elink;
-} uhci_qh_t;
-
-#endif /* _DEV_PCI_UHCIREG_H_ */
diff --git a/sys/dev/usb/uhcivar.h b/sys/dev/usb/uhcivar.h
deleted file mode 100644
index 0df23f1..0000000
--- a/sys/dev/usb/uhcivar.h
+++ /dev/null
@@ -1,206 +0,0 @@
-/* $NetBSD: uhcivar.h,v 1.33 2002/02/11 11:41:30 augustss Exp $ */
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) 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.
- */
-
-/*
- * To avoid having 1024 TDs for each isochronous transfer we introduce
- * a virtual frame list. Every UHCI_VFRAMELIST_COUNT entries in the real
- * frame list points to a non-active TD. These, in turn, form the
- * starts of the virtual frame list. This also has the advantage that it
- * simplifies linking in/out of TDs/QHs in the schedule.
- * Furthermore, initially each of the inactive TDs point to an inactive
- * QH that forms the start of the interrupt traffic for that slot.
- * Each of these QHs point to the same QH that is the start of control
- * traffic. This QH points at another QH which is the start of the
- * bulk traffic.
- *
- * UHCI_VFRAMELIST_COUNT should be a power of 2 and <= UHCI_FRAMELIST_COUNT.
- */
-#define UHCI_VFRAMELIST_COUNT 128
-
-typedef struct uhci_soft_qh uhci_soft_qh_t;
-typedef struct uhci_soft_td uhci_soft_td_t;
-
-typedef union {
- struct uhci_soft_qh *sqh;
- struct uhci_soft_td *std;
-} uhci_soft_td_qh_t;
-
-/*
- * An interrupt info struct contains the information needed to
- * execute a requested routine when the controller generates an
- * interrupt. Since we cannot know which transfer generated
- * the interrupt all structs are linked together so they can be
- * searched at interrupt time.
- */
-typedef struct uhci_intr_info {
- struct uhci_softc *sc;
- usbd_xfer_handle xfer;
- uhci_soft_td_t *stdstart;
- uhci_soft_td_t *stdend;
- LIST_ENTRY(uhci_intr_info) list;
-#ifdef DIAGNOSTIC
- int isdone;
-#endif
-} uhci_intr_info_t;
-
-struct uhci_xfer {
- struct usbd_xfer xfer;
- uhci_intr_info_t iinfo;
- struct usb_task abort_task;
- int curframe;
- u_int32_t uhci_xfer_flags;
-};
-
-#define UHCI_XFER_ABORTING 0x0001 /* xfer is aborting. */
-#define UHCI_XFER_ABORTWAIT 0x0002 /* abort completion is being awaited. */
-
-#define UXFER(xfer) ((struct uhci_xfer *)(xfer))
-
-/*
- * Extra information that we need for a TD.
- */
-struct uhci_soft_td {
- uhci_td_t td; /* The real TD, must be first */
- uhci_soft_td_qh_t link; /* soft version of the td_link field */
- uhci_physaddr_t physaddr; /* TD's physical address. */
- usb_dma_t aux_dma; /* Auxillary storage if needed. */
- void *aux_data; /* Original aux data virtual address. */
- int aux_len; /* Auxillary storage size. */
-};
-/*
- * Make the size such that it is a multiple of UHCI_TD_ALIGN. This way
- * we can pack a number of soft TD together and have the real TD well
- * aligned.
- * NOTE: Minimum size is 32 bytes.
- */
-#define UHCI_STD_SIZE ((sizeof (struct uhci_soft_td) + UHCI_TD_ALIGN - 1) / UHCI_TD_ALIGN * UHCI_TD_ALIGN)
-#define UHCI_STD_CHUNK (PAGE_SIZE / UHCI_STD_SIZE)
-
-/*
- * Extra information that we need for a QH.
- */
-struct uhci_soft_qh {
- uhci_qh_t qh; /* The real QH, must be first */
- uhci_soft_qh_t *hlink; /* soft version of qh_hlink */
- uhci_soft_td_t *elink; /* soft version of qh_elink */
- uhci_physaddr_t physaddr; /* QH's physical address. */
- int pos; /* Timeslot position */
-};
-/* 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)
-#define UHCI_SQH_CHUNK (PAGE_SIZE / UHCI_SQH_SIZE)
-
-/*
- * Information about an entry in the virtual frame list.
- */
-struct uhci_vframe {
- uhci_soft_td_t *htd; /* pointer to dummy TD */
- uhci_soft_td_t *etd; /* pointer to last TD */
- uhci_soft_qh_t *hqh; /* pointer to dummy QH */
- uhci_soft_qh_t *eqh; /* pointer to last QH */
- u_int bandwidth; /* max bandwidth used by this frame */
-};
-
-#define UHCI_SCFLG_DONEINIT 0x0001 /* uhci_init() done */
-
-typedef struct uhci_softc {
- struct usbd_bus sc_bus; /* base device */
- int sc_flags;
- bus_space_tag_t iot;
- bus_space_handle_t ioh;
- bus_size_t sc_size;
- void *ih;
-
- struct resource *io_res;
- struct resource *irq_res;
- uhci_physaddr_t *sc_pframes;
- usb_dma_t sc_dma;
- struct uhci_vframe sc_vframes[UHCI_VFRAMELIST_COUNT];
-
- uhci_soft_qh_t *sc_lctl_start; /* dummy QH for low speed control */
- uhci_soft_qh_t *sc_lctl_end; /* last control QH */
- uhci_soft_qh_t *sc_hctl_start; /* dummy QH for high speed control */
- uhci_soft_qh_t *sc_hctl_end; /* last control QH */
- uhci_soft_qh_t *sc_bulk_start; /* dummy QH for bulk */
- uhci_soft_qh_t *sc_bulk_end; /* last bulk transfer */
- uhci_soft_qh_t *sc_last_qh; /* dummy QH at the end */
- u_int32_t sc_loops; /* number of QHs that wants looping */
-
- uhci_soft_td_t *sc_freetds; /* TD free list */
- uhci_soft_qh_t *sc_freeqhs; /* QH free list */
-
- STAILQ_HEAD(, usbd_xfer) sc_free_xfers; /* free xfers */
-
- u_int8_t sc_addr; /* device address */
- u_int8_t sc_conf; /* device configuration */
-
- u_int8_t sc_saved_sof;
- u_int16_t sc_saved_frnum;
-
-#ifdef USB_USE_SOFTINTR
- char sc_softwake;
-#endif /* USB_USE_SOFTINTR */
-
- char sc_isreset;
- char sc_suspend;
- char sc_dying;
-
- 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_intr_xfer; /* root hub interrupt transfer */
- struct callout sc_poll_handle;
-
- char sc_vendor[16]; /* vendor string for root hub */
- int sc_id_vendor; /* vendor ID for root hub */
-
-#if defined(__NetBSD__)
- void *sc_powerhook; /* cookie from power hook */
- void *sc_shutdownhook; /* cookie from shutdown hook */
-#endif
-} uhci_softc_t;
-
-usbd_status uhci_init(uhci_softc_t *);
-int uhci_intr(void *);
-int uhci_detach(uhci_softc_t *, int);
-void uhci_shutdown(void *v);
-void uhci_power(int state, void *priv);
-
diff --git a/sys/dev/usb/uhid.c b/sys/dev/usb/uhid.c
deleted file mode 100644
index d821c01..0000000
--- a/sys/dev/usb/uhid.c
+++ /dev/null
@@ -1,755 +0,0 @@
-/* $NetBSD: uhid.c,v 1.46 2001/11/13 06:24:55 lukem Exp $ */
-
-/* Also already merged from NetBSD:
- * $NetBSD: uhid.c,v 1.54 2002/09/23 05:51:21 simonb Exp $
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) 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.
- */
-
-/*
- * HID spec: http://www.usb.org/developers/devclass_docs/HID1_11.pdf
- */
-
-/*
- * XXX TODO: Convert this driver to use si_drv[12] rather than the
- * devclass_get_softc junk
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/clist.h>
-#include <sys/kernel.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/mutex.h>
-#include <sys/signalvar.h>
-#include <sys/fcntl.h>
-#include <sys/ioccom.h>
-#include <sys/filio.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/ioccom.h>
-#include <sys/conf.h>
-#include <sys/selinfo.h>
-#include <sys/proc.h>
-#include <sys/poll.h>
-#include <sys/sysctl.h>
-#include <sys/ttycom.h>
-#include <sys/uio.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbhid.h>
-
-#include "usbdevs.h"
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include <dev/usb/hid.h>
-
-/* Replacement report descriptors for devices shipped with broken ones */
-#include <dev/usb/ugraphire_rdesc.h>
-#include <dev/usb/uxb360gp_rdesc.h>
-
-/* For hid blacklist quirk */
-#include <dev/usb/usb_quirks.h>
-
-#ifdef USB_DEBUG
-#define DPRINTF(x) if (uhiddebug) printf x
-#define DPRINTFN(n,x) if (uhiddebug>(n)) printf x
-int uhiddebug = 0;
-SYSCTL_NODE(_hw_usb, OID_AUTO, uhid, CTLFLAG_RW, 0, "USB uhid");
-SYSCTL_INT(_hw_usb_uhid, OID_AUTO, debug, CTLFLAG_RW,
- &uhiddebug, 0, "uhid debug level");
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-struct uhid_softc {
- device_t sc_dev; /* base device */
- usbd_device_handle sc_udev;
- usbd_interface_handle sc_iface; /* interface */
- usbd_pipe_handle sc_intrpipe; /* interrupt pipe */
- int sc_ep_addr;
-
- int sc_isize;
- int sc_osize;
- int sc_fsize;
- u_int8_t sc_iid;
- u_int8_t sc_oid;
- u_int8_t sc_fid;
-
- u_char *sc_ibuf;
- u_char *sc_obuf;
-
- void *sc_repdesc;
- int sc_repdesc_size;
-
- struct clist sc_q;
- struct selinfo sc_rsel;
- struct proc *sc_async; /* process that wants SIGIO */
- u_char sc_state; /* driver state */
-#define UHID_OPEN 0x01 /* device is open */
-#define UHID_ASLP 0x02 /* waiting for device data */
-#define UHID_NEEDCLEAR 0x04 /* needs clearing endpoint stall */
-#define UHID_IMMED 0x08 /* return read data immediately */
-
- int sc_refcnt;
- u_char sc_dying;
-
- struct cdev *dev;
-};
-
-#define UHIDUNIT(dev) (dev2unit(dev))
-#define UHID_CHUNK 128 /* chunk size for read */
-#define UHID_BSIZE 1020 /* buffer size */
-
-d_open_t uhidopen;
-d_close_t uhidclose;
-d_read_t uhidread;
-d_write_t uhidwrite;
-d_ioctl_t uhidioctl;
-d_poll_t uhidpoll;
-
-
-static struct cdevsw uhid_cdevsw = {
- .d_version = D_VERSION,
- .d_flags = D_NEEDGIANT,
- .d_open = uhidopen,
- .d_close = uhidclose,
- .d_read = uhidread,
- .d_write = uhidwrite,
- .d_ioctl = uhidioctl,
- .d_poll = uhidpoll,
- .d_name = "uhid",
-};
-
-static void uhid_intr(usbd_xfer_handle, usbd_private_handle,
- usbd_status);
-
-static int uhid_do_read(struct uhid_softc *, struct uio *uio, int);
-static int uhid_do_write(struct uhid_softc *, struct uio *uio, int);
-static int uhid_do_ioctl(struct uhid_softc *, u_long, caddr_t, int,
- struct thread *);
-
-MODULE_DEPEND(uhid, usb, 1, 1, 1);
-
-static device_probe_t uhid_match;
-static device_attach_t uhid_attach;
-static device_detach_t uhid_detach;
-
-static device_method_t uhid_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, uhid_match),
- DEVMETHOD(device_attach, uhid_attach),
- DEVMETHOD(device_detach, uhid_detach),
-
- { 0, 0 }
-};
-
-static driver_t uhid_driver = {
- "uhid",
- uhid_methods,
- sizeof(struct uhid_softc)
-};
-
-static devclass_t uhid_devclass;
-
-DRIVER_MODULE(uhid, uhub, uhid_driver, uhid_devclass, usbd_driver_load, 0);
-
-static int
-uhid_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usb_interface_descriptor_t *id;
-
- if (uaa->iface == NULL)
- return (UMATCH_NONE);
- id = usbd_get_interface_descriptor(uaa->iface);
- if (id == NULL)
- return (UMATCH_NONE);
- if (id->bInterfaceClass != UICLASS_HID) {
- /* The Xbox 360 gamepad doesn't use the HID class. */
- if (id->bInterfaceClass != UICLASS_VENDOR ||
- id->bInterfaceSubClass != UISUBCLASS_XBOX360_CONTROLLER ||
- id->bInterfaceProtocol != UIPROTO_XBOX360_GAMEPAD)
- return (UMATCH_NONE);
- }
- if (usbd_get_quirks(uaa->device)->uq_flags & UQ_HID_IGNORE)
- return (UMATCH_NONE);
-#if 0
- if (uaa->matchlvl)
- return (uaa->matchlvl);
-#endif
-
- return (UMATCH_IFACECLASS_GENERIC);
-}
-
-static int
-uhid_attach(device_t self)
-{
- struct uhid_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usbd_interface_handle iface = uaa->iface;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
- int size;
- void *desc;
- const void *descptr;
- usbd_status err;
-
- sc->sc_dev = self;
- sc->sc_udev = uaa->device;
- sc->sc_iface = iface;
- id = usbd_get_interface_descriptor(iface);
-
- ed = usbd_interface2endpoint_descriptor(iface, 0);
- if (ed == NULL) {
- printf("%s: could not read endpoint descriptor\n",
- device_get_nameunit(sc->sc_dev));
- sc->sc_dying = 1;
- return ENXIO;
- }
-
- DPRINTFN(10,("uhid_attach: bLength=%d bDescriptorType=%d "
- "bEndpointAddress=%d-%s bmAttributes=%d wMaxPacketSize=%d"
- " bInterval=%d\n",
- ed->bLength, ed->bDescriptorType,
- ed->bEndpointAddress & UE_ADDR,
- UE_GET_DIR(ed->bEndpointAddress)==UE_DIR_IN? "in" : "out",
- ed->bmAttributes & UE_XFERTYPE,
- UGETW(ed->wMaxPacketSize), ed->bInterval));
-
- if (UE_GET_DIR(ed->bEndpointAddress) != UE_DIR_IN ||
- (ed->bmAttributes & UE_XFERTYPE) != UE_INTERRUPT) {
- printf("%s: unexpected endpoint\n", device_get_nameunit(sc->sc_dev));
- sc->sc_dying = 1;
- return ENXIO;
- }
-
- sc->sc_ep_addr = ed->bEndpointAddress;
-
- descptr = NULL;
- if (uaa->vendor == USB_VENDOR_WACOM) {
- /* The report descriptor for the Wacom Graphire is broken. */
- if (uaa->product == USB_PRODUCT_WACOM_GRAPHIRE) {
- size = sizeof uhid_graphire_report_descr;
- descptr = uhid_graphire_report_descr;
- } else if (uaa->product == USB_PRODUCT_WACOM_GRAPHIRE3_4X5) {
- static uByte reportbuf[] = {2, 2, 2};
-
- /*
- * The Graphire3 needs 0x0202 to be written to
- * feature report ID 2 before it'll start
- * returning digitizer data.
- */
- usbd_set_report(uaa->iface, UHID_FEATURE_REPORT, 2,
- &reportbuf, sizeof reportbuf);
-
- size = sizeof uhid_graphire3_4x5_report_descr;
- descptr = uhid_graphire3_4x5_report_descr;
- }
- } else if (id->bInterfaceClass == UICLASS_VENDOR &&
- id->bInterfaceSubClass == UISUBCLASS_XBOX360_CONTROLLER &&
- id->bInterfaceProtocol == UIPROTO_XBOX360_GAMEPAD) {
- static uByte reportbuf[] = {1, 3, 0};
-
- /* The LEDs on the gamepad are blinking by default, turn off. */
- usbd_set_report(uaa->iface, UHID_OUTPUT_REPORT, 0,
- &reportbuf, sizeof reportbuf);
-
- /* The Xbox 360 gamepad has no report descriptor. */
- size = sizeof uhid_xb360gp_report_descr;
- descptr = uhid_xb360gp_report_descr;
- }
-
- if (descptr) {
- desc = malloc(size, M_USBDEV, M_NOWAIT);
- if (desc == NULL)
- err = USBD_NOMEM;
- else {
- err = USBD_NORMAL_COMPLETION;
- memcpy(desc, descptr, size);
- }
- } else {
- desc = NULL;
- err = usbd_read_report_desc(uaa->iface, &desc, &size,M_USBDEV);
- }
-
- if (err) {
- printf("%s: no report descriptor\n", device_get_nameunit(sc->sc_dev));
- sc->sc_dying = 1;
- return ENXIO;
- }
-
- (void)usbd_set_idle(iface, 0, 0);
-
- sc->sc_isize = hid_report_size(desc, size, hid_input, &sc->sc_iid);
- sc->sc_osize = hid_report_size(desc, size, hid_output, &sc->sc_oid);
- sc->sc_fsize = hid_report_size(desc, size, hid_feature, &sc->sc_fid);
-
- sc->sc_repdesc = desc;
- sc->sc_repdesc_size = size;
- sc->dev = make_dev(&uhid_cdevsw, device_get_unit(self),
- UID_ROOT, GID_OPERATOR,
- 0644, "uhid%d", device_get_unit(self));
- return 0;
-}
-
-static int
-uhid_detach(device_t self)
-{
- struct uhid_softc *sc = device_get_softc(self);
- int s;
-
- DPRINTF(("uhid_detach: sc=%p\n", sc));
- sc->sc_dying = 1;
- if (sc->sc_intrpipe != NULL)
- usbd_abort_pipe(sc->sc_intrpipe);
-
- if (sc->sc_state & UHID_OPEN) {
- s = splusb();
- if (--sc->sc_refcnt >= 0) {
- /* Wake everyone */
- wakeup(&sc->sc_q);
- /* Wait for processes to go away. */
- usb_detach_wait(sc->sc_dev);
- }
- splx(s);
- }
- destroy_dev(sc->dev);
-
- if (sc->sc_repdesc)
- free(sc->sc_repdesc, M_USBDEV);
-
- return (0);
-}
-
-void
-uhid_intr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status)
-{
- struct uhid_softc *sc = addr;
-
-#ifdef USB_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 ="));
- for (i = 0; i < cc; i++)
- DPRINTF((" %02x", sc->sc_ibuf[i]));
- DPRINTF(("\n"));
- }
-#endif
-
- if (status == USBD_CANCELLED)
- return;
-
- if (status != USBD_NORMAL_COMPLETION) {
- DPRINTF(("uhid_intr: status=%d\n", status));
- if (status == USBD_STALLED)
- sc->sc_state |= UHID_NEEDCLEAR;
- return;
- }
-
- (void) b_to_q(sc->sc_ibuf, sc->sc_isize, &sc->sc_q);
-
- if (sc->sc_state & UHID_ASLP) {
- sc->sc_state &= ~UHID_ASLP;
- DPRINTFN(5, ("uhid_intr: waking %p\n", &sc->sc_q));
- wakeup(&sc->sc_q);
- }
- selwakeuppri(&sc->sc_rsel, PZERO);
- if (sc->sc_async != NULL) {
- DPRINTFN(3, ("uhid_intr: sending SIGIO %p\n", sc->sc_async));
- PROC_LOCK(sc->sc_async);
- psignal(sc->sc_async, SIGIO);
- PROC_UNLOCK(sc->sc_async);
- }
-}
-
-int
-uhidopen(struct cdev *dev, int flag, int mode, struct thread *p)
-{
- struct uhid_softc *sc;
- usbd_status err;
-
- sc = devclass_get_softc(uhid_devclass, UHIDUNIT(dev));
- if (sc == NULL)
- return (ENXIO);
-
- DPRINTF(("uhidopen: sc=%p\n", sc));
-
- if (sc->sc_dying)
- return (ENXIO);
-
- if (sc->sc_state & UHID_OPEN)
- return (EBUSY);
- sc->sc_state |= UHID_OPEN;
-
- clist_alloc_cblocks(&sc->sc_q, UHID_BSIZE, UHID_BSIZE);
- sc->sc_ibuf = malloc(sc->sc_isize, M_USBDEV, M_WAITOK);
- sc->sc_obuf = malloc(sc->sc_osize, M_USBDEV, M_WAITOK);
-
- /* 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);
- if (err) {
- DPRINTF(("uhidopen: usbd_open_pipe_intr failed, "
- "error=%d\n",err));
- free(sc->sc_ibuf, M_USBDEV);
- free(sc->sc_obuf, M_USBDEV);
- sc->sc_ibuf = sc->sc_obuf = NULL;
-
- sc->sc_state &= ~UHID_OPEN;
- return (EIO);
- }
-
- sc->sc_state &= ~UHID_IMMED;
-
- sc->sc_async = 0;
-
- return (0);
-}
-
-int
-uhidclose(struct cdev *dev, int flag, int mode, struct thread *p)
-{
- struct uhid_softc *sc;
-
- sc = devclass_get_softc(uhid_devclass, UHIDUNIT(dev));
-
- DPRINTF(("uhidclose: sc=%p\n", sc));
-
- /* Disable interrupts. */
- usbd_abort_pipe(sc->sc_intrpipe);
- usbd_close_pipe(sc->sc_intrpipe);
- sc->sc_intrpipe = 0;
-
- ndflush(&sc->sc_q, sc->sc_q.c_cc);
- clist_free_cblocks(&sc->sc_q);
-
- free(sc->sc_ibuf, M_USBDEV);
- free(sc->sc_obuf, M_USBDEV);
- sc->sc_ibuf = sc->sc_obuf = NULL;
-
- sc->sc_state &= ~UHID_OPEN;
-
- sc->sc_async = 0;
-
- return (0);
-}
-
-int
-uhid_do_read(struct uhid_softc *sc, struct uio *uio, int flag)
-{
- int s;
- int error = 0;
- size_t length;
- u_char buffer[UHID_CHUNK];
- usbd_status err;
-
- DPRINTFN(1, ("uhidread\n"));
- if (sc->sc_state & UHID_IMMED) {
- DPRINTFN(1, ("uhidread immed\n"));
-
- err = usbd_get_report(sc->sc_iface, UHID_INPUT_REPORT,
- sc->sc_iid, buffer, sc->sc_isize);
- if (err)
- return (EIO);
- return (uiomove(buffer, sc->sc_isize, uio));
- }
-
- s = splusb();
- while (sc->sc_q.c_cc == 0) {
- if (flag & O_NONBLOCK) {
- splx(s);
- return (EWOULDBLOCK);
- }
- sc->sc_state |= UHID_ASLP;
- DPRINTFN(5, ("uhidread: sleep on %p\n", &sc->sc_q));
- error = tsleep(&sc->sc_q, PZERO | PCATCH, "uhidrea", 0);
- DPRINTFN(5, ("uhidread: woke, error=%d\n", error));
- if (sc->sc_dying)
- error = EIO;
- if (error) {
- sc->sc_state &= ~UHID_ASLP;
- break;
- }
- if (sc->sc_state & UHID_NEEDCLEAR) {
- DPRINTFN(-1,("uhidread: clearing stall\n"));
- sc->sc_state &= ~UHID_NEEDCLEAR;
- usbd_clear_endpoint_stall(sc->sc_intrpipe);
- }
- }
- splx(s);
-
- /* Transfer as many chunks as possible. */
- while (sc->sc_q.c_cc > 0 && uio->uio_resid > 0 && !error) {
- length = min(sc->sc_q.c_cc, uio->uio_resid);
- if (length > sizeof(buffer))
- length = sizeof(buffer);
-
- /* Remove a small chunk from the input queue. */
- (void) q_to_b(&sc->sc_q, buffer, length);
- DPRINTFN(5, ("uhidread: got %lu chars\n", (u_long)length));
-
- /* Copy the data to the user process. */
- if ((error = uiomove(buffer, length, uio)) != 0)
- break;
- }
-
- return (error);
-}
-
-int
-uhidread(struct cdev *dev, struct uio *uio, int flag)
-{
- struct uhid_softc *sc;
- int error;
-
- sc = devclass_get_softc(uhid_devclass, UHIDUNIT(dev));
- sc->sc_refcnt++;
- error = uhid_do_read(sc, uio, flag);
- if (--sc->sc_refcnt < 0)
- usb_detach_wakeup(sc->sc_dev);
- return (error);
-}
-
-int
-uhid_do_write(struct uhid_softc *sc, struct uio *uio, int flag)
-{
- int error;
- int size;
- usbd_status err;
-
- DPRINTFN(1, ("uhidwrite\n"));
-
- if (sc->sc_dying)
- return (EIO);
-
- size = sc->sc_osize;
- error = 0;
- if (uio->uio_resid != size)
- return (EINVAL);
- error = uiomove(sc->sc_obuf, size, uio);
- 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);
- else
- err = usbd_set_report(sc->sc_iface, UHID_OUTPUT_REPORT,
- 0, sc->sc_obuf, size);
- if (err)
- error = EIO;
- }
-
- return (error);
-}
-
-int
-uhidwrite(struct cdev *dev, struct uio *uio, int flag)
-{
- struct uhid_softc *sc;
- int error;
-
- sc = devclass_get_softc(uhid_devclass, UHIDUNIT(dev));
- sc->sc_refcnt++;
- error = uhid_do_write(sc, uio, flag);
- if (--sc->sc_refcnt < 0)
- usb_detach_wakeup(sc->sc_dev);
- return (error);
-}
-
-int
-uhid_do_ioctl(struct uhid_softc *sc, u_long cmd, caddr_t addr, int flag,
- struct thread *p)
-{
- struct usb_ctl_report_desc *rd;
- struct usb_ctl_report *re;
- int size, id;
- usbd_status err;
-
- DPRINTFN(2, ("uhidioctl: cmd=%lx\n", cmd));
-
- if (sc->sc_dying)
- return (EIO);
-
- switch (cmd) {
- case FIONBIO:
- /* All handled in the upper FS layer. */
- break;
-
- case FIOASYNC:
- if (*(int *)addr) {
- if (sc->sc_async != NULL)
- return (EBUSY);
- sc->sc_async = p->td_proc;
- DPRINTF(("uhid_do_ioctl: FIOASYNC %p\n", sc->sc_async));
- } else
- sc->sc_async = NULL;
- break;
-
- /* XXX this is not the most general solution. */
- case TIOCSPGRP:
- if (sc->sc_async == NULL)
- return (EINVAL);
- if (*(int *)addr != sc->sc_async->p_pgid)
- return (EPERM);
- break;
-
- case USB_GET_REPORT_DESC:
- rd = (struct usb_ctl_report_desc *)addr;
- size = min(sc->sc_repdesc_size, sizeof rd->ucrd_data);
- rd->ucrd_size = size;
- memcpy(rd->ucrd_data, sc->sc_repdesc, size);
- break;
-
- case USB_SET_IMMED:
- 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);
- if (err)
- return (EOPNOTSUPP);
-
- sc->sc_state |= UHID_IMMED;
- } else
- sc->sc_state &= ~UHID_IMMED;
- break;
-
- case USB_GET_REPORT:
- re = (struct usb_ctl_report *)addr;
- switch (re->ucr_report) {
- case UHID_INPUT_REPORT:
- size = sc->sc_isize;
- id = sc->sc_iid;
- break;
- case UHID_OUTPUT_REPORT:
- size = sc->sc_osize;
- id = sc->sc_oid;
- break;
- case UHID_FEATURE_REPORT:
- size = sc->sc_fsize;
- id = sc->sc_fid;
- break;
- default:
- return (EINVAL);
- }
- err = usbd_get_report(sc->sc_iface, re->ucr_report, id, re->ucr_data,
- size);
- if (err)
- return (EIO);
- break;
-
- case USB_SET_REPORT:
- re = (struct usb_ctl_report *)addr;
- switch (re->ucr_report) {
- case UHID_INPUT_REPORT:
- size = sc->sc_isize;
- id = sc->sc_iid;
- break;
- case UHID_OUTPUT_REPORT:
- size = sc->sc_osize;
- id = sc->sc_oid;
- break;
- case UHID_FEATURE_REPORT:
- size = sc->sc_fsize;
- id = sc->sc_fid;
- break;
- default:
- return (EINVAL);
- }
- err = usbd_set_report(sc->sc_iface, re->ucr_report, id, re->ucr_data,
- size);
- if (err)
- return (EIO);
- break;
-
- case USB_GET_REPORT_ID:
- *(int *)addr = 0; /* XXX: we only support reportid 0? */
- break;
-
- default:
- return (EINVAL);
- }
- return (0);
-}
-
-int
-uhidioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *p)
-{
- struct uhid_softc *sc;
- int error;
-
- sc = devclass_get_softc(uhid_devclass, UHIDUNIT(dev));
- sc->sc_refcnt++;
- error = uhid_do_ioctl(sc, cmd, addr, flag, p);
- if (--sc->sc_refcnt < 0)
- usb_detach_wakeup(sc->sc_dev);
- return (error);
-}
-
-int
-uhidpoll(struct cdev *dev, int events, struct thread *p)
-{
- struct uhid_softc *sc;
- int revents = 0;
- int s;
-
- sc = devclass_get_softc(uhid_devclass, UHIDUNIT(dev));
- if (sc->sc_dying)
- return (EIO);
-
- s = splusb();
- if (events & (POLLOUT | POLLWRNORM))
- revents |= events & (POLLOUT | POLLWRNORM);
- if (events & (POLLIN | POLLRDNORM)) {
- if (sc->sc_q.c_cc > 0)
- revents |= events & (POLLIN | POLLRDNORM);
- else
- selrecord(p, &sc->sc_rsel);
- }
-
- splx(s);
- return (revents);
-}
diff --git a/sys/dev/usb/uhub.c b/sys/dev/usb/uhub.c
deleted file mode 100644
index 86fbba2..0000000
--- a/sys/dev/usb/uhub.c
+++ /dev/null
@@ -1,703 +0,0 @@
-/* $NetBSD: uhub.c,v 1.68 2004/06/29 06:30:05 mycroft 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 (lennart@augustsson.net) 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * USB spec: http://www.usb.org/developers/docs/usbspec.zip
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/sysctl.h>
-
-#include <machine/bus.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include <dev/usb/usbdivar.h>
-
-#define UHUB_INTR_INTERVAL 255 /* ms */
-
-#ifdef USB_DEBUG
-#define DPRINTF(x) if (uhubdebug) printf x
-#define DPRINTFN(n,x) if (uhubdebug > (n)) printf x
-#define DEVPRINTF(x) if (uhubdebug) device_printf x
-#define DEVPRINTFN(n, x)if (uhubdebug > (n)) device_printf x
-int uhubdebug = 0;
-SYSCTL_NODE(_hw_usb, OID_AUTO, uhub, CTLFLAG_RW, 0, "USB uhub");
-SYSCTL_INT(_hw_usb_uhub, OID_AUTO, debug, CTLFLAG_RW,
- &uhubdebug, 0, "uhub debug level");
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#define DEVPRINTF(x)
-#define DEVPRINTFN(n,x)
-#endif
-
-struct uhub_softc {
- device_t sc_dev; /* base device */
- usbd_device_handle sc_hub; /* USB device */
- usbd_pipe_handle sc_ipipe; /* interrupt pipe */
- u_int8_t sc_status[32]; /* max 255 ports */
- u_char sc_running;
-};
-#define UHUB_PROTO(sc) ((sc)->sc_hub->ddesc.bDeviceProtocol)
-#define UHUB_IS_HIGH_SPEED(sc) (UHUB_PROTO(sc) != UDPROTO_FSHUB)
-#define UHUB_IS_SINGLE_TT(sc) (UHUB_PROTO(sc) == UDPROTO_HSHUBSTT)
-
-static usbd_status uhub_explore(usbd_device_handle hub);
-static void uhub_intr(usbd_xfer_handle, usbd_private_handle,usbd_status);
-
-/*
- * We need two attachment points:
- * hub to usb and hub to hub
- * Every other driver only connects to hubs
- */
-
-static device_probe_t uhub_match;
-static device_attach_t uhub_attach;
-static device_detach_t uhub_detach;
-static bus_child_location_str_t uhub_child_location_str;
-static bus_child_pnpinfo_str_t uhub_child_pnpinfo_str;
-
-static device_method_t uhub_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, uhub_match),
- DEVMETHOD(device_attach, uhub_attach),
- DEVMETHOD(device_detach, uhub_detach),
- DEVMETHOD(device_suspend, bus_generic_suspend),
- DEVMETHOD(device_resume, bus_generic_resume),
- DEVMETHOD(device_shutdown, bus_generic_shutdown),
-
- DEVMETHOD(bus_child_pnpinfo_str, uhub_child_pnpinfo_str),
- DEVMETHOD(bus_child_location_str, uhub_child_location_str),
- /* XXX driver_added needs special care */
- DEVMETHOD(bus_driver_added, bus_generic_driver_added),
- { 0, 0 }
-};
-
-static driver_t uhub_driver = {
- "uhub",
- uhub_methods,
- sizeof(struct uhub_softc)
-};
-
-static devclass_t uhub_devclass;
-
-/* Create the driver instance for the hub connected to usb case. */
-devclass_t uhubroot_devclass;
-
-static device_method_t uhubroot_methods[] = {
- DEVMETHOD(device_probe, uhub_match),
- DEVMETHOD(device_attach, uhub_attach),
- DEVMETHOD(device_detach, uhub_detach),
- DEVMETHOD(device_suspend, bus_generic_suspend),
- DEVMETHOD(device_resume, bus_generic_resume),
- DEVMETHOD(device_shutdown, bus_generic_shutdown),
-
- DEVMETHOD(bus_child_location_str, uhub_child_location_str),
- DEVMETHOD(bus_child_pnpinfo_str, uhub_child_pnpinfo_str),
- /* XXX driver_added needs special care */
- DEVMETHOD(bus_driver_added, bus_generic_driver_added),
-
- {0,0}
-};
-
-static driver_t uhubroot_driver = {
- "uhub",
- uhubroot_methods,
- sizeof(struct uhub_softc)
-};
-
-static int
-uhub_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usb_device_descriptor_t *dd = usbd_get_device_descriptor(uaa->device);
-
- DPRINTFN(5,("uhub_match, dd=%p\n", dd));
- /*
- * The subclass for hubs seems to be 0 for some and 1 for others,
- * so we just ignore the subclass.
- */
- if (uaa->iface == NULL && dd->bDeviceClass == UDCLASS_HUB)
- return (UMATCH_DEVCLASS_DEVSUBCLASS);
- return (UMATCH_NONE);
-}
-
-int
-uhub_attach(device_t self)
-{
- struct uhub_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usbd_device_handle dev = uaa->device;
- usbd_status err;
- struct usbd_hub *hub = NULL;
- usb_device_request_t req;
- usb_hub_descriptor_t hubdesc;
- int p, port, nports, nremov, pwrdly;
- usbd_interface_handle iface;
- usb_endpoint_descriptor_t *ed;
- struct usbd_tt *tts = NULL;
-
- DPRINTFN(1,("uhub_attach\n"));
- sc->sc_hub = dev;
- sc->sc_dev = self;
-
- if (dev->depth > 0 && UHUB_IS_HIGH_SPEED(sc)) {
- device_printf(sc->sc_dev, "%s transaction translator%s\n",
- UHUB_IS_SINGLE_TT(sc) ? "single" : "multiple",
- UHUB_IS_SINGLE_TT(sc) ? "" : "s");
- }
- err = usbd_set_config_index(dev, 0, 1);
- if (err) {
- DEVPRINTF((sc->sc_dev, "configuration failed, error=%s\n",
- usbd_errstr(err)));
- return (ENXIO);
- }
-
- if (dev->depth > USB_HUB_MAX_DEPTH) {
- device_printf(sc->sc_dev, "hub depth (%d) exceeded, hub ignored\n",
- USB_HUB_MAX_DEPTH);
- return (ENXIO);
- }
-
- /* Get hub descriptor. */
- req.bmRequestType = UT_READ_CLASS_DEVICE;
- req.bRequest = UR_GET_DESCRIPTOR;
- USETW2(req.wValue, (dev->address > 1 ? UDESC_HUB : 0), 0);
- USETW(req.wIndex, 0);
- USETW(req.wLength, USB_HUB_DESCRIPTOR_SIZE);
- DPRINTFN(1,("usb_init_hub: getting hub descriptor\n"));
- err = usbd_do_request(dev, &req, &hubdesc);
- nports = hubdesc.bNbrPorts;
- if (!err && nports > 7) {
- USETW(req.wLength, USB_HUB_DESCRIPTOR_SIZE + (nports+1) / 8);
- err = usbd_do_request(dev, &req, &hubdesc);
- }
- if (err) {
- DEVPRINTF((sc->sc_dev, "getting hub descriptor failed: %s\n",
- usbd_errstr(err)));
- return (ENXIO);
- }
-
- for (nremov = 0, port = 1; port <= nports; port++)
- if (!UHD_NOT_REMOV(&hubdesc, port))
- nremov++;
- device_printf(sc->sc_dev, "%d port%s with %d removable, %s powered\n",
- nports, nports != 1 ? "s" : "", nremov,
- dev->self_powered ? "self" : "bus");
-
- if (nports == 0) {
- device_printf(sc->sc_dev, "no ports, hub ignored\n");
- goto bad;
- }
-
- hub = malloc(sizeof(*hub) + (nports-1) * sizeof(struct usbd_port),
- M_USBDEV, M_NOWAIT);
- if (hub == NULL) {
- return (ENXIO);
- }
- dev->hub = hub;
- dev->hub->hubsoftc = sc;
- hub->explore = uhub_explore;
- hub->hubdesc = hubdesc;
-
- DPRINTFN(1,("usbhub_init_hub: selfpowered=%d, parent=%p, "
- "parent->selfpowered=%d\n",
- dev->self_powered, dev->powersrc->parent,
- dev->powersrc->parent ?
- dev->powersrc->parent->self_powered : 0));
-
- if (!dev->self_powered && dev->powersrc->parent != NULL &&
- !dev->powersrc->parent->self_powered) {
- device_printf(sc->sc_dev, "bus powered hub connected to bus "
- "powered hub, ignored\n");
- goto bad;
- }
-
- /* Set up interrupt pipe. */
- err = usbd_device2interface_handle(dev, 0, &iface);
- if (err) {
- device_printf(sc->sc_dev, "no interface handle\n");
- goto bad;
- }
- ed = usbd_interface2endpoint_descriptor(iface, 0);
- if (ed == NULL) {
- device_printf(sc->sc_dev, "no endpoint descriptor\n");
- goto bad;
- }
- if ((ed->bmAttributes & UE_XFERTYPE) != UE_INTERRUPT) {
- device_printf(sc->sc_dev, "bad interrupt endpoint\n");
- goto bad;
- }
-
- err = usbd_open_pipe_intr(iface, ed->bEndpointAddress,
- USBD_SHORT_XFER_OK, &sc->sc_ipipe, sc, sc->sc_status,
- (nports + 1 + 7) / 8, uhub_intr, UHUB_INTR_INTERVAL);
- if (err) {
- device_printf(sc->sc_dev, "cannot open interrupt pipe\n");
- goto bad;
- }
-
- /* Wait with power off for a while. */
- usbd_delay_ms(dev, USB_POWER_DOWN_TIME);
-
- usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, dev, sc->sc_dev);
-
- /*
- * To have the best chance of success we do things in the exact same
- * order as Windoze98. This should not be necessary, but some
- * devices do not follow the USB specs to the letter.
- *
- * These are the events on the bus when a hub is attached:
- * Get device and config descriptors (see attach code)
- * Get hub descriptor (see above)
- * For all ports
- * turn on power
- * wait for power to become stable
- * (all below happens in explore code)
- * For all ports
- * clear C_PORT_CONNECTION
- * For all ports
- * get port status
- * if device connected
- * wait 100 ms
- * turn on reset
- * wait
- * clear C_PORT_RESET
- * get port status
- * proceed with device attachment
- */
-
- if (UHUB_IS_HIGH_SPEED(sc)) {
- tts = malloc((UHUB_IS_SINGLE_TT(sc) ? 1 : nports) *
- sizeof (struct usbd_tt), M_USBDEV, M_NOWAIT);
- if (!tts)
- goto bad;
- }
-
- /* Set up data structures */
- for (p = 0; p < nports; p++) {
- struct usbd_port *up = &hub->ports[p];
- up->device = NULL;
- up->parent = dev;
- up->portno = p+1;
- if (dev->self_powered)
- /* Self powered hub, give ports maximum current. */
- up->power = USB_MAX_POWER;
- else
- up->power = USB_MIN_POWER;
- up->restartcnt = 0;
- if (UHUB_IS_HIGH_SPEED(sc)) {
- up->tt = &tts[UHUB_IS_SINGLE_TT(sc) ? 0 : p];
- up->tt->hub = hub;
- } else {
- up->tt = NULL;
- }
- }
-
- /* XXX should check for none, individual, or ganged power? */
-
- pwrdly = dev->hub->hubdesc.bPwrOn2PwrGood * UHD_PWRON_FACTOR
- + USB_EXTRA_POWER_UP_TIME;
- for (port = 1; port <= nports; port++) {
- /* Turn the power on. */
- err = usbd_set_port_feature(dev, port, UHF_PORT_POWER);
- if (err)
- device_printf(sc->sc_dev,
- "port %d power on failed, %s\n", port,
- usbd_errstr(err));
- DPRINTF(("usb_init_port: turn on port %d power\n", port));
- /* Wait for stable power. */
- usbd_delay_ms(dev, pwrdly);
- }
-
- /* The usual exploration will finish the setup. */
-
- sc->sc_running = 1;
- return (0);
- bad:
- if (hub)
- free(hub, M_USBDEV);
- dev->hub = NULL;
- return (ENXIO);
-}
-
-usbd_status
-uhub_explore(usbd_device_handle dev)
-{
- usb_hub_descriptor_t *hd = &dev->hub->hubdesc;
- struct uhub_softc *sc = dev->hub->hubsoftc;
- struct usbd_port *up;
- usbd_status err;
- int speed;
- int port;
- int change, status;
-
- DPRINTFN(10, ("uhub_explore dev=%p addr=%d\n", dev, dev->address));
-
- if (!sc->sc_running)
- return (USBD_NOT_STARTED);
-
- /* Ignore hubs that are too deep. */
- if (dev->depth > USB_HUB_MAX_DEPTH)
- return (USBD_TOO_DEEP);
-
- for(port = 1; port <= hd->bNbrPorts; port++) {
- up = &dev->hub->ports[port-1];
- err = usbd_get_port_status(dev, port, &up->status);
- if (err) {
- DPRINTF(("uhub_explore: get port status failed, "
- "error=%s\n", usbd_errstr(err)));
- continue;
- }
- status = UGETW(up->status.wPortStatus);
- change = UGETW(up->status.wPortChange);
- DEVPRINTFN(3,(sc->sc_dev,
- "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 0x%x\n", change));
- usbd_clear_port_feature(dev, port, UHF_C_PORT_ENABLE);
- if (change & UPS_C_CONNECT_STATUS) {
- /* Ignore the port error if the device
- vanished. */
- } else if (status & UPS_PORT_ENABLED) {
- device_printf(sc->sc_dev,
- "illegal enable change, port %d\n", port);
- } else {
- /* Port error condition. */
- if (up->restartcnt) /* no message first time */
- device_printf(sc->sc_dev,
- "port error, restarting port %d\n",
- port);
-
- if (up->restartcnt++ < USBD_RESTART_MAX)
- goto disco;
- else
- device_printf(sc->sc_dev,
- "port error, giving up port %d\n",
- port);
- }
- }
- if (!(change & UPS_C_CONNECT_STATUS)) {
- DPRINTFN(3,("uhub_explore: port=%d !C_CONNECT_"
- "STATUS\n", port));
- /* No status change, just do recursive explore. */
- if (up->device != NULL && up->device->hub != NULL)
- up->device->hub->explore(up->device);
-#if 0 && defined(DIAGNOSTIC)
- if (up->device == NULL &&
- (status & UPS_CURRENT_CONNECT_STATUS))
- deivce_printf(sc->sc_dev,
- "connected, no device\n");
-#endif
- continue;
- }
-
- /* We have a connect status change, handle it. */
-
- DPRINTF(("uhub_explore: status change hub=%d port=%d\n",
- dev->address, port));
- usbd_clear_port_feature(dev, port, UHF_C_PORT_CONNECTION);
- /*usbd_clear_port_feature(dev, port, UHF_C_PORT_ENABLE);*/
- /*
- * If there is already a device on the port the change status
- * must mean that is has disconnected. Looking at the
- * current connect status is not enough to figure this out
- * since a new unit may have been connected before we handle
- * the disconnect.
- */
- disco:
- if (up->device != NULL) {
- /* Disconnected */
- DPRINTF(("uhub_explore: device addr=%d disappeared "
- "on port %d\n", up->device->address, port));
- usb_disconnect_port(up, sc->sc_dev);
- usbd_clear_port_feature(dev, port,
- UHF_C_PORT_CONNECTION);
- }
- if (!(status & UPS_CURRENT_CONNECT_STATUS)) {
- /* Nothing connected, just ignore it. */
- DPRINTFN(3,("uhub_explore: port=%d !CURRENT_CONNECT"
- "_STATUS\n", port));
- continue;
- }
-
- /* Connected */
-
- if (!(status & UPS_PORT_POWER))
- device_printf(sc->sc_dev,
- "strange, connected port %d has no power\n", port);
-
- /* Wait for maximum device power up time. */
- usbd_delay_ms(dev, USB_PORT_POWERUP_DELAY);
-
- /* Reset port, which implies enabling it. */
- if (usbd_reset_port(dev, port, &up->status)) {
- device_printf(sc->sc_dev, "port %d reset failed\n",
- port);
- continue;
- }
- /* Get port status again, it might have changed during reset */
- err = usbd_get_port_status(dev, port, &up->status);
- if (err) {
- DPRINTF(("uhub_explore: get port status failed, "
- "error=%s\n", usbd_errstr(err)));
- continue;
- }
- status = UGETW(up->status.wPortStatus);
- change = UGETW(up->status.wPortChange);
- if (!(status & UPS_CURRENT_CONNECT_STATUS)) {
- /* Nothing connected, just ignore it. */
-#ifdef DIAGNOSTIC
- device_printf(sc->sc_dev,
- "port %d, device disappeared after reset\n", port);
-#endif
- continue;
- }
-
-#if 0
- if (UHUB_IS_HIGH_SPEED(sc) && !(status & UPS_HIGH_SPEED)) {
- device_printf(sc->sc_dev,
- "port %d, transaction translation not implemented,"
- " low/full speed device ignored\n", port);
- continue;
- }
-#endif
-
- /* Figure out device speed */
- if (status & UPS_HIGH_SPEED)
- speed = USB_SPEED_HIGH;
- else if (status & UPS_LOW_SPEED)
- speed = USB_SPEED_LOW;
- else
- speed = USB_SPEED_FULL;
- /* Get device info and set its address. */
- err = usbd_new_device(sc->sc_dev, dev->bus,
- dev->depth + 1, speed, port, up);
- /* XXX retry a few times? */
- if (err) {
- DPRINTFN(-1,("uhub_explore: usb_new_device failed, "
- "error=%s\n", usbd_errstr(err)));
- /* Avoid addressing problems by disabling. */
- /* usbd_reset_port(dev, port, &up->status); */
-
- /*
- * The unit refused to accept a new address, or had
- * some other serious problem. Since we cannot leave
- * at 0 we have to disable the port instead.
- */
- device_printf(sc->sc_dev,
- "device problem (%s), disabling port %d\n",
- usbd_errstr(err), port);
- usbd_clear_port_feature(dev, port, UHF_PORT_ENABLE);
- } else {
- /* The port set up succeeded, reset error count. */
- up->restartcnt = 0;
-
- if (up->device->hub)
- up->device->hub->explore(up->device);
- }
- }
- return (USBD_NORMAL_COMPLETION);
-}
-
-/*
- * Called from process context when the hub is gone.
- * Detach all devices on active ports.
- */
-static int
-uhub_detach(device_t self)
-{
- struct uhub_softc *sc = device_get_softc(self);
- struct usbd_hub *hub = sc->sc_hub->hub;
- struct usbd_port *rup;
- int port, nports;
-
- DPRINTF(("uhub_detach: sc=%port\n", sc));
- if (hub == NULL) /* Must be partially working */
- return (0);
-
- usbd_abort_pipe(sc->sc_ipipe);
- usbd_close_pipe(sc->sc_ipipe);
-
- nports = hub->hubdesc.bNbrPorts;
- for(port = 0; port < nports; port++) {
- rup = &hub->ports[port];
- if (rup->device)
- usb_disconnect_port(rup, self);
- }
-
- usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_hub, sc->sc_dev);
-
- if (hub->ports[0].tt)
- free(hub->ports[0].tt, M_USBDEV);
- free(hub, M_USBDEV);
- sc->sc_hub->hub = NULL;
-
- return (0);
-}
-
-int
-uhub_child_location_str(device_t cbdev, device_t child, char *buf,
- size_t buflen)
-{
- struct uhub_softc *sc = device_get_softc(cbdev);
- usbd_device_handle devhub = sc->sc_hub;
- usbd_device_handle dev;
- int nports;
- int port;
- int i;
-
- mtx_lock(&Giant);
- 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) {
- if (dev->ifacenums == NULL) {
- snprintf(buf, buflen,
- "port=%i", port);
- } else {
- snprintf(buf, buflen,
- "port=%i interface=%i",
- port, dev->ifacenums[i]);
- }
- goto found_dev;
- }
- }
- }
- }
- DPRINTFN(0,("uhub_child_location_str: device not on hub\n"));
- buf[0] = '\0';
-found_dev:
- mtx_unlock(&Giant);
- return (0);
-}
-
-int
-uhub_child_pnpinfo_str(device_t cbdev, device_t child, char *buf,
- size_t buflen)
-{
- struct uhub_softc *sc = device_get_softc(cbdev);
- usbd_device_handle devhub = sc->sc_hub;
- usbd_device_handle dev;
- struct usbd_interface *iface;
- char serial[128];
- int nports;
- int port;
- int i;
-
- mtx_lock(&Giant);
- 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) {
- goto found_dev;
- }
- }
- }
- }
- DPRINTFN(0,("uhub_child_pnpinfo_str: device not on hub\n"));
- buf[0] = '\0';
- mtx_unlock(&Giant);
- return (0);
-
-found_dev:
- /* XXX can sleep */
- (void)usbd_get_string(dev, dev->ddesc.iSerialNumber, serial,
- sizeof(serial));
- if (dev->ifacenums == NULL) {
- snprintf(buf, buflen, "vendor=0x%04x product=0x%04x "
- "devclass=0x%02x devsubclass=0x%02x "
- "release=0x%04x sernum=\"%s\"",
- UGETW(dev->ddesc.idVendor), UGETW(dev->ddesc.idProduct),
- dev->ddesc.bDeviceClass, dev->ddesc.bDeviceSubClass,
- UGETW(dev->ddesc.bcdDevice), serial);
- } else {
- iface = &dev->ifaces[dev->ifacenums[i]];
- snprintf(buf, buflen, "vendor=0x%04x product=0x%04x "
- "devclass=0x%02x devsubclass=0x%02x "
- "release=0x%04x sernum=\"%s\" "
- "intclass=0x%02x intsubclass=0x%02x",
- UGETW(dev->ddesc.idVendor), UGETW(dev->ddesc.idProduct),
- dev->ddesc.bDeviceClass, dev->ddesc.bDeviceSubClass,
- UGETW(dev->ddesc.bcdDevice), serial,
- iface->idesc->bInterfaceClass,
- iface->idesc->bInterfaceSubClass);
- }
- mtx_unlock(&Giant);
- return (0);
-}
-
-/*
- * Hub interrupt.
- * This an indication that some port has changed status.
- * Notify the bus event handler thread that we need
- * to be explored again.
- */
-void
-uhub_intr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status)
-{
- struct uhub_softc *sc = addr;
-
- DPRINTFN(5,("uhub_intr: sc=%p\n", sc));
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall_async(sc->sc_ipipe);
- else if (status == USBD_NORMAL_COMPLETION)
- usb_needs_explore(sc->sc_hub);
-}
-
-MODULE_DEPEND(uhub, usb, 1, 1, 1);
-DRIVER_MODULE(uhub, usb, uhubroot_driver, uhubroot_devclass, 0, 0);
-DRIVER_MODULE(uhub, uhub, uhub_driver, uhub_devclass, usbd_driver_load, 0);
diff --git a/sys/dev/usb/uipaq.c b/sys/dev/usb/uipaq.c
deleted file mode 100644
index a231a67..0000000
--- a/sys/dev/usb/uipaq.c
+++ /dev/null
@@ -1,822 +0,0 @@
-/* $NetBSD: uipaq.c,v 1.4 2006/11/16 01:33:27 christos Exp $ */
-/* $OpenBSD: uipaq.c,v 1.1 2005/06/17 23:50:33 deraadt Exp $ */
-
-/*
- * Copyright (c) 2000-2005 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) 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.
- */
-
-/*
- * iPAQ driver
- *
- * 19 July 2003: Incorporated changes suggested by Sam Lawrance from
- * the uppc module
- *
- *
- * Contact isis@cs.umd.edu if you have any questions/comments about this driver
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/bus.h>
-#include <sys/conf.h>
-#include <sys/tty.h>
-#include <sys/module.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbhid.h>
-
-#include <dev/usb/usbcdc.h> /*UCDC_* stuff */
-
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include "usbdevs.h"
-
-#include <dev/usb/ucomvar.h>
-
-#ifdef UIPAQ_DEBUG
-#define DPRINTF(x) if (uipaqdebug) printf x
-#define DPRINTFN(n,x) if (uipaqdebug>(n)) printf x
-int uipaqdebug = 0;
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-#define UIPAQ_CONFIG_NO 1
-#define UIPAQ_IFACE_INDEX 0
-
-#define UIPAQIBUFSIZE 1024
-#define UIPAQOBUFSIZE 1024
-
-struct uipaq_softc {
- struct ucom_softc sc_ucom;
- u_int16_t sc_lcr; /* state for DTR/RTS */
- u_int16_t sc_flags;
-
-};
-
-/* Callback routines */
-static void uipaq_set(void *, int, int, int);
-
-/* Support routines. */
-/* based on uppc module by Sam Lawrance */
-static void uipaq_dtr(struct uipaq_softc *sc, int onoff);
-static void uipaq_rts(struct uipaq_softc *sc, int onoff);
-static void uipaq_break(struct uipaq_softc* sc, int onoff);
-
-int uipaq_detach(device_t self);
-
-struct ucom_callback uipaq_callback = {
- .ucom_set = uipaq_set
-};
-
-struct uipaq_type {
- struct usb_devno uv_dev;
- u_int16_t uv_flags;
-};
-
-/*
- * Much of this list is generated from lists of other drivers that support
- * the same hardware. Numeric values are used where no usbdevs entries
- * exist.
- */
-static const struct uipaq_type uipaq_devs[] = {
- {{ 0x0104, 0x00be }, 0}, /* Socket USB Sync */
- {{ 0x04ad, 0x0301 }, 0}, /* USB Sync 0301 */
- {{ 0x04ad, 0x0302 }, 0}, /* USB Sync 0302 */
- {{ 0x04ad, 0x0303 }, 0}, /* USB Sync 0303 */
- {{ 0x04ad, 0x0306 }, 0}, /* GPS Pocket PC USB Sync */
- {{ 0x0536, 0x01a0 }, 0}, /* HHP PDT */
- {{ 0x067e, 0x1001 }, 0}, /* Intermec Mobile Computer */
- {{ 0x094b, 0x0001 }, 0}, /* Linkup Systems USB Sync */
- {{ 0x0960, 0x0065 }, 0}, /* BCOM USB Sync 0065 */
- {{ 0x0960, 0x0066 }, 0}, /* BCOM USB Sync 0066 */
- {{ 0x0960, 0x0067 }, 0}, /* BCOM USB Sync 0067 */
- {{ 0x0961, 0x0010 }, 0}, /* Portatec USB Sync */
- {{ 0x099e, 0x0052 }, 0}, /* Trimble GeoExplorer */
- {{ 0x099e, 0x4000 }, 0}, /* TDS Data Collector */
- {{ 0x0c44, 0x03a2 }, 0}, /* Motorola iDEN Smartphone */
- {{ 0x0c8e, 0x6000 }, 0}, /* Cesscom Luxian Series */
- {{ 0x0cad, 0x9001 }, 0}, /* Motorola PowerPad Pocket PCDevice */
- {{ 0x0f4e, 0x0200 }, 0}, /* Freedom Scientific USB Sync */
- {{ 0x0f98, 0x0201 }, 0}, /* Cyberbank USB Sync */
- {{ 0x0fb8, 0x3001 }, 0}, /* Wistron USB Sync */
- {{ 0x0fb8, 0x3002 }, 0}, /* Wistron USB Sync */
- {{ 0x0fb8, 0x3003 }, 0}, /* Wistron USB Sync */
- {{ 0x0fb8, 0x4001 }, 0}, /* Wistron USB Sync */
- {{ 0x1066, 0x00ce }, 0}, /* E-TEN USB Sync */
- {{ 0x1066, 0x0300 }, 0}, /* E-TEN P3XX Pocket PC */
- {{ 0x1066, 0x0500 }, 0}, /* E-TEN P5XX Pocket PC */
- {{ 0x1066, 0x0600 }, 0}, /* E-TEN P6XX Pocket PC */
- {{ 0x1066, 0x0700 }, 0}, /* E-TEN P7XX Pocket PC */
- {{ 0x1114, 0x0001 }, 0}, /* Psion Teklogix Sync 753x */
- {{ 0x1114, 0x0004 }, 0}, /* Psion Teklogix Sync netBookPro */
- {{ 0x1114, 0x0006 }, 0}, /* Psion Teklogix Sync 7525 */
- {{ 0x1182, 0x1388 }, 0}, /* VES USB Sync */
- {{ 0x11d9, 0x1002 }, 0}, /* Rugged Pocket PC 2003 */
- {{ 0x11d9, 0x1003 }, 0}, /* Rugged Pocket PC 2003 */
- {{ 0x1231, 0xce01 }, 0}, /* USB Sync 03 */
- {{ 0x1231, 0xce02 }, 0}, /* USB Sync 03 */
- {{ 0x3340, 0x011c }, 0}, /* Mio DigiWalker PPC StrongARM */
- {{ 0x3340, 0x0326 }, 0}, /* Mio DigiWalker 338 */
- {{ 0x3340, 0x0426 }, 0}, /* Mio DigiWalker 338 */
- {{ 0x3340, 0x043a }, 0}, /* Mio DigiWalker USB Sync */
- {{ 0x3340, 0x051c }, 0}, /* MiTAC USB Sync 528 */
- {{ 0x3340, 0x053a }, 0}, /* Mio DigiWalker SmartPhone USB Sync */
- {{ 0x3340, 0x071c }, 0}, /* MiTAC USB Sync */
- {{ 0x3340, 0x0b1c }, 0}, /* Generic PPC StrongARM */
- {{ 0x3340, 0x0e3a }, 0}, /* Generic PPC USB Sync */
- {{ 0x3340, 0x0f1c }, 0}, /* Itautec USB Sync */
- {{ 0x3340, 0x0f3a }, 0}, /* Generic SmartPhone USB Sync */
- {{ 0x3340, 0x1326 }, 0}, /* Itautec USB Sync */
- {{ 0x3340, 0x191c }, 0}, /* YAKUMO USB Sync */
- {{ 0x3340, 0x2326 }, 0}, /* Vobis USB Sync */
- {{ 0x3340, 0x3326 }, 0}, /* MEDION Winodws Moble USB Sync */
- {{ 0x3708, 0x20ce }, 0}, /* Legend USB Sync */
- {{ 0x3708, 0x21ce }, 0}, /* Lenovo USB Sync */
- {{ 0x4113, 0x0210 }, 0}, /* Mobile Media Technology USB Sync */
- {{ 0x4113, 0x0211 }, 0}, /* Mobile Media Technology USB Sync */
- {{ 0x4113, 0x0400 }, 0}, /* Mobile Media Technology USB Sync */
- {{ 0x4113, 0x0410 }, 0}, /* Mobile Media Technology USB Sync */
- {{ 0x4505, 0x0010 }, 0}, /* Smartphone */
- {{ 0x5e04, 0xce00 }, 0}, /* SAGEM Wireless Assistant */
- {{ USB_VENDOR_ACER, 0x1631 }, 0}, /* c10 Series */
- {{ USB_VENDOR_ACER, 0x1632 }, 0}, /* c20 Series */
- {{ USB_VENDOR_ACER, 0x16e1 }, 0}, /* Acer n10 Handheld USB Sync */
- {{ USB_VENDOR_ACER, 0x16e2 }, 0}, /* Acer n20 Handheld USB Sync */
- {{ USB_VENDOR_ACER, 0x16e3 }, 0}, /* Acer n30 Handheld USB Sync */
- {{ USB_VENDOR_ASUS, 0x4200 }, 0}, /* ASUS USB Sync */
- {{ USB_VENDOR_ASUS, 0x4201 }, 0}, /* ASUS USB Sync */
- {{ USB_VENDOR_ASUS, 0x4202 }, 0}, /* ASUS USB Sync */
- {{ USB_VENDOR_ASUS, 0x9200 }, 0}, /* ASUS USB Sync */
- {{ USB_VENDOR_ASUS, 0x9202 }, 0}, /* ASUS USB Sync */
- {{ USB_VENDOR_ASUS, USB_PRODUCT_ASUS_P535 }, 0},
- {{ USB_VENDOR_CASIO, 0x2001 }, 0}, /* CASIO USB Sync 2001 */
- {{ USB_VENDOR_CASIO, 0x2003 }, 0}, /* CASIO USB Sync 2003 */
- {{ USB_VENDOR_CASIO, USB_PRODUCT_CASIO_BE300 } , 0},
- {{ USB_VENDOR_COMPAL, 0x0531 }, 0}, /* MyGuide 7000 XL USB Sync */
- {{ USB_VENDOR_COMPAQ, 0x0032 }, 0}, /* Compaq iPAQ USB Sync */
- {{ USB_VENDOR_COMPAQ, USB_PRODUCT_COMPAQ_IPAQPOCKETPC } , 0},
- {{ USB_VENDOR_DELL, 0x4001 }, 0}, /* Dell Axim USB Sync */
- {{ USB_VENDOR_DELL, 0x4002 }, 0}, /* Dell Axim USB Sync */
- {{ USB_VENDOR_DELL, 0x4003 }, 0}, /* Dell Axim USB Sync */
- {{ USB_VENDOR_DELL, 0x4004 }, 0}, /* Dell Axim USB Sync */
- {{ USB_VENDOR_DELL, 0x4005 }, 0}, /* Dell Axim USB Sync */
- {{ USB_VENDOR_DELL, 0x4006 }, 0}, /* Dell Axim USB Sync */
- {{ USB_VENDOR_DELL, 0x4007 }, 0}, /* Dell Axim USB Sync */
- {{ USB_VENDOR_DELL, 0x4008 }, 0}, /* Dell Axim USB Sync */
- {{ USB_VENDOR_DELL, 0x4009 }, 0}, /* Dell Axim USB Sync */
- {{ USB_VENDOR_FSC, 0x1001 }, 0}, /* Fujitsu Siemens Computers USB Sync */
- {{ USB_VENDOR_FUJITSU, 0x1058 }, 0}, /* FUJITSU USB Sync */
- {{ USB_VENDOR_FUJITSU, 0x1079 }, 0}, /* FUJITSU USB Sync */
- {{ USB_VENDOR_GIGASET, 0x0601 }, 0}, /* Askey USB Sync */
- {{ USB_VENDOR_HITACHI, 0x0014 }, 0}, /* Hitachi USB Sync */
- {{ USB_VENDOR_HP, 0x1216 }, 0}, /* HP USB Sync 1612 */
- {{ USB_VENDOR_HP, 0x2016 }, 0}, /* HP USB Sync 1620 */
- {{ USB_VENDOR_HP, 0x2116 }, 0}, /* HP USB Sync 1621 */
- {{ USB_VENDOR_HP, 0x2216 }, 0}, /* HP USB Sync 1622 */
- {{ USB_VENDOR_HP, 0x3016 }, 0}, /* HP USB Sync 1630 */
- {{ USB_VENDOR_HP, 0x3116 }, 0}, /* HP USB Sync 1631 */
- {{ USB_VENDOR_HP, 0x3216 }, 0}, /* HP USB Sync 1632 */
- {{ USB_VENDOR_HP, 0x4016 }, 0}, /* HP USB Sync 1640 */
- {{ USB_VENDOR_HP, 0x4116 }, 0}, /* HP USB Sync 1641 */
- {{ USB_VENDOR_HP, 0x4216 }, 0}, /* HP USB Sync 1642 */
- {{ USB_VENDOR_HP, 0x5016 }, 0}, /* HP USB Sync 1650 */
- {{ USB_VENDOR_HP, 0x5116 }, 0}, /* HP USB Sync 1651 */
- {{ USB_VENDOR_HP, 0x5216 }, 0}, /* HP USB Sync 1652 */
- {{ USB_VENDOR_HP, USB_PRODUCT_HP_2215 }, 0 },
- {{ USB_VENDOR_HP, USB_PRODUCT_HP_568J }, 0},
- {{ USB_VENDOR_HTC, 0x00cf }, 0}, /* HTC USB Modem */
- {{ USB_VENDOR_HTC, 0x0a01 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a02 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a03 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a04 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a05 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a06 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a07 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a08 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a09 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a0a }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a0b }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a0c }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a0d }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a0e }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a0f }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a10 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a11 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a12 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a13 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a14 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a15 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a16 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a17 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a18 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a19 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a1a }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a1b }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a1c }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a1d }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a1e }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a1f }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a20 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a21 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a22 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a23 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a24 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a25 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a26 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a27 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a28 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a29 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a2a }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a2b }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a2c }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a2d }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a2e }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a2f }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a30 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a31 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a32 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a33 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a34 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a35 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a36 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a37 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a38 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a39 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a3a }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a3b }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a3c }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a3d }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a3e }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a3f }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a40 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a41 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a42 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a43 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a44 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a45 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a46 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a47 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a48 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a49 }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a4a }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a4b }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a4c }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a4d }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a4e }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a4f }, 0}, /* PocketPC USB Sync */
- {{ USB_VENDOR_HTC, 0x0a50 }, 0}, /* HTC SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a52 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a53 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a54 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a55 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a56 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a57 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a58 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a59 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a5a }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a5b }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a5c }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a5d }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a5e }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a5f }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a60 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a61 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a62 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a63 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a64 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a65 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a66 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a67 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a68 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a69 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a6a }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a6b }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a6c }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a6d }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a6e }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a6f }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a70 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a71 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a72 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a73 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a74 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a75 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a76 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a77 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a78 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a79 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a7a }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a7b }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a7c }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a7d }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a7e }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a7f }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a80 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a81 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a82 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a83 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a84 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a85 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a86 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a87 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a88 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a89 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a8a }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a8b }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a8c }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a8d }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a8e }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a8f }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a90 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a91 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a92 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a93 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a94 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a95 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a96 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a97 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a98 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a99 }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a9a }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a9b }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a9c }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a9d }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a9e }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0a9f }, 0}, /* SmartPhone USB Sync */
- {{ USB_VENDOR_HTC, 0x0bce }, 0}, /* "High Tech Computer Corp" */
- {{ USB_VENDOR_HTC, USB_PRODUCT_HTC_PPC6700MODEM }, 0},
- {{ USB_VENDOR_HTC, USB_PRODUCT_HTC_SMARTPHONE }, 0},
- {{ USB_VENDOR_HTC, USB_PRODUCT_HTC_WINMOBILE }, 0},
- {{ USB_VENDOR_JVC, 0x3011 }, 0}, /* JVC USB Sync */
- {{ USB_VENDOR_JVC, 0x3012 }, 0}, /* JVC USB Sync */
- {{ USB_VENDOR_LG, 0x9c01 }, 0}, /* LGE USB Sync */
- {{ USB_VENDOR_MICROSOFT, 0x00ce }, 0}, /* Microsoft USB Sync */
- {{ USB_VENDOR_MICROSOFT, 0x0400 }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x0401 }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x0402 }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x0403 }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x0404 }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x0405 }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x0406 }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x0407 }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x0408 }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x0409 }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x040a }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x040b }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x040c }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x040d }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x040e }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x040f }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x0410 }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x0411 }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x0412 }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x0413 }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x0414 }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x0415 }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x0416 }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x0417 }, 0}, /* Windows Pocket PC 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x0432 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0433 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0434 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0435 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0436 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0437 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0438 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0439 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x043a }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x043b }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x043c }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x043d }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x043e }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x043f }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0440 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0441 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0442 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0443 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0444 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0445 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0446 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0447 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0448 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0449 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x044a }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x044b }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x044c }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x044d }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x044e }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x044f }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0450 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0451 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0452 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0453 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0454 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0455 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0456 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0457 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0458 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0459 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x045a }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x045b }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x045c }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x045d }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x045e }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x045f }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0460 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0461 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0462 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0463 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0464 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0465 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0466 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0467 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0468 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0469 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x046a }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x046b }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x046c }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x046d }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x046e }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x046f }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0470 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0471 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0472 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0473 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0474 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0475 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0476 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0477 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0478 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x0479 }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x047a }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x047b }, 0}, /* Windows Pocket PC 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x04c8 }, 0}, /* Windows Smartphone 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x04c9 }, 0}, /* Windows Smartphone 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x04ca }, 0}, /* Windows Smartphone 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x04cb }, 0}, /* Windows Smartphone 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x04cc }, 0}, /* Windows Smartphone 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x04cd }, 0}, /* Windows Smartphone 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x04ce }, 0}, /* Windows Smartphone 2002 */
- {{ USB_VENDOR_MICROSOFT, 0x04d7 }, 0}, /* Windows Smartphone 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x04d8 }, 0}, /* Windows Smartphone 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x04d9 }, 0}, /* Windows Smartphone 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x04da }, 0}, /* Windows Smartphone 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x04db }, 0}, /* Windows Smartphone 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x04dc }, 0}, /* Windows Smartphone 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x04dd }, 0}, /* Windows Smartphone 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x04de }, 0}, /* Windows Smartphone 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x04df }, 0}, /* Windows Smartphone 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x04e0 }, 0}, /* Windows Smartphone 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x04e1 }, 0}, /* Windows Smartphone 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x04e2 }, 0}, /* Windows Smartphone 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x04e3 }, 0}, /* Windows Smartphone 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x04e4 }, 0}, /* Windows Smartphone 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x04e5 }, 0}, /* Windows Smartphone 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x04e6 }, 0}, /* Windows Smartphone 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x04e7 }, 0}, /* Windows Smartphone 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x04e8 }, 0}, /* Windows Smartphone 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x04e9 }, 0}, /* Windows Smartphone 2003 */
- {{ USB_VENDOR_MICROSOFT, 0x04ea }, 0}, /* Windows Smartphone 2003 */
- {{ USB_VENDOR_MOTOROLA2, 0x4204 }, 0}, /* Motorola MPx200 Smartphone */
- {{ USB_VENDOR_MOTOROLA2, 0x4214 }, 0}, /* Motorola MPc GSM */
- {{ USB_VENDOR_MOTOROLA2, 0x4224 }, 0}, /* Motorola MPx220 Smartphone */
- {{ USB_VENDOR_MOTOROLA2, 0x4234 }, 0}, /* Motorola MPc CDMA */
- {{ USB_VENDOR_MOTOROLA2, 0x4244 }, 0}, /* Motorola MPx100 Smartphone */
- {{ USB_VENDOR_NEC, 0x00d5 }, 0}, /* NEC USB Sync */
- {{ USB_VENDOR_NEC, 0x00d6 }, 0}, /* NEC USB Sync */
- {{ USB_VENDOR_NEC, 0x00d7 }, 0}, /* NEC USB Sync */
- {{ USB_VENDOR_NEC, 0x8024 }, 0}, /* NEC USB Sync */
- {{ USB_VENDOR_NEC, 0x8025 }, 0}, /* NEC USB Sync */
- {{ USB_VENDOR_PANASONIC, 0x2500 }, 0}, /* Panasonic USB Sync */
- {{ USB_VENDOR_SAMSUNG, 0x5f00 }, 0}, /* Samsung NEXiO USB Sync */
- {{ USB_VENDOR_SAMSUNG, 0x5f01 }, 0}, /* Samsung NEXiO USB Sync */
- {{ USB_VENDOR_SAMSUNG, 0x5f02 }, 0}, /* Samsung NEXiO USB Sync */
- {{ USB_VENDOR_SAMSUNG, 0x5f03 }, 0}, /* Samsung NEXiO USB Sync */
- {{ USB_VENDOR_SAMSUNG, 0x5f04 }, 0}, /* Samsung NEXiO USB Sync */
- {{ USB_VENDOR_SAMSUNG, 0x6611 }, 0}, /* Samsung MITs USB Sync */
- {{ USB_VENDOR_SAMSUNG, 0x6613 }, 0}, /* Samsung MITs USB Sync */
- {{ USB_VENDOR_SAMSUNG, 0x6615 }, 0}, /* Samsung MITs USB Sync */
- {{ USB_VENDOR_SAMSUNG, 0x6617 }, 0}, /* Samsung MITs USB Sync */
- {{ USB_VENDOR_SAMSUNG, 0x6619 }, 0}, /* Samsung MITs USB Sync */
- {{ USB_VENDOR_SAMSUNG, 0x661b }, 0}, /* Samsung MITs USB Sync */
- {{ USB_VENDOR_SAMSUNG, 0x662e }, 0}, /* Samsung MITs USB Sync */
- {{ USB_VENDOR_SAMSUNG, 0x6630 }, 0}, /* Samsung MITs USB Sync */
- {{ USB_VENDOR_SAMSUNG, 0x6632 }, 0}, /* Samsung MITs USB Sync */
- {{ USB_VENDOR_SHARP, 0x9102 }, 0}, /* SHARP WS003SH USB Modem */
- {{ USB_VENDOR_SHARP, 0x9121 }, 0}, /* SHARP WS004SH USB Modem */
- {{ USB_VENDOR_SHARP, 0x9151 }, 0}, /* SHARP S01SH USB Modem */
- {{ USB_VENDOR_SHARP, USB_PRODUCT_SHARP_WZERO3ES }, 0},
- {{ USB_VENDOR_SYMBOL, 0x2000 }, 0}, /* Symbol USB Sync */
- {{ USB_VENDOR_SYMBOL, 0x2001 }, 0}, /* Symbol USB Sync 0x2001 */
- {{ USB_VENDOR_SYMBOL, 0x2002 }, 0}, /* Symbol USB Sync 0x2002 */
- {{ USB_VENDOR_SYMBOL, 0x2003 }, 0}, /* Symbol USB Sync 0x2003 */
- {{ USB_VENDOR_SYMBOL, 0x2004 }, 0}, /* Symbol USB Sync 0x2004 */
- {{ USB_VENDOR_SYMBOL, 0x2005 }, 0}, /* Symbol USB Sync 0x2005 */
- {{ USB_VENDOR_SYMBOL, 0x2006 }, 0}, /* Symbol USB Sync 0x2006 */
- {{ USB_VENDOR_SYMBOL, 0x2007 }, 0}, /* Symbol USB Sync 0x2007 */
- {{ USB_VENDOR_SYMBOL, 0x2008 }, 0}, /* Symbol USB Sync 0x2008 */
- {{ USB_VENDOR_SYMBOL, 0x2009 }, 0}, /* Symbol USB Sync 0x2009 */
- {{ USB_VENDOR_SYMBOL, 0x200a }, 0}, /* Symbol USB Sync 0x200a */
- {{ USB_VENDOR_TOSHIBA, 0x0700 }, 0}, /* TOSHIBA USB Sync 0700 */
- {{ USB_VENDOR_TOSHIBA, 0x0705 }, 0}, /* TOSHIBA Pocket PC e310 */
- {{ USB_VENDOR_TOSHIBA, 0x0707 }, 0}, /* TOSHIBA Pocket PC e330 Series */
- {{ USB_VENDOR_TOSHIBA, 0x0708 }, 0}, /* TOSHIBA Pocket PC e350Series */
- {{ USB_VENDOR_TOSHIBA, 0x0709 }, 0}, /* TOSHIBA Pocket PC e750 Series */
- {{ USB_VENDOR_TOSHIBA, 0x070a }, 0}, /* TOSHIBA Pocket PC e400 Series */
- {{ USB_VENDOR_TOSHIBA, 0x070b }, 0}, /* TOSHIBA Pocket PC e800 Series */
- {{ USB_VENDOR_TOSHIBA, USB_PRODUCT_TOSHIBA_POCKETPC_E740 }, 0}, /* TOSHIBA Pocket PC e740 */
- {{ USB_VENDOR_VIEWSONIC, 0x0ed9 }, 0}, /* ViewSonic Color Pocket PC V35 */
- {{ USB_VENDOR_VIEWSONIC, 0x1527 }, 0}, /* ViewSonic Color Pocket PC V36 */
- {{ USB_VENDOR_VIEWSONIC, 0x1529 }, 0}, /* ViewSonic Color Pocket PC V37 */
- {{ USB_VENDOR_VIEWSONIC, 0x152b }, 0}, /* ViewSonic Color Pocket PC V38 */
- {{ USB_VENDOR_VIEWSONIC, 0x152e }, 0}, /* ViewSonic Pocket PC */
- {{ USB_VENDOR_VIEWSONIC, 0x1921 }, 0}, /* ViewSonic Communicator Pocket PC */
- {{ USB_VENDOR_VIEWSONIC, 0x1922 }, 0}, /* ViewSonic Smartphone */
- {{ USB_VENDOR_VIEWSONIC, 0x1923 }, 0}, /* ViewSonic Pocket PC V30 */
-};
-
-#define uipaq_lookup(v, p) ((const struct uipaq_type *)usb_lookup(uipaq_devs, v, p))
-
-static int
-uipaq_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
-
- if (uaa->iface != NULL)
- return (UMATCH_NONE);
-
- DPRINTFN(20,("uipaq: vendor=0x%x, product=0x%x\n",
- uaa->vendor, uaa->product));
-
- return (uipaq_lookup(uaa->vendor, uaa->product) != NULL ?
- UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
-}
-
-static int
-uipaq_attach(device_t self)
-{
- usb_device_request_t req;
- struct uipaq_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usbd_device_handle dev = uaa->device;
- usbd_interface_handle iface;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
- int i;
- usbd_status err;
- struct ucom_softc *ucom = &sc->sc_ucom;
-
- ucom->sc_dev = self;
- ucom->sc_udev = dev;
-
- DPRINTFN(10,("\nuipaq_attach: sc=%p\n", sc));
-
- /* Move the device into the configured state. */
- err = usbd_set_config_no(dev, UIPAQ_CONFIG_NO, 1);
- if (err) {
- device_printf(ucom->sc_dev,
- "failed to set configuration: %s\n", usbd_errstr(err));
- goto bad;
- }
-
- err = usbd_device2interface_handle(dev, UIPAQ_IFACE_INDEX, &iface);
- if (err) {
- device_printf(ucom->sc_dev, "failed to get interface: %s\n",
- usbd_errstr(err));
- goto bad;
- }
-
- sc->sc_flags = uipaq_lookup(uaa->vendor, uaa->product)->uv_flags;
- id = usbd_get_interface_descriptor(iface);
- ucom->sc_iface = iface;
- ucom->sc_ibufsize = UIPAQIBUFSIZE;
- ucom->sc_obufsize = UIPAQOBUFSIZE;
- ucom->sc_ibufsizepad = UIPAQIBUFSIZE;
- ucom->sc_opkthdrlen = 0;
- ucom->sc_callback = &uipaq_callback;
- ucom->sc_parent = sc;
- ucom->sc_bulkin_no = ucom->sc_bulkout_no = -1;
- for (i=0; i<id->bNumEndpoints; i++) {
- ed = usbd_interface2endpoint_descriptor(iface, i);
- if (ed == NULL) {
- device_printf(ucom->sc_dev,
- "no endpoint descriptor for %d\n", i);
- goto bad;
- }
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
- ucom->sc_bulkin_no = ed->bEndpointAddress;
- } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
- (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
- ucom->sc_bulkout_no = ed->bEndpointAddress;
- }
- }
- if (ucom->sc_bulkin_no == -1 || ucom->sc_bulkout_no == -1) {
- device_printf(ucom->sc_dev,
- "no proper endpoints found (%d,%d)\n",
- ucom->sc_bulkin_no, ucom->sc_bulkout_no);
- return (ENXIO);
- }
- /*
- * Send magic bytes, cribbed from Linux ipaq driver that claims
- * to have sniffed them from Win98.
- */
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UCDC_SET_CONTROL_LINE_STATE;
- USETW(req.wValue, UCDC_LINE_DTR);
- USETW(req.wIndex, 0x0);
- USETW(req.wLength, 0);
- for (i = 0; i < 100; i++) {
- err = usbd_do_request_flags(ucom->sc_udev, &req, NULL, 0, NULL, 100);
- if (!err)
- break;
- usbd_delay_ms(dev, 1000);
- }
- ucom_attach(&sc->sc_ucom);
- return (0);
-bad:
- DPRINTF(("uipaq_attach: ATTACH ERROR\n"));
- ucom->sc_dying = 1;
- return (ENXIO);
-}
-
-void
-uipaq_dtr(struct uipaq_softc* sc, int onoff)
-{
- usb_device_request_t req;
- struct ucom_softc *ucom = &sc->sc_ucom;
- usbd_status err;
- int retries = 3;
-
- DPRINTF(("%s: uipaq_dtr: onoff=%x\n", device_get_nameunit(ucom->sc_dev), onoff));
-
- /* Avoid sending unnecessary requests */
- if (onoff && (sc->sc_lcr & UCDC_LINE_DTR))
- return;
- if (!onoff && !(sc->sc_lcr & UCDC_LINE_DTR))
- return;
-
- /* Other parameters depend on reg */
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UCDC_SET_CONTROL_LINE_STATE;
- sc->sc_lcr = onoff ? sc->sc_lcr | UCDC_LINE_DTR : sc->sc_lcr & ~UCDC_LINE_DTR;
- USETW(req.wValue, sc->sc_lcr);
- USETW(req.wIndex, 0x0);
- USETW(req.wLength, 0);
-
- /* Fire off the request a few times if necessary */
- while (retries) {
- err = usbd_do_request(ucom->sc_udev, &req, NULL);
- if (!err)
- break;
- retries--;
- }
-}
-
-void
-uipaq_rts(struct uipaq_softc* sc, int onoff)
-{
- usb_device_request_t req;
- struct ucom_softc *ucom = &sc->sc_ucom;
- usbd_status err;
- int retries = 3;
-
- DPRINTF(("%s: uipaq_rts: onoff=%x\n", device_get_nameunit(ucom->sc_dev), onoff));
-
- /* Avoid sending unnecessary requests */
- if (onoff && (sc->sc_lcr & UCDC_LINE_RTS)) return;
- if (!onoff && !(sc->sc_lcr & UCDC_LINE_RTS)) return;
-
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UCDC_SET_CONTROL_LINE_STATE;
- sc->sc_lcr = onoff ? sc->sc_lcr | UCDC_LINE_RTS : sc->sc_lcr & ~UCDC_LINE_RTS;
- USETW(req.wValue, sc->sc_lcr);
- USETW(req.wIndex, 0x0);
- USETW(req.wLength, 0);
-
- while (retries) {
- err = usbd_do_request(ucom->sc_udev, &req, NULL);
- if (!err)
- break;
- retries--;
- }
-}
-
-void
-uipaq_break(struct uipaq_softc* sc, int onoff)
-{
- usb_device_request_t req;
- struct ucom_softc *ucom = &sc->sc_ucom;
- usbd_status err;
- int retries = 3;
-
- DPRINTF(("%s: uipaq_break: onoff=%x\n", device_get_nameunit(ucom->sc_dev), onoff));
-
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UCDC_SEND_BREAK;
-
- USETW(req.wValue, onoff ? UCDC_BREAK_ON : UCDC_BREAK_OFF);
- USETW(req.wIndex, 0x0);
- USETW(req.wLength, 0);
-
- while (retries) {
- err = usbd_do_request(ucom->sc_udev, &req, NULL);
- if (!err)
- break;
- retries--;
- }
-}
-
-void
-uipaq_set(void *addr, int portno, int reg, int onoff)
-{
- struct uipaq_softc* sc = addr;
- struct ucom_softc *ucom = &sc->sc_ucom;
-
- switch (reg) {
- case UCOM_SET_DTR:
- uipaq_dtr(addr, onoff);
- break;
- case UCOM_SET_RTS:
- uipaq_rts(addr, onoff);
- break;
- case UCOM_SET_BREAK:
- uipaq_break(addr, onoff);
- break;
- default:
- printf("%s: unhandled set request: reg=%x onoff=%x\n",
- device_get_nameunit(ucom->sc_dev), reg, onoff);
- return;
- }
-}
-
-int
-uipaq_detach(device_t self)
-{
- struct uipaq_softc *sc = device_get_softc(self);
- struct ucom_softc *ucom = &sc->sc_ucom;
- int rv = 0;
-
- DPRINTF(("uipaq_detach: sc=%p flags=%d\n", sc, flags));
- ucom->sc_dying = 1;
-
- rv = ucom_detach(ucom);
-
- return (rv);
-}
-
-static device_method_t uipaq_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, uipaq_match),
- DEVMETHOD(device_attach, uipaq_attach),
- DEVMETHOD(device_detach, uipaq_detach),
-
- { 0, 0 }
-};
-static driver_t uipaq_driver = {
- "ucom",
- uipaq_methods,
- sizeof (struct uipaq_softc)
-};
-
-DRIVER_MODULE(uipaq, uhub, uipaq_driver, ucom_devclass, usbd_driver_load, 0);
-MODULE_DEPEND(uipaq, usb, 1, 1, 1);
-MODULE_DEPEND(uipaq, ucom, UCOM_MINVER, UCOM_PREFVER, UCOM_MAXVER);
diff --git a/sys/dev/usb/ukbd.c b/sys/dev/usb/ukbd.c
deleted file mode 100644
index 5a7c9fc..0000000
--- a/sys/dev/usb/ukbd.c
+++ /dev/null
@@ -1,1538 +0,0 @@
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) 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.
- *
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * HID spec: http://www.usb.org/developers/devclass_docs/HID1_11.pdf
- */
-
-#include "opt_compat.h"
-#include "opt_kbd.h"
-#include "opt_ukbd.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/ioccom.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/file.h>
-#include <sys/limits.h>
-#include <sys/selinfo.h>
-#include <sys/sysctl.h>
-#include <sys/uio.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbhid.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include "usbdevs.h"
-#include <dev/usb/usb_quirks.h>
-#include <dev/usb/hid.h>
-
-#include <sys/kbio.h>
-#include <dev/kbd/kbdreg.h>
-
-#define UKBD_EMULATE_ATSCANCODE 1
-
-#define DRIVER_NAME "ukbd"
-
-#define delay(d) DELAY(d)
-
-#ifdef USB_DEBUG
-#define DPRINTF(x) if (ukbddebug) printf x
-#define DPRINTFN(n,x) if (ukbddebug>(n)) printf x
-int ukbddebug = 0;
-SYSCTL_NODE(_hw_usb, OID_AUTO, ukbd, CTLFLAG_RW, 0, "USB ukbd");
-SYSCTL_INT(_hw_usb_ukbd, OID_AUTO, debug, CTLFLAG_RW,
- &ukbddebug, 0, "ukbd debug level");
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-#define UPROTO_BOOT_KEYBOARD 1
-
-#define NKEYCODE 6
-
-struct ukbd_data {
- u_int8_t modifiers;
-#define MOD_CONTROL_L 0x01
-#define MOD_CONTROL_R 0x10
-#define MOD_SHIFT_L 0x02
-#define MOD_SHIFT_R 0x20
-#define MOD_ALT_L 0x04
-#define MOD_ALT_R 0x40
-#define MOD_WIN_L 0x08
-#define MOD_WIN_R 0x80
- u_int8_t reserved;
- u_int8_t keycode[NKEYCODE];
-};
-
-#define MAXKEYS (NMOD+2*NKEYCODE)
-
-typedef struct ukbd_softc {
- device_t sc_dev; /* base device */
-} ukbd_softc_t;
-
-#define UKBD_CHUNK 128 /* chunk size for read */
-#define UKBD_BSIZE 1020 /* buffer size */
-
-typedef void usbd_intr_t(usbd_xfer_handle, usbd_private_handle, usbd_status);
-typedef void usbd_disco_t(void *);
-
-static usbd_intr_t ukbd_intr;
-static int ukbd_driver_load(module_t mod, int what, void *arg);
-
-static device_probe_t ukbd_match;
-static device_attach_t ukbd_attach;
-static device_detach_t ukbd_detach;
-static device_resume_t ukbd_resume;
-
-static device_method_t ukbd_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, ukbd_match),
- DEVMETHOD(device_attach, ukbd_attach),
- DEVMETHOD(device_detach, ukbd_detach),
- DEVMETHOD(device_resume, ukbd_resume),
-
- { 0, 0 }
-};
-
-static driver_t ukbd_driver = {
- "ukbd",
- ukbd_methods,
- sizeof(struct ukbd_softc)
-};
-
-static devclass_t ukbd_devclass;
-
-MODULE_DEPEND(ukbd, usb, 1, 1, 1);
-DRIVER_MODULE(ukbd, uhub, ukbd_driver, ukbd_devclass, ukbd_driver_load, 0);
-
-static int
-ukbd_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
-
- keyboard_switch_t *sw;
- void *arg[2];
- int unit = device_get_unit(self);
-
- sw = kbd_get_switch(DRIVER_NAME);
- if (sw == NULL)
- return (UMATCH_NONE);
-
- arg[0] = (void *)uaa;
- arg[1] = (void *)ukbd_intr;
- if ((*sw->probe)(unit, (void *)arg, 0))
- return (UMATCH_NONE);
-
- if (usbd_get_quirks(uaa->device)->uq_flags & UQ_KBD_IGNORE)
- return (UMATCH_NONE);
-
- return (UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO);
-}
-
-static int
-ukbd_attach(device_t self)
-{
- struct ukbd_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usbd_interface_handle iface = uaa->iface;
- usb_interface_descriptor_t *id;
-
- keyboard_switch_t *sw;
- keyboard_t *kbd;
- void *arg[2];
- int unit = device_get_unit(self);
-
- sc->sc_dev = self;
- sw = kbd_get_switch(DRIVER_NAME);
- if (sw == NULL)
- return ENXIO;
-
- id = usbd_get_interface_descriptor(iface);
-
- arg[0] = (void *)uaa;
- arg[1] = (void *)ukbd_intr;
- kbd = NULL;
- if ((*sw->probe)(unit, (void *)arg, 0))
- return ENXIO;
- if ((*sw->init)(unit, &kbd, (void *)arg, 0))
- return ENXIO;
- (*sw->enable)(kbd);
-
-#ifdef KBD_INSTALL_CDEV
- if (kbd_attach(kbd))
- return ENXIO;
-#endif
- if (bootverbose)
- (*sw->diag)(kbd, bootverbose);
-
- return 0;
-}
-
-int
-ukbd_detach(device_t self)
-{
- keyboard_t *kbd;
- int error;
-
- kbd = kbd_get_keyboard(kbd_find_keyboard(DRIVER_NAME,
- device_get_unit(self)));
- if (kbd == NULL) {
- DPRINTF(("%s: keyboard not attached!?\n", device_get_nameunit(self)));
- return ENXIO;
- }
- kbdd_disable(kbd);
-
-#ifdef KBD_INSTALL_CDEV
- error = kbd_detach(kbd);
- if (error)
- return error;
-#endif
- error = kbdd_term(kbd);
- if (error)
- return error;
-
- DPRINTF(("%s: disconnected\n", device_get_nameunit(self)));
-
- return (0);
-}
-
-static int
-ukbd_resume(device_t self)
-{
- keyboard_t *kbd;
-
- kbd = kbd_get_keyboard(kbd_find_keyboard(DRIVER_NAME,
- device_get_unit(self)));
- if (kbd)
- kbdd_clear_state(kbd);
- return (0);
-}
-
-void
-ukbd_intr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status)
-{
- keyboard_t *kbd = (keyboard_t *)addr;
-
- kbdd_intr(kbd, (void *)status);
-}
-
-#define UKBD_DEFAULT 0
-
-#define KEY_ERROR 0x01
-
-#define KEY_PRESS 0
-#define KEY_RELEASE 0x400
-#define KEY_INDEX(c) ((c) & ~KEY_RELEASE)
-
-#define SCAN_PRESS 0
-#define SCAN_RELEASE 0x80
-#define SCAN_PREFIX_E0 0x100
-#define SCAN_PREFIX_E1 0x200
-#define SCAN_PREFIX_CTL 0x400
-#define SCAN_PREFIX_SHIFT 0x800
-#define SCAN_PREFIX (SCAN_PREFIX_E0 | SCAN_PREFIX_E1 | SCAN_PREFIX_CTL \
- | SCAN_PREFIX_SHIFT)
-#define SCAN_CHAR(c) ((c) & 0x7f)
-
-#define NMOD 8
-static struct {
- int mask, key;
-} ukbd_mods[NMOD] = {
- { MOD_CONTROL_L, 0xe0 },
- { MOD_CONTROL_R, 0xe4 },
- { MOD_SHIFT_L, 0xe1 },
- { MOD_SHIFT_R, 0xe5 },
- { MOD_ALT_L, 0xe2 },
- { MOD_ALT_R, 0xe6 },
- { MOD_WIN_L, 0xe3 },
- { MOD_WIN_R, 0xe7 },
-};
-
-#define NN 0 /* no translation */
-/*
- * Translate USB keycodes to AT keyboard scancodes.
- */
-/*
- * FIXME: Mac USB keyboard generates:
- * 0x53: keypad NumLock/Clear
- * 0x66: Power
- * 0x67: keypad =
- * 0x68: F13
- * 0x69: F14
- * 0x6a: F15
- */
-static u_int8_t ukbd_trtab[256] = {
- 0, 0, 0, 0, 30, 48, 46, 32, /* 00 - 07 */
- 18, 33, 34, 35, 23, 36, 37, 38, /* 08 - 0F */
- 50, 49, 24, 25, 16, 19, 31, 20, /* 10 - 17 */
- 22, 47, 17, 45, 21, 44, 2, 3, /* 18 - 1F */
- 4, 5, 6, 7, 8, 9, 10, 11, /* 20 - 27 */
- 28, 1, 14, 15, 57, 12, 13, 26, /* 28 - 2F */
- 27, 43, 43, 39, 40, 41, 51, 52, /* 30 - 37 */
- 53, 58, 59, 60, 61, 62, 63, 64, /* 38 - 3F */
- 65, 66, 67, 68, 87, 88, 92, 70, /* 40 - 47 */
- 104, 102, 94, 96, 103, 99, 101, 98, /* 48 - 4F */
- 97, 100, 95, 69, 91, 55, 74, 78, /* 50 - 57 */
- 89, 79, 80, 81, 75, 76, 77, 71, /* 58 - 5F */
- 72, 73, 82, 83, 86, 107, 122, NN, /* 60 - 67 */
- NN, NN, NN, NN, NN, NN, NN, NN, /* 68 - 6F */
- NN, NN, NN, NN, 115, 108, 111, 113, /* 70 - 77 */
- 109, 110, 112, 118, 114, 116, 117, 119, /* 78 - 7F */
- 121, 120, NN, NN, NN, NN, NN, 115, /* 80 - 87 */
- 112, 125, 121, 123, NN, NN, NN, NN, /* 88 - 8F */
- NN, NN, NN, NN, NN, NN, NN, NN, /* 90 - 97 */
- NN, NN, NN, NN, NN, NN, NN, NN, /* 98 - 9F */
- NN, NN, NN, NN, NN, NN, NN, NN, /* A0 - A7 */
- NN, NN, NN, NN, NN, NN, NN, NN, /* A8 - AF */
- NN, NN, NN, NN, NN, NN, NN, NN, /* B0 - B7 */
- NN, NN, NN, NN, NN, NN, NN, NN, /* B8 - BF */
- NN, NN, NN, NN, NN, NN, NN, NN, /* C0 - C7 */
- NN, NN, NN, NN, NN, NN, NN, NN, /* C8 - CF */
- NN, NN, NN, NN, NN, NN, NN, NN, /* D0 - D7 */
- NN, NN, NN, NN, NN, NN, NN, NN, /* D8 - DF */
- 29, 42, 56, 105, 90, 54, 93, 106, /* E0 - E7 */
- NN, NN, NN, NN, NN, NN, NN, NN, /* E8 - EF */
- NN, NN, NN, NN, NN, NN, NN, NN, /* F0 - F7 */
- NN, NN, NN, NN, NN, NN, NN, NN, /* F8 - FF */
-};
-
-typedef struct ukbd_state {
- usbd_interface_handle ks_iface; /* interface */
- usbd_pipe_handle ks_intrpipe; /* interrupt pipe */
- struct usb_attach_arg *ks_uaa;
- int ks_ep_addr;
-
- struct ukbd_data ks_ndata;
- struct ukbd_data ks_odata;
- u_long ks_ntime[NKEYCODE];
- u_long ks_otime[NKEYCODE];
-
-#define INPUTBUFSIZE (NMOD + 2*NKEYCODE)
- u_int ks_input[INPUTBUFSIZE]; /* input buffer */
- int ks_inputs;
- int ks_inputhead;
- int ks_inputtail;
-
- int ks_ifstate;
-#define INTRENABLED (1 << 0)
-#define DISCONNECTED (1 << 1)
-
- struct callout ks_timeout_handle;
-
- int ks_mode; /* input mode (K_XLATE,K_RAW,K_CODE) */
- int ks_flags; /* flags */
-#define COMPOSE (1 << 0)
- int ks_polling;
- int ks_state; /* shift/lock key state */
- int ks_accents; /* accent key index (> 0) */
- u_int ks_composed_char; /* composed char code (> 0) */
-#ifdef UKBD_EMULATE_ATSCANCODE
- u_int ks_buffered_char[2];
- u_int8_t ks_leds; /* store for async led requests */
-#endif
-} ukbd_state_t;
-
-/* keyboard driver declaration */
-static int ukbd_configure(int flags);
-static kbd_probe_t ukbd_probe;
-static kbd_init_t ukbd_init;
-static kbd_term_t ukbd_term;
-static kbd_intr_t ukbd_interrupt;
-static kbd_test_if_t ukbd_test_if;
-static kbd_enable_t ukbd_enable;
-static kbd_disable_t ukbd_disable;
-static kbd_read_t ukbd_read;
-static kbd_check_t ukbd_check;
-static kbd_read_char_t ukbd_read_char;
-static kbd_check_char_t ukbd_check_char;
-static kbd_ioctl_t ukbd_ioctl;
-static kbd_lock_t ukbd_lock;
-static kbd_clear_state_t ukbd_clear_state;
-static kbd_get_state_t ukbd_get_state;
-static kbd_set_state_t ukbd_set_state;
-static kbd_poll_mode_t ukbd_poll;
-
-keyboard_switch_t ukbdsw = {
- ukbd_probe,
- ukbd_init,
- ukbd_term,
- ukbd_interrupt,
- ukbd_test_if,
- ukbd_enable,
- ukbd_disable,
- ukbd_read,
- ukbd_check,
- ukbd_read_char,
- ukbd_check_char,
- ukbd_ioctl,
- ukbd_lock,
- ukbd_clear_state,
- ukbd_get_state,
- ukbd_set_state,
- genkbd_get_fkeystr,
- ukbd_poll,
- genkbd_diag,
-};
-
-KEYBOARD_DRIVER(ukbd, ukbdsw, ukbd_configure);
-
-/* local functions */
-static int ukbd_enable_intr(keyboard_t *kbd, int on,
- usbd_intr_t *func);
-static void ukbd_timeout(void *arg);
-
-static int ukbd_getc(ukbd_state_t *state, int wait);
-static int probe_keyboard(struct usb_attach_arg *uaa, int flags);
-static int init_keyboard(ukbd_state_t *state, int *type,
- int flags);
-static void set_leds(ukbd_state_t *state, int leds);
-static int set_typematic(keyboard_t *kbd, int code);
-#ifdef UKBD_EMULATE_ATSCANCODE
-static int keycode2scancode(int keycode, int shift, int up);
-#endif
-
-/* local variables */
-
-/* the initial key map, accent map and fkey strings */
-#if defined(UKBD_DFLT_KEYMAP) && !defined(KLD_MODULE)
-#define KBD_DFLT_KEYMAP
-#include "ukbdmap.h"
-#endif
-#include <dev/kbd/kbdtables.h>
-
-/* structures for the default keyboard */
-static keyboard_t default_kbd;
-static ukbd_state_t default_kbd_state;
-static keymap_t default_keymap;
-static accentmap_t default_accentmap;
-static fkeytab_t default_fkeytab[NUM_FKEYS];
-
-/*
- * The back door to the keyboard driver!
- * This function is called by the console driver, via the kbdio module,
- * to tickle keyboard drivers when the low-level console is being initialized.
- * Almost nothing in the kernel has been initialied yet. Try to probe
- * keyboards if possible.
- * NOTE: because of the way the low-level conole is initialized, this routine
- * may be called more than once!!
- */
-static int
-ukbd_configure(int flags)
-{
- return 0;
-
-#if 0 /* not yet */
- keyboard_t *kbd;
- device_t device;
- struct usb_attach_arg *uaa;
- void *arg[2];
-
- device = devclass_get_device(ukbd_devclass, UKBD_DEFAULT);
- if (device == NULL)
- return 0;
- uaa = (struct usb_attach_arg *)device_get_ivars(device);
- if (uaa == NULL)
- return 0;
-
- /* probe the default keyboard */
- arg[0] = (void *)uaa;
- arg[1] = (void *)ukbd_intr;
- kbd = NULL;
- if (ukbd_probe(UKBD_DEFAULT, arg, flags))
- return 0;
- if (ukbd_init(UKBD_DEFAULT, &kbd, arg, flags))
- return 0;
-
- /* return the number of found keyboards */
- return 1;
-#endif
-}
-
-/* low-level functions */
-
-/* detect a keyboard */
-static int
-ukbd_probe(int unit, void *arg, int flags)
-{
- void **data;
- struct usb_attach_arg *uaa;
-
- data = (void **)arg;
- uaa = (struct usb_attach_arg *)data[0];
-
- /* XXX */
- if (unit == UKBD_DEFAULT) {
- if (KBD_IS_PROBED(&default_kbd))
- return 0;
- }
- if (probe_keyboard(uaa, flags))
- return ENXIO;
- return 0;
-}
-
-/* reset and initialize the device */
-static int
-ukbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
-{
- keyboard_t *kbd;
- ukbd_state_t *state;
- keymap_t *keymap;
- accentmap_t *accmap;
- fkeytab_t *fkeymap;
- int fkeymap_size;
- void **data = (void **)arg;
- struct usb_attach_arg *uaa = (struct usb_attach_arg *)data[0];
-
- /* XXX */
- if (unit == UKBD_DEFAULT) {
- *kbdp = kbd = &default_kbd;
- if (KBD_IS_INITIALIZED(kbd) && KBD_IS_CONFIGURED(kbd))
- return 0;
- state = &default_kbd_state;
- keymap = &default_keymap;
- accmap = &default_accentmap;
- fkeymap = default_fkeytab;
- fkeymap_size =
- sizeof(default_fkeytab)/sizeof(default_fkeytab[0]);
- } else if (*kbdp == NULL) {
- *kbdp = kbd = malloc(sizeof(*kbd), M_DEVBUF, M_NOWAIT);
- if (kbd == NULL)
- return ENOMEM;
- bzero(kbd, sizeof(*kbd));
- state = malloc(sizeof(*state), M_DEVBUF, M_NOWAIT);
- keymap = malloc(sizeof(key_map), M_DEVBUF, M_NOWAIT);
- accmap = malloc(sizeof(accent_map), M_DEVBUF, M_NOWAIT);
- fkeymap = malloc(sizeof(fkey_tab), M_DEVBUF, M_NOWAIT);
- fkeymap_size = sizeof(fkey_tab)/sizeof(fkey_tab[0]);
- if ((state == NULL) || (keymap == NULL) || (accmap == NULL)
- || (fkeymap == NULL)) {
- if (state != NULL)
- free(state, M_DEVBUF);
- if (keymap != NULL)
- free(keymap, M_DEVBUF);
- if (accmap != NULL)
- free(accmap, M_DEVBUF);
- if (fkeymap != NULL)
- free(fkeymap, M_DEVBUF);
- free(kbd, M_DEVBUF);
- return ENOMEM;
- }
- } else if (KBD_IS_INITIALIZED(*kbdp) && KBD_IS_CONFIGURED(*kbdp)) {
- return 0;
- } else {
- kbd = *kbdp;
- state = (ukbd_state_t *)kbd->kb_data;
- keymap = kbd->kb_keymap;
- accmap = kbd->kb_accentmap;
- fkeymap = kbd->kb_fkeytab;
- fkeymap_size = kbd->kb_fkeytab_size;
- }
-
- if (!KBD_IS_PROBED(kbd)) {
- kbd_init_struct(kbd, DRIVER_NAME, KB_OTHER, unit, flags, 0, 0);
- bzero(state, sizeof(*state));
- bcopy(&key_map, keymap, sizeof(key_map));
- bcopy(&accent_map, accmap, sizeof(accent_map));
- bcopy(fkey_tab, fkeymap,
- imin(fkeymap_size*sizeof(fkeymap[0]), sizeof(fkey_tab)));
- kbd_set_maps(kbd, keymap, accmap, fkeymap, fkeymap_size);
- kbd->kb_data = (void *)state;
-
- if (probe_keyboard(uaa, flags))
- return ENXIO;
- else
- KBD_FOUND_DEVICE(kbd);
- ukbd_clear_state(kbd);
- state->ks_mode = K_XLATE;
- state->ks_iface = uaa->iface;
- state->ks_uaa = uaa;
- state->ks_ifstate = 0;
- callout_init(&state->ks_timeout_handle, 0);
- /*
- * FIXME: set the initial value for lock keys in ks_state
- * according to the BIOS data?
- */
- KBD_PROBE_DONE(kbd);
- }
- if (!KBD_IS_INITIALIZED(kbd) && !(flags & KB_CONF_PROBE_ONLY)) {
- if (KBD_HAS_DEVICE(kbd)
- && init_keyboard((ukbd_state_t *)kbd->kb_data,
- &kbd->kb_type, kbd->kb_flags)) {
- kbd->kb_flags = 0;
- /* XXX: Missing free()'s */
- return ENXIO;
- }
- ukbd_ioctl(kbd, KDSETLED, (caddr_t)&(state->ks_state));
- KBD_INIT_DONE(kbd);
- }
- if (!KBD_IS_CONFIGURED(kbd)) {
- if (kbd_register(kbd) < 0) {
- kbd->kb_flags = 0;
- /* XXX: Missing free()'s */
- return ENXIO;
- }
- if (ukbd_enable_intr(kbd, TRUE, (usbd_intr_t *)data[1]) == 0)
- ukbd_timeout((void *)kbd);
- KBD_CONFIG_DONE(kbd);
- }
-
- return 0;
-}
-
-static int
-ukbd_enable_intr(keyboard_t *kbd, int on, usbd_intr_t *func)
-{
- ukbd_state_t *state = (ukbd_state_t *)kbd->kb_data;
- usbd_status err;
-
- if (on) {
- /* Set up interrupt pipe. */
- if (state->ks_ifstate & INTRENABLED)
- return EBUSY;
-
- state->ks_ifstate |= INTRENABLED;
- err = usbd_open_pipe_intr(state->ks_iface, state->ks_ep_addr,
- USBD_SHORT_XFER_OK,
- &state->ks_intrpipe, kbd,
- &state->ks_ndata,
- sizeof(state->ks_ndata), func,
- USBD_DEFAULT_INTERVAL);
- if (err)
- return (EIO);
- } else {
- /* Disable interrupts. */
- usbd_abort_pipe(state->ks_intrpipe);
- usbd_close_pipe(state->ks_intrpipe);
-
- state->ks_ifstate &= ~INTRENABLED;
- }
-
- return (0);
-}
-
-/* finish using this keyboard */
-static int
-ukbd_term(keyboard_t *kbd)
-{
- ukbd_state_t *state;
- int error;
- int s;
-
- s = splusb();
-
- state = (ukbd_state_t *)kbd->kb_data;
- DPRINTF(("ukbd_term: ks_ifstate=0x%x\n", state->ks_ifstate));
-
- callout_stop(&state->ks_timeout_handle);
-
- if (state->ks_ifstate & INTRENABLED)
- ukbd_enable_intr(kbd, FALSE, NULL);
- if (state->ks_ifstate & INTRENABLED) {
- splx(s);
- DPRINTF(("ukbd_term: INTRENABLED!\n"));
- return ENXIO;
- }
-
- error = kbd_unregister(kbd);
- DPRINTF(("ukbd_term: kbd_unregister() %d\n", error));
- if (error == 0) {
- kbd->kb_flags = 0;
- if (kbd != &default_kbd) {
- free(kbd->kb_keymap, M_DEVBUF);
- free(kbd->kb_accentmap, M_DEVBUF);
- free(kbd->kb_fkeytab, M_DEVBUF);
- free(state, M_DEVBUF);
- free(kbd, M_DEVBUF);
- }
- }
-
- splx(s);
- return error;
-}
-
-
-/* keyboard interrupt routine */
-
-static void
-ukbd_timeout(void *arg)
-{
- keyboard_t *kbd;
- ukbd_state_t *state;
- int s;
-
- kbd = (keyboard_t *)arg;
- state = (ukbd_state_t *)kbd->kb_data;
- s = splusb();
- kbdd_intr(kbd, (void *)USBD_NORMAL_COMPLETION);
- callout_reset(&state->ks_timeout_handle, hz / 40, ukbd_timeout, arg);
- splx(s);
-}
-
-static int
-ukbd_interrupt(keyboard_t *kbd, void *arg)
-{
- usbd_status status = (usbd_status)arg;
- ukbd_state_t *state;
- struct ukbd_data *ud;
- struct timeval tv;
- u_long now;
- int mod, omod;
- int key, c;
- int i, j;
-
- DPRINTFN(5, ("ukbd_intr: status=%d\n", status));
- if (status == USBD_CANCELLED)
- return 0;
-
- state = (ukbd_state_t *)kbd->kb_data;
- ud = &state->ks_ndata;
-
- if (status != USBD_NORMAL_COMPLETION) {
- DPRINTF(("ukbd_intr: status=%d\n", status));
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall_async(state->ks_intrpipe);
- return 0;
- }
-
- if (ud->keycode[0] == KEY_ERROR)
- return 0; /* ignore */
-
- getmicrouptime(&tv);
- now = (u_long)tv.tv_sec*1000 + (u_long)tv.tv_usec/1000;
-
-#define ADDKEY1(c) \
- if (state->ks_inputs < INPUTBUFSIZE) { \
- state->ks_input[state->ks_inputtail] = (c); \
- ++state->ks_inputs; \
- state->ks_inputtail = (state->ks_inputtail + 1)%INPUTBUFSIZE; \
- }
-
- mod = ud->modifiers;
- omod = state->ks_odata.modifiers;
- if (mod != omod) {
- for (i = 0; i < NMOD; i++)
- if (( mod & ukbd_mods[i].mask) !=
- (omod & ukbd_mods[i].mask))
- ADDKEY1(ukbd_mods[i].key |
- (mod & ukbd_mods[i].mask
- ? KEY_PRESS : KEY_RELEASE));
- }
-
- /* Check for released keys. */
- for (i = 0; i < NKEYCODE; i++) {
- key = state->ks_odata.keycode[i];
- if (key == 0)
- continue;
- for (j = 0; j < NKEYCODE; j++) {
- if (ud->keycode[j] == 0)
- continue;
- if (key == ud->keycode[j])
- goto rfound;
- }
- ADDKEY1(key | KEY_RELEASE);
- rfound:
- ;
- }
-
- /* Check for pressed keys. */
- for (i = 0; i < NKEYCODE; i++) {
- key = ud->keycode[i];
- if (key == 0)
- continue;
- state->ks_ntime[i] = now + kbd->kb_delay1;
- for (j = 0; j < NKEYCODE; j++) {
- if (state->ks_odata.keycode[j] == 0)
- continue;
- if (key == state->ks_odata.keycode[j]) {
- state->ks_ntime[i] = state->ks_otime[j];
- if (state->ks_otime[j] > now)
- goto pfound;
- state->ks_ntime[i] = now + kbd->kb_delay2;
- break;
- }
- }
- ADDKEY1(key | KEY_PRESS);
- /*
- * If any other key is presently down, force its repeat to be
- * well in the future (100s). This makes the last key to be
- * pressed do the autorepeat.
- */
- for (j = 0; j < NKEYCODE; j++) {
- if (j != i)
- state->ks_ntime[j] = now + 100 * 1000;
- }
- pfound:
- ;
- }
-
- state->ks_odata = *ud;
- bcopy(state->ks_ntime, state->ks_otime, sizeof(state->ks_ntime));
- if (state->ks_inputs <= 0)
- return 0;
-
-#ifdef USB_DEBUG
- for (i = state->ks_inputhead, j = 0; j < state->ks_inputs; ++j,
- i = (i + 1)%INPUTBUFSIZE) {
- c = state->ks_input[i];
- DPRINTF(("0x%x (%d) %s\n", c, c,
- (c & KEY_RELEASE) ? "released":"pressed"));
- }
- if (ud->modifiers)
- DPRINTF(("mod:0x%04x ", ud->modifiers));
- for (i = 0; i < NKEYCODE; i++) {
- if (ud->keycode[i])
- DPRINTF(("%d ", ud->keycode[i]));
- }
- DPRINTF(("\n"));
-#endif /* USB_DEBUG */
-
- if (state->ks_polling)
- return 0;
-
- if (KBD_IS_ACTIVE(kbd) && KBD_IS_BUSY(kbd)) {
- /* let the callback function to process the input */
- (*kbd->kb_callback.kc_func)(kbd, KBDIO_KEYINPUT,
- kbd->kb_callback.kc_arg);
- } else {
- /* read and discard the input; no one is waiting for it */
- do {
- c = ukbd_read_char(kbd, FALSE);
- } while (c != NOKEY);
- }
-
- return 0;
-}
-
-static int
-ukbd_getc(ukbd_state_t *state, int wait)
-{
- int c;
- int s;
-
- if (state->ks_polling) {
- DPRINTFN(1,("ukbd_getc: polling\n"));
- s = splusb();
- while (state->ks_inputs <= 0) {
- usbd_dopoll(state->ks_iface);
- if (wait == FALSE)
- break;
- }
- splx(s);
- }
- s = splusb();
- if (state->ks_inputs <= 0) {
- c = -1;
- } else {
- c = state->ks_input[state->ks_inputhead];
- --state->ks_inputs;
- state->ks_inputhead = (state->ks_inputhead + 1)%INPUTBUFSIZE;
- }
- splx(s);
- return c;
-}
-
-/* test the interface to the device */
-static int
-ukbd_test_if(keyboard_t *kbd)
-{
- return 0;
-}
-
-/*
- * Enable the access to the device; until this function is called,
- * the client cannot read from the keyboard.
- */
-static int
-ukbd_enable(keyboard_t *kbd)
-{
- int s;
-
- s = splusb();
- KBD_ACTIVATE(kbd);
- splx(s);
- return 0;
-}
-
-/* disallow the access to the device */
-static int
-ukbd_disable(keyboard_t *kbd)
-{
- int s;
-
- s = splusb();
- KBD_DEACTIVATE(kbd);
- splx(s);
- return 0;
-}
-
-/* read one byte from the keyboard if it's allowed */
-static int
-ukbd_read(keyboard_t *kbd, int wait)
-{
- ukbd_state_t *state;
- int usbcode;
-#ifdef UKBD_EMULATE_ATSCANCODE
- int keycode;
- int scancode;
-#endif
-
- state = (ukbd_state_t *)kbd->kb_data;
-#ifdef UKBD_EMULATE_ATSCANCODE
- if (state->ks_buffered_char[0]) {
- scancode = state->ks_buffered_char[0];
- if (scancode & SCAN_PREFIX) {
- state->ks_buffered_char[0] = scancode & ~SCAN_PREFIX;
- return ((scancode & SCAN_PREFIX_E0) ? 0xe0 : 0xe1);
- } else {
- state->ks_buffered_char[0] = state->ks_buffered_char[1];
- state->ks_buffered_char[1] = 0;
- return scancode;
- }
- }
-#endif /* UKBD_EMULATE_ATSCANCODE */
-
- /* XXX */
- usbcode = ukbd_getc(state, wait);
- if (!KBD_IS_ACTIVE(kbd) || (usbcode == -1))
- return -1;
- ++kbd->kb_count;
-#ifdef UKBD_EMULATE_ATSCANCODE
- keycode = ukbd_trtab[KEY_INDEX(usbcode)];
- if (keycode == NN)
- return -1;
-
- scancode = keycode2scancode(keycode, state->ks_ndata.modifiers,
- usbcode & KEY_RELEASE);
- if (scancode & SCAN_PREFIX) {
- if (scancode & SCAN_PREFIX_CTL) {
- state->ks_buffered_char[0] =
- 0x1d | (scancode & SCAN_RELEASE); /* Ctrl */
- state->ks_buffered_char[1] = scancode & ~SCAN_PREFIX;
- } else if (scancode & SCAN_PREFIX_SHIFT) {
- state->ks_buffered_char[0] =
- 0x2a | (scancode & SCAN_RELEASE); /* Shift */
- state->ks_buffered_char[1] =
- scancode & ~SCAN_PREFIX_SHIFT;
- } else {
- state->ks_buffered_char[0] = scancode & ~SCAN_PREFIX;
- state->ks_buffered_char[1] = 0;
- }
- return ((scancode & SCAN_PREFIX_E0) ? 0xe0 : 0xe1);
- }
- return scancode;
-#else /* !UKBD_EMULATE_ATSCANCODE */
- return usbcode;
-#endif /* UKBD_EMULATE_ATSCANCODE */
-}
-
-/* check if data is waiting */
-static int
-ukbd_check(keyboard_t *kbd)
-{
- if (!KBD_IS_ACTIVE(kbd))
- return FALSE;
-#ifdef UKBD_EMULATE_ATSCANCODE
- if (((ukbd_state_t *)kbd->kb_data)->ks_buffered_char[0])
- return TRUE;
-#endif
- if (((ukbd_state_t *)kbd->kb_data)->ks_inputs > 0)
- return TRUE;
- return FALSE;
-}
-
-/* read char from the keyboard */
-static u_int
-ukbd_read_char(keyboard_t *kbd, int wait)
-{
- ukbd_state_t *state;
- u_int action;
- int usbcode;
- int keycode;
-#ifdef UKBD_EMULATE_ATSCANCODE
- int scancode;
-#endif
-
- state = (ukbd_state_t *)kbd->kb_data;
-next_code:
- /* do we have a composed char to return? */
- if (!(state->ks_flags & COMPOSE) && (state->ks_composed_char > 0)) {
- action = state->ks_composed_char;
- state->ks_composed_char = 0;
- if (action > UCHAR_MAX)
- return ERRKEY;
- return action;
- }
-
-#ifdef UKBD_EMULATE_ATSCANCODE
- /* do we have a pending raw scan code? */
- if (state->ks_mode == K_RAW) {
- if (state->ks_buffered_char[0]) {
- scancode = state->ks_buffered_char[0];
- if (scancode & SCAN_PREFIX) {
- state->ks_buffered_char[0] =
- scancode & ~SCAN_PREFIX;
- return ((scancode & SCAN_PREFIX_E0) ? 0xe0 : 0xe1);
- } else {
- state->ks_buffered_char[0] =
- state->ks_buffered_char[1];
- state->ks_buffered_char[1] = 0;
- return scancode;
- }
- }
- }
-#endif /* UKBD_EMULATE_ATSCANCODE */
-
- /* see if there is something in the keyboard port */
- /* XXX */
- usbcode = ukbd_getc(state, wait);
- if (usbcode == -1)
- return NOKEY;
- ++kbd->kb_count;
-
-#ifdef UKBD_EMULATE_ATSCANCODE
- /* USB key index -> key code -> AT scan code */
- keycode = ukbd_trtab[KEY_INDEX(usbcode)];
- if (keycode == NN)
- return NOKEY;
-
- /* return an AT scan code for the K_RAW mode */
- if (state->ks_mode == K_RAW) {
- scancode = keycode2scancode(keycode, state->ks_ndata.modifiers,
- usbcode & KEY_RELEASE);
- if (scancode & SCAN_PREFIX) {
- if (scancode & SCAN_PREFIX_CTL) {
- state->ks_buffered_char[0] =
- 0x1d | (scancode & SCAN_RELEASE);
- state->ks_buffered_char[1] =
- scancode & ~SCAN_PREFIX;
- } else if (scancode & SCAN_PREFIX_SHIFT) {
- state->ks_buffered_char[0] =
- 0x2a | (scancode & SCAN_RELEASE);
- state->ks_buffered_char[1] =
- scancode & ~SCAN_PREFIX_SHIFT;
- } else {
- state->ks_buffered_char[0] =
- scancode & ~SCAN_PREFIX;
- state->ks_buffered_char[1] = 0;
- }
- return ((scancode & SCAN_PREFIX_E0) ? 0xe0 : 0xe1);
- }
- return scancode;
- }
-#else /* !UKBD_EMULATE_ATSCANCODE */
- /* return the byte as is for the K_RAW mode */
- if (state->ks_mode == K_RAW)
- return usbcode;
-
- /* USB key index -> key code */
- keycode = ukbd_trtab[KEY_INDEX(usbcode)];
- if (keycode == NN)
- return NOKEY;
-#endif /* UKBD_EMULATE_ATSCANCODE */
-
- switch (keycode) {
- case 0x38: /* left alt (compose key) */
- if (usbcode & KEY_RELEASE) {
- if (state->ks_flags & COMPOSE) {
- state->ks_flags &= ~COMPOSE;
- if (state->ks_composed_char > UCHAR_MAX)
- state->ks_composed_char = 0;
- }
- } else {
- if (!(state->ks_flags & COMPOSE)) {
- state->ks_flags |= COMPOSE;
- state->ks_composed_char = 0;
- }
- }
- break;
- /* XXX: I don't like these... */
- case 0x5c: /* print screen */
- if (state->ks_flags & ALTS)
- keycode = 0x54; /* sysrq */
- break;
- case 0x68: /* pause/break */
- if (state->ks_flags & CTLS)
- keycode = 0x6c; /* break */
- break;
- }
-
- /* return the key code in the K_CODE mode */
- if (usbcode & KEY_RELEASE)
- keycode |= SCAN_RELEASE;
- if (state->ks_mode == K_CODE)
- return keycode;
-
- /* compose a character code */
- if (state->ks_flags & COMPOSE) {
- switch (keycode) {
- /* key pressed, process it */
- case 0x47: case 0x48: case 0x49: /* keypad 7,8,9 */
- state->ks_composed_char *= 10;
- state->ks_composed_char += keycode - 0x40;
- if (state->ks_composed_char > UCHAR_MAX)
- return ERRKEY;
- goto next_code;
- case 0x4B: case 0x4C: case 0x4D: /* keypad 4,5,6 */
- state->ks_composed_char *= 10;
- state->ks_composed_char += keycode - 0x47;
- if (state->ks_composed_char > UCHAR_MAX)
- return ERRKEY;
- goto next_code;
- case 0x4F: case 0x50: case 0x51: /* keypad 1,2,3 */
- state->ks_composed_char *= 10;
- state->ks_composed_char += keycode - 0x4E;
- if (state->ks_composed_char > UCHAR_MAX)
- return ERRKEY;
- goto next_code;
- case 0x52: /* keypad 0 */
- state->ks_composed_char *= 10;
- if (state->ks_composed_char > UCHAR_MAX)
- return ERRKEY;
- goto next_code;
-
- /* key released, no interest here */
- case SCAN_RELEASE | 0x47:
- case SCAN_RELEASE | 0x48:
- case SCAN_RELEASE | 0x49: /* keypad 7,8,9 */
- case SCAN_RELEASE | 0x4B:
- case SCAN_RELEASE | 0x4C:
- case SCAN_RELEASE | 0x4D: /* keypad 4,5,6 */
- case SCAN_RELEASE | 0x4F:
- case SCAN_RELEASE | 0x50:
- case SCAN_RELEASE | 0x51: /* keypad 1,2,3 */
- case SCAN_RELEASE | 0x52: /* keypad 0 */
- goto next_code;
-
- case 0x38: /* left alt key */
- break;
-
- default:
- if (state->ks_composed_char > 0) {
- state->ks_flags &= ~COMPOSE;
- state->ks_composed_char = 0;
- return ERRKEY;
- }
- break;
- }
- }
-
- /* keycode to key action */
- action = genkbd_keyaction(kbd, SCAN_CHAR(keycode),
- keycode & SCAN_RELEASE, &state->ks_state,
- &state->ks_accents);
- if (action == NOKEY)
- goto next_code;
- else
- return action;
-}
-
-/* check if char is waiting */
-static int
-ukbd_check_char(keyboard_t *kbd)
-{
- ukbd_state_t *state;
-
- if (!KBD_IS_ACTIVE(kbd))
- return FALSE;
- state = (ukbd_state_t *)kbd->kb_data;
- if (!(state->ks_flags & COMPOSE) && (state->ks_composed_char > 0))
- return TRUE;
- return ukbd_check(kbd);
-}
-
-/* some useful control functions */
-static int
-ukbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
-{
- /* trasnlate LED_XXX bits into the device specific bits */
- static u_char ledmap[8] = {
- 0, 2, 1, 3, 4, 6, 5, 7,
- };
- ukbd_state_t *state = kbd->kb_data;
- int s;
- int i;
-#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
- defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
- int ival;
-#endif
-
- s = splusb();
- switch (cmd) {
-
- case KDGKBMODE: /* get keyboard mode */
- *(int *)arg = state->ks_mode;
- break;
-#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
- defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
- case _IO('K', 7):
- ival = IOCPARM_IVAL(arg);
- arg = (caddr_t)&ival;
- /* FALLTHROUGH */
-#endif
- case KDSKBMODE: /* set keyboard mode */
- switch (*(int *)arg) {
- case K_XLATE:
- if (state->ks_mode != K_XLATE) {
- /* make lock key state and LED state match */
- state->ks_state &= ~LOCK_MASK;
- state->ks_state |= KBD_LED_VAL(kbd);
- }
- /* FALLTHROUGH */
- case K_RAW:
- case K_CODE:
- if (state->ks_mode != *(int *)arg) {
- ukbd_clear_state(kbd);
- state->ks_mode = *(int *)arg;
- }
- break;
- default:
- splx(s);
- return EINVAL;
- }
- break;
-
- case KDGETLED: /* get keyboard LED */
- *(int *)arg = KBD_LED_VAL(kbd);
- break;
-#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
- defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
- case _IO('K', 66):
- ival = IOCPARM_IVAL(arg);
- arg = (caddr_t)&ival;
- /* FALLTHROUGH */
-#endif
- case KDSETLED: /* set keyboard LED */
- /* NOTE: lock key state in ks_state won't be changed */
- if (*(int *)arg & ~LOCK_MASK) {
- splx(s);
- return EINVAL;
- }
- i = *(int *)arg;
- /* replace CAPS LED with ALTGR LED for ALTGR keyboards */
- if (state->ks_mode == K_XLATE &&
- kbd->kb_keymap->n_keys > ALTGR_OFFSET) {
- if (i & ALKED)
- i |= CLKED;
- else
- i &= ~CLKED;
- }
- if (KBD_HAS_DEVICE(kbd)) {
- set_leds(state, ledmap[i & LED_MASK]);
- /* XXX: error check? */
- }
- KBD_LED_VAL(kbd) = *(int *)arg;
- break;
-
- case KDGKBSTATE: /* get lock key state */
- *(int *)arg = state->ks_state & LOCK_MASK;
- break;
-#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
- defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
- case _IO('K', 20):
- ival = IOCPARM_IVAL(arg);
- arg = (caddr_t)&ival;
- /* FALLTHROUGH */
-#endif
- case KDSKBSTATE: /* set lock key state */
- if (*(int *)arg & ~LOCK_MASK) {
- splx(s);
- return EINVAL;
- }
- state->ks_state &= ~LOCK_MASK;
- state->ks_state |= *(int *)arg;
- splx(s);
- /* set LEDs and quit */
- return ukbd_ioctl(kbd, KDSETLED, arg);
-
- case KDSETREPEAT: /* set keyboard repeat rate (new interface) */
- splx(s);
- if (!KBD_HAS_DEVICE(kbd))
- return 0;
- if (((int *)arg)[1] < 0)
- return EINVAL;
- if (((int *)arg)[0] < 0)
- return EINVAL;
- else if (((int *)arg)[0] == 0) /* fastest possible value */
- kbd->kb_delay1 = 200;
- else
- kbd->kb_delay1 = ((int *)arg)[0];
- kbd->kb_delay2 = ((int *)arg)[1];
- return 0;
-
-#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
- defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
- case _IO('K', 67):
- ival = IOCPARM_IVAL(arg);
- arg = (caddr_t)&ival;
- /* FALLTHROUGH */
-#endif
- case KDSETRAD: /* set keyboard repeat rate (old interface) */
- splx(s);
- return set_typematic(kbd, *(int *)arg);
-
- case PIO_KEYMAP: /* set keyboard translation table */
- case PIO_KEYMAPENT: /* set keyboard translation table entry */
- case PIO_DEADKEYMAP: /* set accent key translation table */
- state->ks_accents = 0;
- /* FALLTHROUGH */
- default:
- splx(s);
- return genkbd_commonioctl(kbd, cmd, arg);
-
-#ifdef USB_DEBUG
- case USB_SETDEBUG:
- ukbddebug = *(int *)arg;
- break;
-#endif
- }
-
- splx(s);
- return 0;
-}
-
-/* lock the access to the keyboard */
-static int
-ukbd_lock(keyboard_t *kbd, int lock)
-{
- /* XXX ? */
- return TRUE;
-}
-
-/* clear the internal state of the keyboard */
-static void
-ukbd_clear_state(keyboard_t *kbd)
-{
- ukbd_state_t *state;
-
- state = (ukbd_state_t *)kbd->kb_data;
- state->ks_flags = 0;
- state->ks_polling = 0;
- state->ks_state &= LOCK_MASK; /* preserve locking key state */
- state->ks_accents = 0;
- state->ks_composed_char = 0;
-#ifdef UKBD_EMULATE_ATSCANCODE
- state->ks_buffered_char[0] = 0;
- state->ks_buffered_char[1] = 0;
-#endif
- bzero(&state->ks_ndata, sizeof(state->ks_ndata));
- bzero(&state->ks_odata, sizeof(state->ks_odata));
- bzero(&state->ks_ntime, sizeof(state->ks_ntime));
- bzero(&state->ks_otime, sizeof(state->ks_otime));
-}
-
-/* save the internal state */
-static int
-ukbd_get_state(keyboard_t *kbd, void *buf, size_t len)
-{
- if (len == 0)
- return sizeof(ukbd_state_t);
- if (len < sizeof(ukbd_state_t))
- return -1;
- bcopy(kbd->kb_data, buf, sizeof(ukbd_state_t));
- return 0;
-}
-
-/* set the internal state */
-static int
-ukbd_set_state(keyboard_t *kbd, void *buf, size_t len)
-{
- if (len < sizeof(ukbd_state_t))
- return ENOMEM;
- bcopy(buf, kbd->kb_data, sizeof(ukbd_state_t));
- return 0;
-}
-
-static int
-ukbd_poll(keyboard_t *kbd, int on)
-{
- ukbd_state_t *state;
- usbd_device_handle dev;
- int s;
-
- state = (ukbd_state_t *)kbd->kb_data;
- usbd_interface2device_handle(state->ks_iface, &dev);
-
- s = splusb();
- if (on) {
- ++state->ks_polling;
- if (state->ks_polling == 1)
- usbd_set_polling(dev, on);
- } else {
- --state->ks_polling;
- if (state->ks_polling == 0)
- usbd_set_polling(dev, on);
- }
- splx(s);
- return 0;
-}
-
-/* local functions */
-
-static int
-probe_keyboard(struct usb_attach_arg *uaa, int flags)
-{
- usb_interface_descriptor_t *id;
-
- if (!uaa->iface) /* we attach to ifaces only */
- return EINVAL;
-
- /* Check that this is a keyboard that speaks the boot protocol. */
- id = usbd_get_interface_descriptor(uaa->iface);
- if (id
- && id->bInterfaceClass == UICLASS_HID
- && id->bInterfaceSubClass == UISUBCLASS_BOOT
- && id->bInterfaceProtocol == UPROTO_BOOT_KEYBOARD)
- return 0; /* found it */
-
- return EINVAL;
-}
-
-static int
-init_keyboard(ukbd_state_t *state, int *type, int flags)
-{
- usb_endpoint_descriptor_t *ed;
-
- *type = KB_OTHER;
-
- state->ks_ifstate |= DISCONNECTED;
-
- ed = usbd_interface2endpoint_descriptor(state->ks_iface, 0);
- if (!ed) {
- printf("ukbd: could not read endpoint descriptor\n");
- return EIO;
- }
-
- DPRINTFN(10,("ukbd:init_keyboard: \
-bLength=%d bDescriptorType=%d bEndpointAddress=%d-%s bmAttributes=%d wMaxPacketSize=%d bInterval=%d\n",
- ed->bLength, ed->bDescriptorType,
- UE_GET_ADDR(ed->bEndpointAddress),
- UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN ? "in":"out",
- UE_GET_XFERTYPE(ed->bmAttributes),
- UGETW(ed->wMaxPacketSize), ed->bInterval));
-
- if (UE_GET_DIR(ed->bEndpointAddress) != UE_DIR_IN ||
- UE_GET_XFERTYPE(ed->bmAttributes) != UE_INTERRUPT) {
- printf("ukbd: unexpected endpoint\n");
- return EINVAL;
- }
-
- /* Ignore if SETIDLE fails since it is not crucial. */
- usbd_set_idle(state->ks_iface, 0, 0);
-
- state->ks_ep_addr = ed->bEndpointAddress;
- state->ks_ifstate &= ~DISCONNECTED;
-
- return 0;
-}
-
-static void
-set_leds(ukbd_state_t *state, int leds)
-{
-
- DPRINTF(("ukbd:set_leds: state=%p leds=%d\n", state, leds));
- state->ks_leds = leds;
- usbd_set_report_async(state->ks_iface, UHID_OUTPUT_REPORT, 0,
- &state->ks_leds, 1);
-}
-
-static int
-set_typematic(keyboard_t *kbd, int code)
-{
- static int delays[] = { 250, 500, 750, 1000 };
- static int rates[] = { 34, 38, 42, 46, 50, 55, 59, 63,
- 68, 76, 84, 92, 100, 110, 118, 126,
- 136, 152, 168, 184, 200, 220, 236, 252,
- 272, 304, 336, 368, 400, 440, 472, 504 };
-
- if (code & ~0x7f)
- return EINVAL;
- kbd->kb_delay1 = delays[(code >> 5) & 3];
- kbd->kb_delay2 = rates[code & 0x1f];
- return 0;
-}
-
-#ifdef UKBD_EMULATE_ATSCANCODE
-static int
-keycode2scancode(int keycode, int shift, int up)
-{
- static int scan[] = {
- 0x1c, 0x1d, 0x35,
- 0x37 | SCAN_PREFIX_SHIFT, /* PrintScreen */
- 0x38, 0x47, 0x48, 0x49, 0x4b, 0x4d, 0x4f,
- 0x50, 0x51, 0x52, 0x53,
- 0x46, /* XXX Pause/Break */
- 0x5b, 0x5c, 0x5d,
- /* SUN TYPE 6 USB KEYBOARD */
- 0x68, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63,
- 0x64, 0x65, 0x66, 0x67, 0x25, 0x1f, 0x1e,
- 0x20,
- };
- int scancode;
-
- scancode = keycode;
- if ((keycode >= 89) && (keycode < 89 + sizeof(scan)/sizeof(scan[0])))
- scancode = scan[keycode - 89] | SCAN_PREFIX_E0;
- /* Pause/Break */
- if ((keycode == 104) && !(shift & (MOD_CONTROL_L | MOD_CONTROL_R)))
- scancode = 0x45 | SCAN_PREFIX_E1 | SCAN_PREFIX_CTL;
- if (shift & (MOD_SHIFT_L | MOD_SHIFT_R))
- scancode &= ~SCAN_PREFIX_SHIFT;
- return (scancode | (up ? SCAN_RELEASE : SCAN_PRESS));
-}
-#endif /* UKBD_EMULATE_ATSCANCODE */
-
-static int
-ukbd_driver_load(module_t mod, int what, void *arg)
-{
- switch (what) {
- case MOD_LOAD:
- kbd_add_driver(&ukbd_kbd_driver);
- break;
- case MOD_UNLOAD:
- kbd_delete_driver(&ukbd_kbd_driver);
- break;
- }
- return usbd_driver_load(mod, what, arg);
-}
diff --git a/sys/dev/usb/ulpt.c b/sys/dev/usb/ulpt.c
deleted file mode 100644
index 99a1433..0000000
--- a/sys/dev/usb/ulpt.c
+++ /dev/null
@@ -1,815 +0,0 @@
-/* $NetBSD: ulpt.c,v 1.60 2003/10/04 21:19:50 augustss Exp $ */
-
-/*-
- * Copyright (c) 1998, 2003 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * Printer Class spec: http://www.usb.org/developers/data/devclass/usbprint109.PDF
- */
-
-/* XXXimp: need to migrate from devclass_get_softc */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/proc.h>
-#include <sys/kernel.h>
-#include <sys/fcntl.h>
-#include <sys/ioccom.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/uio.h>
-#include <sys/conf.h>
-#include <sys/syslog.h>
-#include <sys/sysctl.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include "usbdevs.h"
-#include <dev/usb/usb_quirks.h>
-
-#define TIMEOUT hz*16 /* wait up to 16 seconds for a ready */
-#define STEP hz/4
-
-#define LPTPRI (PZERO+8)
-#define ULPT_BSIZE PAGE_SIZE
-
-#define ULPT_READS_PER_SEC 5
-#define ULPT_READ_TIMO 10
-
-#ifdef USB_DEBUG
-#define DPRINTF(x) if (ulptdebug) printf x
-#define DPRINTFN(n,x) if (ulptdebug>(n)) printf x
-int ulptdebug = 0;
-SYSCTL_NODE(_hw_usb, OID_AUTO, ulpt, CTLFLAG_RW, 0, "USB ulpt");
-SYSCTL_INT(_hw_usb_ulpt, OID_AUTO, debug, CTLFLAG_RW,
- &ulptdebug, 0, "ulpt debug level");
-#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 {
- device_t sc_dev;
- usbd_device_handle sc_udev; /* device */
- usbd_interface_handle sc_iface; /* interface */
- int sc_ifaceno;
-
- int sc_out;
- usbd_pipe_handle sc_out_pipe; /* bulk out pipe */
- usbd_xfer_handle sc_out_xfer;
- void *sc_out_buf;
-
- int sc_in;
- usbd_pipe_handle sc_in_pipe; /* bulk in pipe */
- usbd_xfer_handle sc_in_xfer;
- void *sc_in_buf;
-
- struct callout sc_read_callout;
- int sc_has_callout;
-
- 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;
-
- struct cdev *dev;
- struct cdev *dev_noprime;
-};
-
-static d_open_t ulptopen;
-static d_close_t ulptclose;
-static d_write_t ulptwrite;
-static d_read_t ulptread;
-static d_ioctl_t ulptioctl;
-
-
-static struct cdevsw ulpt_cdevsw = {
- .d_version = D_VERSION,
- .d_flags = D_NEEDGIANT,
- .d_open = ulptopen,
- .d_close = ulptclose,
- .d_write = ulptwrite,
- .d_read = ulptread,
- .d_ioctl = ulptioctl,
- .d_name = "ulpt",
-};
-
-void ulpt_disco(void *);
-
-int ulpt_do_write(struct ulpt_softc *, struct uio *uio, int);
-int ulpt_do_read(struct ulpt_softc *, struct uio *uio, int);
-int ulpt_status(struct ulpt_softc *);
-void ulpt_reset(struct ulpt_softc *);
-int ulpt_statusmsg(u_char, struct ulpt_softc *);
-void ulpt_read_cb(usbd_xfer_handle xfer, usbd_private_handle priv,
- usbd_status status);
-void ulpt_tick(void *xsc);
-
-#if 0
-void ieee1284_print_id(char *);
-#endif
-
-#define ULPTUNIT(s) (dev2unit(s) & 0x1f)
-#define ULPTFLAGS(s) (dev2unit(s) & 0xe0)
-
-static device_probe_t ulpt_match;
-static device_attach_t ulpt_attach;
-static device_detach_t ulpt_detach;
-
-static device_method_t ulpt_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, ulpt_match),
- DEVMETHOD(device_attach, ulpt_attach),
- DEVMETHOD(device_detach, ulpt_detach),
-
- { 0, 0 }
-};
-
-static driver_t ulpt_driver = {
- "ulpt",
- ulpt_methods,
- sizeof(struct ulpt_softc)
-};
-
-static devclass_t ulpt_devclass;
-
-MODULE_DEPEND(umass, usb, 1, 1, 1);
-DRIVER_MODULE(ulpt, uhub, ulpt_driver, ulpt_devclass, usbd_driver_load, 0);
-
-static int
-ulpt_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
- 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 ||
- id->bInterfaceProtocol == UIPROTO_PRINTER_1284))
- return (UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO);
- return (UMATCH_NONE);
-}
-
-static int
-ulpt_attach(device_t self)
-{
- struct ulpt_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usbd_device_handle dev = uaa->device;
- usbd_interface_handle iface = uaa->iface;
- usb_interface_descriptor_t *ifcd = usbd_get_interface_descriptor(iface);
- usb_interface_descriptor_t *id, *iend;
- usb_config_descriptor_t *cdesc;
- usbd_status err;
- usb_endpoint_descriptor_t *ed;
- u_int8_t epcount;
- int i, altno;
-
- DPRINTFN(10,("ulpt_attach: sc=%p\n", sc));
- sc->sc_dev = self;
-
- /* XXX
- * Stepping through the alternate settings needs to be abstracted out.
- */
- cdesc = usbd_get_config_descriptor(dev);
- if (cdesc == NULL) {
- printf("%s: failed to get configuration descriptor\n",
- device_get_nameunit(sc->sc_dev));
- return ENXIO;
- }
- iend = (usb_interface_descriptor_t *)
- ((char *)cdesc + UGETW(cdesc->wTotalLength));
-#ifdef DIAGNOSTIC
- if (ifcd < (usb_interface_descriptor_t *)cdesc ||
- ifcd >= iend)
- panic("ulpt: iface desc out of range");
-#endif
- /* Step through all the descriptors looking for bidir mode */
- for (id = ifcd, altno = 0;
- id < iend;
- id = (void *)((char *)id + id->bLength)) {
- if (id->bDescriptorType == UDESC_INTERFACE &&
- id->bInterfaceNumber == ifcd->bInterfaceNumber) {
- if (id->bInterfaceClass == UICLASS_PRINTER &&
- id->bInterfaceSubClass == UISUBCLASS_PRINTER &&
- (id->bInterfaceProtocol == UIPROTO_PRINTER_BI /* ||
- id->bInterfaceProtocol == UIPROTO_PRINTER_1284 */))
- goto found;
- altno++;
- }
- }
- id = ifcd; /* not found, use original */
- found:
- if (id != ifcd) {
- /* Found a new bidir setting */
- DPRINTF(("ulpt_attach: set altno = %d\n", altno));
- err = usbd_set_interface(iface, altno);
- if (err) {
- printf("%s: setting alternate interface failed\n",
- device_get_nameunit(sc->sc_dev));
- sc->sc_dying = 1;
- return ENXIO;
- }
- }
-
- epcount = 0;
- (void)usbd_endpoint_count(iface, &epcount);
-
- sc->sc_in = -1;
- sc->sc_out = -1;
- for (i = 0; i < epcount; i++) {
- ed = usbd_interface2endpoint_descriptor(iface, i);
- if (ed == NULL) {
- printf("%s: couldn't get ep %d\n",
- device_get_nameunit(sc->sc_dev), i);
- return ENXIO;
- }
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
- sc->sc_in = ed->bEndpointAddress;
- } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
- sc->sc_out = ed->bEndpointAddress;
- }
- }
- if (sc->sc_out == -1) {
- printf("%s: could not find bulk out endpoint\n",
- device_get_nameunit(sc->sc_dev));
- sc->sc_dying = 1;
- return ENXIO;
- }
-
- if (usbd_get_quirks(dev)->uq_flags & UQ_BROKEN_BIDIR) {
- /* This device doesn't handle reading properly. */
- sc->sc_in = -1;
- }
-
- printf("%s: using %s-directional mode\n", device_get_nameunit(sc->sc_dev),
- sc->sc_in >= 0 ? "bi" : "uni");
-
- DPRINTFN(10, ("ulpt_attach: bulk=%d\n", sc->sc_out));
-
- sc->sc_iface = iface;
- sc->sc_ifaceno = id->bInterfaceNumber;
- sc->sc_udev = dev;
-
-#if 0
-/*
- * This code is disabled because for some mysterious reason 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, USBD_DEFAULT_TIMEOUT);
- if (err) {
- printf("%s: cannot get device id\n", device_get_nameunit(sc->sc_dev));
- } else if (alen <= 2) {
- printf("%s: empty device id, no printer connected?\n",
- device_get_nameunit(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 <", device_get_nameunit(sc->sc_dev));
- ieee1284_print_id(devinfo+2);
- printf(">\n");
- }
- }
-#endif
-
- 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));
-
- usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev);
-
- return 0;
-}
-
-
-static int
-ulpt_detach(device_t self)
-{
- struct ulpt_softc *sc = device_get_softc(self);
- int s;
-
- DPRINTF(("ulpt_detach: sc=%p\n", sc));
-
- sc->sc_dying = 1;
- if (sc->sc_out_pipe != NULL)
- usbd_abort_pipe(sc->sc_out_pipe);
- if (sc->sc_in_pipe != NULL)
- usbd_abort_pipe(sc->sc_in_pipe);
-
- s = splusb();
- if (--sc->sc_refcnt >= 0) {
- /* There is noone to wake, aborting the pipe is enough */
- /* Wait for processes to go away. */
- usb_detach_wait(sc->sc_dev);
- }
- splx(s);
-
- destroy_dev(sc->dev);
- destroy_dev(sc->dev_noprime);
-
- usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev);
-
- return (0);
-}
-
-int
-ulpt_status(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(struct ulpt_softc *sc)
-{
- usb_device_request_t req;
-
- DPRINTFN(1, ("ulpt_reset\n"));
- req.bRequest = UR_SOFT_RESET;
- USETW(req.wValue, 0);
- USETW(req.wIndex, sc->sc_ifaceno);
- USETW(req.wLength, 0);
-
- /*
- * There was a mistake in the USB printer 1.0 spec that gave the
- * request type as UT_WRITE_CLASS_OTHER; it should have been
- * UT_WRITE_CLASS_INTERFACE. Many printers use the old one,
- * so we try both.
- */
- req.bmRequestType = UT_WRITE_CLASS_OTHER;
- if (usbd_do_request(sc->sc_udev, &req, 0)) { /* 1.0 */
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- (void)usbd_do_request(sc->sc_udev, &req, 0); /* 1.1 */
- }
-}
-#if 0
-static void
-ulpt_input(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- struct ulpt_softc *sc = priv;
- u_int32_t count;
-
- /* Don't loop on errors or 0-length input. */
- usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
- if (status != USBD_NORMAL_COMPLETION || count == 0)
- return;
-
- DPRINTFN(2,("ulpt_input: got some data\n"));
- /* Do it again. */
- if (xfer == sc->sc_in_xfer1)
- usbd_transfer(sc->sc_in_xfer2);
- else
- usbd_transfer(sc->sc_in_xfer1);
-}
-#endif
-
-int ulptusein = 1;
-
-/*
- * Reset the printer, then wait until it's selected and not busy.
- */
-int
-ulptopen(struct cdev *dev, int flag, int mode, struct thread *p)
-{
- u_char flags = ULPTFLAGS(dev);
- struct ulpt_softc *sc;
- usbd_status err;
- int error;
-
- sc = devclass_get_softc(ulpt_devclass, ULPTUNIT(dev));
- if (sc == NULL)
- return (ENXIO);
-
- 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(USB_DEBUG)
- /* 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
-
-
- error = 0;
- sc->sc_refcnt++;
-
- if ((flags & ULPT_NOPRIME) == 0) {
- ulpt_reset(sc);
- if (sc->sc_dying) {
- error = ENXIO;
- sc->sc_state = 0;
- goto done;
- }
- }
-
- err = usbd_open_pipe(sc->sc_iface, sc->sc_out, 0, &sc->sc_out_pipe);
- if (err) {
- error = EIO;
- goto err0;
- }
- sc->sc_out_xfer = usbd_alloc_xfer(sc->sc_udev);
- if (sc->sc_out_xfer == NULL) {
- error = ENOMEM;
- goto err1;
- }
- sc->sc_out_buf = usbd_alloc_buffer(sc->sc_out_xfer, ULPT_BSIZE);
- if (sc->sc_out_buf == NULL) {
- error = ENOMEM;
- goto err2;
- }
-
- if (ulptusein && sc->sc_in != -1) {
- DPRINTF(("ulpt_open: open input pipe\n"));
- err = usbd_open_pipe(sc->sc_iface, sc->sc_in,0,&sc->sc_in_pipe);
- if (err) {
- error = EIO;
- goto err2;
- }
- sc->sc_in_xfer = usbd_alloc_xfer(sc->sc_udev);
- if (sc->sc_in_xfer == NULL) {
- error = ENOMEM;
- goto err3;
- }
- sc->sc_in_buf = usbd_alloc_buffer(sc->sc_in_xfer, ULPT_BSIZE);
- if (sc->sc_in_buf == NULL) {
- error = ENOMEM;
- goto err4;
- }
-
- /* If it's not opened for read the set up a reader. */
- if (!(flag & FREAD)) {
- DPRINTF(("ulpt_open: start read callout\n"));
- callout_init(&sc->sc_read_callout, 0);
- callout_reset(&sc->sc_read_callout, hz/5, ulpt_tick,
- sc);
- sc->sc_has_callout = 1;
- }
- }
-
- sc->sc_state = ULPT_OPEN;
- goto done;
-
- err4:
- usbd_free_xfer(sc->sc_in_xfer);
- sc->sc_in_xfer = NULL;
- err3:
- usbd_close_pipe(sc->sc_in_pipe);
- sc->sc_in_pipe = NULL;
- err2:
- usbd_free_xfer(sc->sc_out_xfer);
- sc->sc_out_xfer = NULL;
- err1:
- usbd_close_pipe(sc->sc_out_pipe);
- sc->sc_out_pipe = NULL;
- err0:
- sc->sc_state = 0;
-
- done:
- if (--sc->sc_refcnt < 0)
- usb_detach_wakeup(sc->sc_dev);
-
- DPRINTF(("ulptopen: done, error=%d\n", error));
- return (error);
-}
-
-int
-ulpt_statusmsg(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", device_get_nameunit(sc->sc_dev));
- else if (new & LPS_NOPAPER)
- log(LOG_NOTICE, "%s: out of paper\n", device_get_nameunit(sc->sc_dev));
- else if (new & LPS_NERR)
- log(LOG_NOTICE, "%s: output error\n", device_get_nameunit(sc->sc_dev));
-
- return (status);
-}
-
-int
-ulptclose(struct cdev *dev, int flag, int mode, struct thread *p)
-{
- struct ulpt_softc *sc;
-
- sc = devclass_get_softc(ulpt_devclass, ULPTUNIT(dev));
-
- if (sc->sc_state != ULPT_OPEN)
- /* We are being forced to close before the open completed. */
- return (0);
-
- if (sc->sc_has_callout) {
- callout_stop(&sc->sc_read_callout);
- sc->sc_has_callout = 0;
- }
-
- if (sc->sc_out_pipe != NULL) {
- usbd_abort_pipe(sc->sc_out_pipe);
- usbd_close_pipe(sc->sc_out_pipe);
- sc->sc_out_pipe = NULL;
- }
- if (sc->sc_out_xfer != NULL) {
- usbd_free_xfer(sc->sc_out_xfer);
- sc->sc_out_xfer = NULL;
- }
-
- if (sc->sc_in_pipe != NULL) {
- usbd_abort_pipe(sc->sc_in_pipe);
- usbd_close_pipe(sc->sc_in_pipe);
- sc->sc_in_pipe = NULL;
- }
- if (sc->sc_in_xfer != NULL) {
- usbd_free_xfer(sc->sc_in_xfer);
- sc->sc_in_xfer = NULL;
- }
-
- sc->sc_state = 0;
-
- DPRINTF(("ulptclose: closed\n"));
- return (0);
-}
-
-int
-ulpt_do_write(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 = sc->sc_out_xfer;
- bufp = sc->sc_out_buf;
- 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_out_pipe, USBD_NO_COPY,
- USBD_NO_TIMEOUT, bufp, &n, "ulptwr");
- if (err) {
- DPRINTF(("ulptwrite: error=%d\n", err));
- error = EIO;
- break;
- }
- }
-
- return (error);
-}
-
-int
-ulptwrite(struct cdev *dev, struct uio *uio, int flags)
-{
- struct ulpt_softc *sc;
- int error;
-
- sc = devclass_get_softc(ulpt_devclass, ULPTUNIT(dev));
-
- if (sc->sc_dying)
- return (EIO);
-
- sc->sc_refcnt++;
- error = ulpt_do_write(sc, uio, flags);
- if (--sc->sc_refcnt < 0)
- usb_detach_wakeup(sc->sc_dev);
- return (error);
-}
-
-int
-ulpt_do_read(struct ulpt_softc *sc, struct uio *uio, int flags)
-{
- u_int32_t n, on;
- int error = 0;
- void *bufp;
- usbd_xfer_handle xfer;
- usbd_status err;
-
- DPRINTF(("ulptread\n"));
-
- if (sc->sc_in_pipe == NULL)
- return 0;
-
- xfer = sc->sc_in_xfer;
- bufp = sc->sc_in_buf;
- while ((n = min(ULPT_BSIZE, uio->uio_resid)) != 0) {
- DPRINTFN(1, ("ulptread: transfer %d bytes\n", n));
- on = n;
- err = usbd_bulk_transfer(xfer, sc->sc_in_pipe,
- USBD_NO_COPY | USBD_SHORT_XFER_OK,
- USBD_NO_TIMEOUT, bufp, &n, "ulptrd");
- if (err) {
- DPRINTF(("ulptread: error=%d\n", err));
- error = EIO;
- break;
- }
- error = uiomove(bufp, n, uio);
- if (error)
- break;
- if (on != n)
- break;
- }
-
- return (error);
-}
-
-int
-ulptread(struct cdev *dev, struct uio *uio, int flags)
-{
- struct ulpt_softc *sc;
- int error;
-
- sc = devclass_get_softc(ulpt_devclass, ULPTUNIT(dev));
-
- if (sc->sc_dying)
- return (EIO);
-
- sc->sc_refcnt++;
- error = ulpt_do_read(sc, uio, flags);
- if (--sc->sc_refcnt < 0)
- usb_detach_wakeup(sc->sc_dev);
- return (error);
-}
-
-void
-ulpt_read_cb(usbd_xfer_handle xfer, usbd_private_handle priv,
- usbd_status status)
-{
- usbd_status err;
- u_int32_t n;
- usbd_private_handle xsc;
- struct ulpt_softc *sc;
-
- usbd_get_xfer_status(xfer, &xsc, NULL, &n, &err);
- sc = xsc;
-
- DPRINTFN(1,("ulpt_read_cb: start sc=%p, err=%d n=%d\n", sc, err, n));
-
-#ifdef ULPT_DEBUG
- if (!err && n > 0)
- DPRINTF(("ulpt_tick: discarding %d bytes\n", n));
-#endif
- if (!err || err == USBD_TIMEOUT)
- callout_reset(&sc->sc_read_callout, hz / ULPT_READS_PER_SEC,
- ulpt_tick, sc);
-}
-
-void
-ulpt_tick(void *xsc)
-{
- struct ulpt_softc *sc = xsc;
- usbd_status err;
-
- if (sc == NULL || sc->sc_dying)
- return;
-
- DPRINTFN(1,("ulpt_tick: start sc=%p\n", sc));
-
- usbd_setup_xfer(sc->sc_in_xfer, sc->sc_in_pipe, sc, sc->sc_in_buf,
- ULPT_BSIZE, USBD_NO_COPY | USBD_SHORT_XFER_OK,
- ULPT_READ_TIMO, ulpt_read_cb);
- err = usbd_transfer(sc->sc_in_xfer);
- DPRINTFN(1,("ulpt_tick: err=%d\n", err));
-}
-
-int
-ulptioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *p)
-{
- int error = 0;
-
- switch (cmd) {
- default:
- error = ENODEV;
- }
-
- return (error);
-}
-
-#if 0
-/* XXX This does not belong here. */
-/*
- * Print select parts of an IEEE 1284 device ID.
- */
-void
-ieee1284_print_id(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
diff --git a/sys/dev/usb/umass.c b/sys/dev/usb/umass.c
deleted file mode 100644
index b0b73cc..0000000
--- a/sys/dev/usb/umass.c
+++ /dev/null
@@ -1,3611 +0,0 @@
-/*-
- * Copyright (c) 1999 MAEKAWA Masahide <bishop@rr.iij4u.or.jp>,
- * Nick Hibma <n_hibma@freebsd.org>
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- * $FreeBSD$
- * $NetBSD: umass.c,v 1.28 2000/04/02 23:46:53 augustss Exp $
- */
-
-/* Also already merged from NetBSD:
- * $NetBSD: umass.c,v 1.67 2001/11/25 19:05:22 augustss Exp $
- * $NetBSD: umass.c,v 1.90 2002/11/04 19:17:33 pooka Exp $
- * $NetBSD: umass.c,v 1.108 2003/11/07 17:03:25 wiz Exp $
- * $NetBSD: umass.c,v 1.109 2003/12/04 13:57:31 keihan Exp $
- */
-
-/*
- * Universal Serial Bus Mass Storage Class specs:
- * http://www.usb.org/developers/devclass_docs/usb_msc_overview_1.2.pdf
- * http://www.usb.org/developers/devclass_docs/usbmassbulk_10.pdf
- * http://www.usb.org/developers/devclass_docs/usb_msc_cbi_1.1.pdf
- * http://www.usb.org/developers/devclass_docs/usbmass-ufi10.pdf
- */
-
-/*
- * Ported to NetBSD by Lennart Augustsson <augustss@NetBSD.org>.
- * Parts of the code written by Jason R. Thorpe <thorpej@shagadelic.org>.
- */
-
-/*
- * The driver handles 3 Wire Protocols
- * - Command/Bulk/Interrupt (CBI)
- * - Command/Bulk/Interrupt with Command Completion Interrupt (CBI with CCI)
- * - Mass Storage Bulk-Only (BBB)
- * (BBB refers Bulk/Bulk/Bulk for Command/Data/Status phases)
- *
- * Over these wire protocols it handles the following command protocols
- * - SCSI
- * - UFI (floppy command set)
- * - 8070i (ATAPI)
- *
- * UFI and 8070i (ATAPI) are transformed versions of the SCSI command set. The
- * sc->transform method is used to convert the commands into the appropriate
- * format (if at all necessary). For example, UFI requires all commands to be
- * 12 bytes in length amongst other things.
- *
- * The source code below is marked and can be split into a number of pieces
- * (in this order):
- *
- * - probe/attach/detach
- * - generic transfer routines
- * - BBB
- * - CBI
- * - CBI_I (in addition to functions from CBI)
- * - CAM (Common Access Method)
- * - SCSI
- * - UFI
- * - 8070i (ATAPI)
- *
- * The protocols are implemented using a state machine, for the transfers as
- * well as for the resets. The state machine is contained in umass_*_state.
- * The state machine is started through either umass_*_transfer or
- * umass_*_reset.
- *
- * The reason for doing this is a) CAM performs a lot better this way and b) it
- * avoids using tsleep from interrupt context (for example after a failed
- * transfer).
- */
-
-/*
- * The SCSI related part of this driver has been derived from the
- * dev/ppbus/vpo.c driver, by Nicolas Souchu (nsouch@freebsd.org).
- *
- * The CAM layer uses so called actions which are messages sent to the host
- * adapter for completion. The actions come in through umass_cam_action. The
- * appropriate block of routines is called depending on the transport protocol
- * in use. When the transfer has finished, these routines call
- * umass_cam_cb again to complete the CAM command.
- */
-
-/*
- * XXX Currently CBI with CCI is not supported because it bombs the system
- * when the device is detached (low frequency interrupts are detached
- * too late.
- */
-#undef CBI_I
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/bus.h>
-#include <sys/sysctl.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include "usbdevs.h"
-
-#include <cam/cam.h>
-#include <cam/cam_ccb.h>
-#include <cam/cam_sim.h>
-#include <cam/cam_xpt_sim.h>
-#include <cam/scsi/scsi_all.h>
-#include <cam/scsi/scsi_da.h>
-
-#include <cam/cam_periph.h>
-
-#ifdef USB_DEBUG
-#define DIF(m, x) if (umassdebug & (m)) do { x ; } while (0)
-#define DPRINTF(m, x) if (umassdebug & (m)) printf x
-#define UDMASS_GEN 0x00010000 /* general */
-#define UDMASS_SCSI 0x00020000 /* scsi */
-#define UDMASS_UFI 0x00040000 /* ufi command set */
-#define UDMASS_ATAPI 0x00080000 /* 8070i command set */
-#define UDMASS_CMD (UDMASS_SCSI|UDMASS_UFI|UDMASS_ATAPI)
-#define UDMASS_USB 0x00100000 /* USB general */
-#define UDMASS_BBB 0x00200000 /* Bulk-Only transfers */
-#define UDMASS_CBI 0x00400000 /* CBI transfers */
-#define UDMASS_WIRE (UDMASS_BBB|UDMASS_CBI)
-#define UDMASS_ALL 0xffff0000 /* all of the above */
-int umassdebug = 0;
-SYSCTL_NODE(_hw_usb, OID_AUTO, umass, CTLFLAG_RW, 0, "USB umass");
-SYSCTL_INT(_hw_usb_umass, OID_AUTO, debug, CTLFLAG_RW,
- &umassdebug, 0, "umass debug level");
-#else
-#define DIF(m, x) /* nop */
-#define DPRINTF(m, x) /* nop */
-#endif
-
-
-/* Generic definitions */
-
-/* Direction for umass_*_transfer */
-#define DIR_NONE 0
-#define DIR_IN 1
-#define DIR_OUT 2
-
-/* device name */
-#define DEVNAME "umass"
-#define DEVNAME_SIM "umass-sim"
-
-#define UMASS_MAX_TRANSFER_SIZE 65536
-/* Approximate maximum transfer speeds (assumes 33% overhead). */
-#define UMASS_FULL_TRANSFER_SPEED 1000
-#define UMASS_HIGH_TRANSFER_SPEED 40000
-#define UMASS_FLOPPY_TRANSFER_SPEED 20
-
-#define UMASS_TIMEOUT 5000 /* msecs */
-
-/* CAM specific definitions */
-
-#define UMASS_SCSIID_MAX 1 /* maximum number of drives expected */
-#define UMASS_SCSIID_HOST UMASS_SCSIID_MAX
-
-#define MS_TO_TICKS(ms) ((ms) * hz / 1000)
-
-
-/* Bulk-Only features */
-
-#define UR_BBB_RESET 0xff /* Bulk-Only reset */
-#define UR_BBB_GET_MAX_LUN 0xfe /* Get maximum lun */
-
-/* Command Block Wrapper */
-typedef struct {
- uDWord dCBWSignature;
-# define CBWSIGNATURE 0x43425355
- uDWord dCBWTag;
- uDWord dCBWDataTransferLength;
- uByte bCBWFlags;
-# define CBWFLAGS_OUT 0x00
-# define CBWFLAGS_IN 0x80
- uByte bCBWLUN;
- uByte bCDBLength;
-# define CBWCDBLENGTH 16
- uByte CBWCDB[CBWCDBLENGTH];
-} __packed umass_bbb_cbw_t;
-#define UMASS_BBB_CBW_SIZE 31
-
-/* Command Status Wrapper */
-typedef struct {
- uDWord dCSWSignature;
-# define CSWSIGNATURE 0x53425355
-# define CSWSIGNATURE_IMAGINATION_DBX1 0x43425355
-# define CSWSIGNATURE_OLYMPUS_C1 0x55425355
- uDWord dCSWTag;
- uDWord dCSWDataResidue;
- uByte bCSWStatus;
-# define CSWSTATUS_GOOD 0x0
-# define CSWSTATUS_FAILED 0x1
-# define CSWSTATUS_PHASE 0x2
-} __packed umass_bbb_csw_t;
-#define UMASS_BBB_CSW_SIZE 13
-
-/* CBI features */
-
-#define UR_CBI_ADSC 0x00
-
-typedef unsigned char umass_cbi_cbl_t[16]; /* Command block */
-
-typedef union {
- struct {
- unsigned char type;
- #define IDB_TYPE_CCI 0x00
- unsigned char value;
- #define IDB_VALUE_PASS 0x00
- #define IDB_VALUE_FAIL 0x01
- #define IDB_VALUE_PHASE 0x02
- #define IDB_VALUE_PERSISTENT 0x03
- #define IDB_VALUE_STATUS_MASK 0x03
- } common;
-
- struct {
- unsigned char asc;
- unsigned char ascq;
- } ufi;
-} umass_cbi_sbl_t;
-
-
-
-struct umass_softc; /* see below */
-
-typedef void (*transfer_cb_f) (struct umass_softc *sc, void *priv,
- int residue, int status);
-#define STATUS_CMD_OK 0 /* everything ok */
-#define STATUS_CMD_UNKNOWN 1 /* will have to fetch sense */
-#define STATUS_CMD_FAILED 2 /* transfer was ok, command failed */
-#define STATUS_WIRE_FAILED 3 /* couldn't even get command across */
-
-typedef void (*wire_reset_f) (struct umass_softc *sc, int status);
-typedef void (*wire_transfer_f) (struct umass_softc *sc, int lun,
- void *cmd, int cmdlen, void *data, int datalen,
- int dir, u_int timeout, transfer_cb_f cb, void *priv);
-typedef void (*wire_state_f) (usbd_xfer_handle xfer,
- usbd_private_handle priv, usbd_status err);
-
-typedef int (*command_transform_f) (struct umass_softc *sc,
- unsigned char *cmd, int cmdlen,
- unsigned char **rcmd, int *rcmdlen);
-
-
-struct umass_devdescr_t {
- u_int32_t vid;
-# define VID_WILDCARD 0xffffffff
-# define VID_EOT 0xfffffffe
- u_int32_t pid;
-# define PID_WILDCARD 0xffffffff
-# define PID_EOT 0xfffffffe
- u_int32_t rid;
-# define RID_WILDCARD 0xffffffff
-# define RID_EOT 0xfffffffe
-
- /* wire and command protocol */
- u_int16_t proto;
-# define UMASS_PROTO_BBB 0x0001 /* USB wire protocol */
-# define UMASS_PROTO_CBI 0x0002
-# define UMASS_PROTO_CBI_I 0x0004
-# define UMASS_PROTO_WIRE 0x00ff /* USB wire protocol mask */
-# define UMASS_PROTO_SCSI 0x0100 /* command protocol */
-# define UMASS_PROTO_ATAPI 0x0200
-# define UMASS_PROTO_UFI 0x0400
-# define UMASS_PROTO_RBC 0x0800
-# define UMASS_PROTO_COMMAND 0xff00 /* command protocol mask */
-
- /* Device specific quirks */
- u_int16_t quirks;
-# define NO_QUIRKS 0x0000
- /* The drive does not support Test Unit Ready. Convert to Start Unit
- */
-# define NO_TEST_UNIT_READY 0x0001
- /* The drive does not reset the Unit Attention state after REQUEST
- * SENSE has been sent. The INQUIRY command does not reset the UA
- * either, and so CAM runs in circles trying to retrieve the initial
- * INQUIRY data.
- */
-# define RS_NO_CLEAR_UA 0x0002
- /* The drive does not support START STOP. */
-# define NO_START_STOP 0x0004
- /* Don't ask for full inquiry data (255b). */
-# define FORCE_SHORT_INQUIRY 0x0008
- /* Needs to be initialised the Shuttle way */
-# define SHUTTLE_INIT 0x0010
- /* Drive needs to be switched to alternate iface 1 */
-# define ALT_IFACE_1 0x0020
- /* Drive does not do 1Mb/s, but just floppy speeds (20kb/s) */
-# define FLOPPY_SPEED 0x0040
- /* The device can't count and gets the residue of transfers wrong */
-# define IGNORE_RESIDUE 0x0080
- /* No GetMaxLun call */
-# define NO_GETMAXLUN 0x0100
- /* The device uses a weird CSWSIGNATURE. */
-# define WRONG_CSWSIG 0x0200
- /* Device cannot handle INQUIRY so fake a generic response */
-# define NO_INQUIRY 0x0400
- /* Device cannot handle INQUIRY EVPD, return CHECK CONDITION */
-# define NO_INQUIRY_EVPD 0x0800
- /* Pad all RBC requests to 12 bytes. */
-# define RBC_PAD_TO_12 0x1000
- /* Device reports number of sectors from READ_CAPACITY, not max
- * sector number.
- */
-# define READ_CAPACITY_OFFBY1 0x2000
- /* Device cannot handle a SCSI synchronize cache command. Normally
- * this quirk would be handled in the cam layer, but for IDE bridges
- * we need to associate the quirk with the bridge and not the
- * underlying disk device. This is handled by faking a success result.
- */
-# define NO_SYNCHRONIZE_CACHE 0x4000
-};
-
-static struct umass_devdescr_t umass_devdescrs[] = {
- { USB_VENDOR_ADDONICS2, USB_PRODUCT_ADDONICS2_CABLE_205, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_QUIRKS
- },
- { USB_VENDOR_AIPTEK, USB_PRODUCT_AIPTEK_POCKETCAM3M, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_QUIRKS
- },
- { USB_VENDOR_ALCOR, USB_PRODUCT_ALCOR_UMCR_9361, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_GETMAXLUN
- },
- { USB_VENDOR_ASAHIOPTICAL, USB_PRODUCT_ASAHIOPTICAL_OPTIO230, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_INQUIRY
- },
- { USB_VENDOR_ASAHIOPTICAL, USB_PRODUCT_ASAHIOPTICAL_OPTIO330, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_INQUIRY
- },
- { USB_VENDOR_ASAHIOPTICAL, PID_WILDCARD, RID_WILDCARD,
- UMASS_PROTO_ATAPI | UMASS_PROTO_CBI_I,
- RS_NO_CLEAR_UA
- },
- { USB_VENDOR_ADDON, USB_PRODUCT_ADDON_ATTACHE, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- IGNORE_RESIDUE
- },
- { USB_VENDOR_ADDON, USB_PRODUCT_ADDON_A256MB, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- IGNORE_RESIDUE
- },
- { USB_VENDOR_ADDON, USB_PRODUCT_ADDON_DISKPRO512, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- IGNORE_RESIDUE
- },
- { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_USB2SCSI, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_QUIRKS
- },
- { USB_VENDOR_CASIO, USB_PRODUCT_CASIO_QV_DIGICAM, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_CBI,
- NO_INQUIRY
- },
- { USB_VENDOR_CCYU, USB_PRODUCT_CCYU_ED1064, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_QUIRKS
- },
- { USB_VENDOR_CENTURY, USB_PRODUCT_CENTURY_EX35QUAT, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- FORCE_SHORT_INQUIRY | NO_START_STOP | IGNORE_RESIDUE
- },
- { USB_VENDOR_DESKNOTE, USB_PRODUCT_DESKNOTE_UCR_61S2B, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_QUIRKS
- },
- { USB_VENDOR_DMI, USB_PRODUCT_DMI_CFSM_RW, RID_WILDCARD,
- UMASS_PROTO_SCSI,
- NO_GETMAXLUN
- },
- { USB_VENDOR_EPSON, USB_PRODUCT_EPSON_STYLUS_875DC, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_CBI,
- NO_INQUIRY
- },
- { USB_VENDOR_EPSON, USB_PRODUCT_EPSON_STYLUS_895, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_GETMAXLUN
- },
- { USB_VENDOR_FEIYA, USB_PRODUCT_FEIYA_5IN1, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_QUIRKS
- },
- { USB_VENDOR_FREECOM, USB_PRODUCT_FREECOM_DVD, RID_WILDCARD,
- UMASS_PROTO_SCSI,
- NO_QUIRKS
- },
- { USB_VENDOR_FUJIPHOTO, USB_PRODUCT_FUJIPHOTO_MASS0100, RID_WILDCARD,
- UMASS_PROTO_ATAPI | UMASS_PROTO_CBI_I,
- RS_NO_CLEAR_UA
- },
- { USB_VENDOR_GENESYS, USB_PRODUCT_GENESYS_GL641USB2IDE, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- FORCE_SHORT_INQUIRY | NO_START_STOP | IGNORE_RESIDUE
- },
- { USB_VENDOR_GENESYS, USB_PRODUCT_GENESYS_GL641USB2IDE_2, RID_WILDCARD,
- UMASS_PROTO_ATAPI | UMASS_PROTO_BBB,
- FORCE_SHORT_INQUIRY | NO_START_STOP | IGNORE_RESIDUE
- },
- { USB_VENDOR_GENESYS, USB_PRODUCT_GENESYS_GL641USB, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- FORCE_SHORT_INQUIRY | NO_START_STOP | IGNORE_RESIDUE
- },
- { USB_VENDOR_GENESYS, USB_PRODUCT_GENESYS_GL641USB_2, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- WRONG_CSWSIG
- },
- { USB_VENDOR_HAGIWARA, USB_PRODUCT_HAGIWARA_FG, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_QUIRKS
- },
- { USB_VENDOR_HAGIWARA, USB_PRODUCT_HAGIWARA_FGSM, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_QUIRKS
- },
- { USB_VENDOR_HITACHI, USB_PRODUCT_HITACHI_DVDCAM_USB, RID_WILDCARD,
- UMASS_PROTO_ATAPI | UMASS_PROTO_CBI_I,
- NO_INQUIRY
- },
- { USB_VENDOR_HITACHI, USB_PRODUCT_HITACHI_DVDCAM_DZ_MV100A, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_CBI,
- NO_GETMAXLUN
- },
- { USB_VENDOR_HP, USB_PRODUCT_HP_CDW4E, RID_WILDCARD,
- UMASS_PROTO_ATAPI,
- NO_QUIRKS
- },
- { USB_VENDOR_HP, USB_PRODUCT_HP_CDW8200, RID_WILDCARD,
- UMASS_PROTO_ATAPI | UMASS_PROTO_CBI_I,
- NO_TEST_UNIT_READY | NO_START_STOP
- },
- { USB_VENDOR_IMAGINATION, USB_PRODUCT_IMAGINATION_DBX1, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- WRONG_CSWSIG
- },
- { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_ATAPI, RID_WILDCARD,
- UMASS_PROTO_RBC | UMASS_PROTO_CBI,
- NO_QUIRKS
- },
- { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_STORAGE_V2, RID_WILDCARD,
- UMASS_PROTO_RBC | UMASS_PROTO_CBI,
- NO_QUIRKS
- },
- { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_USBCABLE, RID_WILDCARD,
- UMASS_PROTO_ATAPI | UMASS_PROTO_CBI,
- NO_TEST_UNIT_READY | NO_START_STOP | ALT_IFACE_1
- },
- { USB_VENDOR_IODATA, USB_PRODUCT_IODATA_IU_CD2, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_QUIRKS
- },
- { USB_VENDOR_IODATA, USB_PRODUCT_IODATA_DVR_UEH8, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_QUIRKS
- },
- { USB_VENDOR_IOMEGA, USB_PRODUCT_IOMEGA_ZIP100, RID_WILDCARD,
- /* XXX This is not correct as there are Zip drives that use ATAPI.
- */
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_TEST_UNIT_READY
- },
- { USB_VENDOR_KYOCERA, USB_PRODUCT_KYOCERA_FINECAM_L3, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_INQUIRY
- },
- { USB_VENDOR_KYOCERA, USB_PRODUCT_KYOCERA_FINECAM_S3X, RID_WILDCARD,
- UMASS_PROTO_ATAPI | UMASS_PROTO_CBI,
- NO_INQUIRY
- },
- { USB_VENDOR_KYOCERA, USB_PRODUCT_KYOCERA_FINECAM_S4, RID_WILDCARD,
- UMASS_PROTO_ATAPI | UMASS_PROTO_CBI,
- NO_INQUIRY
- },
- { USB_VENDOR_KYOCERA, USB_PRODUCT_KYOCERA_FINECAM_S5, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_INQUIRY
- },
- { USB_VENDOR_LACIE, USB_PRODUCT_LACIE_HD, RID_WILDCARD,
- UMASS_PROTO_RBC | UMASS_PROTO_CBI,
- NO_QUIRKS
- },
- { USB_VENDOR_LEXAR, USB_PRODUCT_LEXAR_CF_READER, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_INQUIRY
- },
- { USB_VENDOR_LEXAR, USB_PRODUCT_LEXAR_JUMPSHOT, RID_WILDCARD,
- UMASS_PROTO_SCSI,
- NO_QUIRKS
- },
- { USB_VENDOR_LOGITEC, USB_PRODUCT_LOGITEC_LDR_H443SU2, RID_WILDCARD,
- UMASS_PROTO_SCSI,
- NO_QUIRKS
- },
- { USB_VENDOR_LOGITEC, USB_PRODUCT_LOGITEC_LDR_H443U2, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_QUIRKS
- },
- { USB_VENDOR_MELCO, USB_PRODUCT_MELCO_DUBPXXG, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- FORCE_SHORT_INQUIRY | NO_START_STOP | IGNORE_RESIDUE
- },
- { USB_VENDOR_MICROTECH, USB_PRODUCT_MICROTECH_DPCM, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_CBI,
- NO_TEST_UNIT_READY | NO_START_STOP
- },
- { USB_VENDOR_MICROTECH, USB_PRODUCT_MICROTECH_SCSIDB25, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_QUIRKS
- },
- { USB_VENDOR_MICROTECH, USB_PRODUCT_MICROTECH_SCSIHD50, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_QUIRKS
- },
- { USB_VENDOR_MINOLTA, USB_PRODUCT_MINOLTA_E223, RID_WILDCARD,
- UMASS_PROTO_SCSI,
- NO_QUIRKS
- },
- { USB_VENDOR_MINOLTA, USB_PRODUCT_MINOLTA_F300, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_QUIRKS
- },
- { USB_VENDOR_MITSUMI, USB_PRODUCT_MITSUMI_CDRRW, RID_WILDCARD,
- UMASS_PROTO_ATAPI | UMASS_PROTO_CBI,
- NO_QUIRKS
- },
- { USB_VENDOR_MITSUMI, USB_PRODUCT_MITSUMI_FDD, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_GETMAXLUN
- },
- { USB_VENDOR_MOTOROLA2, USB_PRODUCT_MOTOROLA2_E398, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- FORCE_SHORT_INQUIRY | NO_INQUIRY_EVPD | NO_GETMAXLUN
- },
- { USB_VENDOR_MSYSTEMS, USB_PRODUCT_MSYSTEMS_DISKONKEY, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- IGNORE_RESIDUE | NO_GETMAXLUN | RS_NO_CLEAR_UA
- },
- { USB_VENDOR_MSYSTEMS, USB_PRODUCT_MSYSTEMS_DISKONKEY2, RID_WILDCARD,
- UMASS_PROTO_ATAPI | UMASS_PROTO_BBB,
- NO_QUIRKS
- },
- { USB_VENDOR_MYSON, USB_PRODUCT_MYSON_HEDEN, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_INQUIRY | IGNORE_RESIDUE
- },
- { USB_VENDOR_NEODIO, USB_PRODUCT_NEODIO_ND3260, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- FORCE_SHORT_INQUIRY
- },
- { USB_VENDOR_NETAC, USB_PRODUCT_NETAC_CF_CARD, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_INQUIRY
- },
- { USB_VENDOR_NETAC, USB_PRODUCT_NETAC_ONLYDISK, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- IGNORE_RESIDUE
- },
- { USB_VENDOR_NETCHIP, USB_PRODUCT_NETCHIP_CLIK_40, RID_WILDCARD,
- UMASS_PROTO_ATAPI,
- NO_INQUIRY
- },
- { USB_VENDOR_NIKON, USB_PRODUCT_NIKON_D300, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_QUIRKS
- },
- { USB_VENDOR_OLYMPUS, USB_PRODUCT_OLYMPUS_C1, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- WRONG_CSWSIG
- },
- { USB_VENDOR_OLYMPUS, USB_PRODUCT_OLYMPUS_C700, RID_WILDCARD,
- UMASS_PROTO_SCSI,
- NO_GETMAXLUN
- },
- { USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_CFMS_RW, RID_WILDCARD,
- UMASS_PROTO_SCSI,
- NO_QUIRKS
- },
- { USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_CFSM_COMBO, RID_WILDCARD,
- UMASS_PROTO_SCSI,
- NO_QUIRKS
- },
- { USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_CFSM_READER, RID_WILDCARD,
- UMASS_PROTO_SCSI,
- NO_QUIRKS
- },
- { USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_CFSM_READER2, RID_WILDCARD,
- UMASS_PROTO_SCSI,
- NO_QUIRKS
- },
- { USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_SDS_HOTFIND_D, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_GETMAXLUN | NO_SYNCHRONIZE_CACHE
- },
- { USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_MDCFE_B_CF_READER, RID_WILDCARD,
- UMASS_PROTO_SCSI,
- NO_QUIRKS
- },
- { USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_MDSM_B_READER, RID_WILDCARD,
- UMASS_PROTO_SCSI,
- NO_INQUIRY
- },
- { USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_READER, RID_WILDCARD,
- UMASS_PROTO_SCSI,
- NO_QUIRKS
- },
- { USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_UCF100, RID_WILDCARD,
- UMASS_PROTO_ATAPI | UMASS_PROTO_BBB,
- NO_INQUIRY | NO_GETMAXLUN
- },
- { USB_VENDOR_ONSPEC2, USB_PRODUCT_ONSPEC2_IMAGEMATE_SDDR55, RID_WILDCARD,
- UMASS_PROTO_SCSI,
- NO_GETMAXLUN
- },
- { USB_VENDOR_PANASONIC, USB_PRODUCT_PANASONIC_KXL840AN, RID_WILDCARD,
- UMASS_PROTO_ATAPI | UMASS_PROTO_BBB,
- NO_GETMAXLUN
- },
- { USB_VENDOR_PANASONIC, USB_PRODUCT_PANASONIC_KXLCB20AN, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_QUIRKS
- },
- { USB_VENDOR_PANASONIC, USB_PRODUCT_PANASONIC_KXLCB35AN, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_QUIRKS
- },
- { USB_VENDOR_PANASONIC, USB_PRODUCT_PANASONIC_LS120CAM, RID_WILDCARD,
- UMASS_PROTO_UFI,
- NO_QUIRKS
- },
- { USB_VENDOR_PLEXTOR, USB_PRODUCT_PLEXTOR_40_12_40U, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_TEST_UNIT_READY
- },
- { USB_VENDOR_PNY, USB_PRODUCT_PNY_ATTACHE2, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- IGNORE_RESIDUE | NO_START_STOP
- },
- { USB_VENDOR_SAMSUNG, USB_PRODUCT_SAMSUNG_YP_U2, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- SHUTTLE_INIT | NO_GETMAXLUN
- },
- { USB_VENDOR_SAMSUNG_TECHWIN, USB_PRODUCT_SAMSUNG_TECHWIN_DIGIMAX_410, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_INQUIRY
- },
- { USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDDR05A, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_CBI,
- READ_CAPACITY_OFFBY1 | NO_GETMAXLUN
- },
- { USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDDR09, RID_WILDCARD,
- UMASS_PROTO_SCSI,
- READ_CAPACITY_OFFBY1 | NO_GETMAXLUN
- },
- { USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDDR12, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_CBI,
- READ_CAPACITY_OFFBY1 | NO_GETMAXLUN
- },
- { USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDDR31, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- READ_CAPACITY_OFFBY1
- },
- { USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDCZ2_256, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- IGNORE_RESIDUE
- },
- { USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDCZ4_128, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- IGNORE_RESIDUE
- },
- { USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SDCZ4_256, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- IGNORE_RESIDUE
- },
- { USB_VENDOR_SCANLOGIC, USB_PRODUCT_SCANLOGIC_SL11R, RID_WILDCARD,
- UMASS_PROTO_ATAPI | UMASS_PROTO_BBB,
- NO_INQUIRY
- },
- { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_CDRW, RID_WILDCARD,
- UMASS_PROTO_ATAPI | UMASS_PROTO_CBI,
- NO_QUIRKS
- },
- { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_CF, RID_WILDCARD,
- UMASS_PROTO_ATAPI | UMASS_PROTO_CBI,
- NO_QUIRKS
- },
- { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSB, RID_WILDCARD,
- UMASS_PROTO_ATAPI | UMASS_PROTO_CBI_I,
- NO_TEST_UNIT_READY | NO_START_STOP | SHUTTLE_INIT
- },
- { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSBATAPI, RID_WILDCARD,
- UMASS_PROTO_ATAPI | UMASS_PROTO_CBI,
- NO_QUIRKS
- },
- { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSBCFSM, RID_WILDCARD,
- UMASS_PROTO_SCSI,
- NO_QUIRKS
- },
- { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSCSI, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_QUIRKS
- },
- { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_HIFD, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_CBI,
- NO_GETMAXLUN
- },
- { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_SDDR09, RID_WILDCARD,
- UMASS_PROTO_SCSI,
- NO_GETMAXLUN
- },
- { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_ZIOMMC, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_CBI,
- NO_GETMAXLUN
- },
- { USB_VENDOR_SIGMATEL, USB_PRODUCT_SIGMATEL_I_BEAD100, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- SHUTTLE_INIT
- },
- { USB_VENDOR_SIIG, USB_PRODUCT_SIIG_WINTERREADER, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- IGNORE_RESIDUE
- },
- { USB_VENDOR_SKANHEX, USB_PRODUCT_SKANHEX_MD_7425, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_INQUIRY
- },
- { USB_VENDOR_SKANHEX, USB_PRODUCT_SKANHEX_SX_520Z, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_INQUIRY
- },
- { USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_40_MS, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_INQUIRY
- },
- { USB_VENDOR_SONY, USB_PRODUCT_SONY_DSC, 0x0500,
- UMASS_PROTO_RBC | UMASS_PROTO_CBI,
- RBC_PAD_TO_12
- },
- { USB_VENDOR_SONY, USB_PRODUCT_SONY_DSC, 0x0600,
- UMASS_PROTO_RBC | UMASS_PROTO_CBI,
- RBC_PAD_TO_12
- },
- { USB_VENDOR_SONY, USB_PRODUCT_SONY_DSC, RID_WILDCARD,
- UMASS_PROTO_RBC | UMASS_PROTO_CBI,
- NO_QUIRKS
- },
- { USB_VENDOR_SONY, USB_PRODUCT_SONY_HANDYCAM, 0x0500,
- UMASS_PROTO_RBC | UMASS_PROTO_CBI,
- RBC_PAD_TO_12
- },
- { USB_VENDOR_SONY, USB_PRODUCT_SONY_HANDYCAM, RID_WILDCARD,
- UMASS_PROTO_RBC | UMASS_PROTO_CBI,
- NO_QUIRKS
- },
- { USB_VENDOR_SONY, USB_PRODUCT_SONY_MS_MSC_U03, RID_WILDCARD,
- UMASS_PROTO_UFI | UMASS_PROTO_CBI,
- NO_GETMAXLUN
- },
- { USB_VENDOR_SONY, USB_PRODUCT_SONY_MS_NW_MS7, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_GETMAXLUN
- },
- { USB_VENDOR_SONY, USB_PRODUCT_SONY_MS_PEG_N760C, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_INQUIRY
- },
- { USB_VENDOR_SONY, USB_PRODUCT_SONY_MSACUS1, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_GETMAXLUN
- },
- { USB_VENDOR_SONY, USB_PRODUCT_SONY_MSC, RID_WILDCARD,
- UMASS_PROTO_RBC | UMASS_PROTO_CBI,
- NO_QUIRKS
- },
- { USB_VENDOR_SONY, USB_PRODUCT_SONY_PORTABLE_HDD_V2, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_QUIRKS
- },
- { USB_VENDOR_TAUGA, USB_PRODUCT_TAUGA_CAMERAMATE, RID_WILDCARD,
- UMASS_PROTO_SCSI,
- NO_QUIRKS
- },
- { USB_VENDOR_TEAC, USB_PRODUCT_TEAC_FD05PUB, RID_WILDCARD,
- UMASS_PROTO_UFI | UMASS_PROTO_CBI,
- NO_QUIRKS
- },
- { USB_VENDOR_TREK, USB_PRODUCT_TREK_MEMKEY, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_INQUIRY
- },
- { USB_VENDOR_TREK, USB_PRODUCT_TREK_THUMBDRIVE_8MB, RID_WILDCARD,
- UMASS_PROTO_ATAPI | UMASS_PROTO_BBB,
- IGNORE_RESIDUE
- },
- { USB_VENDOR_TRUMPION, USB_PRODUCT_TRUMPION_C3310, RID_WILDCARD,
- UMASS_PROTO_UFI | UMASS_PROTO_CBI,
- NO_QUIRKS
- },
- { USB_VENDOR_TRUMPION, USB_PRODUCT_TRUMPION_MP3, RID_WILDCARD,
- UMASS_PROTO_RBC,
- NO_QUIRKS
- },
- { USB_VENDOR_TRUMPION, USB_PRODUCT_TRUMPION_T33520, RID_WILDCARD,
- UMASS_PROTO_SCSI,
- NO_QUIRKS
- },
- { USB_VENDOR_TWINMOS, USB_PRODUCT_TWINMOS_MDIV, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_QUIRKS
- },
- { USB_VENDOR_VIA, USB_PRODUCT_VIA_USB2IDEBRIDGE, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_SYNCHRONIZE_CACHE
- },
- { USB_VENDOR_VIVITAR, USB_PRODUCT_VIVITAR_35XX, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_INQUIRY
- },
- { USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_COMBO, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- FORCE_SHORT_INQUIRY | NO_START_STOP | IGNORE_RESIDUE
- },
- { USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_EXTHDD, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- FORCE_SHORT_INQUIRY | NO_START_STOP | IGNORE_RESIDUE
- },
- { USB_VENDOR_WESTERN, USB_PRODUCT_WESTERN_MYBOOK, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_INQUIRY_EVPD
- },
- { USB_VENDOR_WINMAXGROUP, USB_PRODUCT_WINMAXGROUP_FLASH64MC, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- NO_INQUIRY
- },
- { USB_VENDOR_YANO, USB_PRODUCT_YANO_FW800HD, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_BBB,
- FORCE_SHORT_INQUIRY | NO_START_STOP | IGNORE_RESIDUE
- },
- { USB_VENDOR_YANO, USB_PRODUCT_YANO_U640MO, RID_WILDCARD,
- UMASS_PROTO_ATAPI | UMASS_PROTO_CBI_I,
- FORCE_SHORT_INQUIRY
- },
- { USB_VENDOR_YEDATA, USB_PRODUCT_YEDATA_FLASHBUSTERU, RID_WILDCARD,
- UMASS_PROTO_SCSI | UMASS_PROTO_CBI,
- NO_GETMAXLUN
- },
- { USB_VENDOR_ZORAN, USB_PRODUCT_ZORAN_EX20DSC, RID_WILDCARD,
- UMASS_PROTO_ATAPI | UMASS_PROTO_CBI,
- NO_QUIRKS
- },
- { VID_EOT, PID_EOT, RID_EOT, 0, 0 }
-};
-
-
-/* the per device structure */
-struct umass_softc {
- device_t sc_dev; /* base device */
- usbd_device_handle sc_udev; /* USB device */
-
- struct cam_sim *umass_sim; /* SCSI Interface Module */
-
- unsigned char flags; /* various device flags */
-# define UMASS_FLAGS_GONE 0x01 /* devices is no more */
-
- u_int16_t proto; /* wire and cmd protocol */
- u_int16_t quirks; /* they got it almost right */
-
- usbd_interface_handle iface; /* Mass Storage interface */
- int ifaceno; /* MS iface number */
-
- u_int8_t bulkin; /* bulk-in Endpoint Address */
- u_int8_t bulkout; /* bulk-out Endpoint Address */
- u_int8_t intrin; /* intr-in Endp. (CBI) */
- usbd_pipe_handle bulkin_pipe;
- usbd_pipe_handle bulkout_pipe;
- usbd_pipe_handle intrin_pipe;
-
- /* Reset the device in a wire protocol specific way */
- wire_reset_f reset;
-
- /* The start of a wire transfer. It prepares the whole transfer (cmd,
- * data, and status stage) and initiates it. It is up to the state
- * machine (below) to handle the various stages and errors in these
- */
- wire_transfer_f transfer;
-
- /* The state machine, handling the various states during a transfer */
- wire_state_f state;
-
- /* The command transform function is used to conver the SCSI commands
- * into their derivatives, like UFI, ATAPI, and friends.
- */
- command_transform_f transform; /* command transform */
-
- /* Bulk specific variables for transfers in progress */
- umass_bbb_cbw_t cbw; /* command block wrapper */
- umass_bbb_csw_t csw; /* command status wrapper*/
- /* CBI specific variables for transfers in progress */
- umass_cbi_cbl_t cbl; /* command block */
- umass_cbi_sbl_t sbl; /* status block */
-
- /* generic variables for transfers in progress */
- /* ctrl transfer requests */
- usb_device_request_t request;
-
- /* xfer handles
- * Most of our operations are initiated from interrupt context, so
- * we need to avoid using the one that is in use. We want to avoid
- * allocating them in the interrupt context as well.
- */
- /* indices into array below */
-# define XFER_BBB_CBW 0 /* Bulk-Only */
-# define XFER_BBB_DATA 1
-# define XFER_BBB_DCLEAR 2
-# define XFER_BBB_CSW1 3
-# define XFER_BBB_CSW2 4
-# define XFER_BBB_SCLEAR 5
-# define XFER_BBB_RESET1 6
-# define XFER_BBB_RESET2 7
-# define XFER_BBB_RESET3 8
-
-# define XFER_CBI_CB 0 /* CBI */
-# define XFER_CBI_DATA 1
-# define XFER_CBI_STATUS 2
-# define XFER_CBI_DCLEAR 3
-# define XFER_CBI_SCLEAR 4
-# define XFER_CBI_RESET1 5
-# define XFER_CBI_RESET2 6
-# define XFER_CBI_RESET3 7
-
-# define XFER_NR 9 /* maximum number */
-
- usbd_xfer_handle transfer_xfer[XFER_NR]; /* for ctrl xfers */
-
- int transfer_dir; /* data direction */
- void *transfer_data; /* data buffer */
- int transfer_datalen; /* (maximum) length */
- int transfer_actlen; /* actual length */
- transfer_cb_f transfer_cb; /* callback */
- void *transfer_priv; /* for callback */
- int transfer_status;
-
- int transfer_state;
-# define TSTATE_ATTACH 0 /* in attach */
-# define TSTATE_IDLE 1
-# define TSTATE_BBB_COMMAND 2 /* CBW transfer */
-# define TSTATE_BBB_DATA 3 /* Data transfer */
-# define TSTATE_BBB_DCLEAR 4 /* clear endpt stall */
-# define TSTATE_BBB_STATUS1 5 /* clear endpt stall */
-# define TSTATE_BBB_SCLEAR 6 /* clear endpt stall */
-# define TSTATE_BBB_STATUS2 7 /* CSW transfer */
-# define TSTATE_BBB_RESET1 8 /* reset command */
-# define TSTATE_BBB_RESET2 9 /* in clear stall */
-# define TSTATE_BBB_RESET3 10 /* out clear stall */
-# define TSTATE_CBI_COMMAND 11 /* command transfer */
-# define TSTATE_CBI_DATA 12 /* data transfer */
-# define TSTATE_CBI_STATUS 13 /* status transfer */
-# define TSTATE_CBI_DCLEAR 14 /* clear ep stall */
-# define TSTATE_CBI_SCLEAR 15 /* clear ep stall */
-# define TSTATE_CBI_RESET1 16 /* reset command */
-# define TSTATE_CBI_RESET2 17 /* in clear stall */
-# define TSTATE_CBI_RESET3 18 /* out clear stall */
-# define TSTATE_STATES 19 /* # of states above */
-
-
- /* SCSI/CAM specific variables */
- unsigned char cam_scsi_command[CAM_MAX_CDBLEN];
- unsigned char cam_scsi_command2[CAM_MAX_CDBLEN];
- struct scsi_sense cam_scsi_sense;
- struct scsi_sense cam_scsi_test_unit_ready;
- struct callout cam_scsi_rescan_ch;
-
- int timeout; /* in msecs */
-
- int maxlun; /* maximum LUN number */
-};
-
-#ifdef USB_DEBUG
-char *states[TSTATE_STATES+1] = {
- /* should be kept in sync with the list at transfer_state */
- "Attach",
- "Idle",
- "BBB CBW",
- "BBB Data",
- "BBB Data bulk-in/-out clear stall",
- "BBB CSW, 1st attempt",
- "BBB CSW bulk-in clear stall",
- "BBB CSW, 2nd attempt",
- "BBB Reset",
- "BBB bulk-in clear stall",
- "BBB bulk-out clear stall",
- "CBI Command",
- "CBI Data",
- "CBI Status",
- "CBI Data bulk-in/-out clear stall",
- "CBI Status intr-in clear stall",
- "CBI Reset",
- "CBI bulk-in clear stall",
- "CBI bulk-out clear stall",
- NULL
-};
-#endif
-
-/* If device cannot return valid inquiry data, fake it */
-static uint8_t fake_inq_data[SHORT_INQUIRY_LENGTH] = {
- 0, /*removable*/ 0x80, SCSI_REV_2, SCSI_REV_2,
- /*additional_length*/ 31, 0, 0, 0
-};
-
-/* USB device probe/attach/detach functions */
-static device_probe_t umass_match;
-static device_attach_t umass_attach;
-static device_detach_t umass_detach;
-
-static device_method_t umass_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, umass_match),
- DEVMETHOD(device_attach, umass_attach),
- DEVMETHOD(device_detach, umass_detach),
-
- { 0, 0 }
-};
-
-static driver_t umass_driver = {
- "umass",
- umass_methods,
- sizeof(struct umass_softc)
-};
-
-static devclass_t umass_devclass;
-
-static int umass_match_proto (struct umass_softc *sc,
- usbd_interface_handle iface,
- usbd_device_handle udev);
-
-/* quirk functions */
-static void umass_init_shuttle (struct umass_softc *sc);
-
-/* generic transfer functions */
-static usbd_status umass_setup_transfer (struct umass_softc *sc,
- usbd_pipe_handle pipe,
- void *buffer, int buflen, int flags,
- usbd_xfer_handle xfer);
-static usbd_status umass_setup_ctrl_transfer (struct umass_softc *sc,
- usbd_device_handle udev,
- usb_device_request_t *req,
- void *buffer, int buflen, int flags,
- usbd_xfer_handle xfer);
-static void umass_clear_endpoint_stall (struct umass_softc *sc,
- u_int8_t endpt, usbd_pipe_handle pipe,
- int state, usbd_xfer_handle xfer);
-static void umass_reset (struct umass_softc *sc,
- transfer_cb_f cb, void *priv);
-
-/* Bulk-Only related functions */
-static void umass_bbb_reset (struct umass_softc *sc, int status);
-static void umass_bbb_transfer (struct umass_softc *sc, int lun,
- void *cmd, int cmdlen,
- void *data, int datalen, int dir, u_int timeout,
- transfer_cb_f cb, void *priv);
-static void umass_bbb_state (usbd_xfer_handle xfer,
- usbd_private_handle priv,
- usbd_status err);
-static int umass_bbb_get_max_lun
- (struct umass_softc *sc);
-
-/* CBI related functions */
-static int umass_cbi_adsc (struct umass_softc *sc,
- char *buffer, int buflen,
- usbd_xfer_handle xfer);
-static void umass_cbi_reset (struct umass_softc *sc, int status);
-static void umass_cbi_transfer (struct umass_softc *sc, int lun,
- void *cmd, int cmdlen,
- void *data, int datalen, int dir, u_int timeout,
- transfer_cb_f cb, void *priv);
-static void umass_cbi_state (usbd_xfer_handle xfer,
- usbd_private_handle priv, usbd_status err);
-
-/* CAM related functions */
-static void umass_cam_action (struct cam_sim *sim, union ccb *ccb);
-static void umass_cam_poll (struct cam_sim *sim);
-
-static void umass_cam_cb (struct umass_softc *sc, void *priv,
- int residue, int status);
-static void umass_cam_sense_cb (struct umass_softc *sc, void *priv,
- int residue, int status);
-static void umass_cam_quirk_cb (struct umass_softc *sc, void *priv,
- int residue, int status);
-
-static void umass_cam_rescan_callback
- (struct cam_periph *periph,union ccb *ccb);
-static void umass_cam_rescan (void *addr);
-
-static int umass_cam_attach_sim (struct umass_softc *sc);
-static int umass_cam_attach (struct umass_softc *sc);
-static int umass_cam_detach_sim (struct umass_softc *sc);
-
-
-/* SCSI specific functions */
-static int umass_scsi_transform (struct umass_softc *sc,
- unsigned char *cmd, int cmdlen,
- unsigned char **rcmd, int *rcmdlen);
-
-/* UFI specific functions */
-#define UFI_COMMAND_LENGTH 12 /* UFI commands are always 12 bytes */
-static int umass_ufi_transform (struct umass_softc *sc,
- unsigned char *cmd, int cmdlen,
- unsigned char **rcmd, int *rcmdlen);
-
-/* ATAPI (8070i) specific functions */
-#define ATAPI_COMMAND_LENGTH 12 /* ATAPI commands are always 12 bytes */
-static int umass_atapi_transform (struct umass_softc *sc,
- unsigned char *cmd, int cmdlen,
- unsigned char **rcmd, int *rcmdlen);
-
-/* RBC specific functions */
-static int umass_rbc_transform (struct umass_softc *sc,
- unsigned char *cmd, int cmdlen,
- unsigned char **rcmd, int *rcmdlen);
-
-#ifdef USB_DEBUG
-/* General debugging functions */
-static void umass_bbb_dump_cbw (struct umass_softc *sc, umass_bbb_cbw_t *cbw);
-static void umass_bbb_dump_csw (struct umass_softc *sc, umass_bbb_csw_t *csw);
-static void umass_cbi_dump_cmd (struct umass_softc *sc, void *cmd, int cmdlen);
-static void umass_dump_buffer (struct umass_softc *sc, u_int8_t *buffer,
- int buflen, int printlen);
-#endif
-
-MODULE_DEPEND(umass, cam, 1, 1, 1);
-MODULE_DEPEND(umass, usb, 1, 1, 1);
-
-/*
- * USB device probe/attach/detach
- */
-
-/*
- * Match the device we are seeing with the devices supported. Fill in the
- * description in the softc accordingly. This function is called from both
- * probe and attach.
- */
-
-static int
-umass_match_proto(struct umass_softc *sc, usbd_interface_handle iface,
- usbd_device_handle udev)
-{
- usb_device_descriptor_t *dd;
- usb_interface_descriptor_t *id;
- int i;
- int found = 0;
-
- sc->sc_udev = udev;
- sc->proto = 0;
- sc->quirks = 0;
-
- dd = usbd_get_device_descriptor(udev);
-
- /* An entry specifically for Y-E Data devices as they don't fit in the
- * device description table.
- */
- if (UGETW(dd->idVendor) == USB_VENDOR_YEDATA
- && UGETW(dd->idProduct) == USB_PRODUCT_YEDATA_FLASHBUSTERU) {
-
- /* Revisions < 1.28 do not handle the interrupt endpoint
- * very well.
- */
- if (UGETW(dd->bcdDevice) < 0x128) {
- sc->proto = UMASS_PROTO_UFI | UMASS_PROTO_CBI;
- } else {
- sc->proto = UMASS_PROTO_UFI | UMASS_PROTO_CBI_I;
- }
-
- /*
- * Revisions < 1.28 do not have the TEST UNIT READY command
- * Revisions == 1.28 have a broken TEST UNIT READY
- */
- if (UGETW(dd->bcdDevice) <= 0x128)
- sc->quirks |= NO_TEST_UNIT_READY;
-
- sc->quirks |= RS_NO_CLEAR_UA | FLOPPY_SPEED;
- return(UMATCH_VENDOR_PRODUCT);
- }
-
- /* Check the list of supported devices for a match. While looking,
- * check for wildcarded and fully matched. First match wins.
- */
- for (i = 0; umass_devdescrs[i].vid != VID_EOT && !found; i++) {
- if (umass_devdescrs[i].vid == VID_WILDCARD &&
- umass_devdescrs[i].pid == PID_WILDCARD &&
- umass_devdescrs[i].rid == RID_WILDCARD) {
- printf("umass: ignoring invalid wildcard quirk\n");
- continue;
- }
- if ((umass_devdescrs[i].vid == UGETW(dd->idVendor) ||
- umass_devdescrs[i].vid == VID_WILDCARD)
- && (umass_devdescrs[i].pid == UGETW(dd->idProduct) ||
- umass_devdescrs[i].pid == PID_WILDCARD)) {
- if (umass_devdescrs[i].rid == RID_WILDCARD) {
- sc->proto = umass_devdescrs[i].proto;
- sc->quirks = umass_devdescrs[i].quirks;
- return (UMATCH_VENDOR_PRODUCT);
- } else if (umass_devdescrs[i].rid ==
- UGETW(dd->bcdDevice)) {
- sc->proto = umass_devdescrs[i].proto;
- sc->quirks = umass_devdescrs[i].quirks;
- return (UMATCH_VENDOR_PRODUCT_REV);
- } /* else RID does not match */
- }
- }
-
- /* Check for a standards compliant device */
- id = usbd_get_interface_descriptor(iface);
- if (id == NULL || id->bInterfaceClass != UICLASS_MASS)
- return(UMATCH_NONE);
-
- switch (id->bInterfaceSubClass) {
- case UISUBCLASS_SCSI:
- sc->proto |= UMASS_PROTO_SCSI;
- break;
- case UISUBCLASS_UFI:
- sc->proto |= UMASS_PROTO_UFI;
- break;
- case UISUBCLASS_RBC:
- sc->proto |= UMASS_PROTO_RBC;
- break;
- case UISUBCLASS_SFF8020I:
- case UISUBCLASS_SFF8070I:
- sc->proto |= UMASS_PROTO_ATAPI;
- break;
- default:
- DPRINTF(UDMASS_GEN, ("%s: Unsupported command protocol %d\n",
- device_get_nameunit(sc->sc_dev), id->bInterfaceSubClass));
- return(UMATCH_NONE);
- }
-
- switch (id->bInterfaceProtocol) {
- case UIPROTO_MASS_CBI:
- sc->proto |= UMASS_PROTO_CBI;
- break;
- case UIPROTO_MASS_CBI_I:
- sc->proto |= UMASS_PROTO_CBI_I;
- break;
- case UIPROTO_MASS_BBB_OLD:
- case UIPROTO_MASS_BBB:
- sc->proto |= UMASS_PROTO_BBB;
- break;
- default:
- DPRINTF(UDMASS_GEN, ("%s: Unsupported wire protocol %d\n",
- device_get_nameunit(sc->sc_dev), id->bInterfaceProtocol));
- return(UMATCH_NONE);
- }
-
- return(UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO);
-}
-
-static int
-umass_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
- struct umass_softc *sc = device_get_softc(self);
-
- sc->sc_dev = self;
- if (uaa->iface == NULL)
- return(UMATCH_NONE);
-
- return(umass_match_proto(sc, uaa->iface, uaa->device));
-}
-
-static int
-umass_attach(device_t self)
-{
- struct umass_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
- int i;
- int err;
-
- /*
- * the softc struct is bzero-ed in device_set_driver. We can safely
- * call umass_detach without specifically initialising the struct.
- */
- sc->sc_dev = self;
- sc->iface = uaa->iface;
- sc->ifaceno = uaa->ifaceno;
- callout_init(&sc->cam_scsi_rescan_ch, 0);
-
- /* initialise the proto and drive values in the umass_softc (again) */
- (void) umass_match_proto(sc, sc->iface, uaa->device);
-
- id = usbd_get_interface_descriptor(sc->iface);
-#ifdef USB_DEBUG
- printf("%s: ", device_get_nameunit(sc->sc_dev));
- switch (sc->proto&UMASS_PROTO_COMMAND) {
- case UMASS_PROTO_SCSI:
- printf("SCSI");
- break;
- case UMASS_PROTO_ATAPI:
- printf("8070i (ATAPI)");
- break;
- case UMASS_PROTO_UFI:
- printf("UFI");
- break;
- case UMASS_PROTO_RBC:
- printf("RBC");
- break;
- default:
- printf("(unknown 0x%02x)", sc->proto&UMASS_PROTO_COMMAND);
- break;
- }
- printf(" over ");
- switch (sc->proto&UMASS_PROTO_WIRE) {
- case UMASS_PROTO_BBB:
- printf("Bulk-Only");
- break;
- case UMASS_PROTO_CBI: /* uses Comand/Bulk pipes */
- printf("CBI");
- break;
- case UMASS_PROTO_CBI_I: /* uses Comand/Bulk/Interrupt pipes */
- printf("CBI with CCI");
-#ifndef CBI_I
- printf(" (using CBI)");
-#endif
- break;
- default:
- printf("(unknown 0x%02x)", sc->proto&UMASS_PROTO_WIRE);
- }
- printf("; quirks = 0x%04x\n", sc->quirks);
-#endif
-
-#ifndef CBI_I
- if (sc->proto & UMASS_PROTO_CBI_I) {
- /* See beginning of file for comment on the use of CBI with CCI */
- sc->proto = (sc->proto & ~UMASS_PROTO_CBI_I) | UMASS_PROTO_CBI;
- }
-#endif
-
- if (sc->quirks & ALT_IFACE_1) {
- err = usbd_set_interface(uaa->iface, 1);
- if (err) {
- DPRINTF(UDMASS_USB, ("%s: could not switch to "
- "Alt Interface %d\n",
- device_get_nameunit(sc->sc_dev), 1));
- umass_detach(self);
- return ENXIO;
- }
- }
-
- /*
- * In addition to the Control endpoint the following endpoints
- * are required:
- * a) bulk-in endpoint.
- * b) bulk-out endpoint.
- * and for Control/Bulk/Interrupt with CCI (CBI_I)
- * c) intr-in
- *
- * The endpoint addresses are not fixed, so we have to read them
- * from the device descriptors of the current interface.
- */
- for (i = 0 ; i < id->bNumEndpoints ; i++) {
- ed = usbd_interface2endpoint_descriptor(sc->iface, i);
- if (!ed) {
- printf("%s: could not read endpoint descriptor\n",
- device_get_nameunit(sc->sc_dev));
- return ENXIO;
- }
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN
- && (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
- sc->bulkin = ed->bEndpointAddress;
- } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT
- && (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
- sc->bulkout = ed->bEndpointAddress;
- } else if (sc->proto & UMASS_PROTO_CBI_I
- && UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN
- && (ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT) {
- sc->intrin = ed->bEndpointAddress;
-#ifdef USB_DEBUG
- if (UGETW(ed->wMaxPacketSize) > 2) {
- DPRINTF(UDMASS_CBI, ("%s: intr size is %d\n",
- device_get_nameunit(sc->sc_dev),
- UGETW(ed->wMaxPacketSize)));
- }
-#endif
- }
- }
-
- /* check whether we found all the endpoints we need */
- if (!sc->bulkin || !sc->bulkout
- || (sc->proto & UMASS_PROTO_CBI_I && !sc->intrin) ) {
- DPRINTF(UDMASS_USB, ("%s: endpoint not found %d/%d/%d\n",
- device_get_nameunit(sc->sc_dev),
- sc->bulkin, sc->bulkout, sc->intrin));
- umass_detach(self);
- return ENXIO;
- }
-
- /* Open the bulk-in and -out pipe */
- err = usbd_open_pipe(sc->iface, sc->bulkout,
- USBD_EXCLUSIVE_USE, &sc->bulkout_pipe);
- if (err) {
- DPRINTF(UDMASS_USB, ("%s: cannot open %d-out pipe (bulk)\n",
- device_get_nameunit(sc->sc_dev), sc->bulkout));
- umass_detach(self);
- return ENXIO;
- }
- err = usbd_open_pipe(sc->iface, sc->bulkin,
- USBD_EXCLUSIVE_USE, &sc->bulkin_pipe);
- if (err) {
- DPRINTF(UDMASS_USB, ("%s: could not open %d-in pipe (bulk)\n",
- device_get_nameunit(sc->sc_dev), sc->bulkin));
- umass_detach(self);
- return ENXIO;
- }
- /* Open the intr-in pipe if the protocol is CBI with CCI.
- * Note: early versions of the Zip drive do have an interrupt pipe, but
- * this pipe is unused.
- *
- * We do not open the interrupt pipe as an interrupt pipe, but as a
- * normal bulk endpoint. We send an IN transfer down the wire at the
- * appropriate time, because we know exactly when to expect data on
- * that endpoint. This saves bandwidth, but more important, makes the
- * code for handling the data on that endpoint simpler. No data
- * arriving concurrently.
- */
- if (sc->proto & UMASS_PROTO_CBI_I) {
- err = usbd_open_pipe(sc->iface, sc->intrin,
- USBD_EXCLUSIVE_USE, &sc->intrin_pipe);
- if (err) {
- DPRINTF(UDMASS_USB, ("%s: couldn't open %d-in (intr)\n",
- device_get_nameunit(sc->sc_dev), sc->intrin));
- umass_detach(self);
- return ENXIO;
- }
- }
-
- /* initialisation of generic part */
- sc->transfer_state = TSTATE_ATTACH;
-
- /* request a sufficient number of xfer handles */
- for (i = 0; i < XFER_NR; i++) {
- sc->transfer_xfer[i] = usbd_alloc_xfer(uaa->device);
- if (!sc->transfer_xfer[i]) {
- DPRINTF(UDMASS_USB, ("%s: Out of memory\n",
- device_get_nameunit(sc->sc_dev)));
- umass_detach(self);
- return ENXIO;
- }
- }
-
- /* Initialise the wire protocol specific methods */
- if (sc->proto & UMASS_PROTO_BBB) {
- sc->reset = umass_bbb_reset;
- sc->transfer = umass_bbb_transfer;
- sc->state = umass_bbb_state;
- } else if (sc->proto & (UMASS_PROTO_CBI|UMASS_PROTO_CBI_I)) {
- sc->reset = umass_cbi_reset;
- sc->transfer = umass_cbi_transfer;
- sc->state = umass_cbi_state;
-#ifdef USB_DEBUG
- } else {
- panic("%s:%d: Unknown proto 0x%02x",
- __FILE__, __LINE__, sc->proto);
-#endif
- }
-
- if (sc->proto & UMASS_PROTO_SCSI)
- sc->transform = umass_scsi_transform;
- else if (sc->proto & UMASS_PROTO_UFI)
- sc->transform = umass_ufi_transform;
- else if (sc->proto & UMASS_PROTO_ATAPI)
- sc->transform = umass_atapi_transform;
- else if (sc->proto & UMASS_PROTO_RBC)
- sc->transform = umass_rbc_transform;
-#ifdef USB_DEBUG
- else
- panic("No transformation defined for command proto 0x%02x",
- sc->proto & UMASS_PROTO_COMMAND);
-#endif
-
- /* From here onwards the device can be used. */
-
- if (sc->quirks & SHUTTLE_INIT)
- umass_init_shuttle(sc);
-
- /* Get the maximum LUN supported by the device.
- */
- if (((sc->proto & UMASS_PROTO_WIRE) == UMASS_PROTO_BBB) &&
- !(sc->quirks & NO_GETMAXLUN))
- sc->maxlun = umass_bbb_get_max_lun(sc);
- else
- sc->maxlun = 0;
-
- if ((sc->proto & UMASS_PROTO_SCSI) ||
- (sc->proto & UMASS_PROTO_ATAPI) ||
- (sc->proto & UMASS_PROTO_UFI) ||
- (sc->proto & UMASS_PROTO_RBC)) {
- /* Prepare the SCSI command block */
- sc->cam_scsi_sense.opcode = REQUEST_SENSE;
- sc->cam_scsi_test_unit_ready.opcode = TEST_UNIT_READY;
-
- /* register the SIM */
- err = umass_cam_attach_sim(sc);
- if (err) {
- umass_detach(self);
- return ENXIO;
- }
- /* scan the new sim */
- err = umass_cam_attach(sc);
- if (err) {
- umass_cam_detach_sim(sc);
- umass_detach(self);
- return ENXIO;
- }
- } else {
- panic("%s:%d: Unknown proto 0x%02x",
- __FILE__, __LINE__, sc->proto);
- }
-
- sc->transfer_state = TSTATE_IDLE;
- DPRINTF(UDMASS_GEN, ("%s: Attach finished\n", device_get_nameunit(sc->sc_dev)));
-
- return 0;
-}
-
-static int
-umass_detach(device_t self)
-{
- struct umass_softc *sc = device_get_softc(self);
- int err = 0;
- int i;
-
- DPRINTF(UDMASS_USB, ("%s: detached\n", device_get_nameunit(sc->sc_dev)));
-
- sc->flags |= UMASS_FLAGS_GONE;
-
- /* abort all the pipes in case there are transfers active. */
- usbd_abort_default_pipe(sc->sc_udev);
- if (sc->bulkout_pipe)
- usbd_abort_pipe(sc->bulkout_pipe);
- if (sc->bulkin_pipe)
- usbd_abort_pipe(sc->bulkin_pipe);
- if (sc->intrin_pipe)
- usbd_abort_pipe(sc->intrin_pipe);
-
- callout_drain(&sc->cam_scsi_rescan_ch);
- if ((sc->proto & UMASS_PROTO_SCSI) ||
- (sc->proto & UMASS_PROTO_ATAPI) ||
- (sc->proto & UMASS_PROTO_UFI) ||
- (sc->proto & UMASS_PROTO_RBC))
- /* detach the SCSI host controller (SIM) */
- err = umass_cam_detach_sim(sc);
-
- for (i = 0; i < XFER_NR; i++)
- if (sc->transfer_xfer[i])
- usbd_free_xfer(sc->transfer_xfer[i]);
-
- /* remove all the pipes */
- if (sc->bulkout_pipe)
- usbd_close_pipe(sc->bulkout_pipe);
- if (sc->bulkin_pipe)
- usbd_close_pipe(sc->bulkin_pipe);
- if (sc->intrin_pipe)
- usbd_close_pipe(sc->intrin_pipe);
-
- return(err);
-}
-
-static void
-umass_init_shuttle(struct umass_softc *sc)
-{
- usb_device_request_t req;
- u_char status[2];
-
- /* The Linux driver does this, but no one can tell us what the
- * command does.
- */
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = 1; /* XXX unknown command */
- USETW(req.wValue, 0);
- USETW(req.wIndex, sc->ifaceno);
- USETW(req.wLength, sizeof status);
- (void) usbd_do_request(sc->sc_udev, &req, &status);
-
- DPRINTF(UDMASS_GEN, ("%s: Shuttle init returned 0x%02x%02x\n",
- device_get_nameunit(sc->sc_dev), status[0], status[1]));
-}
-
- /*
- * Generic functions to handle transfers
- */
-
-static usbd_status
-umass_setup_transfer(struct umass_softc *sc, usbd_pipe_handle pipe,
- void *buffer, int buflen, int flags,
- usbd_xfer_handle xfer)
-{
- usbd_status err;
-
- /* Initialise a USB transfer and then schedule it */
-
- (void) usbd_setup_xfer(xfer, pipe, (void *) sc, buffer, buflen, flags,
- sc->timeout, sc->state);
-
- err = usbd_transfer(xfer);
- if (err && err != USBD_IN_PROGRESS) {
- DPRINTF(UDMASS_BBB, ("%s: failed to setup transfer, %s\n",
- device_get_nameunit(sc->sc_dev), usbd_errstr(err)));
- return(err);
- }
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-
-static usbd_status
-umass_setup_ctrl_transfer(struct umass_softc *sc, usbd_device_handle udev,
- usb_device_request_t *req,
- void *buffer, int buflen, int flags,
- usbd_xfer_handle xfer)
-{
- usbd_status err;
-
- /* Initialise a USB control transfer and then schedule it */
-
- (void) usbd_setup_default_xfer(xfer, udev, (void *) sc,
- sc->timeout, req, buffer, buflen, flags, sc->state);
-
- err = usbd_transfer(xfer);
- if (err && err != USBD_IN_PROGRESS) {
- DPRINTF(UDMASS_BBB, ("%s: failed to setup ctrl transfer, %s\n",
- device_get_nameunit(sc->sc_dev), usbd_errstr(err)));
-
- /* do not reset, as this would make us loop */
- return(err);
- }
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-static void
-umass_clear_endpoint_stall(struct umass_softc *sc,
- u_int8_t endpt, usbd_pipe_handle pipe,
- int state, usbd_xfer_handle xfer)
-{
- usbd_device_handle udev;
-
- DPRINTF(UDMASS_BBB, ("%s: Clear endpoint 0x%02x stall\n",
- device_get_nameunit(sc->sc_dev), endpt));
-
- usbd_interface2device_handle(sc->iface, &udev);
-
- sc->transfer_state = state;
-
- usbd_clear_endpoint_toggle(pipe);
-
- sc->request.bmRequestType = UT_WRITE_ENDPOINT;
- sc->request.bRequest = UR_CLEAR_FEATURE;
- USETW(sc->request.wValue, UF_ENDPOINT_HALT);
- USETW(sc->request.wIndex, endpt);
- USETW(sc->request.wLength, 0);
- umass_setup_ctrl_transfer(sc, udev, &sc->request, NULL, 0, 0, xfer);
-}
-
-static void
-umass_reset(struct umass_softc *sc, transfer_cb_f cb, void *priv)
-{
- sc->transfer_cb = cb;
- sc->transfer_priv = priv;
-
- /* The reset is a forced reset, so no error (yet) */
- sc->reset(sc, STATUS_CMD_OK);
-}
-
-/*
- * Bulk protocol specific functions
- */
-
-static void
-umass_bbb_reset(struct umass_softc *sc, int status)
-{
- usbd_device_handle udev;
-
- KASSERT(sc->proto & UMASS_PROTO_BBB,
- ("%s: umass_bbb_reset: wrong sc->proto 0x%02x\n",
- device_get_nameunit(sc->sc_dev), sc->proto));
-
- /*
- * Reset recovery (5.3.4 in Universal Serial Bus Mass Storage Class)
- *
- * For Reset Recovery the host shall issue in the following order:
- * a) a Bulk-Only Mass Storage Reset
- * b) a Clear Feature HALT to the Bulk-In endpoint
- * c) a Clear Feature HALT to the Bulk-Out endpoint
- *
- * This is done in 3 steps, states:
- * TSTATE_BBB_RESET1
- * TSTATE_BBB_RESET2
- * TSTATE_BBB_RESET3
- *
- * If the reset doesn't succeed, the device should be port reset.
- */
-
- DPRINTF(UDMASS_BBB, ("%s: Bulk Reset\n",
- device_get_nameunit(sc->sc_dev)));
-
- sc->transfer_state = TSTATE_BBB_RESET1;
- sc->transfer_status = status;
-
- usbd_interface2device_handle(sc->iface, &udev);
-
- /* reset is a class specific interface write */
- sc->request.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- sc->request.bRequest = UR_BBB_RESET;
- USETW(sc->request.wValue, 0);
- USETW(sc->request.wIndex, sc->ifaceno);
- USETW(sc->request.wLength, 0);
- umass_setup_ctrl_transfer(sc, udev, &sc->request, NULL, 0, 0,
- sc->transfer_xfer[XFER_BBB_RESET1]);
-}
-
-static void
-umass_bbb_transfer(struct umass_softc *sc, int lun, void *cmd, int cmdlen,
- void *data, int datalen, int dir, u_int timeout,
- transfer_cb_f cb, void *priv)
-{
- KASSERT(sc->proto & UMASS_PROTO_BBB,
- ("%s: umass_bbb_transfer: wrong sc->proto 0x%02x\n",
- device_get_nameunit(sc->sc_dev), sc->proto));
-
- /* Be a little generous. */
- sc->timeout = timeout + UMASS_TIMEOUT;
-
- /*
- * Do a Bulk-Only transfer with cmdlen bytes from cmd, possibly
- * a data phase of datalen bytes from/to the device and finally a
- * csw read phase.
- * If the data direction was inbound a maximum of datalen bytes
- * is stored in the buffer pointed to by data.
- *
- * umass_bbb_transfer initialises the transfer and lets the state
- * machine in umass_bbb_state handle the completion. It uses the
- * following states:
- * TSTATE_BBB_COMMAND
- * -> TSTATE_BBB_DATA
- * -> TSTATE_BBB_STATUS
- * -> TSTATE_BBB_STATUS2
- * -> TSTATE_BBB_IDLE
- *
- * An error in any of those states will invoke
- * umass_bbb_reset.
- */
-
- /* check the given arguments */
- KASSERT(datalen == 0 || data != NULL,
- ("%s: datalen > 0, but no buffer",device_get_nameunit(sc->sc_dev)));
- KASSERT(cmdlen <= CBWCDBLENGTH,
- ("%s: cmdlen exceeds CDB length in CBW (%d > %d)",
- device_get_nameunit(sc->sc_dev), cmdlen, CBWCDBLENGTH));
- KASSERT(dir == DIR_NONE || datalen > 0,
- ("%s: datalen == 0 while direction is not NONE\n",
- device_get_nameunit(sc->sc_dev)));
- KASSERT(datalen == 0 || dir != DIR_NONE,
- ("%s: direction is NONE while datalen is not zero\n",
- device_get_nameunit(sc->sc_dev)));
- KASSERT(sizeof(umass_bbb_cbw_t) == UMASS_BBB_CBW_SIZE,
- ("%s: CBW struct does not have the right size (%ld vs. %d)\n",
- device_get_nameunit(sc->sc_dev),
- (long)sizeof(umass_bbb_cbw_t), UMASS_BBB_CBW_SIZE));
- KASSERT(sizeof(umass_bbb_csw_t) == UMASS_BBB_CSW_SIZE,
- ("%s: CSW struct does not have the right size (%ld vs. %d)\n",
- device_get_nameunit(sc->sc_dev),
- (long)sizeof(umass_bbb_csw_t), UMASS_BBB_CSW_SIZE));
-
- /*
- * Determine the direction of the data transfer and the length.
- *
- * dCBWDataTransferLength (datalen) :
- * This field indicates the number of bytes of data that the host
- * intends to transfer on the IN or OUT Bulk endpoint(as indicated by
- * the Direction bit) during the execution of this command. If this
- * field is set to 0, the device will expect that no data will be
- * transferred IN or OUT during this command, regardless of the value
- * of the Direction bit defined in dCBWFlags.
- *
- * dCBWFlags (dir) :
- * The bits of the Flags field are defined as follows:
- * Bits 0-6 reserved
- * Bit 7 Direction - this bit shall be ignored if the
- * dCBWDataTransferLength field is zero.
- * 0 = data Out from host to device
- * 1 = data In from device to host
- */
-
- /* Fill in the Command Block Wrapper
- * We fill in all the fields, so there is no need to bzero it first.
- */
- USETDW(sc->cbw.dCBWSignature, CBWSIGNATURE);
- /* We don't care about the initial value, as long as the values are unique */
- USETDW(sc->cbw.dCBWTag, UGETDW(sc->cbw.dCBWTag) + 1);
- USETDW(sc->cbw.dCBWDataTransferLength, datalen);
- /* DIR_NONE is treated as DIR_OUT (0x00) */
- sc->cbw.bCBWFlags = (dir == DIR_IN? CBWFLAGS_IN:CBWFLAGS_OUT);
- sc->cbw.bCBWLUN = lun;
- sc->cbw.bCDBLength = cmdlen;
- bcopy(cmd, sc->cbw.CBWCDB, cmdlen);
-
- DIF(UDMASS_BBB, umass_bbb_dump_cbw(sc, &sc->cbw));
-
- /* store the details for the data transfer phase */
- sc->transfer_dir = dir;
- sc->transfer_data = data;
- sc->transfer_datalen = datalen;
- sc->transfer_actlen = 0;
- sc->transfer_cb = cb;
- sc->transfer_priv = priv;
- sc->transfer_status = STATUS_CMD_OK;
-
- /* move from idle to the command state */
- sc->transfer_state = TSTATE_BBB_COMMAND;
-
- /* Send the CBW from host to device via bulk-out endpoint. */
- if (umass_setup_transfer(sc, sc->bulkout_pipe,
- &sc->cbw, UMASS_BBB_CBW_SIZE, 0,
- sc->transfer_xfer[XFER_BBB_CBW])) {
- umass_bbb_reset(sc, STATUS_WIRE_FAILED);
- }
-}
-
-
-static void
-umass_bbb_state(usbd_xfer_handle xfer, usbd_private_handle priv,
- usbd_status err)
-{
- struct umass_softc *sc = (struct umass_softc *) priv;
- usbd_xfer_handle next_xfer;
-
- KASSERT(sc->proto & UMASS_PROTO_BBB,
- ("%s: umass_bbb_state: wrong sc->proto 0x%02x\n",
- device_get_nameunit(sc->sc_dev), sc->proto));
-
- /*
- * State handling for BBB transfers.
- *
- * The subroutine is rather long. It steps through the states given in
- * Annex A of the Bulk-Only specification.
- * Each state first does the error handling of the previous transfer
- * and then prepares the next transfer.
- * Each transfer is done asynchronously so after the request/transfer
- * has been submitted you will find a 'return;'.
- */
-
- DPRINTF(UDMASS_BBB, ("%s: Handling BBB state %d (%s), xfer=%p, %s\n",
- device_get_nameunit(sc->sc_dev), sc->transfer_state,
- states[sc->transfer_state], xfer, usbd_errstr(err)));
-
- /* Give up if the device has detached. */
- if (sc->flags & UMASS_FLAGS_GONE) {
- sc->transfer_state = TSTATE_IDLE;
- sc->transfer_cb(sc, sc->transfer_priv, sc->transfer_datalen,
- STATUS_CMD_FAILED);
- return;
- }
-
- switch (sc->transfer_state) {
-
- /***** Bulk Transfer *****/
- case TSTATE_BBB_COMMAND:
- /* Command transport phase, error handling */
- if (err) {
- DPRINTF(UDMASS_BBB, ("%s: failed to send CBW\n",
- device_get_nameunit(sc->sc_dev)));
- /* If the device detects that the CBW is invalid, then
- * the device may STALL both bulk endpoints and require
- * a Bulk-Reset
- */
- umass_bbb_reset(sc, STATUS_WIRE_FAILED);
- return;
- }
-
- /* Data transport phase, setup transfer */
- sc->transfer_state = TSTATE_BBB_DATA;
- if (sc->transfer_dir == DIR_IN) {
- if (umass_setup_transfer(sc, sc->bulkin_pipe,
- sc->transfer_data, sc->transfer_datalen,
- USBD_SHORT_XFER_OK,
- sc->transfer_xfer[XFER_BBB_DATA]))
- umass_bbb_reset(sc, STATUS_WIRE_FAILED);
-
- return;
- } else if (sc->transfer_dir == DIR_OUT) {
- if (umass_setup_transfer(sc, sc->bulkout_pipe,
- sc->transfer_data, sc->transfer_datalen,
- 0, /* fixed length transfer */
- sc->transfer_xfer[XFER_BBB_DATA]))
- umass_bbb_reset(sc, STATUS_WIRE_FAILED);
-
- return;
- } else {
- DPRINTF(UDMASS_BBB, ("%s: no data phase\n",
- device_get_nameunit(sc->sc_dev)));
- }
-
- /* FALLTHROUGH if no data phase, err == 0 */
- case TSTATE_BBB_DATA:
- /* Command transport phase, error handling (ignored if no data
- * phase (fallthrough from previous state)) */
- if (sc->transfer_dir != DIR_NONE) {
- /* retrieve the length of the transfer that was done */
- usbd_get_xfer_status(xfer, NULL, NULL,
- &sc->transfer_actlen, NULL);
-
- if (err) {
- DPRINTF(UDMASS_BBB, ("%s: Data-%s %db failed, "
- "%s\n", device_get_nameunit(sc->sc_dev),
- (sc->transfer_dir == DIR_IN?"in":"out"),
- sc->transfer_datalen,usbd_errstr(err)));
-
- if (err == USBD_STALLED) {
- umass_clear_endpoint_stall(sc,
- (sc->transfer_dir == DIR_IN?
- sc->bulkin:sc->bulkout),
- (sc->transfer_dir == DIR_IN?
- sc->bulkin_pipe:sc->bulkout_pipe),
- TSTATE_BBB_DCLEAR,
- sc->transfer_xfer[XFER_BBB_DCLEAR]);
- return;
- } else {
- /* Unless the error is a pipe stall the
- * error is fatal.
- */
- umass_bbb_reset(sc,STATUS_WIRE_FAILED);
- return;
- }
- }
- }
-
- DIF(UDMASS_BBB, if (sc->transfer_dir == DIR_IN)
- umass_dump_buffer(sc, sc->transfer_data,
- sc->transfer_datalen, 48));
-
-
-
- /* FALLTHROUGH, err == 0 (no data phase or successfull) */
- case TSTATE_BBB_DCLEAR: /* stall clear after data phase */
- case TSTATE_BBB_SCLEAR: /* stall clear after status phase */
- /* Reading of CSW after bulk stall condition in data phase
- * (TSTATE_BBB_DATA2) or bulk-in stall condition after
- * reading CSW (TSTATE_BBB_SCLEAR).
- * In the case of no data phase or successfull data phase,
- * err == 0 and the following if block is passed.
- */
- if (err) { /* should not occur */
- /* try the transfer below, even if clear stall failed */
- DPRINTF(UDMASS_BBB, ("%s: bulk-%s stall clear failed"
- ", %s\n", device_get_nameunit(sc->sc_dev),
- (sc->transfer_dir == DIR_IN? "in":"out"),
- usbd_errstr(err)));
- umass_bbb_reset(sc, STATUS_WIRE_FAILED);
- return;
- }
-
- /* Status transport phase, setup transfer */
- if (sc->transfer_state == TSTATE_BBB_COMMAND ||
- sc->transfer_state == TSTATE_BBB_DATA ||
- sc->transfer_state == TSTATE_BBB_DCLEAR) {
- /* After no data phase, successfull data phase and
- * after clearing bulk-in/-out stall condition
- */
- sc->transfer_state = TSTATE_BBB_STATUS1;
- next_xfer = sc->transfer_xfer[XFER_BBB_CSW1];
- } else {
- /* After first attempt of fetching CSW */
- sc->transfer_state = TSTATE_BBB_STATUS2;
- next_xfer = sc->transfer_xfer[XFER_BBB_CSW2];
- }
-
- /* Read the Command Status Wrapper via bulk-in endpoint. */
- if (umass_setup_transfer(sc, sc->bulkin_pipe,
- &sc->csw, UMASS_BBB_CSW_SIZE, 0,
- next_xfer)) {
- umass_bbb_reset(sc, STATUS_WIRE_FAILED);
- return;
- }
-
- return;
- case TSTATE_BBB_STATUS1: /* first attempt */
- case TSTATE_BBB_STATUS2: /* second attempt */
- /* Status transfer, error handling */
- if (err) {
- DPRINTF(UDMASS_BBB, ("%s: Failed to read CSW, %s%s\n",
- device_get_nameunit(sc->sc_dev), usbd_errstr(err),
- (sc->transfer_state == TSTATE_BBB_STATUS1?
- ", retrying":"")));
-
- /* If this was the first attempt at fetching the CSW
- * retry it, otherwise fail.
- */
- if (sc->transfer_state == TSTATE_BBB_STATUS1) {
- umass_clear_endpoint_stall(sc,
- sc->bulkin, sc->bulkin_pipe,
- TSTATE_BBB_SCLEAR,
- sc->transfer_xfer[XFER_BBB_SCLEAR]);
- return;
- } else {
- umass_bbb_reset(sc, STATUS_WIRE_FAILED);
- return;
- }
- }
-
- DIF(UDMASS_BBB, umass_bbb_dump_csw(sc, &sc->csw));
-
- /* Translate weird command-status signatures. */
- if (sc->quirks & WRONG_CSWSIG) {
- u_int32_t dCSWSignature = UGETDW(sc->csw.dCSWSignature);
- if (dCSWSignature == CSWSIGNATURE_OLYMPUS_C1 ||
- dCSWSignature == CSWSIGNATURE_IMAGINATION_DBX1)
- USETDW(sc->csw.dCSWSignature, CSWSIGNATURE);
- }
-
- int Residue;
- Residue = UGETDW(sc->csw.dCSWDataResidue);
- if (Residue == 0 &&
- sc->transfer_datalen - sc->transfer_actlen != 0)
- Residue = sc->transfer_datalen - sc->transfer_actlen;
-
- /* Check CSW and handle any error */
- if (UGETDW(sc->csw.dCSWSignature) != CSWSIGNATURE) {
- /* Invalid CSW: Wrong signature or wrong tag might
- * indicate that the device is confused -> reset it.
- */
- printf("%s: Invalid CSW: sig 0x%08x should be 0x%08x\n",
- device_get_nameunit(sc->sc_dev),
- UGETDW(sc->csw.dCSWSignature),
- CSWSIGNATURE);
-
- umass_bbb_reset(sc, STATUS_WIRE_FAILED);
- return;
- } else if (UGETDW(sc->csw.dCSWTag)
- != UGETDW(sc->cbw.dCBWTag)) {
- printf("%s: Invalid CSW: tag %d should be %d\n",
- device_get_nameunit(sc->sc_dev),
- UGETDW(sc->csw.dCSWTag),
- UGETDW(sc->cbw.dCBWTag));
-
- umass_bbb_reset(sc, STATUS_WIRE_FAILED);
- return;
-
- /* CSW is valid here */
- } else if (sc->csw.bCSWStatus > CSWSTATUS_PHASE) {
- printf("%s: Invalid CSW: status %d > %d\n",
- device_get_nameunit(sc->sc_dev),
- sc->csw.bCSWStatus,
- CSWSTATUS_PHASE);
-
- umass_bbb_reset(sc, STATUS_WIRE_FAILED);
- return;
- } else if (sc->csw.bCSWStatus == CSWSTATUS_PHASE) {
- printf("%s: Phase Error, residue = %d\n",
- device_get_nameunit(sc->sc_dev), Residue);
-
- umass_bbb_reset(sc, STATUS_WIRE_FAILED);
- return;
-
- } else if (sc->transfer_actlen > sc->transfer_datalen) {
- /* Buffer overrun! Don't let this go by unnoticed */
- panic("%s: transferred %db instead of %db",
- device_get_nameunit(sc->sc_dev),
- sc->transfer_actlen, sc->transfer_datalen);
-
- } else if (sc->csw.bCSWStatus == CSWSTATUS_FAILED) {
- DPRINTF(UDMASS_BBB, ("%s: Command Failed, res = %d\n",
- device_get_nameunit(sc->sc_dev), Residue));
-
- /* SCSI command failed but transfer was succesful */
- sc->transfer_state = TSTATE_IDLE;
- sc->transfer_cb(sc, sc->transfer_priv, Residue,
- STATUS_CMD_FAILED);
- return;
-
- } else { /* success */
- sc->transfer_state = TSTATE_IDLE;
- sc->transfer_cb(sc, sc->transfer_priv, Residue,
- STATUS_CMD_OK);
-
- return;
- }
-
- /***** Bulk Reset *****/
- case TSTATE_BBB_RESET1:
- if (err)
- printf("%s: BBB reset failed, %s\n",
- device_get_nameunit(sc->sc_dev), usbd_errstr(err));
-
- umass_clear_endpoint_stall(sc,
- sc->bulkin, sc->bulkin_pipe, TSTATE_BBB_RESET2,
- sc->transfer_xfer[XFER_BBB_RESET2]);
-
- return;
- case TSTATE_BBB_RESET2:
- if (err) /* should not occur */
- printf("%s: BBB bulk-in clear stall failed, %s\n",
- device_get_nameunit(sc->sc_dev), usbd_errstr(err));
- /* no error recovery, otherwise we end up in a loop */
-
- umass_clear_endpoint_stall(sc,
- sc->bulkout, sc->bulkout_pipe, TSTATE_BBB_RESET3,
- sc->transfer_xfer[XFER_BBB_RESET3]);
-
- return;
- case TSTATE_BBB_RESET3:
- if (err) /* should not occur */
- printf("%s: BBB bulk-out clear stall failed, %s\n",
- device_get_nameunit(sc->sc_dev), usbd_errstr(err));
- /* no error recovery, otherwise we end up in a loop */
-
- sc->transfer_state = TSTATE_IDLE;
- if (sc->transfer_priv) {
- sc->transfer_cb(sc, sc->transfer_priv,
- sc->transfer_datalen,
- sc->transfer_status);
- }
-
- return;
-
- /***** Default *****/
- default:
- panic("%s: Unknown state %d",
- device_get_nameunit(sc->sc_dev), sc->transfer_state);
- }
-}
-
-static int
-umass_bbb_get_max_lun(struct umass_softc *sc)
-{
- usbd_device_handle udev;
- usb_device_request_t req;
- usbd_status err;
- usb_interface_descriptor_t *id;
- int maxlun = 0;
- u_int8_t buf = 0;
-
- usbd_interface2device_handle(sc->iface, &udev);
- id = usbd_get_interface_descriptor(sc->iface);
-
- /* The Get Max Lun command is a class-specific request. */
- req.bmRequestType = UT_READ_CLASS_INTERFACE;
- req.bRequest = UR_BBB_GET_MAX_LUN;
- USETW(req.wValue, 0);
- USETW(req.wIndex, id->bInterfaceNumber);
- USETW(req.wLength, 1);
-
- err = usbd_do_request(udev, &req, &buf);
- switch (err) {
- case USBD_NORMAL_COMPLETION:
- maxlun = buf;
- DPRINTF(UDMASS_BBB, ("%s: Max Lun is %d\n",
- device_get_nameunit(sc->sc_dev), maxlun));
- break;
- case USBD_STALLED:
- case USBD_SHORT_XFER:
- default:
- /* Device doesn't support Get Max Lun request. */
- printf("%s: Get Max Lun not supported (%s)\n",
- device_get_nameunit(sc->sc_dev), usbd_errstr(err));
- /* XXX Should we port_reset the device? */
- break;
- }
-
- return(maxlun);
-}
-
-/*
- * Command/Bulk/Interrupt (CBI) specific functions
- */
-
-static int
-umass_cbi_adsc(struct umass_softc *sc, char *buffer, int buflen,
- usbd_xfer_handle xfer)
-{
- usbd_device_handle udev;
-
- KASSERT(sc->proto & (UMASS_PROTO_CBI|UMASS_PROTO_CBI_I),
- ("%s: umass_cbi_adsc: wrong sc->proto 0x%02x\n",
- device_get_nameunit(sc->sc_dev), sc->proto));
-
- usbd_interface2device_handle(sc->iface, &udev);
-
- sc->request.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- sc->request.bRequest = UR_CBI_ADSC;
- USETW(sc->request.wValue, 0);
- USETW(sc->request.wIndex, sc->ifaceno);
- USETW(sc->request.wLength, buflen);
- return umass_setup_ctrl_transfer(sc, udev, &sc->request, buffer,
- buflen, 0, xfer);
-}
-
-
-static void
-umass_cbi_reset(struct umass_softc *sc, int status)
-{
- int i;
-# define SEND_DIAGNOSTIC_CMDLEN 12
-
- KASSERT(sc->proto & (UMASS_PROTO_CBI|UMASS_PROTO_CBI_I),
- ("%s: umass_cbi_reset: wrong sc->proto 0x%02x\n",
- device_get_nameunit(sc->sc_dev), sc->proto));
-
- /*
- * Command Block Reset Protocol
- *
- * First send a reset request to the device. Then clear
- * any possibly stalled bulk endpoints.
- *
- * This is done in 3 steps, states:
- * TSTATE_CBI_RESET1
- * TSTATE_CBI_RESET2
- * TSTATE_CBI_RESET3
- *
- * If the reset doesn't succeed, the device should be port reset.
- */
-
- DPRINTF(UDMASS_CBI, ("%s: CBI Reset\n",
- device_get_nameunit(sc->sc_dev)));
-
- KASSERT(sizeof(sc->cbl) >= SEND_DIAGNOSTIC_CMDLEN,
- ("%s: CBL struct is too small (%ld < %d)\n",
- device_get_nameunit(sc->sc_dev),
- (long)sizeof(sc->cbl), SEND_DIAGNOSTIC_CMDLEN));
-
- sc->transfer_state = TSTATE_CBI_RESET1;
- sc->transfer_status = status;
-
- /* The 0x1d code is the SEND DIAGNOSTIC command. To distinguish between
- * the two the last 10 bytes of the cbl is filled with 0xff (section
- * 2.2 of the CBI spec).
- */
- sc->cbl[0] = 0x1d; /* Command Block Reset */
- sc->cbl[1] = 0x04;
- for (i = 2; i < SEND_DIAGNOSTIC_CMDLEN; i++)
- sc->cbl[i] = 0xff;
-
- umass_cbi_adsc(sc, sc->cbl, SEND_DIAGNOSTIC_CMDLEN,
- sc->transfer_xfer[XFER_CBI_RESET1]);
- /* XXX if the command fails we should reset the port on the hub */
-}
-
-static void
-umass_cbi_transfer(struct umass_softc *sc, int lun,
- void *cmd, int cmdlen, void *data, int datalen, int dir,
- u_int timeout, transfer_cb_f cb, void *priv)
-{
- KASSERT(sc->proto & (UMASS_PROTO_CBI|UMASS_PROTO_CBI_I),
- ("%s: umass_cbi_transfer: wrong sc->proto 0x%02x\n",
- device_get_nameunit(sc->sc_dev), sc->proto));
-
- /* Be a little generous. */
- sc->timeout = timeout + UMASS_TIMEOUT;
-
- /*
- * Do a CBI transfer with cmdlen bytes from cmd, possibly
- * a data phase of datalen bytes from/to the device and finally a
- * csw read phase.
- * If the data direction was inbound a maximum of datalen bytes
- * is stored in the buffer pointed to by data.
- *
- * umass_cbi_transfer initialises the transfer and lets the state
- * machine in umass_cbi_state handle the completion. It uses the
- * following states:
- * TSTATE_CBI_COMMAND
- * -> XXX fill in
- *
- * An error in any of those states will invoke
- * umass_cbi_reset.
- */
-
- /* check the given arguments */
- KASSERT(datalen == 0 || data != NULL,
- ("%s: datalen > 0, but no buffer",device_get_nameunit(sc->sc_dev)));
- KASSERT(datalen == 0 || dir != DIR_NONE,
- ("%s: direction is NONE while datalen is not zero\n",
- device_get_nameunit(sc->sc_dev)));
-
- /* store the details for the data transfer phase */
- sc->transfer_dir = dir;
- sc->transfer_data = data;
- sc->transfer_datalen = datalen;
- sc->transfer_actlen = 0;
- sc->transfer_cb = cb;
- sc->transfer_priv = priv;
- sc->transfer_status = STATUS_CMD_OK;
-
- /* move from idle to the command state */
- sc->transfer_state = TSTATE_CBI_COMMAND;
-
- DIF(UDMASS_CBI, umass_cbi_dump_cmd(sc, cmd, cmdlen));
-
- /* Send the Command Block from host to device via control endpoint. */
- if (umass_cbi_adsc(sc, cmd, cmdlen, sc->transfer_xfer[XFER_CBI_CB]))
- umass_cbi_reset(sc, STATUS_WIRE_FAILED);
-}
-
-static void
-umass_cbi_state(usbd_xfer_handle xfer, usbd_private_handle priv,
- usbd_status err)
-{
- struct umass_softc *sc = (struct umass_softc *) priv;
-
- KASSERT(sc->proto & (UMASS_PROTO_CBI|UMASS_PROTO_CBI_I),
- ("%s: umass_cbi_state: wrong sc->proto 0x%02x\n",
- device_get_nameunit(sc->sc_dev), sc->proto));
-
- /*
- * State handling for CBI transfers.
- */
-
- DPRINTF(UDMASS_CBI, ("%s: Handling CBI state %d (%s), xfer=%p, %s\n",
- device_get_nameunit(sc->sc_dev), sc->transfer_state,
- states[sc->transfer_state], xfer, usbd_errstr(err)));
-
- /* Give up if the device has detached. */
- if (sc->flags & UMASS_FLAGS_GONE) {
- sc->transfer_state = TSTATE_IDLE;
- sc->transfer_cb(sc, sc->transfer_priv, sc->transfer_datalen,
- STATUS_CMD_FAILED);
- return;
- }
-
- switch (sc->transfer_state) {
-
- /***** CBI Transfer *****/
- case TSTATE_CBI_COMMAND:
- if (err == USBD_STALLED) {
- DPRINTF(UDMASS_CBI, ("%s: Command Transport failed\n",
- device_get_nameunit(sc->sc_dev)));
- /* Status transport by control pipe (section 2.3.2.1).
- * The command contained in the command block failed.
- *
- * The control pipe has already been unstalled by the
- * USB stack.
- * Section 2.4.3.1.1 states that the bulk in endpoints
- * should not be stalled at this point.
- */
-
- sc->transfer_state = TSTATE_IDLE;
- sc->transfer_cb(sc, sc->transfer_priv,
- sc->transfer_datalen,
- STATUS_CMD_FAILED);
-
- return;
- } else if (err) {
- DPRINTF(UDMASS_CBI, ("%s: failed to send ADSC\n",
- device_get_nameunit(sc->sc_dev)));
- umass_cbi_reset(sc, STATUS_WIRE_FAILED);
-
- return;
- }
-
- sc->transfer_state = TSTATE_CBI_DATA;
- if (sc->transfer_dir == DIR_IN) {
- if (umass_setup_transfer(sc, sc->bulkin_pipe,
- sc->transfer_data, sc->transfer_datalen,
- USBD_SHORT_XFER_OK,
- sc->transfer_xfer[XFER_CBI_DATA]))
- umass_cbi_reset(sc, STATUS_WIRE_FAILED);
-
- } else if (sc->transfer_dir == DIR_OUT) {
- if (umass_setup_transfer(sc, sc->bulkout_pipe,
- sc->transfer_data, sc->transfer_datalen,
- 0, /* fixed length transfer */
- sc->transfer_xfer[XFER_CBI_DATA]))
- umass_cbi_reset(sc, STATUS_WIRE_FAILED);
-
- } else if (sc->proto & UMASS_PROTO_CBI_I) {
- DPRINTF(UDMASS_CBI, ("%s: no data phase\n",
- device_get_nameunit(sc->sc_dev)));
- sc->transfer_state = TSTATE_CBI_STATUS;
- if (umass_setup_transfer(sc, sc->intrin_pipe,
- &sc->sbl, sizeof(sc->sbl),
- 0, /* fixed length transfer */
- sc->transfer_xfer[XFER_CBI_STATUS])){
- umass_cbi_reset(sc, STATUS_WIRE_FAILED);
- }
- } else {
- DPRINTF(UDMASS_CBI, ("%s: no data phase\n",
- device_get_nameunit(sc->sc_dev)));
- /* No command completion interrupt. Request
- * sense data.
- */
- sc->transfer_state = TSTATE_IDLE;
- sc->transfer_cb(sc, sc->transfer_priv,
- 0, STATUS_CMD_UNKNOWN);
- }
-
- return;
-
- case TSTATE_CBI_DATA:
- /* retrieve the length of the transfer that was done */
- usbd_get_xfer_status(xfer,NULL,NULL,&sc->transfer_actlen,NULL);
-
- if (err) {
- DPRINTF(UDMASS_CBI, ("%s: Data-%s %db failed, "
- "%s\n", device_get_nameunit(sc->sc_dev),
- (sc->transfer_dir == DIR_IN?"in":"out"),
- sc->transfer_datalen,usbd_errstr(err)));
-
- if (err == USBD_STALLED) {
- umass_clear_endpoint_stall(sc,
- sc->bulkin, sc->bulkin_pipe,
- TSTATE_CBI_DCLEAR,
- sc->transfer_xfer[XFER_CBI_DCLEAR]);
- } else {
- umass_cbi_reset(sc, STATUS_WIRE_FAILED);
- }
- return;
- }
-
- DIF(UDMASS_CBI, if (sc->transfer_dir == DIR_IN)
- umass_dump_buffer(sc, sc->transfer_data,
- sc->transfer_actlen, 48));
-
- if (sc->proto & UMASS_PROTO_CBI_I) {
- sc->transfer_state = TSTATE_CBI_STATUS;
- if (umass_setup_transfer(sc, sc->intrin_pipe,
- &sc->sbl, sizeof(sc->sbl),
- 0, /* fixed length transfer */
- sc->transfer_xfer[XFER_CBI_STATUS])){
- umass_cbi_reset(sc, STATUS_WIRE_FAILED);
- }
- } else {
- /* No command completion interrupt. Request
- * sense to get status of command.
- */
- sc->transfer_state = TSTATE_IDLE;
- sc->transfer_cb(sc, sc->transfer_priv,
- sc->transfer_datalen - sc->transfer_actlen,
- STATUS_CMD_UNKNOWN);
- }
- return;
-
- case TSTATE_CBI_STATUS:
- if (err) {
- DPRINTF(UDMASS_CBI, ("%s: Status Transport failed\n",
- device_get_nameunit(sc->sc_dev)));
- /* Status transport by interrupt pipe (section 2.3.2.2).
- */
-
- if (err == USBD_STALLED) {
- umass_clear_endpoint_stall(sc,
- sc->intrin, sc->intrin_pipe,
- TSTATE_CBI_SCLEAR,
- sc->transfer_xfer[XFER_CBI_SCLEAR]);
- } else {
- umass_cbi_reset(sc, STATUS_WIRE_FAILED);
- }
- return;
- }
-
- /* Dissect the information in the buffer */
-
- if (sc->proto & UMASS_PROTO_UFI) {
- int status;
-
- /* Section 3.4.3.1.3 specifies that the UFI command
- * protocol returns an ASC and ASCQ in the interrupt
- * data block.
- */
-
- DPRINTF(UDMASS_CBI, ("%s: UFI CCI, ASC = 0x%02x, "
- "ASCQ = 0x%02x\n",
- device_get_nameunit(sc->sc_dev),
- sc->sbl.ufi.asc, sc->sbl.ufi.ascq));
-
- if (sc->sbl.ufi.asc == 0 && sc->sbl.ufi.ascq == 0)
- status = STATUS_CMD_OK;
- else
- status = STATUS_CMD_FAILED;
-
- sc->transfer_state = TSTATE_IDLE;
- sc->transfer_cb(sc, sc->transfer_priv,
- sc->transfer_datalen - sc->transfer_actlen,
- status);
- } else {
- /* Command Interrupt Data Block */
- DPRINTF(UDMASS_CBI, ("%s: type=0x%02x, value=0x%02x\n",
- device_get_nameunit(sc->sc_dev),
- sc->sbl.common.type, sc->sbl.common.value));
-
- if (sc->sbl.common.type == IDB_TYPE_CCI) {
- int err;
-
- if ((sc->sbl.common.value&IDB_VALUE_STATUS_MASK)
- == IDB_VALUE_PASS) {
- err = STATUS_CMD_OK;
- } else if ((sc->sbl.common.value & IDB_VALUE_STATUS_MASK)
- == IDB_VALUE_FAIL ||
- (sc->sbl.common.value & IDB_VALUE_STATUS_MASK)
- == IDB_VALUE_PERSISTENT) {
- err = STATUS_CMD_FAILED;
- } else {
- err = STATUS_WIRE_FAILED;
- }
-
- sc->transfer_state = TSTATE_IDLE;
- sc->transfer_cb(sc, sc->transfer_priv,
- sc->transfer_datalen-sc->transfer_actlen,
- err);
- }
- }
- return;
-
- case TSTATE_CBI_DCLEAR:
- if (err) { /* should not occur */
- printf("%s: CBI bulk-in/out stall clear failed, %s\n",
- device_get_nameunit(sc->sc_dev), usbd_errstr(err));
- umass_cbi_reset(sc, STATUS_WIRE_FAILED);
- }
-
- sc->transfer_state = TSTATE_IDLE;
- sc->transfer_cb(sc, sc->transfer_priv,
- sc->transfer_datalen,
- STATUS_CMD_FAILED);
- return;
-
- case TSTATE_CBI_SCLEAR:
- if (err) /* should not occur */
- printf("%s: CBI intr-in stall clear failed, %s\n",
- device_get_nameunit(sc->sc_dev), usbd_errstr(err));
-
- /* Something really bad is going on. Reset the device */
- umass_cbi_reset(sc, STATUS_CMD_FAILED);
- return;
-
- /***** CBI Reset *****/
- case TSTATE_CBI_RESET1:
- if (err)
- printf("%s: CBI reset failed, %s\n",
- device_get_nameunit(sc->sc_dev), usbd_errstr(err));
-
- umass_clear_endpoint_stall(sc,
- sc->bulkin, sc->bulkin_pipe, TSTATE_CBI_RESET2,
- sc->transfer_xfer[XFER_CBI_RESET2]);
-
- return;
- case TSTATE_CBI_RESET2:
- if (err) /* should not occur */
- printf("%s: CBI bulk-in stall clear failed, %s\n",
- device_get_nameunit(sc->sc_dev), usbd_errstr(err));
- /* no error recovery, otherwise we end up in a loop */
-
- umass_clear_endpoint_stall(sc,
- sc->bulkout, sc->bulkout_pipe, TSTATE_CBI_RESET3,
- sc->transfer_xfer[XFER_CBI_RESET3]);
-
- return;
- case TSTATE_CBI_RESET3:
- if (err) /* should not occur */
- printf("%s: CBI bulk-out stall clear failed, %s\n",
- device_get_nameunit(sc->sc_dev), usbd_errstr(err));
- /* no error recovery, otherwise we end up in a loop */
-
- sc->transfer_state = TSTATE_IDLE;
- if (sc->transfer_priv) {
- sc->transfer_cb(sc, sc->transfer_priv,
- sc->transfer_datalen,
- sc->transfer_status);
- }
-
- return;
-
-
- /***** Default *****/
- default:
- panic("%s: Unknown state %d",
- device_get_nameunit(sc->sc_dev), sc->transfer_state);
- }
-}
-
-
-
-
-/*
- * CAM specific functions (used by SCSI, UFI, 8070i (ATAPI))
- */
-
-static int
-umass_cam_attach_sim(struct umass_softc *sc)
-{
- struct cam_devq *devq; /* Per device Queue */
-
- /* A HBA is attached to the CAM layer.
- *
- * The CAM layer will then after a while start probing for
- * devices on the bus. The number of SIMs is limited to one.
- */
-
- devq = cam_simq_alloc(1 /*maximum openings*/);
- if (devq == NULL)
- return(ENOMEM);
-
- sc->umass_sim = cam_sim_alloc(umass_cam_action, umass_cam_poll,
- DEVNAME_SIM,
- sc /*priv*/,
- device_get_unit(sc->sc_dev) /*unit number*/,
- &Giant,
- 1 /*maximum device openings*/,
- 0 /*maximum tagged device openings*/,
- devq);
- if (sc->umass_sim == NULL) {
- cam_simq_free(devq);
- return(ENOMEM);
- }
-
- if(xpt_bus_register(sc->umass_sim, NULL, device_get_unit(sc->sc_dev)) !=
- CAM_SUCCESS)
- return(ENOMEM);
-
- return(0);
-}
-
-static void
-umass_cam_rescan_callback(struct cam_periph *periph, union ccb *ccb)
-{
-#ifdef USB_DEBUG
- if (ccb->ccb_h.status != CAM_REQ_CMP) {
- DPRINTF(UDMASS_SCSI, ("%s:%d Rescan failed, 0x%04x\n",
- periph->periph_name, periph->unit_number,
- ccb->ccb_h.status));
- } else {
- DPRINTF(UDMASS_SCSI, ("%s%d: Rescan succeeded\n",
- periph->periph_name, periph->unit_number));
- }
-#endif
-
- xpt_free_path(ccb->ccb_h.path);
- free(ccb, M_USBDEV);
-}
-
-static void
-umass_cam_rescan(void *addr)
-{
- struct umass_softc *sc = (struct umass_softc *) addr;
- struct cam_path *path;
- union ccb *ccb;
-
- DPRINTF(UDMASS_SCSI, ("scbus%d: scanning for %s:%d:%d:%d\n",
- cam_sim_path(sc->umass_sim),
- device_get_nameunit(sc->sc_dev), cam_sim_path(sc->umass_sim),
- device_get_unit(sc->sc_dev), CAM_LUN_WILDCARD));
-
- ccb = malloc(sizeof(union ccb), M_USBDEV, M_NOWAIT | M_ZERO);
- if (ccb == NULL)
- return;
- if (xpt_create_path(&path, xpt_periph, cam_sim_path(sc->umass_sim),
- device_get_unit(sc->sc_dev), CAM_LUN_WILDCARD)
- != CAM_REQ_CMP) {
- free(ccb, M_USBDEV);
- return;
- }
-
- xpt_setup_ccb(&ccb->ccb_h, path, 5/*priority (low)*/);
- ccb->ccb_h.func_code = XPT_SCAN_BUS;
- ccb->ccb_h.cbfcnp = umass_cam_rescan_callback;
- ccb->crcn.flags = CAM_FLAG_NONE;
- xpt_action(ccb);
-
- /* The scan is in progress now. */
-}
-
-static int
-umass_cam_attach(struct umass_softc *sc)
-{
-#ifndef USB_DEBUG
- if (bootverbose)
-#endif
- printf("%s:%d:%d:%d: Attached to scbus%d\n",
- device_get_nameunit(sc->sc_dev), cam_sim_path(sc->umass_sim),
- device_get_unit(sc->sc_dev), CAM_LUN_WILDCARD,
- cam_sim_path(sc->umass_sim));
-
- if (!cold) {
- /* Notify CAM of the new device after a short delay. Any
- * failure is benign, as the user can still do it by hand
- * (camcontrol rescan <busno>). Only do this if we are not
- * booting, because CAM does a scan after booting has
- * completed, when interrupts have been enabled.
- */
-
- callout_reset(&sc->cam_scsi_rescan_ch, MS_TO_TICKS(200),
- umass_cam_rescan, sc);
- }
-
- return(0); /* always succesfull */
-}
-
-/* umass_cam_detach
- * detach from the CAM layer
- */
-
-static int
-umass_cam_detach_sim(struct umass_softc *sc)
-{
- if (sc->umass_sim) {
- if (xpt_bus_deregister(cam_sim_path(sc->umass_sim)))
- cam_sim_free(sc->umass_sim, /*free_devq*/TRUE);
- else
- return(EBUSY);
-
- sc->umass_sim = NULL;
- }
-
- return(0);
-}
-
-/* umass_cam_action
- * CAM requests for action come through here
- */
-
-static void
-umass_cam_action(struct cam_sim *sim, union ccb *ccb)
-{
- struct umass_softc *sc = (struct umass_softc *)sim->softc;
-
- /* The softc is still there, but marked as going away. umass_cam_detach
- * has not yet notified CAM of the lost device however.
- */
- if (sc && (sc->flags & UMASS_FLAGS_GONE)) {
- DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d:func_code 0x%04x: "
- "Invalid target (gone)\n",
- device_get_nameunit(sc->sc_dev), cam_sim_path(sc->umass_sim),
- ccb->ccb_h.target_id, ccb->ccb_h.target_lun,
- ccb->ccb_h.func_code));
- ccb->ccb_h.status = CAM_TID_INVALID;
- xpt_done(ccb);
- return;
- }
-
- /* Verify, depending on the operation to perform, that we either got a
- * valid sc, because an existing target was referenced, or otherwise
- * the SIM is addressed.
- *
- * This avoids bombing out at a printf and does give the CAM layer some
- * sensible feedback on errors.
- */
- switch (ccb->ccb_h.func_code) {
- case XPT_SCSI_IO:
- case XPT_RESET_DEV:
- case XPT_GET_TRAN_SETTINGS:
- case XPT_SET_TRAN_SETTINGS:
- case XPT_CALC_GEOMETRY:
- /* the opcodes requiring a target. These should never occur. */
- if (sc == NULL) {
- printf("%s:%d:%d:%d:func_code 0x%04x: "
- "Invalid target (target needed)\n",
- DEVNAME_SIM, cam_sim_path(sc->umass_sim),
- ccb->ccb_h.target_id, ccb->ccb_h.target_lun,
- ccb->ccb_h.func_code);
-
- ccb->ccb_h.status = CAM_TID_INVALID;
- xpt_done(ccb);
- return;
- }
- break;
- case XPT_PATH_INQ:
- case XPT_NOOP:
- /* The opcodes sometimes aimed at a target (sc is valid),
- * sometimes aimed at the SIM (sc is invalid and target is
- * CAM_TARGET_WILDCARD)
- */
- if (sc == NULL && ccb->ccb_h.target_id != CAM_TARGET_WILDCARD) {
- DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d:func_code 0x%04x: "
- "Invalid target (no wildcard)\n",
- DEVNAME_SIM, cam_sim_path(sc->umass_sim),
- ccb->ccb_h.target_id, ccb->ccb_h.target_lun,
- ccb->ccb_h.func_code));
-
- ccb->ccb_h.status = CAM_TID_INVALID;
- xpt_done(ccb);
- return;
- }
- break;
- default:
- /* XXX Hm, we should check the input parameters */
- break;
- }
-
- /* Perform the requested action */
- switch (ccb->ccb_h.func_code) {
- case XPT_SCSI_IO:
- {
- struct ccb_scsiio *csio = &ccb->csio; /* deref union */
- int dir;
- unsigned char *cmd;
- int cmdlen;
- unsigned char *rcmd;
- int rcmdlen;
-
- DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d:XPT_SCSI_IO: "
- "cmd: 0x%02x, flags: 0x%02x, "
- "%db cmd/%db data/%db sense\n",
- device_get_nameunit(sc->sc_dev), cam_sim_path(sc->umass_sim),
- ccb->ccb_h.target_id, ccb->ccb_h.target_lun,
- csio->cdb_io.cdb_bytes[0],
- ccb->ccb_h.flags & CAM_DIR_MASK,
- csio->cdb_len, csio->dxfer_len,
- csio->sense_len));
-
- /* clear the end of the buffer to make sure we don't send out
- * garbage.
- */
- DIF(UDMASS_SCSI, if ((ccb->ccb_h.flags & CAM_DIR_MASK)
- == CAM_DIR_OUT)
- umass_dump_buffer(sc, csio->data_ptr,
- csio->dxfer_len, 48));
-
- if (sc->transfer_state != TSTATE_IDLE) {
- DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d:XPT_SCSI_IO: "
- "I/O in progress, deferring (state %d, %s)\n",
- device_get_nameunit(sc->sc_dev), cam_sim_path(sc->umass_sim),
- ccb->ccb_h.target_id, ccb->ccb_h.target_lun,
- sc->transfer_state,states[sc->transfer_state]));
- ccb->ccb_h.status = CAM_SCSI_BUSY;
- xpt_done(ccb);
- return;
- }
-
- switch(ccb->ccb_h.flags&CAM_DIR_MASK) {
- case CAM_DIR_IN:
- dir = DIR_IN;
- break;
- case CAM_DIR_OUT:
- dir = DIR_OUT;
- break;
- default:
- dir = DIR_NONE;
- }
-
- ccb->ccb_h.status = CAM_REQ_INPROG | CAM_SIM_QUEUED;
-
-
- if (csio->ccb_h.flags & CAM_CDB_POINTER) {
- cmd = (unsigned char *) csio->cdb_io.cdb_ptr;
- } else {
- cmd = (unsigned char *) &csio->cdb_io.cdb_bytes;
- }
- cmdlen = csio->cdb_len;
- rcmd = (unsigned char *) &sc->cam_scsi_command;
- rcmdlen = sizeof(sc->cam_scsi_command);
-
- /* sc->transform will convert the command to the command
- * (format) needed by the specific command set and return
- * the converted command in a buffer pointed to be rcmd.
- * We pass in a buffer, but if the command does not
- * have to be transformed it returns a ptr to the original
- * buffer (see umass_scsi_transform).
- */
-
- switch (sc->transform(sc, cmd, cmdlen, &rcmd, &rcmdlen)) {
- case 1:
- /*
- * Handle EVPD inquiry for broken devices first
- * NO_INQUIRY also implies NO_INQUIRY_EVPD
- */
- if ((sc->quirks & (NO_INQUIRY_EVPD | NO_INQUIRY)) &&
- rcmd[0] == INQUIRY && (rcmd[1] & SI_EVPD)) {
- struct scsi_sense_data *sense;
-
- sense = &ccb->csio.sense_data;
- bzero(sense, sizeof(*sense));
- sense->error_code = SSD_CURRENT_ERROR;
- sense->flags = SSD_KEY_ILLEGAL_REQUEST;
- sense->add_sense_code = 0x24;
- sense->extra_len = 10;
- ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
- ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR |
- CAM_AUTOSNS_VALID;
- xpt_done(ccb);
- return;
- }
- /* Return fake inquiry data for broken devices */
- if ((sc->quirks & NO_INQUIRY) && rcmd[0] == INQUIRY) {
- struct ccb_scsiio *csio = &ccb->csio;
-
- memcpy(csio->data_ptr, &fake_inq_data,
- sizeof(fake_inq_data));
- csio->scsi_status = SCSI_STATUS_OK;
- ccb->ccb_h.status = CAM_REQ_CMP;
- xpt_done(ccb);
- return;
- }
- if ((sc->quirks & NO_SYNCHRONIZE_CACHE) &&
- rcmd[0] == SYNCHRONIZE_CACHE) {
- struct ccb_scsiio *csio = &ccb->csio;
-
- csio->scsi_status = SCSI_STATUS_OK;
- ccb->ccb_h.status = CAM_REQ_CMP;
- xpt_done(ccb);
- return;
- }
- if ((sc->quirks & FORCE_SHORT_INQUIRY) &&
- rcmd[0] == INQUIRY) {
- csio->dxfer_len = SHORT_INQUIRY_LENGTH;
- }
- sc->transfer(sc, ccb->ccb_h.target_lun, rcmd, rcmdlen,
- csio->data_ptr,
- csio->dxfer_len, dir, ccb->ccb_h.timeout,
- umass_cam_cb, (void *) ccb);
- break;
- case 0:
- ccb->ccb_h.status = CAM_REQ_INVALID;
- xpt_done(ccb);
- break;
- case 2:
- ccb->ccb_h.status = CAM_REQ_CMP;
- xpt_done(ccb);
- break;
- }
-
- break;
- }
- case XPT_PATH_INQ:
- {
- struct ccb_pathinq *cpi = &ccb->cpi;
-
- DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d:XPT_PATH_INQ:.\n",
- (sc == NULL? DEVNAME_SIM:device_get_nameunit(sc->sc_dev)),
- cam_sim_path(sc->umass_sim),
- ccb->ccb_h.target_id, ccb->ccb_h.target_lun));
-
- /* host specific information */
- cpi->version_num = 1;
- cpi->hba_inquiry = 0;
- cpi->target_sprt = 0;
- cpi->hba_misc = PIM_NO_6_BYTE;
- cpi->hba_eng_cnt = 0;
- cpi->max_target = UMASS_SCSIID_MAX; /* one target */
- cpi->initiator_id = UMASS_SCSIID_HOST;
- strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
- strncpy(cpi->hba_vid, "USB SCSI", HBA_IDLEN);
- strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
- cpi->unit_number = cam_sim_unit(sim);
- cpi->bus_id = device_get_unit(sc->sc_dev);
- cpi->protocol = PROTO_SCSI;
- cpi->protocol_version = SCSI_REV_2;
- cpi->transport = XPORT_USB;
- cpi->transport_version = 0;
-
- if (sc == NULL) {
- cpi->base_transfer_speed = 0;
- cpi->max_lun = 0;
- } else {
- if (sc->quirks & FLOPPY_SPEED) {
- cpi->base_transfer_speed =
- UMASS_FLOPPY_TRANSFER_SPEED;
- } else if (usbd_get_speed(sc->sc_udev) ==
- USB_SPEED_HIGH) {
- cpi->base_transfer_speed =
- UMASS_HIGH_TRANSFER_SPEED;
- } else {
- cpi->base_transfer_speed =
- UMASS_FULL_TRANSFER_SPEED;
- }
- cpi->max_lun = sc->maxlun;
- }
-
- cpi->ccb_h.status = CAM_REQ_CMP;
- xpt_done(ccb);
- break;
- }
- case XPT_RESET_DEV:
- {
- DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d:XPT_RESET_DEV:.\n",
- device_get_nameunit(sc->sc_dev), cam_sim_path(sc->umass_sim),
- ccb->ccb_h.target_id, ccb->ccb_h.target_lun));
-
- ccb->ccb_h.status = CAM_REQ_INPROG;
- umass_reset(sc, umass_cam_cb, (void *) ccb);
- break;
- }
- case XPT_GET_TRAN_SETTINGS:
- {
- struct ccb_trans_settings *cts = &ccb->cts;
- cts->protocol = PROTO_SCSI;
- cts->protocol_version = SCSI_REV_2;
- cts->transport = XPORT_USB;
- cts->transport_version = 0;
- cts->xport_specific.valid = 0;
-
-
- ccb->ccb_h.status = CAM_REQ_CMP;
- xpt_done(ccb);
- break;
- }
- case XPT_SET_TRAN_SETTINGS:
- {
- DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d:XPT_SET_TRAN_SETTINGS:.\n",
- device_get_nameunit(sc->sc_dev), cam_sim_path(sc->umass_sim),
- ccb->ccb_h.target_id, ccb->ccb_h.target_lun));
-
- ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
- xpt_done(ccb);
- break;
- }
- case XPT_CALC_GEOMETRY:
- {
- cam_calc_geometry(&ccb->ccg, /*extended*/1);
- xpt_done(ccb);
- break;
- }
- case XPT_NOOP:
- {
- DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d:XPT_NOOP:.\n",
- (sc == NULL? DEVNAME_SIM:device_get_nameunit(sc->sc_dev)),
- cam_sim_path(sc->umass_sim),
- ccb->ccb_h.target_id, ccb->ccb_h.target_lun));
-
- ccb->ccb_h.status = CAM_REQ_CMP;
- xpt_done(ccb);
- break;
- }
- default:
- DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d:func_code 0x%04x: "
- "Not implemented\n",
- (sc == NULL? DEVNAME_SIM:device_get_nameunit(sc->sc_dev)),
- cam_sim_path(sc->umass_sim),
- ccb->ccb_h.target_id, ccb->ccb_h.target_lun,
- ccb->ccb_h.func_code));
-
- ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
- xpt_done(ccb);
- break;
- }
-}
-
-static void
-umass_cam_poll(struct cam_sim *sim)
-{
- struct umass_softc *sc = (struct umass_softc *) sim->softc;
-
- DPRINTF(UDMASS_SCSI, ("%s: CAM poll\n",
- device_get_nameunit(sc->sc_dev)));
-
- usbd_set_polling(sc->sc_udev, 1);
- usbd_dopoll(sc->iface);
- usbd_set_polling(sc->sc_udev, 0);
-}
-
-
-/* umass_cam_cb
- * finalise a completed CAM command
- */
-
-static void
-umass_cam_cb(struct umass_softc *sc, void *priv, int residue, int status)
-{
- union ccb *ccb = (union ccb *) priv;
- struct ccb_scsiio *csio = &ccb->csio; /* deref union */
-
- /* If the device is gone, just fail the request. */
- if (sc->flags & UMASS_FLAGS_GONE) {
- ccb->ccb_h.status = CAM_TID_INVALID;
- xpt_done(ccb);
- return;
- }
-
- csio->resid = residue;
-
- switch (status) {
- case STATUS_CMD_OK:
- ccb->ccb_h.status = CAM_REQ_CMP;
- if ((sc->quirks & READ_CAPACITY_OFFBY1) &&
- (ccb->ccb_h.func_code == XPT_SCSI_IO) &&
- (csio->cdb_io.cdb_bytes[0] == READ_CAPACITY)) {
- struct scsi_read_capacity_data *rcap;
- uint32_t maxsector;
-
- rcap = (struct scsi_read_capacity_data *)csio->data_ptr;
- maxsector = scsi_4btoul(rcap->addr) - 1;
- scsi_ulto4b(maxsector, rcap->addr);
- }
- xpt_done(ccb);
- break;
-
- case STATUS_CMD_UNKNOWN:
- case STATUS_CMD_FAILED:
- switch (ccb->ccb_h.func_code) {
- case XPT_SCSI_IO:
- {
- unsigned char *rcmd;
- int rcmdlen;
-
- /* fetch sense data */
- /* the rest of the command was filled in at attach */
- sc->cam_scsi_sense.length = csio->sense_len;
-
- DPRINTF(UDMASS_SCSI,("%s: Fetching %db sense data\n",
- device_get_nameunit(sc->sc_dev), csio->sense_len));
-
- rcmd = (unsigned char *) &sc->cam_scsi_command;
- rcmdlen = sizeof(sc->cam_scsi_command);
-
- if (sc->transform(sc,
- (unsigned char *) &sc->cam_scsi_sense,
- sizeof(sc->cam_scsi_sense),
- &rcmd, &rcmdlen) == 1) {
- if ((sc->quirks & FORCE_SHORT_INQUIRY) && (rcmd[0] == INQUIRY)) {
- csio->sense_len = SHORT_INQUIRY_LENGTH;
- }
- sc->transfer(sc, ccb->ccb_h.target_lun,
- rcmd, rcmdlen,
- &csio->sense_data,
- csio->sense_len, DIR_IN, ccb->ccb_h.timeout,
- umass_cam_sense_cb, (void *) ccb);
- } else {
- panic("transform(REQUEST_SENSE) failed");
- }
- break;
- }
- case XPT_RESET_DEV: /* Reset failed */
- ccb->ccb_h.status = CAM_REQ_CMP_ERR;
- xpt_done(ccb);
- break;
- default:
- panic("umass_cam_cb called for func_code %d",
- ccb->ccb_h.func_code);
- }
- break;
-
- case STATUS_WIRE_FAILED:
- /* the wire protocol failed and will have recovered
- * (hopefully). We return an error to CAM and let CAM retry
- * the command if necessary.
- */
- ccb->ccb_h.status = CAM_REQ_CMP_ERR;
- xpt_done(ccb);
- break;
- default:
- panic("%s: Unknown status %d in umass_cam_cb",
- device_get_nameunit(sc->sc_dev), status);
- }
-}
-
-/* Finalise a completed autosense operation
- */
-static void
-umass_cam_sense_cb(struct umass_softc *sc, void *priv, int residue, int status)
-{
- union ccb *ccb = (union ccb *) priv;
- struct ccb_scsiio *csio = &ccb->csio; /* deref union */
- unsigned char *rcmd;
- int rcmdlen;
-
- if (sc->flags & UMASS_FLAGS_GONE) {
- ccb->ccb_h.status = CAM_AUTOSENSE_FAIL;
- xpt_done(ccb);
- return;
- }
-
- switch (status) {
- case STATUS_CMD_OK:
- case STATUS_CMD_UNKNOWN:
- case STATUS_CMD_FAILED:
- /* Getting sense data always succeeds (apart from wire
- * failures).
- */
- if ((sc->quirks & RS_NO_CLEAR_UA)
- && csio->cdb_io.cdb_bytes[0] == INQUIRY
- && (csio->sense_data.flags & SSD_KEY)
- == SSD_KEY_UNIT_ATTENTION) {
- /* Ignore unit attention errors in the case where
- * the Unit Attention state is not cleared on
- * REQUEST SENSE. They will appear again at the next
- * command.
- */
- ccb->ccb_h.status = CAM_REQ_CMP;
- } else if ((csio->sense_data.flags & SSD_KEY)
- == SSD_KEY_NO_SENSE) {
- /* No problem after all (in the case of CBI without
- * CCI)
- */
- ccb->ccb_h.status = CAM_REQ_CMP;
- } else if ((sc->quirks & RS_NO_CLEAR_UA) &&
- (csio->cdb_io.cdb_bytes[0] == READ_CAPACITY) &&
- ((csio->sense_data.flags & SSD_KEY)
- == SSD_KEY_UNIT_ATTENTION)) {
- /*
- * Some devices do not clear the unit attention error
- * on request sense. We insert a test unit ready
- * command to make sure we clear the unit attention
- * condition, then allow the retry to proceed as
- * usual.
- */
-
- ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR
- | CAM_AUTOSNS_VALID;
- csio->scsi_status = SCSI_STATUS_CHECK_COND;
-
-#if 0
- DELAY(300000);
-#endif
-
- DPRINTF(UDMASS_SCSI,("%s: Doing a sneaky"
- "TEST_UNIT_READY\n",
- device_get_nameunit(sc->sc_dev)));
-
- /* the rest of the command was filled in at attach */
-
- rcmd = (unsigned char *) &sc->cam_scsi_command2;
- rcmdlen = sizeof(sc->cam_scsi_command2);
-
- if (sc->transform(sc,
- (unsigned char *)
- &sc->cam_scsi_test_unit_ready,
- sizeof(sc->cam_scsi_test_unit_ready),
- &rcmd, &rcmdlen) == 1) {
- sc->transfer(sc, ccb->ccb_h.target_lun,
- rcmd, rcmdlen,
- NULL, 0, DIR_NONE, ccb->ccb_h.timeout,
- umass_cam_quirk_cb, (void *) ccb);
- } else {
- panic("transform(TEST_UNIT_READY) failed");
- }
- break;
- } else {
- ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR
- | CAM_AUTOSNS_VALID;
- csio->scsi_status = SCSI_STATUS_CHECK_COND;
- }
- xpt_done(ccb);
- break;
-
- default:
- DPRINTF(UDMASS_SCSI, ("%s: Autosense failed, status %d\n",
- device_get_nameunit(sc->sc_dev), status));
- ccb->ccb_h.status = CAM_AUTOSENSE_FAIL;
- xpt_done(ccb);
- }
-}
-
-/*
- * This completion code just handles the fact that we sent a test-unit-ready
- * after having previously failed a READ CAPACITY with CHECK_COND. Even
- * though this command succeeded, we have to tell CAM to retry.
- */
-static void
-umass_cam_quirk_cb(struct umass_softc *sc, void *priv, int residue, int status)
-{
- union ccb *ccb = (union ccb *) priv;
-
- DPRINTF(UDMASS_SCSI, ("%s: Test unit ready returned status %d\n",
- device_get_nameunit(sc->sc_dev), status));
-
- if (sc->flags & UMASS_FLAGS_GONE) {
- ccb->ccb_h.status = CAM_TID_INVALID;
- xpt_done(ccb);
- return;
- }
-#if 0
- ccb->ccb_h.status = CAM_REQ_CMP;
-#endif
- ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR
- | CAM_AUTOSNS_VALID;
- ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
- xpt_done(ccb);
-}
-
-/*
- * SCSI specific functions
- */
-
-static int
-umass_scsi_transform(struct umass_softc *sc, unsigned char *cmd, int cmdlen,
- unsigned char **rcmd, int *rcmdlen)
-{
- switch (cmd[0]) {
- case TEST_UNIT_READY:
- if (sc->quirks & NO_TEST_UNIT_READY) {
- KASSERT(*rcmdlen >= sizeof(struct scsi_start_stop_unit),
- ("rcmdlen = %d < %ld, buffer too small",
- *rcmdlen,
- (long)sizeof(struct scsi_start_stop_unit)));
- DPRINTF(UDMASS_SCSI, ("%s: Converted TEST_UNIT_READY "
- "to START_UNIT\n", device_get_nameunit(sc->sc_dev)));
- memset(*rcmd, 0, *rcmdlen);
- (*rcmd)[0] = START_STOP_UNIT;
- (*rcmd)[4] = SSS_START;
- return 1;
- }
- /* fallthrough */
- case INQUIRY:
- /* some drives wedge when asked for full inquiry information. */
- if (sc->quirks & FORCE_SHORT_INQUIRY) {
- memcpy(*rcmd, cmd, cmdlen);
- *rcmdlen = cmdlen;
- (*rcmd)[4] = SHORT_INQUIRY_LENGTH;
- return 1;
- }
- /* fallthrough */
- default:
- *rcmd = cmd; /* We don't need to copy it */
- *rcmdlen = cmdlen;
- }
-
- return 1;
-}
-/* RBC specific functions */
-static int
-umass_rbc_transform(struct umass_softc *sc, unsigned char *cmd, int cmdlen,
- unsigned char **rcmd, int *rcmdlen)
-{
- switch (cmd[0]) {
- /* these commands are defined in RBC: */
- case READ_10:
- case READ_CAPACITY:
- case START_STOP_UNIT:
- case SYNCHRONIZE_CACHE:
- case WRITE_10:
- case 0x2f: /* VERIFY_10 is absent from scsi_all.h??? */
- case INQUIRY:
- case MODE_SELECT_10:
- case MODE_SENSE_10:
- case TEST_UNIT_READY:
- case WRITE_BUFFER:
- /* The following commands are not listed in my copy of the RBC specs.
- * CAM however seems to want those, and at least the Sony DSC device
- * appears to support those as well */
- case REQUEST_SENSE:
- case PREVENT_ALLOW:
- if ((sc->quirks & RBC_PAD_TO_12) && cmdlen < 12) {
- *rcmdlen = 12;
- bcopy(cmd, *rcmd, cmdlen);
- bzero(*rcmd + cmdlen, 12 - cmdlen);
- } else {
- *rcmd = cmd; /* We don't need to copy it */
- *rcmdlen = cmdlen;
- }
- return 1;
- /* All other commands are not legal in RBC */
- default:
- printf("%s: Unsupported RBC command 0x%02x",
- device_get_nameunit(sc->sc_dev), cmd[0]);
- printf("\n");
- return 0; /* failure */
- }
-}
-
-/*
- * UFI specific functions
- */
-static int
-umass_ufi_transform(struct umass_softc *sc, unsigned char *cmd, int cmdlen,
- unsigned char **rcmd, int *rcmdlen)
-{
- /* A UFI command is always 12 bytes in length */
- KASSERT(*rcmdlen >= UFI_COMMAND_LENGTH,
- ("rcmdlen = %d < %d, buffer too small",
- *rcmdlen, UFI_COMMAND_LENGTH));
-
- *rcmdlen = UFI_COMMAND_LENGTH;
- memset(*rcmd, 0, UFI_COMMAND_LENGTH);
-
- switch (cmd[0]) {
- /* Commands of which the format has been verified. They should work.
- * Copy the command into the (zeroed out) destination buffer.
- */
- case TEST_UNIT_READY:
- if (sc->quirks & NO_TEST_UNIT_READY) {
- /* Some devices do not support this command.
- * Start Stop Unit should give the same results
- */
- DPRINTF(UDMASS_UFI, ("%s: Converted TEST_UNIT_READY "
- "to START_UNIT\n", device_get_nameunit(sc->sc_dev)));
- (*rcmd)[0] = START_STOP_UNIT;
- (*rcmd)[4] = SSS_START;
- } else {
- memcpy(*rcmd, cmd, cmdlen);
- }
- return 1;
-
- case REZERO_UNIT:
- case REQUEST_SENSE:
- case FORMAT_UNIT:
- case INQUIRY:
- case START_STOP_UNIT:
- case SEND_DIAGNOSTIC:
- case PREVENT_ALLOW:
- case READ_CAPACITY:
- case READ_10:
- case WRITE_10:
- case POSITION_TO_ELEMENT: /* SEEK_10 */
- case WRITE_AND_VERIFY:
- case VERIFY:
- case MODE_SELECT_10:
- case MODE_SENSE_10:
- case READ_12:
- case WRITE_12:
- case READ_FORMAT_CAPACITIES:
- memcpy(*rcmd, cmd, cmdlen);
- return 1;
-
- /*
- * SYNCHRONIZE_CACHE isn't supported by UFI, nor should it be
- * required for UFI devices, so it is appropriate to fake
- * success.
- */
- case SYNCHRONIZE_CACHE:
- return 2;
-
- default:
- printf("%s: Unsupported UFI command 0x%02x\n",
- device_get_nameunit(sc->sc_dev), cmd[0]);
- return 0; /* failure */
- }
-}
-
-/*
- * 8070i (ATAPI) specific functions
- */
-static int
-umass_atapi_transform(struct umass_softc *sc, unsigned char *cmd, int cmdlen,
- unsigned char **rcmd, int *rcmdlen)
-{
- /* An ATAPI command is always 12 bytes in length. */
- KASSERT(*rcmdlen >= ATAPI_COMMAND_LENGTH,
- ("rcmdlen = %d < %d, buffer too small",
- *rcmdlen, ATAPI_COMMAND_LENGTH));
-
- *rcmdlen = ATAPI_COMMAND_LENGTH;
- memset(*rcmd, 0, ATAPI_COMMAND_LENGTH);
-
- switch (cmd[0]) {
- /* Commands of which the format has been verified. They should work.
- * Copy the command into the (zeroed out) destination buffer.
- */
- case INQUIRY:
- memcpy(*rcmd, cmd, cmdlen);
- /* some drives wedge when asked for full inquiry information. */
- if (sc->quirks & FORCE_SHORT_INQUIRY)
- (*rcmd)[4] = SHORT_INQUIRY_LENGTH;
- return 1;
-
- case TEST_UNIT_READY:
- if (sc->quirks & NO_TEST_UNIT_READY) {
- KASSERT(*rcmdlen >= sizeof(struct scsi_start_stop_unit),
- ("rcmdlen = %d < %ld, buffer too small",
- *rcmdlen,
- (long)sizeof(struct scsi_start_stop_unit)));
- DPRINTF(UDMASS_SCSI, ("%s: Converted TEST_UNIT_READY "
- "to START_UNIT\n", device_get_nameunit(sc->sc_dev)));
- memset(*rcmd, 0, *rcmdlen);
- (*rcmd)[0] = START_STOP_UNIT;
- (*rcmd)[4] = SSS_START;
- return 1;
- }
- /* fallthrough */
- case REZERO_UNIT:
- case REQUEST_SENSE:
- case START_STOP_UNIT:
- case SEND_DIAGNOSTIC:
- case PREVENT_ALLOW:
- case READ_CAPACITY:
- case READ_10:
- case WRITE_10:
- case POSITION_TO_ELEMENT: /* SEEK_10 */
- case SYNCHRONIZE_CACHE:
- case MODE_SELECT_10:
- case MODE_SENSE_10:
- case READ_BUFFER:
- case 0x42: /* READ_SUBCHANNEL */
- case 0x43: /* READ_TOC */
- case 0x44: /* READ_HEADER */
- case 0x47: /* PLAY_MSF (Play Minute/Second/Frame) */
- case 0x48: /* PLAY_TRACK */
- case 0x49: /* PLAY_TRACK_REL */
- case 0x4b: /* PAUSE */
- case 0x51: /* READ_DISK_INFO */
- case 0x52: /* READ_TRACK_INFO */
- case 0x54: /* SEND_OPC */
- case 0x59: /* READ_MASTER_CUE */
- case 0x5b: /* CLOSE_TR_SESSION */
- case 0x5c: /* READ_BUFFER_CAP */
- case 0x5d: /* SEND_CUE_SHEET */
- case 0xa1: /* BLANK */
- case 0xa5: /* PLAY_12 */
- case 0xa6: /* EXCHANGE_MEDIUM */
- case 0xad: /* READ_DVD_STRUCTURE */
- case 0xbb: /* SET_CD_SPEED */
- case 0xe5: /* READ_TRACK_INFO_PHILIPS */
- memcpy(*rcmd, cmd, cmdlen);
- return 1;
-
- case READ_12:
- case WRITE_12:
- default:
- printf("%s: Unsupported ATAPI command 0x%02x"
- " - trying anyway\n",
- device_get_nameunit(sc->sc_dev), cmd[0]);
- memcpy(*rcmd, cmd, cmdlen);
- return 1;
- }
-}
-
-
-/* (even the comment is missing) */
-
-DRIVER_MODULE(umass, uhub, umass_driver, umass_devclass, usbd_driver_load, 0);
-
-
-
-#ifdef USB_DEBUG
-static void
-umass_bbb_dump_cbw(struct umass_softc *sc, umass_bbb_cbw_t *cbw)
-{
- int clen = cbw->bCDBLength;
- int dlen = UGETDW(cbw->dCBWDataTransferLength);
- u_int8_t *c = cbw->CBWCDB;
- int tag = UGETDW(cbw->dCBWTag);
- int flags = cbw->bCBWFlags;
-
- DPRINTF(UDMASS_BBB, ("%s: CBW %d: cmd = %db "
- "(0x%02x%02x%02x%02x%02x%02x%s), "
- "data = %db, dir = %s\n",
- device_get_nameunit(sc->sc_dev), tag, clen,
- c[0], c[1], c[2], c[3], c[4], c[5], (clen > 6? "...":""),
- dlen, (flags == CBWFLAGS_IN? "in":
- (flags == CBWFLAGS_OUT? "out":"<invalid>"))));
-}
-
-static void
-umass_bbb_dump_csw(struct umass_softc *sc, umass_bbb_csw_t *csw)
-{
- int sig = UGETDW(csw->dCSWSignature);
- int tag = UGETW(csw->dCSWTag);
- int res = UGETDW(csw->dCSWDataResidue);
- int status = csw->bCSWStatus;
-
- DPRINTF(UDMASS_BBB, ("%s: CSW %d: sig = 0x%08x (%s), tag = %d, "
- "res = %d, status = 0x%02x (%s)\n", device_get_nameunit(sc->sc_dev),
- tag, sig, (sig == CSWSIGNATURE? "valid":"invalid"),
- tag, res,
- status, (status == CSWSTATUS_GOOD? "good":
- (status == CSWSTATUS_FAILED? "failed":
- (status == CSWSTATUS_PHASE? "phase":"<invalid>")))));
-}
-
-static void
-umass_cbi_dump_cmd(struct umass_softc *sc, void *cmd, int cmdlen)
-{
- u_int8_t *c = cmd;
- int dir = sc->transfer_dir;
-
- DPRINTF(UDMASS_BBB, ("%s: cmd = %db "
- "(0x%02x%02x%02x%02x%02x%02x%s), "
- "data = %db, dir = %s\n",
- device_get_nameunit(sc->sc_dev), cmdlen,
- c[0], c[1], c[2], c[3], c[4], c[5], (cmdlen > 6? "...":""),
- sc->transfer_datalen,
- (dir == DIR_IN? "in":
- (dir == DIR_OUT? "out":
- (dir == DIR_NONE? "no data phase": "<invalid>")))));
-}
-
-static void
-umass_dump_buffer(struct umass_softc *sc, u_int8_t *buffer, int buflen,
- int printlen)
-{
- int i, j;
- char s1[40];
- char s2[40];
- char s3[5];
-
- s1[0] = '\0';
- s3[0] = '\0';
-
- sprintf(s2, " buffer=%p, buflen=%d", buffer, buflen);
- for (i = 0; i < buflen && i < printlen; i++) {
- j = i % 16;
- if (j == 0 && i != 0) {
- DPRINTF(UDMASS_GEN, ("%s: 0x %s%s\n",
- device_get_nameunit(sc->sc_dev), s1, s2));
- s2[0] = '\0';
- }
- sprintf(&s1[j*2], "%02x", buffer[i] & 0xff);
- }
- if (buflen > printlen)
- sprintf(s3, " ...");
- DPRINTF(UDMASS_GEN, ("%s: 0x %s%s%s\n",
- device_get_nameunit(sc->sc_dev), s1, s2, s3));
-}
-#endif
diff --git a/sys/dev/usb/umct.c b/sys/dev/usb/umct.c
deleted file mode 100644
index 63de146..0000000
--- a/sys/dev/usb/umct.c
+++ /dev/null
@@ -1,511 +0,0 @@
-/*-
- * Copyright (c) 2003 Scott Long
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * Driver for the MCT (Magic Control Technology) USB-RS232 Converter.
- * Based on the superb documentation from the linux mct_u232 driver by
- * Wolfgang Grandeggar <wolfgang@cec.ch>.
- * This device smells a lot like the Belkin F5U103, except that it has
- * suffered some mild brain-damage. This driver is based off of the ubsa.c
- * driver from Alexander Kabaev <kan@freebsd.org>. Merging the two together
- * might be useful, though the subtle differences might lead to lots of
- * #ifdef's.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/tty.h>
-#include <sys/taskqueue.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include "usbdevs.h"
-#include <dev/usb/ucomvar.h>
-
-/* The UMCT advertises the standard 8250 UART registers */
-#define UMCT_GET_MSR 2 /* Get Modem Status Register */
-#define UMCT_GET_MSR_SIZE 1
-#define UMCT_GET_LCR 6 /* Get Line Control Register */
-#define UMCT_GET_LCR_SIZE 1
-#define UMCT_SET_BAUD 5 /* Set the Baud Rate Divisor */
-#define UMCT_SET_BAUD_SIZE 4
-#define UMCT_SET_LCR 7 /* Set Line Control Register */
-#define UMCT_SET_LCR_SIZE 1
-#define UMCT_SET_MCR 10 /* Set Modem Control Register */
-#define UMCT_SET_MCR_SIZE 1
-
-#define UMCT_INTR_INTERVAL 100
-#define UMCT_IFACE_INDEX 0
-#define UMCT_CONFIG_INDEX 1
-
-struct umct_softc {
- struct ucom_softc sc_ucom;
- int sc_iface_number;
- usbd_interface_handle sc_intr_iface;
- int sc_intr_number;
- usbd_pipe_handle sc_intr_pipe;
- u_char *sc_intr_buf;
- int sc_isize;
- uint8_t sc_lsr;
- uint8_t sc_msr;
- uint8_t sc_lcr;
- uint8_t sc_mcr;
- struct task sc_task;
-};
-
-static void umct_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
-static void umct_get_status(void *, int, u_char *, u_char *);
-static void umct_set(void *, int, int, int);
-static int umct_param(void *, int, struct termios *);
-static int umct_open(void *, int);
-static void umct_close(void *, int);
-static void umct_notify(void *, int count);
-
-static struct ucom_callback umct_callback = {
- umct_get_status, /* ucom_get_status */
- umct_set, /* ucom_set */
- umct_param, /* ucom_param */
- NULL, /* ucom_ioctl */
- umct_open, /* ucom_open */
- umct_close, /* ucom_close */
- NULL, /* ucom_read */
- NULL /* ucom_write */
-};
-
-static const struct umct_product {
- uint16_t vendor;
- uint16_t product;
-} umct_products[] = {
- { USB_VENDOR_MCT, USB_PRODUCT_MCT_USB232 },
- { USB_VENDOR_MCT, USB_PRODUCT_MCT_SITECOM_USB232 },
- { USB_VENDOR_MCT, USB_PRODUCT_MCT_DU_H3SP_USB232 },
- { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5U109 },
- { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5U409 },
- { 0, 0 }
-};
-
-static device_probe_t umct_match;
-static device_attach_t umct_attach;
-static device_detach_t umct_detach;
-
-static device_method_t umct_methods[] = {
- DEVMETHOD(device_probe, umct_match),
- DEVMETHOD(device_attach, umct_attach),
- DEVMETHOD(device_detach, umct_detach),
- { 0, 0 }
-};
-
-static driver_t umct_driver = {
- "ucom",
- umct_methods,
- sizeof(struct umct_softc)
-};
-
-DRIVER_MODULE(umct, uhub, umct_driver, ucom_devclass, usbd_driver_load, 0);
-MODULE_DEPEND(umct, usb, 1, 1, 1);
-MODULE_DEPEND(umct, ucom, UCOM_MINVER, UCOM_PREFVER, UCOM_MAXVER);
-MODULE_VERSION(umct, 1);
-
-static int
-umct_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
- int i;
-
- if (uaa->iface != NULL)
- return (UMATCH_NONE);
-
- for (i = 0; umct_products[i].vendor != 0; i++) {
- if (umct_products[i].vendor == uaa->vendor &&
- umct_products[i].product == uaa->product) {
- return (UMATCH_VENDOR_PRODUCT);
- }
- }
-
- return (UMATCH_NONE);
-}
-
-static int
-umct_attach(device_t self)
-{
- struct umct_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usbd_device_handle dev;
- struct ucom_softc *ucom;
- usb_config_descriptor_t *cdesc;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
- const char *devname;
- usbd_status err;
- int i;
-
- dev = uaa->device;
- bzero(sc, sizeof(struct umct_softc));
- ucom = &sc->sc_ucom;
- ucom->sc_dev = self;
- ucom->sc_udev = dev;
- ucom->sc_iface = uaa->iface;
-
- ucom->sc_bulkout_no = -1;
- ucom->sc_bulkin_no = -1;
- sc->sc_intr_number = -1;
- sc->sc_intr_pipe = NULL;
-
- devname = device_get_nameunit(ucom->sc_dev);
-
- err = usbd_set_config_index(dev, UMCT_CONFIG_INDEX, 1);
- if (err) {
- printf("%s: failed to set configuration: %s\n",
- devname, usbd_errstr(err));
- ucom->sc_dying = 1;
- goto error;
- }
-
- cdesc = usbd_get_config_descriptor(ucom->sc_udev);
- if (cdesc == NULL) {
- printf("%s: failed to get configuration descriptor\n", devname);
- ucom->sc_dying = 1;
- goto error;
- }
-
- err = usbd_device2interface_handle(dev, UMCT_IFACE_INDEX,
- &ucom->sc_iface);
- if (err) {
- printf("%s: failed to get interface: %s\n", devname,
- usbd_errstr(err));
- ucom->sc_dying = 1;
- goto error;
- }
-
- id = usbd_get_interface_descriptor(ucom->sc_iface);
- sc->sc_iface_number = id->bInterfaceNumber;
-
- for (i = 0; i < id->bNumEndpoints; i++) {
- ed = usbd_interface2endpoint_descriptor(ucom->sc_iface, i);
- if (ed == NULL) {
- printf("%s: no endpoint descriptor for %d\n",
- devname, i);
- ucom->sc_dying = 1;
- goto error;
- }
-
- /*
- * The real bulk-in endpoint is also marked as an interrupt.
- * The only way to differentiate it from the real interrupt
- * endpoint is to look at the wMaxPacketSize field.
- */
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN) {
- if (UGETW(ed->wMaxPacketSize) == 0x2) {
- sc->sc_intr_number = ed->bEndpointAddress;
- sc->sc_isize = UGETW(ed->wMaxPacketSize);
- } else {
- ucom->sc_bulkin_no = ed->bEndpointAddress;
- ucom->sc_ibufsize = UGETW(ed->wMaxPacketSize);
- }
- continue;
- }
-
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT) {
- ucom->sc_bulkout_no = ed->bEndpointAddress;
- if (uaa->product == USB_PRODUCT_MCT_SITECOM_USB232)
- ucom->sc_obufsize = 16; /* device is broken */
- else
- ucom->sc_obufsize = UGETW(ed->wMaxPacketSize);
- continue;
- }
-
- printf("%s: warning - unsupported endpoint 0x%x\n", devname,
- ed->bEndpointAddress);
- }
-
- if (sc->sc_intr_number == -1) {
- printf("%s: Could not find interrupt in\n", devname);
- ucom->sc_dying = 1;
- goto error;
- }
-
- sc->sc_intr_iface = ucom->sc_iface;
-
- if (ucom->sc_bulkout_no == -1) {
- printf("%s: Could not find data bulk out\n", devname);
- ucom->sc_dying = 1;
- goto error;
- }
-
- ucom->sc_parent = sc;
- ucom->sc_portno = UCOM_UNK_PORTNO;
- ucom->sc_opkthdrlen = 0;
- ucom->sc_callback = &umct_callback;
- ucom_attach(ucom);
- TASK_INIT(&sc->sc_task, 0, umct_notify, sc);
- return 0;
-
-error:
- return ENXIO;
-}
-
-static int
-umct_detach(device_t self)
-{
- struct umct_softc *sc = device_get_softc(self);
-
- int rv;
-
- if (sc->sc_intr_pipe != NULL) {
- usbd_abort_pipe(sc->sc_intr_pipe);
- usbd_close_pipe(sc->sc_intr_pipe);
- free(sc->sc_intr_buf, M_USBDEV);
- sc->sc_intr_pipe = NULL;
- }
-
- sc->sc_ucom.sc_dying = 1;
-#if 0
- taskqueue_drain(taskqueue_swi_giant);
-#endif
- rv = ucom_detach(&sc->sc_ucom);
- return (rv);
-}
-
-static int
-umct_request(struct umct_softc *sc, uint8_t request, int len, uint32_t value)
-{
- usb_device_request_t req;
- usbd_status err;
- uint8_t oval[4];
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = request;
- USETW(req.wValue, 0);
- USETW(req.wIndex, sc->sc_iface_number);
- USETW(req.wLength, len);
- USETDW(oval, value);
-
- err = usbd_do_request(sc->sc_ucom.sc_udev, &req, oval);
- if (err)
- printf("%s: umct_request: %s\n",
- device_get_nameunit(sc->sc_ucom.sc_dev), usbd_errstr(err));
- return (err);
-}
-
-static void
-umct_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- struct umct_softc *sc;
- u_char *buf;
-
- sc = (struct umct_softc *)priv;
- buf = sc->sc_intr_buf;
- if (sc->sc_ucom.sc_dying)
- return;
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
- return;
-
- usbd_clear_endpoint_stall_async(sc->sc_intr_pipe);
- return;
- }
-
- sc->sc_msr = buf[0];
- sc->sc_lsr = buf[1];
-
- /*
- * Defer notifying the ucom layer as it doesn't like to be bothered
- * from an interrupt context.
- */
- taskqueue_enqueue(taskqueue_swi_giant, &sc->sc_task);
-}
-
-static void
-umct_notify(void *arg, int count)
-{
- struct umct_softc *sc;
-
- sc = (struct umct_softc *)arg;
- if (sc->sc_ucom.sc_dying == 0)
- ucom_status_change(&sc->sc_ucom);
-}
-
-static void
-umct_get_status(void *addr, int portno, u_char *lsr, u_char *msr)
-{
- struct umct_softc *sc;
-
- sc = addr;
- if (lsr != NULL)
- *lsr = sc->sc_lsr;
- if (msr != NULL)
- *msr = sc->sc_msr;
-
- return;
-}
-
-static void
-umct_set(void *addr, int portno, int reg, int onoff)
-{
- struct umct_softc *sc;
-
- sc = addr;
- switch (reg) {
- case UCOM_SET_BREAK:
- sc->sc_lcr &= ~0x40;
- sc->sc_lcr |= (onoff) ? 0x40 : 0;
- umct_request(sc, UMCT_SET_LCR, UMCT_SET_LCR_SIZE, sc->sc_lcr);
- break;
- case UCOM_SET_DTR:
- sc->sc_mcr &= ~0x01;
- sc->sc_mcr |= (onoff) ? 0x01 : 0;
- umct_request(sc, UMCT_SET_MCR, UMCT_SET_MCR_SIZE, sc->sc_mcr);
- break;
- case UCOM_SET_RTS:
- sc->sc_mcr &= ~0x2;
- sc->sc_mcr |= (onoff) ? 0x02 : 0;
- umct_request(sc, UMCT_SET_MCR, UMCT_SET_MCR_SIZE, sc->sc_mcr);
- break;
- default:
- break;
- }
-}
-
-static int
-umct_calc_baud(u_int baud)
-{
- switch(baud) {
- case B300: return (0x1);
- case B600: return (0x2);
- case B1200: return (0x3);
- case B2400: return (0x4);
- case B4800: return (0x6);
- case B9600: return (0x8);
- case B19200: return (0x9);
- case B38400: return (0xa);
- case B57600: return (0xb);
- case 115200: return (0xc);
- case B0:
- default:
- break;
- }
-
- return (0x0);
-}
-
-static int
-umct_param(void *addr, int portno, struct termios *ti)
-{
- struct umct_softc *sc;
- uint32_t value;
-
- sc = addr;
- value = umct_calc_baud(ti->c_ospeed);
- umct_request(sc, UMCT_SET_BAUD, UMCT_SET_BAUD_SIZE, value);
-
- value = sc->sc_lcr & 0x40;
-
- switch (ti->c_cflag & CSIZE) {
- case CS5: value |= 0x0; break;
- case CS6: value |= 0x1; break;
- case CS7: value |= 0x2; break;
- case CS8: value |= 0x3; break;
- default: value |= 0x0; break;
- }
-
- value |= (ti->c_cflag & CSTOPB) ? 0x4 : 0;
- if (ti->c_cflag & PARENB) {
- value |= 0x8;
- value |= (ti->c_cflag & PARODD) ? 0x0 : 0x10;
- }
-
- /*
- * XXX There doesn't seem to be a way to tell the device to use flow
- * control.
- */
-
- sc->sc_lcr = value;
- umct_request(sc, UMCT_SET_LCR, UMCT_SET_LCR_SIZE, value);
-
- return (0);
-}
-
-static int
-umct_open(void *addr, int portno)
-{
- struct umct_softc *sc;
- int err;
-
- sc = addr;
- if (sc->sc_ucom.sc_dying) {
- return (ENXIO);
- }
-
- if (sc->sc_intr_number != -1 && sc->sc_intr_pipe == NULL) {
- sc->sc_intr_buf = malloc(sc->sc_isize, M_USBDEV, M_WAITOK);
- err = usbd_open_pipe_intr(sc->sc_intr_iface, sc->sc_intr_number,
- USBD_SHORT_XFER_OK, &sc->sc_intr_pipe, sc, sc->sc_intr_buf,
- sc->sc_isize, umct_intr, UMCT_INTR_INTERVAL);
- if (err) {
- printf("%s: cannot open interrupt pipe (addr %d)\n",
- device_get_nameunit(sc->sc_ucom.sc_dev),
- sc->sc_intr_number);
- free(sc->sc_intr_buf, M_USBDEV);
- return (EIO);
- }
- }
-
- return (0);
-}
-
-static void
-umct_close(void *addr, int portno)
-{
- struct umct_softc *sc;
- int err;
-
- sc = addr;
- if (sc->sc_ucom.sc_dying)
- return;
-
- if (sc->sc_intr_pipe != NULL) {
- err = usbd_abort_pipe(sc->sc_intr_pipe);
- if (err)
- printf("%s: abort interrupt pipe failed: %s\n",
- device_get_nameunit(sc->sc_ucom.sc_dev), usbd_errstr(err));
- err = usbd_close_pipe(sc->sc_intr_pipe);
- if (err)
- printf("%s: close interrupt pipe failed: %s\n",
- device_get_nameunit(sc->sc_ucom.sc_dev), usbd_errstr(err));
- free(sc->sc_intr_buf, M_USBDEV);
- sc->sc_intr_pipe = NULL;
- }
-}
diff --git a/sys/dev/usb/umodem.c b/sys/dev/usb/umodem.c
deleted file mode 100644
index f0cb17c..0000000
--- a/sys/dev/usb/umodem.c
+++ /dev/null
@@ -1,821 +0,0 @@
-/* $NetBSD: umodem.c,v 1.45 2002/09/23 05:51:23 simonb Exp $ */
-
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-/*-
- * Copyright (c) 2003, M. Warner Losh <imp@freebsd.org>.
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- */
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) 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.
- */
-
-/*
- * Comm Class spec: http://www.usb.org/developers/devclass_docs/usbccs10.pdf
- * http://www.usb.org/developers/devclass_docs/usbcdc11.pdf
- */
-
-/*
- * TODO:
- * - Add error recovery in various places; the big problem is what
- * to do in a callback if there is an error.
- * - Implement a Call Device for modems without multiplexed commands.
- *
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/ioccom.h>
-#include <sys/conf.h>
-#include <sys/serial.h>
-#include <sys/tty.h>
-#include <sys/file.h>
-#include <sys/select.h>
-#include <sys/sysctl.h>
-#include <sys/proc.h>
-#include <sys/bus.h>
-#include <sys/poll.h>
-#include <sys/uio.h>
-#include <sys/taskqueue.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbcdc.h>
-
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include <dev/usb/usb_quirks.h>
-
-#include <dev/usb/ucomvar.h>
-
-#include "usbdevs.h"
-
-#ifdef USB_DEBUG
-int umodemdebug = 0;
-SYSCTL_NODE(_hw_usb, OID_AUTO, umodem, CTLFLAG_RW, 0, "USB umodem");
-SYSCTL_INT(_hw_usb_umodem, OID_AUTO, debug, CTLFLAG_RW,
- &umodemdebug, 0, "umodem debug level");
-#define DPRINTFN(n, x) if (umodemdebug > (n)) printf x
-#else
-#define DPRINTFN(n, x)
-#endif
-#define DPRINTF(x) DPRINTFN(0, x)
-
-static const struct umodem_product {
- u_int16_t vendor;
- u_int16_t product;
- u_int8_t interface;
-} umodem_products[] = {
- /* Kyocera AH-K3001V*/
- { USB_VENDOR_KYOCERA, USB_PRODUCT_KYOCERA_AHK3001V, 0 },
- { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5720, 0 },
- { USB_VENDOR_CURITEL, USB_PRODUCT_CURITEL_PC5740, 0 },
- { 0, 0, 0 },
-};
-
-/*
- * These are the maximum number of bytes transferred per frame.
- * As speeds for umodem deivces increase, these numbers will need to
- * be increased. They should be good for G3 speeds and below.
- */
-#define UMODEMIBUFSIZE 1024
-#define UMODEMOBUFSIZE 1024
-
-#define UMODEM_MODVER 1 /* module version */
-
-struct umodem_softc {
- struct ucom_softc sc_ucom;
-
- device_t sc_dev; /* base device */
-
- usbd_device_handle sc_udev; /* USB device */
-
- int sc_ctl_iface_no;
- usbd_interface_handle sc_ctl_iface; /* control interface */
- int sc_data_iface_no;
- usbd_interface_handle sc_data_iface; /* data interface */
-
- int sc_cm_cap; /* CM capabilities */
- int sc_acm_cap; /* ACM capabilities */
-
- int sc_cm_over_data;
-
- usb_cdc_line_state_t sc_line_state; /* current line state */
- u_char sc_dtr; /* current DTR state */
- u_char sc_rts; /* current RTS state */
-
- u_char sc_opening; /* lock during open */
-
- int sc_ctl_notify; /* Notification endpoint */
- usbd_pipe_handle sc_notify_pipe; /* Notification pipe */
- usb_cdc_notification_t sc_notify_buf; /* Notification structure */
- u_char sc_lsr; /* Local status register */
- u_char sc_msr; /* Modem status register */
-
- struct task sc_task;
-};
-
-static void *umodem_get_desc(usbd_device_handle dev, int type, int subtype);
-static usbd_status umodem_set_comm_feature(struct umodem_softc *sc,
- int feature, int state);
-static usbd_status umodem_set_line_coding(struct umodem_softc *sc,
- usb_cdc_line_state_t *state);
-
-static void umodem_get_caps(usbd_device_handle, int *, int *);
-
-static void umodem_get_status(void *, int portno, u_char *lsr, u_char *msr);
-static void umodem_set(void *, int, int, int);
-static void umodem_dtr(struct umodem_softc *, int);
-static void umodem_rts(struct umodem_softc *, int);
-static void umodem_break(struct umodem_softc *, int);
-static void umodem_set_line_state(struct umodem_softc *);
-static int umodem_param(void *, int, struct termios *);
-static int umodem_ioctl(void *, int, u_long, caddr_t, struct thread *);
-static int umodem_open(void *, int portno);
-static void umodem_close(void *, int portno);
-static void umodem_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
-static void umodem_notify(void *, int);
-
-static struct ucom_callback umodem_callback = {
- .ucom_get_status = umodem_get_status,
- .ucom_set = umodem_set,
- .ucom_param = umodem_param,
- .ucom_ioctl = umodem_ioctl,
- .ucom_open = umodem_open,
- .ucom_close = umodem_close
-};
-
-static device_probe_t umodem_match;
-static device_attach_t umodem_attach;
-static device_detach_t umodem_detach;
-
-static device_method_t umodem_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, umodem_match),
- DEVMETHOD(device_attach, umodem_attach),
- DEVMETHOD(device_detach, umodem_detach),
- { 0, 0 }
-};
-
-static driver_t umodem_driver = {
- "ucom",
- umodem_methods,
- sizeof (struct umodem_softc)
-};
-
-DRIVER_MODULE(umodem, uhub, umodem_driver, ucom_devclass, usbd_driver_load, 0);
-MODULE_DEPEND(umodem, usb, 1, 1, 1);
-MODULE_DEPEND(umodem, ucom, UCOM_MINVER, UCOM_PREFVER, UCOM_MAXVER);
-MODULE_VERSION(umodem, UMODEM_MODVER);
-
-static int
-umodem_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usb_interface_descriptor_t *id;
- usb_device_descriptor_t *dd;
- int cm, acm, i, ret;
-
- if (uaa->iface == NULL)
- return (UMATCH_NONE);
-
- id = usbd_get_interface_descriptor(uaa->iface);
- dd = usbd_get_device_descriptor(uaa->device);
- if (id == NULL || dd == NULL)
- return (UMATCH_NONE);
-
- ret = UMATCH_NONE;
- for (i = 0; umodem_products[i].vendor != 0; i++) {
- if (umodem_products[i].vendor == UGETW(dd->idVendor) &&
- umodem_products[i].product == UGETW(dd->idProduct) &&
- umodem_products[i].interface == id->bInterfaceNumber) {
- ret = UMATCH_VENDOR_PRODUCT;
- break;
- }
- }
-
- if (ret == UMATCH_NONE &&
- id->bInterfaceClass == UICLASS_CDC &&
- id->bInterfaceSubClass == UISUBCLASS_ABSTRACT_CONTROL_MODEL &&
- id->bInterfaceProtocol == UIPROTO_CDC_AT)
- ret = UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO;
-
- if (ret == UMATCH_NONE)
- return (ret);
-
- umodem_get_caps(uaa->device, &cm, &acm);
- if (!(cm & USB_CDC_CM_DOES_CM) ||
- !(cm & USB_CDC_CM_OVER_DATA) ||
- !(acm & USB_CDC_ACM_HAS_LINE))
- return (UMATCH_NONE);
-
- return ret;
-}
-
-static int
-umodem_attach(device_t self)
-{
- struct umodem_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usbd_device_handle dev = uaa->device;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
- usb_cdc_cm_descriptor_t *cmd;
- int data_ifcno;
- int i;
- struct ucom_softc *ucom;
-
- ucom = &sc->sc_ucom;
- ucom->sc_dev = self;
- sc->sc_dev = self;
- ucom->sc_udev = dev;
- ucom->sc_iface = uaa->iface;
-
- sc->sc_udev = dev;
- sc->sc_ctl_iface = uaa->iface;
- id = usbd_get_interface_descriptor(sc->sc_ctl_iface);
- sc->sc_ctl_iface_no = id->bInterfaceNumber;
- device_printf(self, "iclass %d/%d\n", id->bInterfaceClass,
- id->bInterfaceSubClass);
-
- umodem_get_caps(dev, &sc->sc_cm_cap, &sc->sc_acm_cap);
-
- /* Get the data interface no. */
- cmd = umodem_get_desc(dev, UDESC_CS_INTERFACE, UDESCSUB_CDC_CM);
- if (cmd == NULL) {
- device_printf(sc->sc_dev, "no CM descriptor\n");
- goto bad;
- }
- sc->sc_data_iface_no = data_ifcno = cmd->bDataInterface;
-
- device_printf(sc->sc_dev,
- "data interface %d, has %sCM over data, has %sbreak\n",
- data_ifcno, sc->sc_cm_cap & USB_CDC_CM_OVER_DATA ? "" : "no ",
- sc->sc_acm_cap & USB_CDC_ACM_HAS_BREAK ? "" : "no ");
-
- /* Get the data interface too. */
- for (i = 0; i < uaa->nifaces; i++) {
- if (uaa->ifaces[i] != NULL) {
- id = usbd_get_interface_descriptor(uaa->ifaces[i]);
- if (id != NULL && id->bInterfaceNumber == data_ifcno) {
- sc->sc_data_iface = uaa->ifaces[i];
- uaa->ifaces[i] = NULL;
- }
- }
- }
- if (sc->sc_data_iface == NULL) {
- device_printf(sc->sc_dev, "no data interface\n");
- goto bad;
- }
- ucom->sc_iface = sc->sc_data_iface;
-
- /*
- * Find the bulk endpoints.
- * Iterate over all endpoints in the data interface and take note.
- */
- ucom->sc_bulkin_no = ucom->sc_bulkout_no = -1;
-
- id = usbd_get_interface_descriptor(sc->sc_data_iface);
- for (i = 0; i < id->bNumEndpoints; i++) {
- ed = usbd_interface2endpoint_descriptor(sc->sc_data_iface, i);
- if (ed == NULL) {
- device_printf(sc->sc_dev,
- "no endpoint descriptor for %d\n", i);
- goto bad;
- }
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
- ucom->sc_bulkin_no = ed->bEndpointAddress;
- } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
- ucom->sc_bulkout_no = ed->bEndpointAddress;
- }
- }
-
- if (ucom->sc_bulkin_no == -1) {
- device_printf(sc->sc_dev, "Could not find data bulk in\n");
- goto bad;
- }
- if (ucom->sc_bulkout_no == -1) {
- device_printf(sc->sc_dev, "Could not find data bulk out\n");
- goto bad;
- }
-
- if (sc->sc_cm_cap & USB_CDC_CM_OVER_DATA) {
- if (sc->sc_acm_cap & USB_CDC_ACM_HAS_FEATURE)
- umodem_set_comm_feature(sc, UCDC_ABSTRACT_STATE,
- UCDC_DATA_MULTIPLEXED);
- sc->sc_cm_over_data = 1;
- }
-
- /*
- * The standard allows for notification messages (to indicate things
- * like a modem hangup) to come in via an interrupt endpoint
- * off of the control interface. Iterate over the endpoints on
- * the control interface and see if there are any interrupt
- * endpoints; if there are, then register it.
- */
-
- sc->sc_ctl_notify = -1;
- sc->sc_notify_pipe = NULL;
-
- for (i = 0; i < id->bNumEndpoints; i++) {
- ed = usbd_interface2endpoint_descriptor(sc->sc_ctl_iface, i);
- if (ed == NULL)
- continue;
-
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- (ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT) {
- device_printf(sc->sc_dev,
- "status change notification available\n");
- sc->sc_ctl_notify = ed->bEndpointAddress;
- }
- }
-
- sc->sc_dtr = -1;
-
- ucom->sc_parent = sc;
- ucom->sc_portno = UCOM_UNK_PORTNO;
- /* bulkin, bulkout set above */
- ucom->sc_ibufsize = UMODEMIBUFSIZE;
- ucom->sc_obufsize = UMODEMOBUFSIZE;
- ucom->sc_ibufsizepad = UMODEMIBUFSIZE;
- ucom->sc_opkthdrlen = 0;
- ucom->sc_callback = &umodem_callback;
-
- TASK_INIT(&sc->sc_task, 0, umodem_notify, sc);
- ucom_attach(&sc->sc_ucom);
- return 0;
-
- bad:
- ucom->sc_dying = 1;
- return ENXIO;
-}
-
-static int
-umodem_open(void *addr, int portno)
-{
- struct umodem_softc *sc = addr;
- int err;
-
- DPRINTF(("umodem_open: sc=%p\n", sc));
-
- if (sc->sc_ctl_notify != -1 && sc->sc_notify_pipe == NULL) {
- err = usbd_open_pipe_intr(sc->sc_ctl_iface, sc->sc_ctl_notify,
- USBD_SHORT_XFER_OK, &sc->sc_notify_pipe, sc,
- &sc->sc_notify_buf, sizeof(sc->sc_notify_buf),
- umodem_intr, USBD_DEFAULT_INTERVAL);
-
- if (err) {
- DPRINTF(("Failed to establish notify pipe: %s\n",
- usbd_errstr(err)));
- return EIO;
- }
- }
-
- return 0;
-}
-
-static void
-umodem_close(void *addr, int portno)
-{
- struct umodem_softc *sc = addr;
- int err;
-
- DPRINTF(("umodem_close: sc=%p\n", sc));
-
- if (sc->sc_notify_pipe != NULL) {
- err = usbd_abort_pipe(sc->sc_notify_pipe);
- if (err)
- device_printf(sc->sc_dev,
- "abort notify pipe failed: %s\n",
- usbd_errstr(err));
- err = usbd_close_pipe(sc->sc_notify_pipe);
- if (err)
- device_printf(sc->sc_dev,
- "close notify pipe failed: %s\n",
- usbd_errstr(err));
- sc->sc_notify_pipe = NULL;
- }
-}
-
-static void
-umodem_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- struct umodem_softc *sc = priv;
- u_char mstatus;
-
- if (sc->sc_ucom.sc_dying)
- return;
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
- return;
- device_printf(sc->sc_dev, "abnormal status: %s\n",
- usbd_errstr(status));
- return;
- }
-
- if (sc->sc_notify_buf.bmRequestType != UCDC_NOTIFICATION) {
- DPRINTF(("%s: unknown message type (%02x) on notify pipe\n",
- device_get_nameunit(sc->sc_dev),
- sc->sc_notify_buf.bmRequestType));
- return;
- }
-
- switch (sc->sc_notify_buf.bNotification) {
- case UCDC_N_SERIAL_STATE:
- /*
- * Set the serial state in ucom driver based on
- * the bits from the notify message
- */
- if (UGETW(sc->sc_notify_buf.wLength) != 2) {
- device_printf(sc->sc_dev,
- "Invalid notification length! (%d)\n",
- UGETW(sc->sc_notify_buf.wLength));
- break;
- }
- DPRINTF(("%s: notify bytes = %02x%02x\n",
- device_get_nameunit(sc->sc_dev),
- sc->sc_notify_buf.data[0],
- sc->sc_notify_buf.data[1]));
- /* Currently, lsr is always zero. */
- sc->sc_lsr = sc->sc_msr = 0;
- mstatus = sc->sc_notify_buf.data[0];
-
- if (ISSET(mstatus, UCDC_N_SERIAL_RI))
- sc->sc_msr |= SER_RI;
- if (ISSET(mstatus, UCDC_N_SERIAL_DSR))
- sc->sc_msr |= SER_DSR;
- if (ISSET(mstatus, UCDC_N_SERIAL_DCD))
- sc->sc_msr |= SER_DCD;
- /* Deferred notifying to the ucom layer */
- taskqueue_enqueue(taskqueue_swi_giant, &sc->sc_task);
- break;
- default:
- DPRINTF(("%s: unknown notify message: %02x\n",
- device_get_nameunit(sc->sc_dev),
- sc->sc_notify_buf.bNotification));
- break;
- }
-}
-
-static void
-umodem_notify(void *arg, int count)
-{
- struct umodem_softc *sc;
-
- sc = (struct umodem_softc *)arg;
- if (sc->sc_ucom.sc_dying)
- return;
- ucom_status_change(&sc->sc_ucom);
-}
-
-void
-umodem_get_caps(usbd_device_handle dev, int *cm, int *acm)
-{
- usb_cdc_cm_descriptor_t *cmd;
- usb_cdc_acm_descriptor_t *cad;
-
- *cm = *acm = 0;
-
- cmd = umodem_get_desc(dev, UDESC_CS_INTERFACE, UDESCSUB_CDC_CM);
- if (cmd == NULL) {
- DPRINTF(("umodem_get_desc: no CM desc\n"));
- return;
- }
- *cm = cmd->bmCapabilities;
-
- cad = umodem_get_desc(dev, UDESC_CS_INTERFACE, UDESCSUB_CDC_ACM);
- if (cad == NULL) {
- DPRINTF(("umodem_get_desc: no ACM desc\n"));
- return;
- }
- *acm = cad->bmCapabilities;
-}
-
-void
-umodem_get_status(void *addr, int portno, u_char *lsr, u_char *msr)
-{
- struct umodem_softc *sc = addr;
-
- DPRINTF(("umodem_get_status:\n"));
-
- if (lsr != NULL)
- *lsr = sc->sc_lsr;
- if (msr != NULL)
- *msr = sc->sc_msr;
-}
-
-int
-umodem_param(void *addr, int portno, struct termios *t)
-{
- struct umodem_softc *sc = addr;
- usbd_status err;
- usb_cdc_line_state_t ls;
-
- DPRINTF(("umodem_param: sc=%p\n", sc));
-
- USETDW(ls.dwDTERate, t->c_ospeed);
- if (ISSET(t->c_cflag, CSTOPB))
- ls.bCharFormat = UCDC_STOP_BIT_2;
- else
- ls.bCharFormat = UCDC_STOP_BIT_1;
- if (ISSET(t->c_cflag, PARENB)) {
- if (ISSET(t->c_cflag, PARODD))
- ls.bParityType = UCDC_PARITY_ODD;
- else
- ls.bParityType = UCDC_PARITY_EVEN;
- } else
- ls.bParityType = UCDC_PARITY_NONE;
- switch (ISSET(t->c_cflag, CSIZE)) {
- case CS5:
- ls.bDataBits = 5;
- break;
- case CS6:
- ls.bDataBits = 6;
- break;
- case CS7:
- ls.bDataBits = 7;
- break;
- case CS8:
- ls.bDataBits = 8;
- break;
- }
-
- err = umodem_set_line_coding(sc, &ls);
- if (err) {
- DPRINTF(("umodem_param: err=%s\n", usbd_errstr(err)));
- return (EIO);
- }
- return (0);
-}
-
-int
-umodem_ioctl(void *addr, int portno, u_long cmd, caddr_t data,
- struct thread *p)
-{
- struct umodem_softc *sc = addr;
- int error = 0;
-
- if (sc->sc_ucom.sc_dying)
- return (EIO);
-
- DPRINTF(("umodemioctl: cmd=0x%08lx\n", cmd));
-
- switch (cmd) {
- case USB_GET_CM_OVER_DATA:
- *(int *)data = sc->sc_cm_over_data;
- break;
-
- case USB_SET_CM_OVER_DATA:
- if (*(int *)data != sc->sc_cm_over_data) {
- /* XXX change it */
- }
- break;
-
- default:
- DPRINTF(("umodemioctl: unknown\n"));
- error = ENOIOCTL;
- break;
- }
-
- return (error);
-}
-
-void
-umodem_dtr(struct umodem_softc *sc, int onoff)
-{
- DPRINTF(("umodem_modem: onoff=%d\n", onoff));
-
- if (sc->sc_dtr == onoff)
- return;
- sc->sc_dtr = onoff;
-
- umodem_set_line_state(sc);
-}
-
-void
-umodem_rts(struct umodem_softc *sc, int onoff)
-{
- DPRINTF(("umodem_modem: onoff=%d\n", onoff));
-
- if (sc->sc_rts == onoff)
- return;
- sc->sc_rts = onoff;
-
- umodem_set_line_state(sc);
-}
-
-void
-umodem_set_line_state(struct umodem_softc *sc)
-{
- usb_device_request_t req;
- int ls;
-
- ls = (sc->sc_dtr ? UCDC_LINE_DTR : 0) |
- (sc->sc_rts ? UCDC_LINE_RTS : 0);
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UCDC_SET_CONTROL_LINE_STATE;
- USETW(req.wValue, ls);
- USETW(req.wIndex, sc->sc_ctl_iface_no);
- USETW(req.wLength, 0);
-
- (void)usbd_do_request(sc->sc_udev, &req, 0);
-
-}
-
-void
-umodem_break(struct umodem_softc *sc, int onoff)
-{
- usb_device_request_t req;
-
- DPRINTF(("umodem_break: onoff=%d\n", onoff));
-
- if (!(sc->sc_acm_cap & USB_CDC_ACM_HAS_BREAK))
- return;
-
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UCDC_SEND_BREAK;
- USETW(req.wValue, onoff ? UCDC_BREAK_ON : UCDC_BREAK_OFF);
- USETW(req.wIndex, sc->sc_ctl_iface_no);
- USETW(req.wLength, 0);
-
- (void)usbd_do_request(sc->sc_udev, &req, 0);
-}
-
-void
-umodem_set(void *addr, int portno, int reg, int onoff)
-{
- struct umodem_softc *sc = addr;
-
- switch (reg) {
- case UCOM_SET_DTR:
- umodem_dtr(sc, onoff);
- break;
- case UCOM_SET_RTS:
- umodem_rts(sc, onoff);
- break;
- case UCOM_SET_BREAK:
- umodem_break(sc, onoff);
- break;
- default:
- break;
- }
-}
-
-usbd_status
-umodem_set_line_coding(struct umodem_softc *sc, usb_cdc_line_state_t *state)
-{
- usb_device_request_t req;
- usbd_status err;
-
- DPRINTF(("umodem_set_line_coding: rate=%d fmt=%d parity=%d bits=%d\n",
- UGETDW(state->dwDTERate), state->bCharFormat,
- state->bParityType, state->bDataBits));
-
- if (memcmp(state, &sc->sc_line_state, UCDC_LINE_STATE_LENGTH) == 0) {
- DPRINTF(("umodem_set_line_coding: already set\n"));
- return (USBD_NORMAL_COMPLETION);
- }
-
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UCDC_SET_LINE_CODING;
- USETW(req.wValue, 0);
- USETW(req.wIndex, sc->sc_ctl_iface_no);
- USETW(req.wLength, UCDC_LINE_STATE_LENGTH);
-
- err = usbd_do_request(sc->sc_udev, &req, state);
- if (err) {
- DPRINTF(("umodem_set_line_coding: failed, err=%s\n",
- usbd_errstr(err)));
- return (err);
- }
-
- sc->sc_line_state = *state;
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-void *
-umodem_get_desc(usbd_device_handle dev, int type, int subtype)
-{
- usb_descriptor_t *desc;
- usb_config_descriptor_t *cd = usbd_get_config_descriptor(dev);
- uByte *p = (uByte *)cd;
- uByte *end = p + UGETW(cd->wTotalLength);
-
- while (p < end) {
- desc = (usb_descriptor_t *)p;
- if (desc->bDescriptorType == type &&
- desc->bDescriptorSubtype == subtype)
- return (desc);
- p += desc->bLength;
- }
-
- return (0);
-}
-
-usbd_status
-umodem_set_comm_feature(struct umodem_softc *sc, int feature, int state)
-{
- usb_device_request_t req;
- usbd_status err;
- usb_cdc_abstract_state_t ast;
-
- DPRINTF(("umodem_set_comm_feature: feature=%d state=%d\n", feature,
- state));
-
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UCDC_SET_COMM_FEATURE;
- USETW(req.wValue, feature);
- USETW(req.wIndex, sc->sc_ctl_iface_no);
- USETW(req.wLength, UCDC_ABSTRACT_STATE_LENGTH);
- USETW(ast.wState, state);
-
- err = usbd_do_request(sc->sc_udev, &req, &ast);
- if (err) {
- DPRINTF(("umodem_set_comm_feature: feature=%d, err=%s\n",
- feature, usbd_errstr(err)));
- return (err);
- }
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-static int
-umodem_detach(device_t self)
-{
- struct umodem_softc *sc = device_get_softc(self);
- int rv = 0;
-
- DPRINTF(("umodem_detach: sc=%p\n", sc));
-
- if (sc->sc_notify_pipe != NULL) {
- usbd_abort_pipe(sc->sc_notify_pipe);
- usbd_close_pipe(sc->sc_notify_pipe);
- sc->sc_notify_pipe = NULL;
- }
-
- sc->sc_ucom.sc_dying = 1;
- rv = ucom_detach(&sc->sc_ucom);
-
- return (rv);
-}
diff --git a/sys/dev/usb/ums.c b/sys/dev/usb/ums.c
deleted file mode 100644
index 6484303..0000000
--- a/sys/dev/usb/ums.c
+++ /dev/null
@@ -1,972 +0,0 @@
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * HID spec: http://www.usb.org/developers/devclass_docs/HID1_11.pdf
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/ioccom.h>
-#include <sys/conf.h>
-#include <sys/fcntl.h>
-#include <sys/tty.h>
-#include <sys/file.h>
-#include <sys/selinfo.h>
-#include <sys/poll.h>
-#include <sys/sysctl.h>
-#include <sys/uio.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbhid.h>
-
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include "usbdevs.h"
-#include <dev/usb/usb_quirks.h>
-#include <dev/usb/hid.h>
-
-#include <sys/mouse.h>
-
-#ifdef USB_DEBUG
-#define DPRINTF(x) if (umsdebug) printf x
-#define DPRINTFN(n,x) if (umsdebug>(n)) printf x
-int umsdebug = 0;
-SYSCTL_NODE(_hw_usb, OID_AUTO, ums, CTLFLAG_RW, 0, "USB ums");
-SYSCTL_INT(_hw_usb_ums, OID_AUTO, debug, CTLFLAG_RW,
- &umsdebug, 0, "ums debug level");
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-#define UMSUNIT(s) (dev2unit(s)&0x1f)
-
-#define MS_TO_TICKS(ms) ((ms) * hz / 1000)
-
-#define QUEUE_BUFSIZE 400 /* MUST be divisible by 5 _and_ 8 */
-
-struct ums_softc {
- device_t sc_dev; /* base device */
- usbd_interface_handle sc_iface; /* interface */
- usbd_pipe_handle sc_intrpipe; /* interrupt pipe */
- int sc_ep_addr;
-
- u_char *sc_ibuf;
- u_int8_t sc_iid;
- int sc_isize;
- struct hid_location sc_loc_x, sc_loc_y, sc_loc_z, sc_loc_t, sc_loc_w;
- struct hid_location *sc_loc_btn;
-
- struct callout callout_handle; /* for spurious button ups */
-
- int sc_enabled;
- int sc_disconnected; /* device is gone */
-
- int flags; /* device configuration */
-#define UMS_Z 0x01 /* z direction available */
-#define UMS_SPUR_BUT_UP 0x02 /* spurious button up events */
-#define UMS_T 0x04 /* aa direction available (tilt) */
-#define UMS_REVZ 0x08 /* Z-axis is reversed */
- int nbuttons;
-#define MAX_BUTTONS 31 /* chosen because sc_buttons is int */
-
- u_char qbuf[QUEUE_BUFSIZE]; /* must be divisable by 3&4 */
- u_char dummy[100]; /* XXX just for safety and for now */
- int qcount, qhead, qtail;
- mousehw_t hw;
- mousemode_t mode;
- mousestatus_t status;
-
- int state;
-# define UMS_ASLEEP 0x01 /* readFromDevice is waiting */
-# define UMS_SELECT 0x02 /* select is waiting */
- struct selinfo rsel; /* process waiting in select */
-
- struct cdev *dev; /* specfs */
-};
-
-#define MOUSE_FLAGS_MASK (HIO_CONST|HIO_RELATIVE)
-#define MOUSE_FLAGS (HIO_RELATIVE)
-
-static void ums_intr(usbd_xfer_handle xfer,
- usbd_private_handle priv, usbd_status status);
-
-static void ums_add_to_queue(struct ums_softc *sc,
- int dx, int dy, int dz, int dt, int buttons);
-static void ums_add_to_queue_timeout(void *priv);
-
-static int ums_enable(void *);
-static void ums_disable(void *);
-
-static d_open_t ums_open;
-static d_close_t ums_close;
-static d_read_t ums_read;
-static d_ioctl_t ums_ioctl;
-static d_poll_t ums_poll;
-
-
-static struct cdevsw ums_cdevsw = {
- .d_version = D_VERSION,
- .d_flags = D_NEEDGIANT,
- .d_open = ums_open,
- .d_close = ums_close,
- .d_read = ums_read,
- .d_ioctl = ums_ioctl,
- .d_poll = ums_poll,
- .d_name = "ums",
-};
-
-static device_probe_t ums_match;
-static device_attach_t ums_attach;
-static device_detach_t ums_detach;
-
-static device_method_t ums_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, ums_match),
- DEVMETHOD(device_attach, ums_attach),
- DEVMETHOD(device_detach, ums_detach),
-
- { 0, 0 }
-};
-
-static driver_t ums_driver = {
- "ums",
- ums_methods,
- sizeof(struct ums_softc)
-};
-
-static devclass_t ums_devclass;
-
-static int
-ums_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usb_interface_descriptor_t *id;
- int size, ret;
- void *desc;
- usbd_status err;
-
- if (!uaa->iface)
- return (UMATCH_NONE);
- id = usbd_get_interface_descriptor(uaa->iface);
- if (!id || id->bInterfaceClass != UICLASS_HID)
- return (UMATCH_NONE);
-
- err = usbd_read_report_desc(uaa->iface, &desc, &size, M_TEMP);
- if (err)
- return (UMATCH_NONE);
-
- if (hid_is_collection(desc, size,
- HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_MOUSE)))
- ret = UMATCH_IFACECLASS;
- else if (id->bInterfaceClass == UICLASS_HID &&
- id->bInterfaceSubClass == UISUBCLASS_BOOT &&
- id->bInterfaceProtocol == UIPROTO_MOUSE)
- ret = UMATCH_IFACECLASS;
- else
- ret = UMATCH_NONE;
-
- free(desc, M_TEMP);
- return (ret);
-}
-
-static int
-ums_attach(device_t self)
-{
- struct ums_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usbd_interface_handle iface = uaa->iface;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
- int size;
- void *desc;
- usbd_status err;
- u_int32_t flags;
- int i, wheel;
- struct hid_location loc_btn;
-
- sc->sc_disconnected = 1;
- sc->sc_iface = iface;
- id = usbd_get_interface_descriptor(iface);
- sc->sc_dev = self;
- ed = usbd_interface2endpoint_descriptor(iface, 0);
- if (!ed) {
- printf("%s: could not read endpoint descriptor\n",
- device_get_nameunit(sc->sc_dev));
- return ENXIO;
- }
-
- DPRINTFN(10,("ums_attach: bLength=%d bDescriptorType=%d "
- "bEndpointAddress=%d-%s bmAttributes=%d wMaxPacketSize=%d"
- " bInterval=%d\n",
- ed->bLength, ed->bDescriptorType,
- UE_GET_ADDR(ed->bEndpointAddress),
- UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN ? "in":"out",
- UE_GET_XFERTYPE(ed->bmAttributes),
- UGETW(ed->wMaxPacketSize), ed->bInterval));
-
- if (UE_GET_DIR(ed->bEndpointAddress) != UE_DIR_IN ||
- UE_GET_XFERTYPE(ed->bmAttributes) != UE_INTERRUPT) {
- printf("%s: unexpected endpoint\n",
- device_get_nameunit(sc->sc_dev));
- return ENXIO;
- }
-
- err = usbd_read_report_desc(uaa->iface, &desc, &size, M_TEMP);
- if (err)
- return ENXIO;
-
- if (!hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X),
- hid_input, &sc->sc_loc_x, &flags)) {
- printf("%s: mouse has no X report\n", device_get_nameunit(sc->sc_dev));
- return ENXIO;
- }
- if ((flags & MOUSE_FLAGS_MASK) != MOUSE_FLAGS) {
- printf("%s: X report 0x%04x not supported\n",
- device_get_nameunit(sc->sc_dev), flags);
- return ENXIO;
- }
-
- if (!hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Y),
- hid_input, &sc->sc_loc_y, &flags)) {
- printf("%s: mouse has no Y report\n", device_get_nameunit(sc->sc_dev));
- return ENXIO;
- }
- if ((flags & MOUSE_FLAGS_MASK) != MOUSE_FLAGS) {
- printf("%s: Y report 0x%04x not supported\n",
- device_get_nameunit(sc->sc_dev), flags);
- return ENXIO;
- }
-
- /* Try the wheel first as the Z activator since it's tradition. */
- wheel = hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP,
- HUG_WHEEL),
- hid_input, &sc->sc_loc_z, &flags) ||
- hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP,
- HUG_TWHEEL),
- hid_input, &sc->sc_loc_z, &flags);
-
- if (wheel) {
- if ((flags & MOUSE_FLAGS_MASK) != MOUSE_FLAGS) {
- printf("\n%s: Wheel report 0x%04x not supported\n",
- device_get_nameunit(sc->sc_dev), flags);
- sc->sc_loc_z.size = 0; /* Bad Z coord, ignore it */
- } else {
- sc->flags |= UMS_Z;
- if (usbd_get_quirks(uaa->device)->uq_flags &
- UQ_MS_REVZ) {
- /* Some wheels need the Z axis reversed. */
- sc->flags |= UMS_REVZ;
- }
-
- }
- /*
- * We might have both a wheel and Z direction, if so put
- * put the Z on the W coordinate.
- */
- if (hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP,
- HUG_Z),
- hid_input, &sc->sc_loc_w, &flags)) {
- if ((flags & MOUSE_FLAGS_MASK) != MOUSE_FLAGS) {
- printf("\n%s: Z report 0x%04x not supported\n",
- device_get_nameunit(sc->sc_dev), flags);
- sc->sc_loc_w.size = 0; /* Bad Z, ignore */
- }
- }
- } else if (hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP,
- HUG_Z),
- hid_input, &sc->sc_loc_z, &flags)) {
- if ((flags & MOUSE_FLAGS_MASK) != MOUSE_FLAGS) {
- printf("\n%s: Z report 0x%04x not supported\n",
- device_get_nameunit(sc->sc_dev), flags);
- sc->sc_loc_z.size = 0; /* Bad Z coord, ignore it */
- } else {
- sc->flags |= UMS_Z;
- }
- }
-
- /*
- * The Microsoft Wireless Intellimouse 2.0 reports it's wheel
- * using 0x0048 (i've called it HUG_TWHEEL) and seems to expect
- * you to know that the byte after the wheel is the tilt axis.
- * There are no other HID axis descriptors other than X,Y and
- * TWHEEL
- */
- if (hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_TWHEEL),
- hid_input, &sc->sc_loc_t, &flags)) {
- sc->sc_loc_t.pos = sc->sc_loc_t.pos + 8;
- sc->flags |= UMS_T;
- }
-
- /* figure out the number of buttons */
- for (i = 1; i <= MAX_BUTTONS; i++)
- if (!hid_locate(desc, size, HID_USAGE2(HUP_BUTTON, i),
- hid_input, &loc_btn, 0))
- break;
- sc->nbuttons = i - 1;
- sc->sc_loc_btn = malloc(sizeof(struct hid_location)*sc->nbuttons,
- M_USBDEV, M_NOWAIT);
- if (!sc->sc_loc_btn) {
- printf("%s: no memory\n", device_get_nameunit(sc->sc_dev));
- return ENXIO;
- }
-
- printf("%s: %d buttons%s%s.\n", device_get_nameunit(sc->sc_dev),
- sc->nbuttons, sc->flags & UMS_Z? " and Z dir" : "",
- sc->flags & UMS_T?" and a TILT dir": "");
-
- for (i = 1; i <= sc->nbuttons; i++)
- hid_locate(desc, size, HID_USAGE2(HUP_BUTTON, i),
- hid_input, &sc->sc_loc_btn[i-1], 0);
-
- sc->sc_isize = hid_report_size(desc, size, hid_input, &sc->sc_iid);
-
- /*
- * The Microsoft Wireless Notebook Optical Mouse seems to be in worse
- * shape than the Wireless Intellimouse 2.0, as its X, Y, wheel, and
- * all of its other button positions are all off. It also reports that
- * it has two addional buttons and a tilt wheel.
- */
- if (usbd_get_quirks(uaa->device)->uq_flags & UQ_MS_BAD_CLASS) {
- sc->flags = UMS_Z;
- sc->flags |= UMS_SPUR_BUT_UP;
- sc->nbuttons = 3;
- sc->sc_isize = 5;
- sc->sc_iid = 0;
- /* 1st byte of descriptor report contains garbage */
- sc->sc_loc_x.pos = 16;
- sc->sc_loc_y.pos = 24;
- sc->sc_loc_z.pos = 32;
- sc->sc_loc_btn[0].pos = 8;
- sc->sc_loc_btn[1].pos = 9;
- sc->sc_loc_btn[2].pos = 10;
- }
-
- /*
- * The Microsoft Wireless Notebook Optical Mouse 3000 Model 1049 has
- * five Report IDs: 19 23 24 17 18 (in the order they appear in report
- * descriptor), it seems that report id 17 contains the necessary
- * mouse information(3-buttons,X,Y,wheel) so we specify it manually.
- */
- if (uaa->vendor == USB_VENDOR_MICROSOFT &&
- uaa->product == USB_PRODUCT_MICROSOFT_WLNOTEBOOK3) {
- sc->flags = UMS_Z;
- sc->nbuttons = 3;
- sc->sc_isize = 5;
- sc->sc_iid = 17;
- sc->sc_loc_x.pos = 8;
- sc->sc_loc_y.pos = 16;
- sc->sc_loc_z.pos = 24;
- sc->sc_loc_btn[0].pos = 0;
- sc->sc_loc_btn[1].pos = 1;
- sc->sc_loc_btn[2].pos = 2;
- }
-
- sc->sc_ibuf = malloc(sc->sc_isize, M_USB, M_NOWAIT);
- if (!sc->sc_ibuf) {
- printf("%s: no memory\n", device_get_nameunit(sc->sc_dev));
- free(sc->sc_loc_btn, M_USB);
- return ENXIO;
- }
-
- sc->sc_ep_addr = ed->bEndpointAddress;
- sc->sc_disconnected = 0;
- free(desc, M_TEMP);
-
-#ifdef USB_DEBUG
- DPRINTF(("ums_attach: sc=%p\n", sc));
- DPRINTF(("ums_attach: X\t%d/%d\n",
- sc->sc_loc_x.pos, sc->sc_loc_x.size));
- DPRINTF(("ums_attach: Y\t%d/%d\n",
- sc->sc_loc_y.pos, sc->sc_loc_y.size));
- if (sc->flags & UMS_Z)
- DPRINTF(("ums_attach: Z\t%d/%d\n",
- sc->sc_loc_z.pos, sc->sc_loc_z.size));
- for (i = 1; i <= sc->nbuttons; i++) {
- DPRINTF(("ums_attach: B%d\t%d/%d\n",
- i, sc->sc_loc_btn[i-1].pos,sc->sc_loc_btn[i-1].size));
- }
- DPRINTF(("ums_attach: size=%d, id=%d\n", sc->sc_isize, sc->sc_iid));
-#endif
-
- if (sc->nbuttons > MOUSE_MSC_MAXBUTTON)
- sc->hw.buttons = MOUSE_MSC_MAXBUTTON;
- else
- sc->hw.buttons = sc->nbuttons;
- sc->hw.iftype = MOUSE_IF_USB;
- sc->hw.type = MOUSE_MOUSE;
- sc->hw.model = MOUSE_MODEL_GENERIC;
- sc->hw.hwid = 0;
- sc->mode.protocol = MOUSE_PROTO_MSC;
- sc->mode.rate = -1;
- sc->mode.resolution = MOUSE_RES_UNKNOWN;
- sc->mode.accelfactor = 0;
- sc->mode.level = 0;
- sc->mode.packetsize = MOUSE_MSC_PACKETSIZE;
- sc->mode.syncmask[0] = MOUSE_MSC_SYNCMASK;
- sc->mode.syncmask[1] = MOUSE_MSC_SYNC;
-
- sc->status.flags = 0;
- sc->status.button = sc->status.obutton = 0;
- sc->status.dx = sc->status.dy = sc->status.dz = 0;
-
- sc->dev = make_dev(&ums_cdevsw, device_get_unit(self),
- UID_ROOT, GID_OPERATOR,
- 0644, "ums%d", device_get_unit(self));
-
- callout_init(&sc->callout_handle, 0);
- if (usbd_get_quirks(uaa->device)->uq_flags & UQ_SPUR_BUT_UP) {
- DPRINTF(("%s: Spurious button up events\n",
- device_get_nameunit(sc->sc_dev)));
- sc->flags |= UMS_SPUR_BUT_UP;
- }
-
- return 0;
-}
-
-
-static int
-ums_detach(device_t self)
-{
- struct ums_softc *sc = device_get_softc(self);
-
- if (sc->sc_enabled)
- ums_disable(sc);
-
- DPRINTF(("%s: disconnected\n", device_get_nameunit(self)));
-
- free(sc->sc_loc_btn, M_USB);
- free(sc->sc_ibuf, M_USB);
-
- /* someone waiting for data */
- /*
- * XXX If we wakeup the process here, the device will be gone by
- * the time the process gets a chance to notice. *_close and friends
- * should be fixed to handle this case.
- * Or we should do a delayed detach for this.
- * Does this delay now force tsleep to exit with an error?
- */
- if (sc->state & UMS_ASLEEP) {
- sc->state &= ~UMS_ASLEEP;
- wakeup(sc);
- }
- if (sc->state & UMS_SELECT) {
- sc->state &= ~UMS_SELECT;
- selwakeuppri(&sc->rsel, PZERO);
- }
-
- destroy_dev(sc->dev);
-
- return 0;
-}
-
-void
-ums_intr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status)
-{
- struct ums_softc *sc = addr;
- u_char *ibuf;
- int dx, dy, dz, dw, dt;
- int buttons = 0;
- int i;
-
-#define UMS_BUT(i) ((i) < 3 ? (((i) + 2) % 3) : (i))
-
- DPRINTFN(5, ("ums_intr: sc=%p status=%d\n", sc, status));
- DPRINTFN(5, ("ums_intr: data ="));
- for (i = 0; i < sc->sc_isize; i++)
- DPRINTFN(5, (" %02x", sc->sc_ibuf[i]));
- DPRINTFN(5, ("\n"));
-
- if (status == USBD_CANCELLED)
- return;
-
- if (status != USBD_NORMAL_COMPLETION) {
- DPRINTF(("ums_intr: status=%d\n", status));
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall_async(sc->sc_intrpipe);
- if(status != USBD_IOERROR)
- return;
- }
-
- ibuf = sc->sc_ibuf;
- /*
- * The M$ Wireless Intellimouse 2.0 sends 1 extra leading byte of
- * data compared to most USB mice. This byte frequently switches
- * from 0x01 (usual state) to 0x02. I assume it is to allow
- * extra, non-standard, reporting (say battery-life). However
- * at the same time it generates a left-click message on the button
- * byte which causes spurious left-click's where there shouldn't be.
- * This should sort that.
- * Currently it's the only user of UMS_T so use it as an identifier.
- * We probably should switch to some more official quirk.
- *
- * UPDATE: This problem affects the M$ Wireless Notebook Optical Mouse,
- * too. However, the leading byte for this mouse is normally 0x11,
- * and the phantom mouse click occurs when its 0x14.
- */
- if (sc->flags & UMS_T) {
- if (sc->sc_iid) {
- if (*ibuf++ == 0x02)
- return;
- }
- } else if (sc->flags & UMS_SPUR_BUT_UP) {
- DPRINTFN(5, ("ums_intr: #### ibuf[0] =3D %d ####\n", *ibuf));
- if (*ibuf == 0x14 || *ibuf == 0x15)
- return;
- } else {
- if (sc->sc_iid) {
- if (*ibuf++ != sc->sc_iid)
- return;
- }
- }
-
- dx = hid_get_data(ibuf, &sc->sc_loc_x);
- dy = -hid_get_data(ibuf, &sc->sc_loc_y);
- dz = -hid_get_data(ibuf, &sc->sc_loc_z);
- dw = hid_get_data(ibuf, &sc->sc_loc_w);
- if (sc->flags & UMS_REVZ)
- dz = -dz;
- if (sc->flags & UMS_T)
- dt = -hid_get_data(ibuf, &sc->sc_loc_t);
- else
- dt = 0;
- for (i = 0; i < sc->nbuttons; i++)
- if (hid_get_data(ibuf, &sc->sc_loc_btn[i]))
- buttons |= (1 << UMS_BUT(i));
-
- if (dx || dy || dz || dt || dw || (sc->flags & UMS_Z)
- || buttons != sc->status.button) {
- DPRINTFN(5, ("ums_intr: x:%d y:%d z:%d w:%d t:%d buttons:0x%x\n",
- dx, dy, dz, dw, dt, buttons));
-
- sc->status.button = buttons;
- sc->status.dx += dx;
- sc->status.dy += dy;
- sc->status.dz += dz;
- /* sc->status.dt += dt; */ /* no way to export this yet */
- /* sc->status.dw += dw; */ /* idem */
-
- /* Discard data in case of full buffer */
- if (sc->qcount == sizeof(sc->qbuf)) {
- DPRINTF(("Buffer full, discarded packet"));
- return;
- }
-
- /*
- * The Qtronix keyboard has a built in PS/2 port for a mouse.
- * The firmware once in a while posts a spurious button up
- * event. This event we ignore by doing a timeout for 50 msecs.
- * If we receive dx=dy=dz=buttons=0 before we add the event to
- * the queue.
- * In any other case we delete the timeout event.
- */
- if (sc->flags & UMS_SPUR_BUT_UP &&
- dx == 0 && dy == 0 && dz == 0 && dt == 0 && buttons == 0) {
- callout_reset(&sc->callout_handle, MS_TO_TICKS(50),
- ums_add_to_queue_timeout, (void *) sc);
- } else {
- callout_stop(&sc->callout_handle);
- ums_add_to_queue(sc, dx, dy, dz, dt, buttons);
- }
- }
-}
-
-static void
-ums_add_to_queue_timeout(void *priv)
-{
- struct ums_softc *sc = priv;
- int s;
-
- s = splusb();
- ums_add_to_queue(sc, 0, 0, 0, 0, 0);
- splx(s);
-}
-
-static void
-ums_add_to_queue(struct ums_softc *sc, int dx, int dy, int dz, int dt, int buttons)
-{
- /* Discard data in case of full buffer */
- if (sc->qhead+sc->mode.packetsize > sizeof(sc->qbuf)) {
- DPRINTF(("Buffer full, discarded packet"));
- return;
- }
-
- if (dx > 254) dx = 254;
- if (dx < -256) dx = -256;
- if (dy > 254) dy = 254;
- if (dy < -256) dy = -256;
- if (dz > 126) dz = 126;
- if (dz < -128) dz = -128;
- if (dt > 126) dt = 126;
- if (dt < -128) dt = -128;
-
- sc->qbuf[sc->qhead] = sc->mode.syncmask[1];
- sc->qbuf[sc->qhead] |= ~buttons & MOUSE_MSC_BUTTONS;
- sc->qbuf[sc->qhead+1] = dx >> 1;
- sc->qbuf[sc->qhead+2] = dy >> 1;
- sc->qbuf[sc->qhead+3] = dx - (dx >> 1);
- sc->qbuf[sc->qhead+4] = dy - (dy >> 1);
-
- if (sc->mode.level == 1) {
- sc->qbuf[sc->qhead+5] = dz >> 1;
- sc->qbuf[sc->qhead+6] = dz - (dz >> 1);
- sc->qbuf[sc->qhead+7] = ((~buttons >> 3)
- & MOUSE_SYS_EXTBUTTONS);
- }
-
- sc->qhead += sc->mode.packetsize;
- sc->qcount += sc->mode.packetsize;
- /* wrap round at end of buffer */
- if (sc->qhead >= sizeof(sc->qbuf))
- sc->qhead = 0;
-
- /* someone waiting for data */
- if (sc->state & UMS_ASLEEP) {
- sc->state &= ~UMS_ASLEEP;
- wakeup(sc);
- }
- if (sc->state & UMS_SELECT) {
- sc->state &= ~UMS_SELECT;
- selwakeuppri(&sc->rsel, PZERO);
- }
-}
-static int
-ums_enable(v)
- void *v;
-{
- struct ums_softc *sc = v;
-
- usbd_status err;
-
- if (sc->sc_enabled)
- return EBUSY;
-
- sc->sc_enabled = 1;
- sc->qcount = 0;
- sc->qhead = sc->qtail = 0;
- sc->status.flags = 0;
- sc->status.button = sc->status.obutton = 0;
- sc->status.dx = sc->status.dy = sc->status.dz /* = sc->status.dt */ = 0;
-
- callout_handle_init((struct callout_handle *)&sc->callout_handle);
-
- /*
- * Force the report (non-boot) protocol.
- *
- * Mice without boot protocol support may choose not to implement
- * Set_Protocol at all; do not check for error.
- */
- usbd_set_protocol(sc->sc_iface, 1);
-
- /* 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, ums_intr,
- USBD_DEFAULT_INTERVAL);
- if (err) {
- DPRINTF(("ums_enable: usbd_open_pipe_intr failed, error=%d\n",
- err));
- sc->sc_enabled = 0;
- return (EIO);
- }
- return (0);
-}
-
-static void
-ums_disable(priv)
- void *priv;
-{
- struct ums_softc *sc = priv;
-
- callout_stop(&sc->callout_handle);
-
- /* Disable interrupts. */
- usbd_abort_pipe(sc->sc_intrpipe);
- usbd_close_pipe(sc->sc_intrpipe);
-
- sc->sc_enabled = 0;
-
- if (sc->qcount != 0)
- DPRINTF(("Discarded %d bytes in queue\n", sc->qcount));
-}
-
-static int
-ums_open(struct cdev *dev, int flag, int fmt, struct thread *p)
-{
- struct ums_softc *sc;
-
- sc = devclass_get_softc(ums_devclass, UMSUNIT(dev));
- if (sc == NULL)
- return (ENXIO);
-
- return ums_enable(sc);
-}
-
-static int
-ums_close(struct cdev *dev, int flag, int fmt, struct thread *p)
-{
- struct ums_softc *sc;
-
- sc = devclass_get_softc(ums_devclass, UMSUNIT(dev));
- if (!sc)
- return 0;
-
- if (sc->sc_enabled)
- ums_disable(sc);
-
- return 0;
-}
-
-static int
-ums_read(struct cdev *dev, struct uio *uio, int flag)
-{
- struct ums_softc *sc;
- int s;
- char buf[sizeof(sc->qbuf)];
- int l = 0;
- int error;
-
- sc = devclass_get_softc(ums_devclass, UMSUNIT(dev));
- s = splusb();
- if (!sc) {
- splx(s);
- return EIO;
- }
-
- while (sc->qcount == 0 ) {
- if (flag & O_NONBLOCK) { /* non-blocking I/O */
- splx(s);
- return EWOULDBLOCK;
- }
-
- sc->state |= UMS_ASLEEP; /* blocking I/O */
- error = tsleep(sc, PZERO | PCATCH, "umsrea", 0);
- if (error) {
- splx(s);
- return error;
- } else if (!sc->sc_enabled) {
- splx(s);
- return EINTR;
- }
- /* check whether the device is still there */
-
- sc = devclass_get_softc(ums_devclass, UMSUNIT(dev));
- if (!sc) {
- splx(s);
- return EIO;
- }
- }
-
- /*
- * XXX we could optimise the use of splx/splusb somewhat. The writer
- * process only extends qcount and qtail. We could copy them and use the copies
- * to do the copying out of the queue.
- */
-
- while ((sc->qcount > 0) && (uio->uio_resid > 0)) {
- l = (sc->qcount < uio->uio_resid? sc->qcount:uio->uio_resid);
- if (l > sizeof(buf))
- l = sizeof(buf);
- if (l > sizeof(sc->qbuf) - sc->qtail) /* transfer till end of buf */
- l = sizeof(sc->qbuf) - sc->qtail;
-
- splx(s);
- uiomove(&sc->qbuf[sc->qtail], l, uio);
- s = splusb();
-
- if ( sc->qcount - l < 0 ) {
- DPRINTF(("qcount below 0, count=%d l=%d\n", sc->qcount, l));
- sc->qcount = l;
- }
- sc->qcount -= l; /* remove the bytes from the buffer */
- sc->qtail = (sc->qtail + l) % sizeof(sc->qbuf);
- }
- splx(s);
-
- return 0;
-}
-
-static int
-ums_poll(struct cdev *dev, int events, struct thread *p)
-{
- struct ums_softc *sc;
- int revents = 0;
- int s;
-
- sc = devclass_get_softc(ums_devclass, UMSUNIT(dev));
- if (!sc)
- return 0;
-
- s = splusb();
- if (events & (POLLIN | POLLRDNORM)) {
- if (sc->qcount) {
- revents = events & (POLLIN | POLLRDNORM);
- } else {
- sc->state |= UMS_SELECT;
- selrecord(p, &sc->rsel);
- }
- }
- splx(s);
-
- return revents;
-}
-
-int
-ums_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *p)
-{
- struct ums_softc *sc;
- int error = 0;
- int s;
- mousemode_t mode;
-
- sc = devclass_get_softc(ums_devclass, UMSUNIT(dev));
- if (!sc)
- return EIO;
-
- switch(cmd) {
- case MOUSE_GETHWINFO:
- *(mousehw_t *)addr = sc->hw;
- break;
- case MOUSE_GETMODE:
- *(mousemode_t *)addr = sc->mode;
- break;
- case MOUSE_SETMODE:
- mode = *(mousemode_t *)addr;
-
- if (mode.level == -1)
- /* don't change the current setting */
- ;
- else if ((mode.level < 0) || (mode.level > 1))
- return (EINVAL);
-
- s = splusb();
- sc->mode.level = mode.level;
-
- if (sc->mode.level == 0) {
- if (sc->nbuttons > MOUSE_MSC_MAXBUTTON)
- sc->hw.buttons = MOUSE_MSC_MAXBUTTON;
- else
- sc->hw.buttons = sc->nbuttons;
- sc->mode.protocol = MOUSE_PROTO_MSC;
- sc->mode.packetsize = MOUSE_MSC_PACKETSIZE;
- sc->mode.syncmask[0] = MOUSE_MSC_SYNCMASK;
- sc->mode.syncmask[1] = MOUSE_MSC_SYNC;
- } else if (sc->mode.level == 1) {
- if (sc->nbuttons > MOUSE_SYS_MAXBUTTON)
- sc->hw.buttons = MOUSE_SYS_MAXBUTTON;
- else
- sc->hw.buttons = sc->nbuttons;
- sc->mode.protocol = MOUSE_PROTO_SYSMOUSE;
- sc->mode.packetsize = MOUSE_SYS_PACKETSIZE;
- sc->mode.syncmask[0] = MOUSE_SYS_SYNCMASK;
- sc->mode.syncmask[1] = MOUSE_SYS_SYNC;
- }
-
- bzero(sc->qbuf, sizeof(sc->qbuf));
- sc->qhead = sc->qtail = sc->qcount = 0;
- splx(s);
-
- break;
- case MOUSE_GETLEVEL:
- *(int *)addr = sc->mode.level;
- break;
- case MOUSE_SETLEVEL:
- if (*(int *)addr < 0 || *(int *)addr > 1)
- return (EINVAL);
-
- s = splusb();
- sc->mode.level = *(int *)addr;
-
- if (sc->mode.level == 0) {
- if (sc->nbuttons > MOUSE_MSC_MAXBUTTON)
- sc->hw.buttons = MOUSE_MSC_MAXBUTTON;
- else
- sc->hw.buttons = sc->nbuttons;
- sc->mode.protocol = MOUSE_PROTO_MSC;
- sc->mode.packetsize = MOUSE_MSC_PACKETSIZE;
- sc->mode.syncmask[0] = MOUSE_MSC_SYNCMASK;
- sc->mode.syncmask[1] = MOUSE_MSC_SYNC;
- } else if (sc->mode.level == 1) {
- if (sc->nbuttons > MOUSE_SYS_MAXBUTTON)
- sc->hw.buttons = MOUSE_SYS_MAXBUTTON;
- else
- sc->hw.buttons = sc->nbuttons;
- sc->mode.protocol = MOUSE_PROTO_SYSMOUSE;
- sc->mode.packetsize = MOUSE_SYS_PACKETSIZE;
- sc->mode.syncmask[0] = MOUSE_SYS_SYNCMASK;
- sc->mode.syncmask[1] = MOUSE_SYS_SYNC;
- }
-
- bzero(sc->qbuf, sizeof(sc->qbuf));
- sc->qhead = sc->qtail = sc->qcount = 0;
- splx(s);
-
- break;
- case MOUSE_GETSTATUS: {
- mousestatus_t *status = (mousestatus_t *) addr;
-
- s = splusb();
- *status = sc->status;
- sc->status.obutton = sc->status.button;
- sc->status.button = 0;
- sc->status.dx = sc->status.dy
- = sc->status.dz = /* sc->status.dt = */ 0;
- splx(s);
-
- if (status->dx || status->dy || status->dz /* || status->dt */)
- status->flags |= MOUSE_POSCHANGED;
- if (status->button != status->obutton)
- status->flags |= MOUSE_BUTTONSCHANGED;
- break;
- }
- default:
- error = ENOTTY;
- }
-
- return error;
-}
-
-MODULE_DEPEND(ums, usb, 1, 1, 1);
-DRIVER_MODULE(ums, uhub, ums_driver, ums_devclass, usbd_driver_load, 0);
diff --git a/sys/dev/usb/uplcom.c b/sys/dev/usb/uplcom.c
deleted file mode 100644
index ab5ab93..0000000
--- a/sys/dev/usb/uplcom.c
+++ /dev/null
@@ -1,990 +0,0 @@
-/* $NetBSD: uplcom.c,v 1.21 2001/11/13 06:24:56 lukem Exp $ */
-
-/*-
- * Copyright (c) 2001-2003, 2005 Shunsuke Akiyama <akiyama@jp.FreeBSD.org>.
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*-
- * Copyright (c) 2001 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Ichiro FUKUHARA (ichiro@ichiro.org).
- *
- * 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.
- */
-
-/*
- * This driver supports several USB-to-RS232 serial adapters driven by
- * Prolific PL-2303, PL-2303X and probably PL-2303HX USB-to-RS232
- * bridge chip. The adapters are sold under many different brand
- * names.
- *
- * Datasheets are available at Prolific www site at
- * http://www.prolific.com.tw. The datasheets don't contain full
- * programming information for the chip.
- *
- * PL-2303HX is probably programmed the same as PL-2303X.
- *
- * There are several differences between PL-2303 and PL-2303(H)X.
- * PL-2303(H)X can do higher bitrate in bulk mode, has _probably_
- * different command for controlling CRTSCTS and needs special
- * sequence of commands for initialization which aren't also
- * documented in the datasheet.
- */
-
-#include "opt_uplcom.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/malloc.h>
-#include <sys/bus.h>
-#include <sys/ioccom.h>
-#include <sys/fcntl.h>
-#include <sys/conf.h>
-#include <sys/serial.h>
-#include <sys/tty.h>
-#include <sys/file.h>
-#include <sys/selinfo.h>
-#include <sys/proc.h>
-#include <sys/poll.h>
-#include <sys/sysctl.h>
-#include <sys/uio.h>
-#include <sys/taskqueue.h>
-
-#include <machine/bus.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbcdc.h>
-
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdivar.h>
-#include <dev/usb/usbdi_util.h>
-#include "usbdevs.h"
-#include <dev/usb/usb_quirks.h>
-
-#include <dev/usb/ucomvar.h>
-
-SYSCTL_NODE(_hw_usb, OID_AUTO, uplcom, CTLFLAG_RW, 0, "USB uplcom");
-#ifdef USB_DEBUG
-static int uplcomdebug = 0;
-SYSCTL_INT(_hw_usb_uplcom, OID_AUTO, debug, CTLFLAG_RW,
- &uplcomdebug, 0, "uplcom debug level");
-
-#define DPRINTFN(n, x) do { \
- if (uplcomdebug > (n)) \
- printf x; \
- } while (0)
-#else
-#define DPRINTFN(n, x)
-#endif
-#define DPRINTF(x) DPRINTFN(0, x)
-
-#define UPLCOM_MODVER 1 /* module version */
-
-#define UPLCOM_CONFIG_INDEX 0
-#define UPLCOM_IFACE_INDEX 0
-#define UPLCOM_SECOND_IFACE_INDEX 1
-
-#ifndef UPLCOM_INTR_INTERVAL
-#define UPLCOM_INTR_INTERVAL 100 /* ms */
-#endif
-
-#define UPLCOM_SET_REQUEST 0x01
-#define UPLCOM_SET_CRTSCTS 0x41
-#define UPLCOM_SET_CRTSCTS_PL2303X 0x61
-#define RSAQ_STATUS_CTS 0x80
-#define RSAQ_STATUS_DSR 0x02
-#define RSAQ_STATUS_DCD 0x01
-
-#define TYPE_PL2303 0
-#define TYPE_PL2303X 1
-
-struct uplcom_softc {
- struct ucom_softc sc_ucom;
-
- int sc_iface_number; /* interface number */
-
- usbd_interface_handle sc_intr_iface; /* interrupt interface */
- int sc_intr_number; /* interrupt number */
- usbd_pipe_handle sc_intr_pipe; /* interrupt pipe */
- u_char *sc_intr_buf; /* interrupt buffer */
- int sc_isize;
-
- usb_cdc_line_state_t sc_line_state; /* current line state */
- u_char sc_dtr; /* current DTR state */
- u_char sc_rts; /* current RTS state */
- u_char sc_status;
-
- u_char sc_lsr; /* Local status register */
- u_char sc_msr; /* uplcom status register */
-
- int sc_chiptype; /* Type of chip */
-
- struct task sc_task;
-};
-
-/*
- * These are the maximum number of bytes transferred per frame.
- * The output buffer size cannot be increased due to the size encoding.
- */
-#define UPLCOMIBUFSIZE 256
-#define UPLCOMOBUFSIZE 256
-
-static usbd_status uplcom_reset(struct uplcom_softc *);
-static usbd_status uplcom_set_line_coding(struct uplcom_softc *,
- usb_cdc_line_state_t *);
-static usbd_status uplcom_set_crtscts(struct uplcom_softc *);
-static void uplcom_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
-
-static void uplcom_set(void *, int, int, int);
-static void uplcom_dtr(struct uplcom_softc *, int);
-static void uplcom_rts(struct uplcom_softc *, int);
-static void uplcom_break(struct uplcom_softc *, int);
-static void uplcom_set_line_state(struct uplcom_softc *);
-static void uplcom_get_status(void *, int, u_char *, u_char *);
-static int uplcom_param(void *, int, struct termios *);
-static int uplcom_open(void *, int);
-static void uplcom_close(void *, int);
-static void uplcom_notify(void *, int);
-
-struct ucom_callback uplcom_callback = {
- uplcom_get_status,
- uplcom_set,
- uplcom_param,
- NULL,
- uplcom_open,
- uplcom_close,
- NULL,
- NULL
-};
-
-static const struct uplcom_product {
- uint16_t vendor;
- uint16_t product;
- int32_t release; /* release is a 16bit entity,
- * if -1 is specified we "don't care"
- * This is a floor value. The table
- * must have newer revs before older
- * revs (and -1 last).
- */
- char chiptype;
-} uplcom_products [] = {
- { USB_VENDOR_RADIOSHACK, USB_PRODUCT_RADIOSHACK_USBCABLE, -1, TYPE_PL2303 },
-
- /* I/O DATA USB-RSAQ */
- { USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBRSAQ, -1, TYPE_PL2303 },
- /* Prolific Pharos */
- { USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PHAROS, -1, TYPE_PL2303 },
- /* I/O DATA USB-RSAQ2 */
- { USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_RSAQ2, -1, TYPE_PL2303 },
- /* I/O DATA USB-RSAQ3 */
- { USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_RSAQ3, -1, TYPE_PL2303X },
- /* Willcom W-SIM*/
- { USB_VENDOR_PROLIFIC2, USB_PRODUCT_PROLIFIC2_WSIM, -1, TYPE_PL2303X},
- /* PLANEX USB-RS232 URS-03 */
- { USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC232A, -1, TYPE_PL2303 },
- /* TrendNet TU-S9 */
- { USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2303,
- 0x400, TYPE_PL2303X },
- /* ST Lab USB-SERIAL-4 */
- { USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2303,
- 0x300, TYPE_PL2303X },
- /* IOGEAR/ATEN UC-232A (also ST Lab USB-SERIAL-1) */
- { USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2303, -1, TYPE_PL2303 },
- /* TDK USB-PHS Adapter UHA6400 */
- { USB_VENDOR_TDK, USB_PRODUCT_TDK_UHA6400, -1, TYPE_PL2303 },
- /* RATOC REX-USB60 */
- { USB_VENDOR_RATOC, USB_PRODUCT_RATOC_REXUSB60, -1, TYPE_PL2303 },
- /* ELECOM UC-SGT */
- { USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_UCSGT, -1, TYPE_PL2303 },
- { USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_UCSGT0, -1, TYPE_PL2303 },
- /* Sagem USB-Serial Controller */
- { USB_VENDOR_SAGEM, USB_PRODUCT_SAGEM_USBSERIAL, -1, TYPE_PL2303X },
- /* Sony Ericsson USB Cable */
- { USB_VENDOR_SONYERICSSON, USB_PRODUCT_SONYERICSSON_DCU10,
- -1,TYPE_PL2303 },
- /* SOURCENEXT KeikaiDenwa 8 */
- { USB_VENDOR_SOURCENEXT, USB_PRODUCT_SOURCENEXT_KEIKAI8,
- -1, TYPE_PL2303 },
- /* SOURCENEXT KeikaiDenwa 8 with charger */
- { USB_VENDOR_SOURCENEXT, USB_PRODUCT_SOURCENEXT_KEIKAI8_CHG,
- -1, TYPE_PL2303 },
- /* HAL Corporation Crossam2+USB */
- { USB_VENDOR_HAL, USB_PRODUCT_HAL_IMR001, -1, TYPE_PL2303 },
- /* Sitecom USB to Serial */
- { USB_VENDOR_SITECOM, USB_PRODUCT_SITECOM_SERIAL, -1, TYPE_PL2303 },
- /* Tripp-Lite U209-000-R */
- { USB_VENDOR_TRIPPLITE, USB_PRODUCT_TRIPPLITE_U209, -1, TYPE_PL2303X },
- /* Belkin F5U257 */
- { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5U257, -1, TYPE_PL2303X },
- { 0, 0 }
-};
-
-static device_probe_t uplcom_match;
-static device_attach_t uplcom_attach;
-static device_detach_t uplcom_detach;
-
-static device_method_t uplcom_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, uplcom_match),
- DEVMETHOD(device_attach, uplcom_attach),
- DEVMETHOD(device_detach, uplcom_detach),
- { 0, 0 }
-};
-
-static driver_t uplcom_driver = {
- "ucom",
- uplcom_methods,
- sizeof (struct uplcom_softc)
-};
-
-DRIVER_MODULE(uplcom, uhub, uplcom_driver, ucom_devclass, usbd_driver_load, 0);
-MODULE_DEPEND(uplcom, usb, 1, 1, 1);
-MODULE_DEPEND(uplcom, ucom, UCOM_MINVER, UCOM_PREFVER, UCOM_MAXVER);
-MODULE_VERSION(uplcom, UPLCOM_MODVER);
-
-static int uplcominterval = UPLCOM_INTR_INTERVAL;
-
-static int
-sysctl_hw_usb_uplcom_interval(SYSCTL_HANDLER_ARGS)
-{
- int err, val;
-
- val = uplcominterval;
- err = sysctl_handle_int(oidp, &val, 0, req);
- if (err != 0 || req->newptr == NULL)
- return (err);
- if (0 < val && val <= 1000)
- uplcominterval = val;
- else
- err = EINVAL;
-
- return (err);
-}
-
-SYSCTL_PROC(_hw_usb_uplcom, OID_AUTO, interval, CTLTYPE_INT | CTLFLAG_RW,
- 0, sizeof(int), sysctl_hw_usb_uplcom_interval,
- "I", "uplcom interrupt pipe interval");
-
-static int
-uplcom_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
- int i;
-
- if (uaa->iface != NULL)
- return (UMATCH_NONE);
-
- for (i = 0; uplcom_products[i].vendor != 0; i++) {
- if (uplcom_products[i].vendor == uaa->vendor &&
- uplcom_products[i].product == uaa->product &&
- (uplcom_products[i].release <= uaa->release ||
- uplcom_products[i].release == -1)) {
- return (UMATCH_VENDOR_PRODUCT);
- }
- }
- return (UMATCH_NONE);
-}
-
-static int
-uplcom_attach(device_t self)
-{
- struct uplcom_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usbd_device_handle dev = uaa->device;
- struct ucom_softc *ucom;
- usb_config_descriptor_t *cdesc;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
- const char *devname;
- usbd_status err;
- int i;
-
- ucom = &sc->sc_ucom;
- ucom->sc_dev = self;
- ucom->sc_udev = dev;
- ucom->sc_iface = uaa->iface;
-
- devname = device_get_nameunit(ucom->sc_dev);
-
- DPRINTF(("uplcom attach: sc = %p\n", sc));
-
- /* determine chip type */
- for (i = 0; uplcom_products[i].vendor != 0; i++) {
- if (uplcom_products[i].vendor == uaa->vendor &&
- uplcom_products[i].product == uaa->product &&
- (uplcom_products[i].release == uaa->release ||
- uplcom_products[i].release == -1)) {
- sc->sc_chiptype = uplcom_products[i].chiptype;
- break;
- }
- }
-
- /*
- * check we found the device - attach should have ensured we
- * don't get here without matching device
- */
- if (uplcom_products[i].vendor == 0) {
- printf("%s: didn't match\n", devname);
- ucom->sc_dying = 1;
- goto error;
- }
-
-#ifdef USB_DEBUG
- /* print the chip type */
- if (sc->sc_chiptype == TYPE_PL2303X) {
- DPRINTF(("uplcom_attach: chiptype 2303X\n"));
- } else {
- DPRINTF(("uplcom_attach: chiptype 2303\n"));
- }
-#endif
-
- /* initialize endpoints */
- ucom->sc_bulkin_no = ucom->sc_bulkout_no = -1;
- sc->sc_intr_number = -1;
- sc->sc_intr_pipe = NULL;
-
- /* Move the device into the configured state. */
- err = usbd_set_config_index(dev, UPLCOM_CONFIG_INDEX, 1);
- if (err) {
- printf("%s: failed to set configuration: %s\n",
- devname, usbd_errstr(err));
- ucom->sc_dying = 1;
- goto error;
- }
-
- /* get the config descriptor */
- cdesc = usbd_get_config_descriptor(ucom->sc_udev);
-
- if (cdesc == NULL) {
- printf("%s: failed to get configuration descriptor\n",
- device_get_nameunit(ucom->sc_dev));
- ucom->sc_dying = 1;
- goto error;
- }
-
- /* get the (first/common) interface */
- err = usbd_device2interface_handle(dev, UPLCOM_IFACE_INDEX,
- &ucom->sc_iface);
- if (err) {
- printf("%s: failed to get interface: %s\n",
- devname, usbd_errstr(err));
- ucom->sc_dying = 1;
- goto error;
- }
-
- /* Find the interrupt endpoints */
-
- id = usbd_get_interface_descriptor(ucom->sc_iface);
- sc->sc_iface_number = id->bInterfaceNumber;
-
- for (i = 0; i < id->bNumEndpoints; i++) {
- ed = usbd_interface2endpoint_descriptor(ucom->sc_iface, i);
- if (ed == NULL) {
- printf("%s: no endpoint descriptor for %d\n",
- device_get_nameunit(ucom->sc_dev), i);
- ucom->sc_dying = 1;
- goto error;
- }
-
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
- sc->sc_intr_number = ed->bEndpointAddress;
- sc->sc_isize = UGETW(ed->wMaxPacketSize);
- }
- }
-
- if (sc->sc_intr_number == -1) {
- printf("%s: Could not find interrupt in\n",
- device_get_nameunit(ucom->sc_dev));
- ucom->sc_dying = 1;
- goto error;
- }
-
- /* keep interface for interrupt */
- sc->sc_intr_iface = ucom->sc_iface;
-
- /*
- * USB-RSAQ1 has two interface
- *
- * USB-RSAQ1 | USB-RSAQ2
- * -----------------+-----------------
- * Interface 0 |Interface 0
- * Interrupt(0x81) | Interrupt(0x81)
- * -----------------+ BulkIN(0x02)
- * Interface 1 | BulkOUT(0x83)
- * BulkIN(0x02) |
- * BulkOUT(0x83) |
- */
- if (cdesc->bNumInterface == 2) {
- err = usbd_device2interface_handle(dev,
- UPLCOM_SECOND_IFACE_INDEX,
- &ucom->sc_iface);
- if (err) {
- printf("%s: failed to get second interface: %s\n",
- devname, usbd_errstr(err));
- ucom->sc_dying = 1;
- goto error;
- }
- }
-
- /* Find the bulk{in,out} endpoints */
-
- id = usbd_get_interface_descriptor(ucom->sc_iface);
- sc->sc_iface_number = id->bInterfaceNumber;
-
- for (i = 0; i < id->bNumEndpoints; i++) {
- ed = usbd_interface2endpoint_descriptor(ucom->sc_iface, i);
- if (ed == NULL) {
- printf("%s: no endpoint descriptor for %d\n",
- device_get_nameunit(ucom->sc_dev), i);
- ucom->sc_dying = 1;
- goto error;
- }
-
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
- ucom->sc_bulkin_no = ed->bEndpointAddress;
- } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
- ucom->sc_bulkout_no = ed->bEndpointAddress;
- }
- }
-
- if (ucom->sc_bulkin_no == -1) {
- printf("%s: Could not find data bulk in\n",
- device_get_nameunit(ucom->sc_dev));
- ucom->sc_dying = 1;
- goto error;
- }
-
- if (ucom->sc_bulkout_no == -1) {
- printf("%s: Could not find data bulk out\n",
- device_get_nameunit(ucom->sc_dev));
- ucom->sc_dying = 1;
- goto error;
- }
-
- sc->sc_dtr = sc->sc_rts = -1;
- ucom->sc_parent = sc;
- ucom->sc_portno = UCOM_UNK_PORTNO;
- /* bulkin, bulkout set above */
- ucom->sc_ibufsize = UPLCOMIBUFSIZE;
- ucom->sc_obufsize = UPLCOMOBUFSIZE;
- ucom->sc_ibufsizepad = UPLCOMIBUFSIZE;
- ucom->sc_opkthdrlen = 0;
- ucom->sc_callback = &uplcom_callback;
-
- err = uplcom_reset(sc);
-
- if (err) {
- printf("%s: reset failed: %s\n",
- device_get_nameunit(ucom->sc_dev), usbd_errstr(err));
- ucom->sc_dying = 1;
- goto error;
- }
-
- DPRINTF(("uplcom: in = 0x%x, out = 0x%x, intr = 0x%x\n",
- ucom->sc_bulkin_no, ucom->sc_bulkout_no, sc->sc_intr_number));
-
- TASK_INIT(&sc->sc_task, 0, uplcom_notify, sc);
- ucom_attach(&sc->sc_ucom);
- return 0;
-
-error:
- return ENXIO;
-}
-
-static int
-uplcom_detach(device_t self)
-{
- struct uplcom_softc *sc = device_get_softc(self);
- int rv = 0;
-
- DPRINTF(("uplcom_detach: sc = %p\n", sc));
-
- if (sc->sc_intr_pipe != NULL) {
- usbd_abort_pipe(sc->sc_intr_pipe);
- usbd_close_pipe(sc->sc_intr_pipe);
- free(sc->sc_intr_buf, M_USBDEV);
- sc->sc_intr_pipe = NULL;
- }
-
- sc->sc_ucom.sc_dying = 1;
-
- rv = ucom_detach(&sc->sc_ucom);
-
- return (rv);
-}
-
-static usbd_status
-uplcom_reset(struct uplcom_softc *sc)
-{
- usb_device_request_t req;
- usbd_status err;
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = UPLCOM_SET_REQUEST;
- USETW(req.wValue, 0);
- USETW(req.wIndex, sc->sc_iface_number);
- USETW(req.wLength, 0);
-
- err = usbd_do_request(sc->sc_ucom.sc_udev, &req, 0);
- if (err) {
- printf("%s: uplcom_reset: %s\n",
- device_get_nameunit(sc->sc_ucom.sc_dev), usbd_errstr(err));
- return (EIO);
- }
-
- return (0);
-}
-
-struct pl2303x_init {
- uint8_t req_type;
- uint8_t request;
- uint16_t value;
- uint16_t index;
- uint16_t length;
-};
-
-static const struct pl2303x_init pl2303x[] = {
- { UT_READ_VENDOR_DEVICE, UPLCOM_SET_REQUEST, 0x8484, 0, 0 },
- { UT_WRITE_VENDOR_DEVICE, UPLCOM_SET_REQUEST, 0x0404, 0, 0 },
- { UT_READ_VENDOR_DEVICE, UPLCOM_SET_REQUEST, 0x8484, 0, 0 },
- { UT_READ_VENDOR_DEVICE, UPLCOM_SET_REQUEST, 0x8383, 0, 0 },
- { UT_READ_VENDOR_DEVICE, UPLCOM_SET_REQUEST, 0x8484, 0, 0 },
- { UT_WRITE_VENDOR_DEVICE, UPLCOM_SET_REQUEST, 0x0404, 1, 0 },
- { UT_READ_VENDOR_DEVICE, UPLCOM_SET_REQUEST, 0x8484, 0, 0 },
- { UT_READ_VENDOR_DEVICE, UPLCOM_SET_REQUEST, 0x8383, 0, 0 },
- { UT_WRITE_VENDOR_DEVICE, UPLCOM_SET_REQUEST, 0, 1, 0 },
- { UT_WRITE_VENDOR_DEVICE, UPLCOM_SET_REQUEST, 1, 0, 0 },
- { UT_WRITE_VENDOR_DEVICE, UPLCOM_SET_REQUEST, 2, 0x44, 0 }
-};
-#define N_PL2302X_INIT (sizeof(pl2303x)/sizeof(pl2303x[0]))
-
-static usbd_status
-uplcom_pl2303x_init(struct uplcom_softc *sc)
-{
- usb_device_request_t req;
- usbd_status err;
- int i;
-
- for (i = 0; i < N_PL2302X_INIT; i++) {
- req.bmRequestType = pl2303x[i].req_type;
- req.bRequest = pl2303x[i].request;
- USETW(req.wValue, pl2303x[i].value);
- USETW(req.wIndex, pl2303x[i].index);
- USETW(req.wLength, pl2303x[i].length);
-
- err = usbd_do_request(sc->sc_ucom.sc_udev, &req, 0);
- if (err) {
- printf("%s: uplcom_pl2303x_init: %d: %s\n",
- device_get_nameunit(sc->sc_ucom.sc_dev), i,
- usbd_errstr(err));
- return (EIO);
- }
- }
-
- return (0);
-}
-
-static void
-uplcom_set_line_state(struct uplcom_softc *sc)
-{
- usb_device_request_t req;
- int ls;
- usbd_status err;
-
- ls = (sc->sc_dtr ? UCDC_LINE_DTR : 0) |
- (sc->sc_rts ? UCDC_LINE_RTS : 0);
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UCDC_SET_CONTROL_LINE_STATE;
- USETW(req.wValue, ls);
- USETW(req.wIndex, sc->sc_iface_number);
- USETW(req.wLength, 0);
-
- err = usbd_do_request(sc->sc_ucom.sc_udev, &req, 0);
- if (err)
- printf("%s: uplcom_set_line_status: %s\n",
- device_get_nameunit(sc->sc_ucom.sc_dev), usbd_errstr(err));
-}
-
-static void
-uplcom_set(void *addr, int portno, int reg, int onoff)
-{
- struct uplcom_softc *sc = addr;
-
- switch (reg) {
- case UCOM_SET_DTR:
- uplcom_dtr(sc, onoff);
- break;
- case UCOM_SET_RTS:
- uplcom_rts(sc, onoff);
- break;
- case UCOM_SET_BREAK:
- uplcom_break(sc, onoff);
- break;
- default:
- break;
- }
-}
-
-static void
-uplcom_dtr(struct uplcom_softc *sc, int onoff)
-{
- DPRINTF(("uplcom_dtr: onoff = %d\n", onoff));
-
- if (sc->sc_dtr == onoff)
- return;
- sc->sc_dtr = onoff;
-
- uplcom_set_line_state(sc);
-}
-
-static void
-uplcom_rts(struct uplcom_softc *sc, int onoff)
-{
- DPRINTF(("uplcom_rts: onoff = %d\n", onoff));
-
- if (sc->sc_rts == onoff)
- return;
- sc->sc_rts = onoff;
-
- uplcom_set_line_state(sc);
-}
-
-static void
-uplcom_break(struct uplcom_softc *sc, int onoff)
-{
- usb_device_request_t req;
- usbd_status err;
-
- DPRINTF(("uplcom_break: onoff = %d\n", onoff));
-
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UCDC_SEND_BREAK;
- USETW(req.wValue, onoff ? UCDC_BREAK_ON : UCDC_BREAK_OFF);
- USETW(req.wIndex, sc->sc_iface_number);
- USETW(req.wLength, 0);
-
- err = usbd_do_request(sc->sc_ucom.sc_udev, &req, 0);
- if (err)
- printf("%s: uplcom_break: %s\n",
- device_get_nameunit(sc->sc_ucom.sc_dev), usbd_errstr(err));
-}
-
-static usbd_status
-uplcom_set_crtscts(struct uplcom_softc *sc)
-{
- usb_device_request_t req;
- usbd_status err;
-
- DPRINTF(("uplcom_set_crtscts: on\n"));
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = UPLCOM_SET_REQUEST;
- USETW(req.wValue, 0);
- if (sc->sc_chiptype == TYPE_PL2303X)
- USETW(req.wIndex, UPLCOM_SET_CRTSCTS_PL2303X);
- else
- USETW(req.wIndex, UPLCOM_SET_CRTSCTS);
- USETW(req.wLength, 0);
-
- err = usbd_do_request(sc->sc_ucom.sc_udev, &req, 0);
- if (err) {
- printf("%s: uplcom_set_crtscts: %s\n",
- device_get_nameunit(sc->sc_ucom.sc_dev), usbd_errstr(err));
- return (err);
- }
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-static usbd_status
-uplcom_set_line_coding(struct uplcom_softc *sc, usb_cdc_line_state_t *state)
-{
- usb_device_request_t req;
- usbd_status err;
-
- DPRINTF((
-"uplcom_set_line_coding: rate = %d, fmt = %d, parity = %d bits = %d\n",
- UGETDW(state->dwDTERate), state->bCharFormat,
- state->bParityType, state->bDataBits));
-
- if (memcmp(state, &sc->sc_line_state, UCDC_LINE_STATE_LENGTH) == 0) {
- DPRINTF(("uplcom_set_line_coding: already set\n"));
- return (USBD_NORMAL_COMPLETION);
- }
-
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UCDC_SET_LINE_CODING;
- USETW(req.wValue, 0);
- USETW(req.wIndex, sc->sc_iface_number);
- USETW(req.wLength, UCDC_LINE_STATE_LENGTH);
-
- err = usbd_do_request(sc->sc_ucom.sc_udev, &req, state);
- if (err) {
- printf("%s: uplcom_set_line_coding: %s\n",
- device_get_nameunit(sc->sc_ucom.sc_dev), usbd_errstr(err));
- return (err);
- }
-
- sc->sc_line_state = *state;
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-static const int uplcom_rates[] = {
- 75, 150, 300, 600, 1200, 1800, 2400, 3600, 4800, 7200, 9600, 14400,
- 19200, 28800, 38400, 57600, 115200,
- /*
- * Higher speeds are probably possible. PL2303X supports up to
- * 6Mb and can set any rate
- */
- 230400, 460800, 614400, 921600, 1228800
-};
-#define N_UPLCOM_RATES (sizeof(uplcom_rates)/sizeof(uplcom_rates[0]))
-
-static int
-uplcom_param(void *addr, int portno, struct termios *t)
-{
- struct uplcom_softc *sc = addr;
- usbd_status err;
- usb_cdc_line_state_t ls;
- int i;
-
- DPRINTF(("uplcom_param: sc = %p\n", sc));
-
- /* Check requested baud rate */
- for (i = 0; i < N_UPLCOM_RATES; i++)
- if (uplcom_rates[i] == t->c_ospeed)
- break;
- if (i == N_UPLCOM_RATES) {
- DPRINTF(("uplcom_param: bad baud rate (%d)\n", t->c_ospeed));
- return (EIO);
- }
-
- USETDW(ls.dwDTERate, t->c_ospeed);
- if (ISSET(t->c_cflag, CSTOPB))
- ls.bCharFormat = UCDC_STOP_BIT_2;
- else
- ls.bCharFormat = UCDC_STOP_BIT_1;
- if (ISSET(t->c_cflag, PARENB)) {
- if (ISSET(t->c_cflag, PARODD))
- ls.bParityType = UCDC_PARITY_ODD;
- else
- ls.bParityType = UCDC_PARITY_EVEN;
- } else
- ls.bParityType = UCDC_PARITY_NONE;
- switch (ISSET(t->c_cflag, CSIZE)) {
- case CS5:
- ls.bDataBits = 5;
- break;
- case CS6:
- ls.bDataBits = 6;
- break;
- case CS7:
- ls.bDataBits = 7;
- break;
- case CS8:
- ls.bDataBits = 8;
- break;
- }
-
- err = uplcom_set_line_coding(sc, &ls);
- if (err)
- return (EIO);
-
- if (ISSET(t->c_cflag, CRTSCTS)) {
- err = uplcom_set_crtscts(sc);
- if (err)
- return (EIO);
- }
-
- return (0);
-}
-
-static int
-uplcom_open(void *addr, int portno)
-{
- struct uplcom_softc *sc = addr;
- int err;
-
- if (sc->sc_ucom.sc_dying)
- return (ENXIO);
-
- DPRINTF(("uplcom_open: sc = %p\n", sc));
-
- if (sc->sc_intr_number != -1 && sc->sc_intr_pipe == NULL) {
- sc->sc_status = 0; /* clear status bit */
- sc->sc_intr_buf = malloc(sc->sc_isize, M_USBDEV, M_WAITOK);
- err = usbd_open_pipe_intr(sc->sc_intr_iface,
- sc->sc_intr_number,
- USBD_SHORT_XFER_OK,
- &sc->sc_intr_pipe,
- sc,
- sc->sc_intr_buf,
- sc->sc_isize,
- uplcom_intr,
- uplcominterval);
- if (err) {
- printf("%s: cannot open interrupt pipe (addr %d)\n",
- device_get_nameunit(sc->sc_ucom.sc_dev),
- sc->sc_intr_number);
- return (EIO);
- }
- }
-
- if (sc->sc_chiptype == TYPE_PL2303X)
- return (uplcom_pl2303x_init(sc));
-
- return (0);
-}
-
-static void
-uplcom_close(void *addr, int portno)
-{
- struct uplcom_softc *sc = addr;
- int err;
-
- if (sc->sc_ucom.sc_dying)
- return;
-
- DPRINTF(("uplcom_close: close\n"));
-
- if (sc->sc_intr_pipe != NULL) {
- err = usbd_abort_pipe(sc->sc_intr_pipe);
- if (err)
- printf("%s: abort interrupt pipe failed: %s\n",
- device_get_nameunit(sc->sc_ucom.sc_dev),
- usbd_errstr(err));
- err = usbd_close_pipe(sc->sc_intr_pipe);
- if (err)
- printf("%s: close interrupt pipe failed: %s\n",
- device_get_nameunit(sc->sc_ucom.sc_dev),
- usbd_errstr(err));
- free(sc->sc_intr_buf, M_USBDEV);
- sc->sc_intr_pipe = NULL;
- }
-}
-
-static void
-uplcom_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- struct uplcom_softc *sc = priv;
- u_char *buf = sc->sc_intr_buf;
- u_char pstatus;
-
- if (sc->sc_ucom.sc_dying)
- return;
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
- return;
-
- DPRINTF(("%s: uplcom_intr: abnormal status: %s\n",
- device_get_nameunit(sc->sc_ucom.sc_dev),
- usbd_errstr(status)));
- usbd_clear_endpoint_stall_async(sc->sc_intr_pipe);
- return;
- }
-
- DPRINTF(("%s: uplcom status = %02x\n",
- device_get_nameunit(sc->sc_ucom.sc_dev), buf[8]));
-
- sc->sc_lsr = sc->sc_msr = 0;
- pstatus = buf[8];
- if (ISSET(pstatus, RSAQ_STATUS_CTS))
- sc->sc_msr |= SER_CTS;
- else
- sc->sc_msr &= ~SER_CTS;
- if (ISSET(pstatus, RSAQ_STATUS_DSR))
- sc->sc_msr |= SER_DSR;
- else
- sc->sc_msr &= ~SER_DSR;
- if (ISSET(pstatus, RSAQ_STATUS_DCD))
- sc->sc_msr |= SER_DCD;
- else
- sc->sc_msr &= ~SER_DCD;
-
- /* Deferred notifying to the ucom layer */
- taskqueue_enqueue(taskqueue_swi_giant, &sc->sc_task);
-}
-
-static void
-uplcom_notify(void *arg, int count)
-{
- struct uplcom_softc *sc;
-
- sc = (struct uplcom_softc *)arg;
- if (sc->sc_ucom.sc_dying)
- return;
- ucom_status_change(&sc->sc_ucom);
-}
-
-static void
-uplcom_get_status(void *addr, int portno, u_char *lsr, u_char *msr)
-{
- struct uplcom_softc *sc = addr;
-
- DPRINTF(("uplcom_get_status:\n"));
-
- if (lsr != NULL)
- *lsr = sc->sc_lsr;
- if (msr != NULL)
- *msr = sc->sc_msr;
-}
diff --git a/sys/dev/usb/urio.c b/sys/dev/usb/urio.c
deleted file mode 100644
index 5f69918..0000000
--- a/sys/dev/usb/urio.c
+++ /dev/null
@@ -1,518 +0,0 @@
-/*-
- * Copyright (c) 2000 Iwasa Kazmi
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- * This code is based on ugen.c and ulpt.c developed by Lennart Augustsson.
- * This code includes software developed by the NetBSD Foundation, Inc. and
- * its contributors.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-
-/*
- * 2000/3/24 added NetBSD/OpenBSD support (from Alex Nemirovsky)
- * 2000/3/07 use two bulk-pipe handles for read and write (Dirk)
- * 2000/3/06 change major number(143), and copyright header
- * some fix for 4.0 (Dirk)
- * 2000/3/05 codes for FreeBSD 4.x - CURRENT (Thanks to Dirk-Willem van Gulik)
- * 2000/3/01 remove retry code from urioioctl()
- * change method of bulk transfer (no interrupt)
- * 2000/2/28 small fixes for new rio_usb.h
- * 2000/2/24 first version.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/ioccom.h>
-#include <sys/fcntl.h>
-#include <sys/filio.h>
-#include <sys/conf.h>
-#include <sys/uio.h>
-#include <sys/tty.h>
-#include <sys/file.h>
-#include <sys/selinfo.h>
-#include <sys/poll.h>
-#include <sys/sysctl.h>
-#include <sys/uio.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-
-#include "usbdevs.h"
-#include <dev/usb/rio500_usb.h>
-
-#ifdef USB_DEBUG
-#define DPRINTF(x) if (uriodebug) printf x
-#define DPRINTFN(n,x) if (uriodebug>(n)) printf x
-int uriodebug = 0;
-SYSCTL_NODE(_hw_usb, OID_AUTO, urio, CTLFLAG_RW, 0, "USB urio");
-SYSCTL_INT(_hw_usb_urio, OID_AUTO, debug, CTLFLAG_RW,
- &uriodebug, 0, "urio debug level");
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-/* difference of usbd interface */
-#define USBDI 1
-
-#define RIO_OUT 0
-#define RIO_IN 1
-#define RIO_NODIR 2
-
-d_open_t urioopen;
-d_close_t urioclose;
-d_read_t urioread;
-d_write_t uriowrite;
-d_ioctl_t urioioctl;
-
-
-static struct cdevsw urio_cdevsw = {
- .d_version = D_VERSION,
- .d_flags = D_NEEDGIANT,
- .d_open = urioopen,
- .d_close = urioclose,
- .d_read = urioread,
- .d_write = uriowrite,
- .d_ioctl = urioioctl,
- .d_name = "urio",
-};
-#define RIO_UE_GET_DIR(p) ((UE_GET_DIR(p) == UE_DIR_IN) ? RIO_IN :\
- ((UE_GET_DIR(p) == UE_DIR_OUT) ? RIO_OUT :\
- RIO_NODIR))
-
-#define URIO_BBSIZE 1024
-
-struct urio_softc {
- device_t sc_dev;
- usbd_device_handle sc_udev;
- usbd_interface_handle sc_iface;
-
- int sc_opened;
- usbd_pipe_handle sc_pipeh_in;
- usbd_pipe_handle sc_pipeh_out;
- int sc_epaddr[2];
-
- int sc_refcnt;
- struct cdev *sc_dev_t;
- u_char sc_dying;
-};
-
-#define URIOUNIT(n) (dev2unit(n))
-
-#define RIO_RW_TIMEOUT 4000 /* ms */
-
-static device_probe_t urio_match;
-static device_attach_t urio_attach;
-static device_detach_t urio_detach;
-
-static device_method_t urio_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, urio_match),
- DEVMETHOD(device_attach, urio_attach),
- DEVMETHOD(device_detach, urio_detach),
-
- { 0, 0 }
-};
-
-static driver_t urio_driver = {
- "urio",
- urio_methods,
- sizeof(struct urio_softc)
-};
-
-static devclass_t urio_devclass;
-
-static int
-urio_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usb_device_descriptor_t *dd;
-
- DPRINTFN(10,("urio_match\n"));
- if (!uaa->iface)
- return UMATCH_NONE;
-
- dd = usbd_get_device_descriptor(uaa->device);
-
- if (dd &&
- ((UGETW(dd->idVendor) == USB_VENDOR_DIAMOND &&
- UGETW(dd->idProduct) == USB_PRODUCT_DIAMOND_RIO500USB) ||
- (UGETW(dd->idVendor) == USB_VENDOR_DIAMOND2 &&
- (UGETW(dd->idProduct) == USB_PRODUCT_DIAMOND2_RIO600USB ||
- UGETW(dd->idProduct) == USB_PRODUCT_DIAMOND2_RIO800USB))))
- return UMATCH_VENDOR_PRODUCT;
- else
- return UMATCH_NONE;
-}
-
-static int
-urio_attach(device_t self)
-{
- struct urio_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usbd_device_handle udev;
- usbd_interface_handle iface;
- u_int8_t epcount;
- usbd_status r;
- char * ermsg = "<none>";
- int i;
-
- DPRINTFN(10,("urio_attach: sc=%p\n", sc));
- sc->sc_dev = self;
- sc->sc_udev = udev = uaa->device;
-
- if ((!uaa->device) || (!uaa->iface)) {
- ermsg = "device or iface";
- goto nobulk;
- }
- sc->sc_iface = iface = uaa->iface;
- sc->sc_opened = 0;
- sc->sc_pipeh_in = 0;
- sc->sc_pipeh_out = 0;
- sc->sc_refcnt = 0;
-
- r = usbd_endpoint_count(iface, &epcount);
- if (r != USBD_NORMAL_COMPLETION) {
- ermsg = "endpoints";
- goto nobulk;
- }
-
- sc->sc_epaddr[RIO_OUT] = 0xff;
- sc->sc_epaddr[RIO_IN] = 0x00;
-
- for (i = 0; i < epcount; i++) {
- usb_endpoint_descriptor_t *edesc =
- usbd_interface2endpoint_descriptor(iface, i);
- int d;
-
- if (!edesc) {
- ermsg = "interface endpoint";
- goto nobulk;
- }
-
- d = RIO_UE_GET_DIR(edesc->bEndpointAddress);
- if (d != RIO_NODIR)
- sc->sc_epaddr[d] = edesc->bEndpointAddress;
- }
- if ( sc->sc_epaddr[RIO_OUT] == 0xff ||
- sc->sc_epaddr[RIO_IN] == 0x00) {
- ermsg = "Rio I&O";
- goto nobulk;
- }
-
- sc->sc_dev_t = make_dev(&urio_cdevsw, device_get_unit(self),
- UID_ROOT, GID_OPERATOR,
- 0644, "urio%d", device_get_unit(self));
- DPRINTFN(10, ("urio_attach: %p\n", sc->sc_udev));
-
- return 0;
-
- nobulk:
- printf("%s: could not find %s\n", device_get_nameunit(sc->sc_dev),ermsg);
- return ENXIO;
-}
-
-
-int
-urioopen(struct cdev *dev, int flag, int mode, struct thread *p)
-{
- struct urio_softc * sc;
- int unit = URIOUNIT(dev);
- sc = devclass_get_softc(urio_devclass, unit);
- if (sc == NULL)
- return (ENXIO);
-
- DPRINTFN(5, ("urioopen: flag=%d, mode=%d, unit=%d\n",
- flag, mode, unit));
-
- if (sc->sc_opened)
- return EBUSY;
-
- if ((flag & (FWRITE|FREAD)) != (FWRITE|FREAD))
- return EACCES;
-
- sc->sc_opened = 1;
- sc->sc_pipeh_in = 0;
- sc->sc_pipeh_out = 0;
- if (usbd_open_pipe(sc->sc_iface,
- sc->sc_epaddr[RIO_IN], 0, &sc->sc_pipeh_in)
- != USBD_NORMAL_COMPLETION)
- {
- sc->sc_pipeh_in = 0;
- return EIO;
- };
- if (usbd_open_pipe(sc->sc_iface,
- sc->sc_epaddr[RIO_OUT], 0, &sc->sc_pipeh_out)
- != USBD_NORMAL_COMPLETION)
- {
- usbd_close_pipe(sc->sc_pipeh_in);
- sc->sc_pipeh_in = 0;
- sc->sc_pipeh_out = 0;
- return EIO;
- };
- return 0;
-}
-
-int
-urioclose(struct cdev *dev, int flag, int mode, struct thread *p)
-{
- struct urio_softc * sc;
- int unit = URIOUNIT(dev);
- sc = devclass_get_softc(urio_devclass, unit);
-
- DPRINTFN(5, ("urioclose: flag=%d, mode=%d, unit=%d\n", flag, mode, unit));
- if (sc->sc_pipeh_in)
- usbd_close_pipe(sc->sc_pipeh_in);
-
- if (sc->sc_pipeh_out)
- usbd_close_pipe(sc->sc_pipeh_out);
-
- sc->sc_pipeh_in = 0;
- sc->sc_pipeh_out = 0;
- sc->sc_opened = 0;
- sc->sc_refcnt = 0;
- return 0;
-}
-
-int
-urioread(struct cdev *dev, struct uio *uio, int flag)
-{
- struct urio_softc * sc;
- usbd_xfer_handle reqh;
- int unit = URIOUNIT(dev);
- usbd_status r;
- char buf[URIO_BBSIZE];
- u_int32_t n, tn;
- int error = 0;
-
- sc = devclass_get_softc(urio_devclass, unit);
-
- DPRINTFN(5, ("urioread: %d\n", unit));
- if (!sc->sc_opened)
- return EIO;
-
- sc->sc_refcnt++;
- reqh = usbd_alloc_xfer(sc->sc_udev);
- if (reqh == 0)
- return ENOMEM;
- while ((n = min(URIO_BBSIZE, uio->uio_resid)) != 0) {
- DPRINTFN(1, ("urioread: start transfer %d bytes\n", n));
- tn = n;
- usbd_setup_xfer(reqh, sc->sc_pipeh_in, 0, buf, tn,
- 0, RIO_RW_TIMEOUT, 0);
- r = usbd_sync_transfer(reqh);
- if (r != USBD_NORMAL_COMPLETION) {
- DPRINTFN(1, ("urioread: error=%d\n", r));
- usbd_clear_endpoint_stall(sc->sc_pipeh_in);
- tn = 0;
- error = EIO;
- break;
- }
- usbd_get_xfer_status(reqh, 0, 0, &tn, 0);
-
- DPRINTFN(1, ("urioread: got %d bytes\n", tn));
- error = uiomove(buf, tn, uio);
- if (error || tn < n)
- break;
- }
- usbd_free_xfer(reqh);
- return error;
-}
-
-int
-uriowrite(struct cdev *dev, struct uio *uio, int flag)
-{
- struct urio_softc * sc;
- usbd_xfer_handle reqh;
- int unit = URIOUNIT(dev);
- usbd_status r;
- char buf[URIO_BBSIZE];
- u_int32_t n;
- int error = 0;
-
- sc = devclass_get_softc(urio_devclass, unit);
- DPRINTFN(5, ("uriowrite: %d\n", unit));
- if (!sc->sc_opened)
- return EIO;
-
- sc->sc_refcnt++;
- reqh = usbd_alloc_xfer(sc->sc_udev);
- if (reqh == 0)
- return EIO;
- while ((n = min(URIO_BBSIZE, uio->uio_resid)) != 0) {
- error = uiomove(buf, n, uio);
- if (error)
- break;
- DPRINTFN(1, ("uriowrite: transfer %d bytes\n", n));
- usbd_setup_xfer(reqh, sc->sc_pipeh_out, 0, buf, n,
- 0, RIO_RW_TIMEOUT, 0);
- r = usbd_sync_transfer(reqh);
- if (r != USBD_NORMAL_COMPLETION) {
- DPRINTFN(1, ("uriowrite: error=%d\n", r));
- usbd_clear_endpoint_stall(sc->sc_pipeh_out);
- error = EIO;
- break;
- }
- usbd_get_xfer_status(reqh, 0, 0, 0, 0);
- }
-
- usbd_free_xfer(reqh);
- return error;
-}
-
-
-int
-urioioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *p)
-{
- struct urio_softc * sc;
- int unit = URIOUNIT(dev);
- struct RioCommand *rio_cmd;
- int requesttype, len;
- struct iovec iov;
- struct uio uio;
- usb_device_request_t req;
- int req_flags = 0, req_actlen = 0;
- void *ptr = 0;
- int error = 0;
- usbd_status r;
-
- sc = devclass_get_softc(urio_devclass, unit);
- switch (cmd) {
- case RIO_RECV_COMMAND:
- if (!(flag & FWRITE))
- return EPERM;
- rio_cmd = (struct RioCommand *)addr;
- if (rio_cmd == NULL)
- return EINVAL;
- len = rio_cmd->length;
-
- requesttype = rio_cmd->requesttype | UT_READ_VENDOR_DEVICE;
- DPRINTFN(1,("sending command:reqtype=%0x req=%0x value=%0x index=%0x len=%0x\n",
- requesttype, rio_cmd->request, rio_cmd->value, rio_cmd->index, len));
- break;
-
- case RIO_SEND_COMMAND:
- if (!(flag & FWRITE))
- return EPERM;
- rio_cmd = (struct RioCommand *)addr;
- if (rio_cmd == NULL)
- return EINVAL;
- len = rio_cmd->length;
-
- requesttype = rio_cmd->requesttype | UT_WRITE_VENDOR_DEVICE;
- DPRINTFN(1,("sending command:reqtype=%0x req=%0x value=%0x index=%0x len=%0x\n",
- requesttype, rio_cmd->request, rio_cmd->value, rio_cmd->index, len));
- break;
-
- default:
- return EINVAL;
- break;
- }
-
- /* Send rio control message */
- req.bmRequestType = requesttype;
- req.bRequest = rio_cmd->request;
- USETW(req.wValue, rio_cmd->value);
- USETW(req.wIndex, rio_cmd->index);
- USETW(req.wLength, len);
-
- if (len < 0 || len > 32767)
- return EINVAL;
- if (len != 0) {
- iov.iov_base = (caddr_t)rio_cmd->buffer;
- iov.iov_len = len;
- uio.uio_iov = &iov;
- uio.uio_iovcnt = 1;
- uio.uio_resid = len;
- uio.uio_offset = 0;
- uio.uio_segflg = UIO_USERSPACE;
- uio.uio_rw =
- req.bmRequestType & UT_READ ?
- UIO_READ : UIO_WRITE;
- uio.uio_td = p;
- ptr = malloc(len, M_TEMP, M_WAITOK);
- if (uio.uio_rw == UIO_WRITE) {
- error = uiomove(ptr, len, &uio);
- if (error)
- goto ret;
- }
- }
-
- r = usbd_do_request_flags(sc->sc_udev, &req,
- ptr, req_flags, &req_actlen,
- USBD_DEFAULT_TIMEOUT);
- if (r == USBD_NORMAL_COMPLETION) {
- error = 0;
- if (len != 0) {
- if (uio.uio_rw == UIO_READ) {
- error = uiomove(ptr, len, &uio);
- }
- }
- } else {
- error = EIO;
- }
-
-ret:
- if (ptr)
- free(ptr, M_TEMP);
- return error;
-}
-
-static int
-urio_detach(device_t self)
-{
- struct urio_softc *sc = device_get_softc(self);
- int s;
-
- DPRINTF(("urio_detach: sc=%p\n", sc));
- sc->sc_dying = 1;
- if (sc->sc_pipeh_in)
- usbd_abort_pipe(sc->sc_pipeh_in);
-
- if (sc->sc_pipeh_out)
- usbd_abort_pipe(sc->sc_pipeh_out);
-
- s = splusb();
- if (--sc->sc_refcnt >= 0) {
- /* Wait for processes to go away. */
- usb_detach_wait(sc->sc_dev);
- }
- splx(s);
-
- destroy_dev(sc->sc_dev_t);
- /* XXX not implemented yet */
- device_set_desc(self, NULL);
- return 0;
-}
-
-MODULE_DEPEND(uscanner, usb, 1, 1, 1);
-DRIVER_MODULE(urio, uhub, urio_driver, urio_devclass, usbd_driver_load, 0);
diff --git a/sys/dev/usb/usb.c b/sys/dev/usb/usb.c
deleted file mode 100644
index b1b7d44..0000000
--- a/sys/dev/usb/usb.c
+++ /dev/null
@@ -1,939 +0,0 @@
-/* $NetBSD: usb.c,v 1.68 2002/02/20 20:30:12 christos Exp $ */
-
-/* Also already merged from NetBSD:
- * $NetBSD: usb.c,v 1.70 2002/05/09 21:54:32 augustss Exp $
- * $NetBSD: usb.c,v 1.71 2002/06/01 23:51:04 lukem Exp $
- * $NetBSD: usb.c,v 1.73 2002/09/23 05:51:19 simonb Exp $
- * $NetBSD: usb.c,v 1.80 2003/11/07 17:03:25 wiz Exp $
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) 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.
- */
-
-/*
- * USB specifications and other documentation can be found at
- * http://www.usb.org/developers/docs/ and
- * http://www.usb.org/developers/devclass_docs/
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/mutex.h>
-#include <sys/unistd.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/fcntl.h>
-#include <sys/filio.h>
-#include <sys/uio.h>
-#include <sys/kthread.h>
-#include <sys/proc.h>
-#include <sys/conf.h>
-#include <sys/poll.h>
-#include <sys/selinfo.h>
-#include <sys/signalvar.h>
-#include <sys/sysctl.h>
-#include <sys/uio.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-
-#define USBUNIT(d) (dev2unit(d)) /* usb_discover device nodes, kthread */
-#define USB_DEV_MINOR 255 /* event queue device */
-
-MALLOC_DEFINE(M_USB, "USB", "USB");
-MALLOC_DEFINE(M_USBDEV, "USBdev", "USB device");
-MALLOC_DEFINE(M_USBHC, "USBHC", "USB host controller");
-
-#include "usb_if.h"
-
-#include <machine/bus.h>
-
-#include <dev/usb/usbdivar.h>
-#include <dev/usb/usb_quirks.h>
-
-/* Define this unconditionally in case a kernel module is loaded that
- * has been compiled with debugging options.
- */
-SYSCTL_NODE(_hw, OID_AUTO, usb, CTLFLAG_RW, 0, "USB debugging");
-
-#ifdef USB_DEBUG
-#define DPRINTF(x) if (usbdebug) printf x
-#define DPRINTFN(n,x) if (usbdebug>(n)) printf x
-int usbdebug = 0;
-SYSCTL_INT(_hw_usb, OID_AUTO, debug, CTLFLAG_RW,
- &usbdebug, 0, "usb debug level");
-/*
- * 0 - do usual exploration
- * 1 - do not use timeout exploration
- * >1 - do no exploration
- */
-int usb_noexplore = 0;
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-struct usb_softc {
- device_t sc_dev; /* base device */
- struct cdev *sc_usbdev; /* /dev/usbN device */
- TAILQ_ENTRY(usb_softc) sc_coldexplist; /* cold needs-explore list */
- usbd_bus_handle sc_bus; /* USB controller */
- struct usbd_port sc_port; /* dummy port for root hub */
-
- struct proc *sc_event_thread;
-
- char sc_dying;
-};
-
-struct usb_taskq {
- TAILQ_HEAD(, usb_task) tasks;
- struct proc *task_thread_proc;
- const char *name;
- int taskcreated; /* task thread exists. */
-};
-
-static struct usb_taskq usb_taskq[USB_NUM_TASKQS];
-
-d_open_t usbopen;
-d_close_t usbclose;
-d_read_t usbread;
-d_ioctl_t usbioctl;
-d_poll_t usbpoll;
-
-struct cdevsw usb_cdevsw = {
- .d_version = D_VERSION,
- .d_flags = D_NEEDGIANT,
- .d_open = usbopen,
- .d_close = usbclose,
- .d_read = usbread,
- .d_ioctl = usbioctl,
- .d_poll = usbpoll,
- .d_name = "usb",
-};
-
-static void usb_discover(void *);
-static void usb_create_event_thread(void *);
-static void usb_event_thread(void *);
-static void usb_task_thread(void *);
-
-static struct cdev *usb_dev; /* The /dev/usb device. */
-static int usb_ndevs; /* Number of /dev/usbN devices. */
-/* Busses to explore at the end of boot-time device configuration. */
-static TAILQ_HEAD(, usb_softc) usb_coldexplist =
- TAILQ_HEAD_INITIALIZER(usb_coldexplist);
-
-#define USB_MAX_EVENTS 100
-struct usb_event_q {
- struct usb_event ue;
- TAILQ_ENTRY(usb_event_q) next;
-};
-static TAILQ_HEAD(, usb_event_q) usb_events =
- TAILQ_HEAD_INITIALIZER(usb_events);
-static int usb_nevents = 0;
-static struct selinfo usb_selevent;
-static struct proc *usb_async_proc; /* process that wants USB SIGIO */
-static int usb_dev_open = 0;
-static void usb_add_event(int, struct usb_event *);
-
-static int usb_get_next_event(struct usb_event *);
-
-static const char *usbrev_str[] = USBREV_STR;
-
-static device_probe_t usb_match;
-static device_attach_t usb_attach;
-static device_detach_t usb_detach;
-static bus_child_detached_t usb_child_detached;
-
-static device_method_t usb_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, usb_match),
- DEVMETHOD(device_attach, usb_attach),
- DEVMETHOD(device_detach, usb_detach),
- DEVMETHOD(device_suspend, bus_generic_suspend),
- DEVMETHOD(device_resume, bus_generic_resume),
- DEVMETHOD(device_shutdown, bus_generic_shutdown),
-
- /* Bus interface */
- DEVMETHOD(bus_child_detached, usb_child_detached),
-
- { 0, 0 }
-};
-
-static driver_t usb_driver = {
- "usb",
- usb_methods,
- sizeof(struct usb_softc)
-};
-
-static devclass_t usb_devclass;
-
-DRIVER_MODULE(usb, ohci, usb_driver, usb_devclass, 0, 0);
-DRIVER_MODULE(usb, uhci, usb_driver, usb_devclass, 0, 0);
-DRIVER_MODULE(usb, ehci, usb_driver, usb_devclass, 0, 0);
-DRIVER_MODULE(usb, slhci, usb_driver, usb_devclass, 0, 0);
-MODULE_VERSION(usb, 1);
-
-static int
-usb_match(device_t self)
-{
- DPRINTF(("usbd_match\n"));
- return (UMATCH_GENERIC);
-}
-
-static int
-usb_attach(device_t self)
-{
- struct usb_softc *sc = device_get_softc(self);
- void *aux = device_get_ivars(self);
- usbd_device_handle dev;
- usbd_status err;
- int usbrev;
- int speed;
- struct usb_event ue;
-
- sc->sc_dev = self;
-
- DPRINTF(("usbd_attach\n"));
-
- usbd_init();
- sc->sc_bus = aux;
- sc->sc_bus->usbctl = sc;
- sc->sc_port.power = USB_MAX_POWER;
-
- printf("%s", device_get_nameunit(sc->sc_dev));
- usbrev = sc->sc_bus->usbrev;
- printf(": USB revision %s", usbrev_str[usbrev]);
- switch (usbrev) {
- case USBREV_1_0:
- case USBREV_1_1:
- speed = USB_SPEED_FULL;
- break;
- case USBREV_2_0:
- speed = USB_SPEED_HIGH;
- break;
- default:
- printf(", not supported\n");
- sc->sc_dying = 1;
- return ENXIO;
- }
- printf("\n");
-
- /* Make sure not to use tsleep() if we are cold booting. */
- if (cold)
- sc->sc_bus->use_polling++;
-
- ue.u.ue_ctrlr.ue_bus = device_get_unit(sc->sc_dev);
- usb_add_event(USB_EVENT_CTRLR_ATTACH, &ue);
-
-#ifdef USB_USE_SOFTINTR
-#ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
- /* XXX we should have our own level */
- sc->sc_bus->soft = softintr_establish(IPL_SOFTNET,
- sc->sc_bus->methods->soft_intr, sc->sc_bus);
- if (sc->sc_bus->soft == NULL) {
- printf("%s: can't register softintr\n", device_get_nameunit(sc->sc_dev));
- sc->sc_dying = 1;
- return ENXIO;
- }
-#else
- usb_callout_init(sc->sc_bus->softi);
-#endif
-#endif
-
- err = usbd_new_device(sc->sc_dev, sc->sc_bus, 0, speed, 0,
- &sc->sc_port);
- if (!err) {
- dev = sc->sc_port.device;
- if (dev->hub == NULL) {
- sc->sc_dying = 1;
- printf("%s: root device is not a hub\n",
- device_get_nameunit(sc->sc_dev));
- return ENXIO;
- }
- sc->sc_bus->root_hub = dev;
-#if 1
- /*
- * Turning this code off will delay attachment of USB devices
- * until the USB event thread is running, which means that
- * the keyboard will not work until after cold boot.
- */
- if (cold) {
- /* Explore high-speed busses before others. */
- if (speed == USB_SPEED_HIGH)
- dev->hub->explore(sc->sc_bus->root_hub);
- else
- TAILQ_INSERT_TAIL(&usb_coldexplist, sc,
- sc_coldexplist);
- }
-#endif
- } else {
- printf("%s: root hub problem, error=%d\n",
- device_get_nameunit(sc->sc_dev), err);
- sc->sc_dying = 1;
- }
- if (cold)
- sc->sc_bus->use_polling--;
-
- /* XXX really do right config_pending_incr(); */
- usb_create_event_thread(sc);
- /* The per controller devices (used for usb_discover) */
- /* XXX This is redundant now, but old usbd's will want it */
- sc->sc_usbdev = make_dev(&usb_cdevsw, device_get_unit(self), UID_ROOT,
- GID_OPERATOR, 0660, "usb%d", device_get_unit(self));
- if (usb_ndevs++ == 0) {
- /* The device spitting out events */
- usb_dev = make_dev(&usb_cdevsw, USB_DEV_MINOR, UID_ROOT,
- GID_OPERATOR, 0660, "usb");
- }
- return 0;
-}
-
-static const char *taskq_names[] = USB_TASKQ_NAMES;
-
-void
-usb_create_event_thread(void *arg)
-{
- struct usb_softc *sc = arg;
- struct usb_taskq *taskq;
- int i;
-
- if (kproc_create(usb_event_thread, sc, &sc->sc_event_thread,
- RFHIGHPID, 0, device_get_nameunit(sc->sc_dev))) {
- printf("%s: unable to create event thread for\n",
- device_get_nameunit(sc->sc_dev));
- panic("usb_create_event_thread");
- }
- for (i = 0; i < USB_NUM_TASKQS; i++) {
- taskq = &usb_taskq[i];
-
- if (taskq->taskcreated == 0) {
- taskq->taskcreated = 1;
- taskq->name = taskq_names[i];
- TAILQ_INIT(&taskq->tasks);
- if (kproc_create(usb_task_thread, taskq,
- &taskq->task_thread_proc, RFHIGHPID, 0,
- taskq->name)) {
- printf("unable to create task thread\n");
- panic("usb_create_event_thread task");
- }
- }
- }
-}
-
-/*
- * Add a task to be performed by the task thread. This function can be
- * called from any context and the task will be executed in a process
- * context ASAP.
- */
-void
-usb_add_task(usbd_device_handle dev, struct usb_task *task, int queue)
-{
- struct usb_taskq *taskq;
- int s;
-
- s = splusb();
- taskq = &usb_taskq[queue];
- if (task->queue == -1) {
- DPRINTFN(2,("usb_add_task: task=%p\n", task));
- TAILQ_INSERT_TAIL(&taskq->tasks, task, next);
- task->queue = queue;
- } else {
- DPRINTFN(3,("usb_add_task: task=%p on q\n", task));
- }
- wakeup(&taskq->tasks);
- splx(s);
-}
-
-void
-usb_rem_task(usbd_device_handle dev, struct usb_task *task)
-{
- struct usb_taskq *taskq;
- int s;
-
- s = splusb();
- if (task->queue != -1) {
- taskq = &usb_taskq[task->queue];
- TAILQ_REMOVE(&taskq->tasks, task, next);
- task->queue = -1;
- }
- splx(s);
-}
-
-void
-usb_event_thread(void *arg)
-{
- static int newthread_wchan;
- struct usb_softc *sc = arg;
-
- mtx_lock(&Giant);
-
- DPRINTF(("usb_event_thread: start\n"));
-
- /*
- * In case this controller is a companion controller to an
- * EHCI controller we need to wait until the EHCI controller
- * has grabbed the port. What we do here is wait until no new
- * USB threads have been created in a while. XXX we actually
- * just want to wait for the PCI slot to be fully scanned.
- *
- * Note that when you `kldload usb' it actually attaches the
- * devices in order that the drivers appear in the kld, not the
- * normal PCI order, since the addition of each driver within
- * usb.ko (ohci, ehci etc.) causes a separate PCI bus re-scan.
- */
- wakeup(&newthread_wchan);
- for (;;) {
- if (tsleep(&newthread_wchan , PWAIT, "usbets", hz * 4) != 0)
- break;
- }
-
- /* Make sure first discover does something. */
- sc->sc_bus->needs_explore = 1;
- usb_discover(sc);
- /* XXX really do right config_pending_decr(); */
-
- while (!sc->sc_dying) {
-#ifdef USB_DEBUG
- if (usb_noexplore < 2)
-#endif
- usb_discover(sc);
-#ifdef USB_DEBUG
- (void)tsleep(&sc->sc_bus->needs_explore, PWAIT, "usbevt",
- usb_noexplore ? 0 : hz * 60);
-#else
- (void)tsleep(&sc->sc_bus->needs_explore, PWAIT, "usbevt",
- hz * 60);
-#endif
- DPRINTFN(2,("usb_event_thread: woke up\n"));
- }
- sc->sc_event_thread = NULL;
-
- /* In case parent is waiting for us to exit. */
- wakeup(sc);
-
- DPRINTF(("usb_event_thread: exit\n"));
- while (mtx_owned(&Giant))
- mtx_unlock(&Giant);
- kproc_exit(0);
-}
-
-void
-usb_task_thread(void *arg)
-{
- struct usb_task *task;
- struct usb_taskq *taskq;
- int s;
-
- mtx_lock(&Giant);
-
- taskq = arg;
- DPRINTF(("usb_task_thread: start taskq %s\n", taskq->name));
-
- s = splusb();
- while (usb_ndevs > 0) {
- task = TAILQ_FIRST(&taskq->tasks);
- if (task == NULL) {
- tsleep(&taskq->tasks, PWAIT, "usbtsk", 0);
- task = TAILQ_FIRST(&taskq->tasks);
- }
- DPRINTFN(2,("usb_task_thread: woke up task=%p\n", task));
- if (task != NULL) {
- TAILQ_REMOVE(&taskq->tasks, task, next);
- task->queue = -1;
- splx(s);
- task->fun(task->arg);
- s = splusb();
- }
- }
- splx(s);
-
- taskq->taskcreated = 0;
- wakeup(&taskq->taskcreated);
-
- DPRINTF(("usb_event_thread: exit\n"));
- while (mtx_owned(&Giant))
- mtx_unlock(&Giant);
- kproc_exit(0);
-}
-
-int
-usbopen(struct cdev *dev, int flag, int mode, struct thread *p)
-{
- int unit = USBUNIT(dev);
- struct usb_softc *sc;
-
- if (unit == USB_DEV_MINOR) {
- if (usb_dev_open)
- return (EBUSY);
- usb_dev_open = 1;
- usb_async_proc = 0;
- return (0);
- }
- sc = devclass_get_softc(usb_devclass, unit);
- if (sc == NULL)
- return (ENXIO);
- if (sc->sc_dying)
- return (EIO);
-
- return (0);
-}
-
-int
-usbread(struct cdev *dev, struct uio *uio, int flag)
-{
- struct usb_event ue;
- int unit = USBUNIT(dev);
- int s, error, n;
-
- if (unit != USB_DEV_MINOR)
- return (ENODEV);
-
- if (uio->uio_resid != sizeof(struct usb_event))
- return (EINVAL);
-
- error = 0;
- s = splusb();
- for (;;) {
- n = usb_get_next_event(&ue);
- if (n != 0)
- break;
- if (flag & O_NONBLOCK) {
- error = EWOULDBLOCK;
- break;
- }
- error = tsleep(&usb_events, PZERO | PCATCH, "usbrea", 0);
- if (error)
- break;
- }
- splx(s);
- if (!error)
- error = uiomove((void *)&ue, uio->uio_resid, uio);
-
- return (error);
-}
-
-int
-usbclose(struct cdev *dev, int flag, int mode, struct thread *p)
-{
- int unit = USBUNIT(dev);
-
- if (unit == USB_DEV_MINOR) {
- usb_async_proc = 0;
- usb_dev_open = 0;
- }
-
- return (0);
-}
-
-int
-usbioctl(struct cdev *devt, u_long cmd, caddr_t data, int flag, struct thread *p)
-{
- struct usb_softc *sc;
- int unit = USBUNIT(devt);
-
- if (unit == USB_DEV_MINOR) {
- switch (cmd) {
- case FIONBIO:
- /* All handled in the upper FS layer. */
- return (0);
-
- case FIOASYNC:
- if (*(int *)data)
- usb_async_proc = p->td_proc;
- else
- usb_async_proc = 0;
- return (0);
-
- default:
- return (EINVAL);
- }
- }
- sc = devclass_get_softc(usb_devclass, unit);
- if (sc->sc_dying)
- return (EIO);
-
- switch (cmd) {
- /* This part should be deleted */
- case USB_DISCOVER:
- break;
- case USB_REQUEST:
- {
- struct usb_ctl_request *ur = (void *)data;
- int len = UGETW(ur->ucr_request.wLength);
- struct iovec iov;
- struct uio uio;
- void *ptr = 0;
- int addr = ur->ucr_addr;
- usbd_status err;
- int error = 0;
-
- DPRINTF(("usbioctl: USB_REQUEST addr=%d len=%d\n", addr, len));
- if (len < 0 || len > 32768)
- return (EINVAL);
- if (addr < 0 || addr >= USB_MAX_DEVICES ||
- sc->sc_bus->devices[addr] == 0)
- return (EINVAL);
- if (len != 0) {
- iov.iov_base = (caddr_t)ur->ucr_data;
- iov.iov_len = len;
- uio.uio_iov = &iov;
- uio.uio_iovcnt = 1;
- uio.uio_resid = len;
- uio.uio_offset = 0;
- uio.uio_segflg = UIO_USERSPACE;
- uio.uio_rw =
- ur->ucr_request.bmRequestType & UT_READ ?
- UIO_READ : UIO_WRITE;
- uio.uio_td = p;
- ptr = malloc(len, M_TEMP, M_WAITOK);
- if (uio.uio_rw == UIO_WRITE) {
- error = uiomove(ptr, len, &uio);
- if (error)
- goto ret;
- }
- }
- err = usbd_do_request_flags(sc->sc_bus->devices[addr],
- &ur->ucr_request, ptr, ur->ucr_flags, &ur->ucr_actlen,
- USBD_DEFAULT_TIMEOUT);
- if (err) {
- error = EIO;
- goto ret;
- }
- if (len != 0) {
- if (uio.uio_rw == UIO_READ) {
- error = uiomove(ptr, len, &uio);
- if (error)
- goto ret;
- }
- }
- ret:
- if (ptr)
- free(ptr, M_TEMP);
- return (error);
- }
-
- case USB_DEVICEINFO:
- {
- struct usb_device_info *di = (void *)data;
- int addr = di->udi_addr;
- usbd_device_handle dev;
-
- if (addr < 1 || addr >= USB_MAX_DEVICES)
- return (EINVAL);
- dev = sc->sc_bus->devices[addr];
- if (dev == NULL)
- return (ENXIO);
- usbd_fill_deviceinfo(dev, di, 1);
- break;
- }
-
- case USB_DEVICESTATS:
- *(struct usb_device_stats *)data = sc->sc_bus->stats;
- break;
-
- default:
- return (EINVAL);
- }
- return (0);
-}
-
-int
-usbpoll(struct cdev *dev, int events, struct thread *p)
-{
- int revents, mask, s;
- int unit = USBUNIT(dev);
-
- if (unit == 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 {
- return (0); /* select/poll never wakes up - back compat */
- }
-}
-
-/* Explore device tree from the root. */
-static void
-usb_discover(void *v)
-{
- struct usb_softc *sc = v;
-
- /* splxxx should be changed to mutexes for preemption safety some day */
- int s;
-
- DPRINTFN(2,("usb_discover\n"));
-#ifdef USB_DEBUG
- if (usb_noexplore > 1)
- return;
-#endif
-
- /*
- * We need mutual exclusion while traversing the device tree,
- * but this is guaranteed since this function is only called
- * from the event thread for the controller.
- */
- s = splusb();
- while (sc->sc_bus->needs_explore && !sc->sc_dying) {
- sc->sc_bus->needs_explore = 0;
- splx(s);
- sc->sc_bus->root_hub->hub->explore(sc->sc_bus->root_hub);
- s = splusb();
- }
- splx(s);
-}
-
-void
-usb_needs_explore(usbd_device_handle dev)
-{
- DPRINTFN(2,("usb_needs_explore\n"));
- dev->bus->needs_explore = 1;
- wakeup(&dev->bus->needs_explore);
-}
-
-/* Called at splusb() */
-int
-usb_get_next_event(struct usb_event *ue)
-{
- struct usb_event_q *ueq;
-
- if (usb_nevents <= 0)
- return (0);
- ueq = TAILQ_FIRST(&usb_events);
-#ifdef DIAGNOSTIC
- if (ueq == NULL) {
- printf("usb: usb_nevents got out of sync! %d\n", usb_nevents);
- usb_nevents = 0;
- return (0);
- }
-#endif
- *ue = ueq->ue;
- TAILQ_REMOVE(&usb_events, ueq, next);
- free(ueq, M_USBDEV);
- usb_nevents--;
- return (1);
-}
-
-void
-usbd_add_dev_event(int type, usbd_device_handle udev)
-{
- struct usb_event ue;
-
- usbd_fill_deviceinfo(udev, &ue.u.ue_device, USB_EVENT_IS_ATTACH(type));
- usb_add_event(type, &ue);
-}
-
-void
-usbd_add_drv_event(int type, usbd_device_handle udev, device_t dev)
-{
- struct usb_event ue;
-
- ue.u.ue_driver.ue_cookie = udev->cookie;
- strncpy(ue.u.ue_driver.ue_devname, device_get_nameunit(dev),
- sizeof ue.u.ue_driver.ue_devname);
- usb_add_event(type, &ue);
-}
-
-void
-usb_add_event(int type, struct usb_event *uep)
-{
- struct usb_event_q *ueq;
- struct usb_event ue;
- struct timeval thetime;
- int s;
-
- ueq = malloc(sizeof *ueq, M_USBDEV, M_WAITOK);
- ueq->ue = *uep;
- ueq->ue.ue_type = type;
- microtime(&thetime);
- TIMEVAL_TO_TIMESPEC(&thetime, &ueq->ue.ue_time);
-
- s = splusb();
- if (USB_EVENT_IS_DETACH(type)) {
- struct usb_event_q *ueqi, *ueqi_next;
-
- for (ueqi = TAILQ_FIRST(&usb_events); ueqi; ueqi = ueqi_next) {
- ueqi_next = TAILQ_NEXT(ueqi, next);
- if (ueqi->ue.u.ue_driver.ue_cookie.cookie ==
- uep->u.ue_device.udi_cookie.cookie) {
- TAILQ_REMOVE(&usb_events, ueqi, next);
- free(ueqi, M_USBDEV);
- usb_nevents--;
- ueqi_next = TAILQ_FIRST(&usb_events);
- }
- }
- }
- if (usb_nevents >= USB_MAX_EVENTS) {
- /* Too many queued events, drop an old one. */
- DPRINTF(("usb: event dropped\n"));
- (void)usb_get_next_event(&ue);
- }
- TAILQ_INSERT_TAIL(&usb_events, ueq, next);
- usb_nevents++;
- wakeup(&usb_events);
- selwakeuppri(&usb_selevent, PZERO);
- if (usb_async_proc != NULL) {
- PROC_LOCK(usb_async_proc);
- psignal(usb_async_proc, SIGIO);
- PROC_UNLOCK(usb_async_proc);
- }
- splx(s);
-}
-
-void
-usb_schedsoftintr(usbd_bus_handle bus)
-{
- DPRINTFN(10,("usb_schedsoftintr: polling=%d\n", bus->use_polling));
-#ifdef USB_USE_SOFTINTR
- if (bus->use_polling) {
- bus->methods->soft_intr(bus);
- } else {
-#ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
- softintr_schedule(bus->soft);
-#else
- if (!callout_pending(&bus->softi))
- callout_reset(&bus->softi, 0, bus->methods->soft_intr,
- bus);
-#endif /* __HAVE_GENERIC_SOFT_INTERRUPTS */
- }
-#else
- bus->methods->soft_intr(bus);
-#endif /* USB_USE_SOFTINTR */
-}
-
-static int
-usb_detach(device_t self)
-{
- struct usb_softc *sc = device_get_softc(self);
- struct usb_event ue;
- struct usb_taskq *taskq;
- int i;
-
- DPRINTF(("usb_detach: start\n"));
-
- sc->sc_dying = 1;
-
- /* Make all devices disconnect. */
- if (sc->sc_port.device != NULL)
- usb_disconnect_port(&sc->sc_port, self);
-
- /* Kill off event thread. */
- if (sc->sc_event_thread != NULL) {
- wakeup(&sc->sc_bus->needs_explore);
- if (tsleep(sc, PWAIT, "usbdet", hz * 60))
- printf("%s: event thread didn't die\n",
- device_get_nameunit(sc->sc_dev));
- DPRINTF(("usb_detach: event thread dead\n"));
- }
-
- destroy_dev(sc->sc_usbdev);
- if (--usb_ndevs == 0) {
- destroy_dev(usb_dev);
- usb_dev = NULL;
- for (i = 0; i < USB_NUM_TASKQS; i++) {
- taskq = &usb_taskq[i];
- wakeup(&taskq->tasks);
- if (tsleep(&taskq->taskcreated, PWAIT, "usbtdt",
- hz * 60)) {
- printf("usb task thread %s didn't die\n",
- taskq->name);
- }
- }
- }
-
- usbd_finish();
-
-#ifdef USB_USE_SOFTINTR
-#ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
- if (sc->sc_bus->soft != NULL) {
- softintr_disestablish(sc->sc_bus->soft);
- sc->sc_bus->soft = NULL;
- }
-#else
- callout_stop(&sc->sc_bus->softi);
-#endif
-#endif
-
- ue.u.ue_ctrlr.ue_bus = device_get_unit(sc->sc_dev);
- usb_add_event(USB_EVENT_CTRLR_DETACH, &ue);
-
- return (0);
-}
-
-static void
-usb_child_detached(device_t self, device_t child)
-{
- struct usb_softc *sc = device_get_softc(self);
-
- /* XXX, should check it is the right device. */
- sc->sc_port.device = NULL;
-}
-
-/* Explore USB busses at the end of device configuration. */
-static void
-usb_cold_explore(void *arg)
-{
- struct usb_softc *sc;
-
- KASSERT(cold || TAILQ_EMPTY(&usb_coldexplist),
- ("usb_cold_explore: busses to explore when !cold"));
- while (!TAILQ_EMPTY(&usb_coldexplist)) {
- sc = TAILQ_FIRST(&usb_coldexplist);
- TAILQ_REMOVE(&usb_coldexplist, sc, sc_coldexplist);
-
- sc->sc_bus->use_polling++;
- sc->sc_port.device->hub->explore(sc->sc_bus->root_hub);
- sc->sc_bus->use_polling--;
- }
-}
-
-SYSINIT(usb_cold_explore, SI_SUB_CONFIGURE, SI_ORDER_MIDDLE,
- usb_cold_explore, NULL);
diff --git a/sys/dev/usb/usb.h b/sys/dev/usb/usb.h
deleted file mode 100644
index 7e64cac..0000000
--- a/sys/dev/usb/usb.h
+++ /dev/null
@@ -1,708 +0,0 @@
-/* $NetBSD: usb.h,v 1.69 2002/09/22 23:20:50 augustss Exp $ */
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) 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.
- */
-
-
-#ifndef _USB_H_
-#define _USB_H_
-
-#include <sys/types.h>
-#include <sys/time.h>
-
-#if defined(_KERNEL)
-#include "opt_usb.h"
-
-#ifdef SYSCTL_DECL
-SYSCTL_DECL(_hw_usb);
-#endif
-
-#include <sys/malloc.h>
-
-MALLOC_DECLARE(M_USB);
-MALLOC_DECLARE(M_USBDEV);
-MALLOC_DECLARE(M_USBHC);
-#endif /* _KERNEL */
-
-#define PWR_RESUME 0
-#define PWR_SUSPEND 1
-#define PWR_STANDBY 2
-#define PWR_SOFTSUSPEND 3
-#define PWR_SOFTSTANDBY 4
-#define PWR_SOFTRESUME 5
-
-/* These two defines are used by usbd to autoload the usb kld */
-#define USB_KLD "usb" /* name of usb module */
-#define USB_UHUB "usb/uhub" /* root hub */
-
-#define USB_STACK_VERSION 2
-
-#define USB_MAX_DEVICES 128
-#define USB_START_ADDR 0
-
-#define USB_CONTROL_ENDPOINT 0
-#define USB_MAX_ENDPOINTS 16
-
-#define USB_FRAMES_PER_SECOND 1000
-
-/*
- * The USB records contain some unaligned little-endian word
- * components. The U[SG]ETW macros take care of both the alignment
- * and endian problem and should always be used to access non-byte
- * values.
- */
-typedef u_int8_t uByte;
-typedef u_int8_t uWord[2];
-typedef u_int8_t uDWord[4];
-
-#define USETW2(w,h,l) ((w)[0] = (u_int8_t)(l), (w)[1] = (u_int8_t)(h))
-
-#if 1
-#define UGETW(w) ((w)[0] | ((w)[1] << 8))
-#define USETW(w,v) ((w)[0] = (u_int8_t)(v), (w)[1] = (u_int8_t)((v) >> 8))
-#define UGETDW(w) ((w)[0] | ((w)[1] << 8) | ((w)[2] << 16) | ((w)[3] << 24))
-#define USETDW(w,v) ((w)[0] = (u_int8_t)(v), \
- (w)[1] = (u_int8_t)((v) >> 8), \
- (w)[2] = (u_int8_t)((v) >> 16), \
- (w)[3] = (u_int8_t)((v) >> 24))
-#else
-/*
- * On little-endian machines that can handle unanliged accesses
- * (e.g. i386) these macros can be replaced by the following.
- */
-#define UGETW(w) (*(u_int16_t *)(w))
-#define USETW(w,v) (*(u_int16_t *)(w) = (v))
-#define UGETDW(w) (*(u_int32_t *)(w))
-#define USETDW(w,v) (*(u_int32_t *)(w) = (v))
-#endif
-
-#define UPACKED __packed
-
-typedef struct {
- uByte bmRequestType;
- uByte bRequest;
- uWord wValue;
- uWord wIndex;
- uWord wLength;
-} UPACKED usb_device_request_t;
-
-#define UT_WRITE 0x00
-#define UT_READ 0x80
-#define UT_STANDARD 0x00
-#define UT_CLASS 0x20
-#define UT_VENDOR 0x40
-#define UT_DEVICE 0x00
-#define UT_INTERFACE 0x01
-#define UT_ENDPOINT 0x02
-#define UT_OTHER 0x03
-
-#define UT_READ_DEVICE (UT_READ | UT_STANDARD | UT_DEVICE)
-#define UT_READ_INTERFACE (UT_READ | UT_STANDARD | UT_INTERFACE)
-#define UT_READ_ENDPOINT (UT_READ | UT_STANDARD | UT_ENDPOINT)
-#define UT_WRITE_DEVICE (UT_WRITE | UT_STANDARD | UT_DEVICE)
-#define UT_WRITE_INTERFACE (UT_WRITE | UT_STANDARD | UT_INTERFACE)
-#define UT_WRITE_ENDPOINT (UT_WRITE | UT_STANDARD | UT_ENDPOINT)
-#define UT_READ_CLASS_DEVICE (UT_READ | UT_CLASS | UT_DEVICE)
-#define UT_READ_CLASS_INTERFACE (UT_READ | UT_CLASS | UT_INTERFACE)
-#define UT_READ_CLASS_OTHER (UT_READ | UT_CLASS | UT_OTHER)
-#define UT_READ_CLASS_ENDPOINT (UT_READ | UT_CLASS | UT_ENDPOINT)
-#define UT_WRITE_CLASS_DEVICE (UT_WRITE | UT_CLASS | UT_DEVICE)
-#define UT_WRITE_CLASS_INTERFACE (UT_WRITE | UT_CLASS | UT_INTERFACE)
-#define UT_WRITE_CLASS_OTHER (UT_WRITE | UT_CLASS | UT_OTHER)
-#define UT_WRITE_CLASS_ENDPOINT (UT_WRITE | UT_CLASS | UT_ENDPOINT)
-#define UT_READ_VENDOR_DEVICE (UT_READ | UT_VENDOR | UT_DEVICE)
-#define UT_READ_VENDOR_INTERFACE (UT_READ | UT_VENDOR | UT_INTERFACE)
-#define UT_READ_VENDOR_OTHER (UT_READ | UT_VENDOR | UT_OTHER)
-#define UT_READ_VENDOR_ENDPOINT (UT_READ | UT_VENDOR | UT_ENDPOINT)
-#define UT_WRITE_VENDOR_DEVICE (UT_WRITE | UT_VENDOR | UT_DEVICE)
-#define UT_WRITE_VENDOR_INTERFACE (UT_WRITE | UT_VENDOR | UT_INTERFACE)
-#define UT_WRITE_VENDOR_OTHER (UT_WRITE | UT_VENDOR | UT_OTHER)
-#define UT_WRITE_VENDOR_ENDPOINT (UT_WRITE | UT_VENDOR | UT_ENDPOINT)
-
-/* Requests */
-#define UR_GET_STATUS 0x00
-#define UR_CLEAR_FEATURE 0x01
-#define UR_SET_FEATURE 0x03
-#define UR_SET_ADDRESS 0x05
-#define UR_GET_DESCRIPTOR 0x06
-#define UDESC_DEVICE 0x01
-#define UDESC_CONFIG 0x02
-#define UDESC_STRING 0x03
-#define UDESC_INTERFACE 0x04
-#define UDESC_ENDPOINT 0x05
-#define UDESC_DEVICE_QUALIFIER 0x06
-#define UDESC_OTHER_SPEED_CONFIGURATION 0x07
-#define UDESC_INTERFACE_POWER 0x08
-#define UDESC_OTG 0x09
-#define UDESC_CS_DEVICE 0x21 /* class specific */
-#define UDESC_CS_CONFIG 0x22
-#define UDESC_CS_STRING 0x23
-#define UDESC_CS_INTERFACE 0x24
-#define UDESC_CS_ENDPOINT 0x25
-#define UDESC_HUB 0x29
-#define UR_SET_DESCRIPTOR 0x07
-#define UR_GET_CONFIG 0x08
-#define UR_SET_CONFIG 0x09
-#define UR_GET_INTERFACE 0x0a
-#define UR_SET_INTERFACE 0x0b
-#define UR_SYNCH_FRAME 0x0c
-
-/* Feature numbers */
-#define UF_ENDPOINT_HALT 0
-#define UF_DEVICE_REMOTE_WAKEUP 1
-#define UF_TEST_MODE 2
-
-#define USB_MAX_IPACKET 8 /* maximum size of the initial packet */
-
-#define USB_2_MAX_CTRL_PACKET 64
-#define USB_2_MAX_BULK_PACKET 512
-
-typedef struct {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDescriptorSubtype;
-} UPACKED usb_descriptor_t;
-
-typedef struct {
- uByte bLength;
- uByte bDescriptorType;
- uWord bcdUSB;
-#define UD_USB_2_0 0x0200
-#define UD_IS_USB2(d) (UGETW((d)->bcdUSB) >= UD_USB_2_0)
- uByte bDeviceClass;
- uByte bDeviceSubClass;
- uByte bDeviceProtocol;
- uByte bMaxPacketSize;
- /* The fields below are not part of the initial descriptor. */
- uWord idVendor;
- uWord idProduct;
- uWord bcdDevice;
- uByte iManufacturer;
- uByte iProduct;
- uByte iSerialNumber;
- uByte bNumConfigurations;
-} UPACKED usb_device_descriptor_t;
-#define USB_DEVICE_DESCRIPTOR_SIZE 18
-
-typedef struct {
- uByte bLength;
- uByte bDescriptorType;
- uWord wTotalLength;
- uByte bNumInterface;
- uByte bConfigurationValue;
- uByte iConfiguration;
- uByte bmAttributes;
-#define UC_BUS_POWERED 0x80
-#define UC_SELF_POWERED 0x40
-#define UC_REMOTE_WAKEUP 0x20
- uByte bMaxPower; /* max current in 2 mA units */
-#define UC_POWER_FACTOR 2
-} UPACKED usb_config_descriptor_t;
-#define USB_CONFIG_DESCRIPTOR_SIZE 9
-
-typedef struct {
- uByte bLength;
- uByte bDescriptorType;
- uByte bInterfaceNumber;
- uByte bAlternateSetting;
- uByte bNumEndpoints;
- uByte bInterfaceClass;
- uByte bInterfaceSubClass;
- uByte bInterfaceProtocol;
- uByte iInterface;
-} UPACKED usb_interface_descriptor_t;
-#define USB_INTERFACE_DESCRIPTOR_SIZE 9
-
-typedef struct {
- uByte bLength;
- uByte bDescriptorType;
- uByte bEndpointAddress;
-#define UE_GET_DIR(a) ((a) & 0x80)
-#define UE_SET_DIR(a,d) ((a) | (((d)&1) << 7))
-#define UE_DIR_IN 0x80
-#define UE_DIR_OUT 0x00
-#define UE_ADDR 0x0f
-#define UE_GET_ADDR(a) ((a) & UE_ADDR)
- uByte bmAttributes;
-#define UE_XFERTYPE 0x03
-#define UE_CONTROL 0x00
-#define UE_ISOCHRONOUS 0x01
-#define UE_BULK 0x02
-#define UE_INTERRUPT 0x03
-#define UE_GET_XFERTYPE(a) ((a) & UE_XFERTYPE)
-#define UE_ISO_TYPE 0x0c
-#define UE_ISO_ASYNC 0x04
-#define UE_ISO_ADAPT 0x08
-#define UE_ISO_SYNC 0x0c
-#define UE_GET_ISO_TYPE(a) ((a) & UE_ISO_TYPE)
- uWord wMaxPacketSize;
-#define UE_GET_TRANS(a) (((a) >> 11) & 0x3)
-#define UE_GET_SIZE(a) ((a) & 0x7ff)
- uByte bInterval;
-} UPACKED usb_endpoint_descriptor_t;
-#define USB_ENDPOINT_DESCRIPTOR_SIZE 7
-
-typedef struct {
- uByte bLength;
- uByte bDescriptorType;
- uWord bString[127];
-} UPACKED usb_string_descriptor_t;
-#define USB_MAX_STRING_LEN 128
-#define USB_LANGUAGE_TABLE 0 /* # of the string language id table */
-
-/* Hub specific request */
-#define UR_GET_BUS_STATE 0x02
-#define UR_CLEAR_TT_BUFFER 0x08
-#define UR_RESET_TT 0x09
-#define UR_GET_TT_STATE 0x0a
-#define UR_STOP_TT 0x0b
-
-/* Hub features */
-#define UHF_C_HUB_LOCAL_POWER 0
-#define UHF_C_HUB_OVER_CURRENT 1
-#define UHF_PORT_CONNECTION 0
-#define UHF_PORT_ENABLE 1
-#define UHF_PORT_SUSPEND 2
-#define UHF_PORT_OVER_CURRENT 3
-#define UHF_PORT_RESET 4
-#define UHF_PORT_POWER 8
-#define UHF_PORT_LOW_SPEED 9
-#define UHF_C_PORT_CONNECTION 16
-#define UHF_C_PORT_ENABLE 17
-#define UHF_C_PORT_SUSPEND 18
-#define UHF_C_PORT_OVER_CURRENT 19
-#define UHF_C_PORT_RESET 20
-#define UHF_PORT_TEST 21
-#define UHF_PORT_INDICATOR 22
-
-typedef struct {
- uByte bDescLength;
- uByte bDescriptorType;
- uByte bNbrPorts;
- uWord wHubCharacteristics;
-#define UHD_PWR 0x0003
-#define UHD_PWR_GANGED 0x0000
-#define UHD_PWR_INDIVIDUAL 0x0001
-#define UHD_PWR_NO_SWITCH 0x0002
-#define UHD_COMPOUND 0x0004
-#define UHD_OC 0x0018
-#define UHD_OC_GLOBAL 0x0000
-#define UHD_OC_INDIVIDUAL 0x0008
-#define UHD_OC_NONE 0x0010
-#define UHD_TT_THINK 0x0060
-#define UHD_TT_THINK_8 0x0000
-#define UHD_TT_THINK_16 0x0020
-#define UHD_TT_THINK_24 0x0040
-#define UHD_TT_THINK_32 0x0060
-#define UHD_PORT_IND 0x0080
- uByte bPwrOn2PwrGood; /* delay in 2 ms units */
-#define UHD_PWRON_FACTOR 2
- uByte bHubContrCurrent;
- uByte DeviceRemovable[32]; /* max 255 ports */
-#define UHD_NOT_REMOV(desc, i) \
- (((desc)->DeviceRemovable[(i)/8] >> ((i) % 8)) & 1)
- /* deprecated */ uByte PortPowerCtrlMask[1];
-} UPACKED usb_hub_descriptor_t;
-#define USB_HUB_DESCRIPTOR_SIZE 9 /* includes deprecated PortPowerCtrlMask */
-
-typedef struct {
- uByte bLength;
- uByte bDescriptorType;
- uWord bcdUSB;
- uByte bDeviceClass;
- uByte bDeviceSubClass;
- uByte bDeviceProtocol;
- uByte bMaxPacketSize0;
- uByte bNumConfigurations;
- uByte bReserved;
-} UPACKED usb_device_qualifier_t;
-#define USB_DEVICE_QUALIFIER_SIZE 10
-
-typedef struct {
- uByte bLength;
- uByte bDescriptorType;
- uByte bmAttributes;
-#define UOTG_SRP 0x01
-#define UOTG_HNP 0x02
-} UPACKED usb_otg_descriptor_t;
-
-/* OTG feature selectors */
-#define UOTG_B_HNP_ENABLE 3
-#define UOTG_A_HNP_SUPPORT 4
-#define UOTG_A_ALT_HNP_SUPPORT 5
-
-typedef struct {
- uWord wStatus;
-/* Device status flags */
-#define UDS_SELF_POWERED 0x0001
-#define UDS_REMOTE_WAKEUP 0x0002
-/* Endpoint status flags */
-#define UES_HALT 0x0001
-} UPACKED usb_status_t;
-
-typedef struct {
- uWord wHubStatus;
-#define UHS_LOCAL_POWER 0x0001
-#define UHS_OVER_CURRENT 0x0002
- uWord wHubChange;
-} UPACKED usb_hub_status_t;
-
-typedef struct {
- uWord wPortStatus;
-#define UPS_CURRENT_CONNECT_STATUS 0x0001
-#define UPS_PORT_ENABLED 0x0002
-#define UPS_SUSPEND 0x0004
-#define UPS_OVERCURRENT_INDICATOR 0x0008
-#define UPS_RESET 0x0010
-#define UPS_PORT_POWER 0x0100
-#define UPS_LOW_SPEED 0x0200
-#define UPS_HIGH_SPEED 0x0400
-#define UPS_PORT_TEST 0x0800
-#define UPS_PORT_INDICATOR 0x1000
- uWord wPortChange;
-#define UPS_C_CONNECT_STATUS 0x0001
-#define UPS_C_PORT_ENABLED 0x0002
-#define UPS_C_SUSPEND 0x0004
-#define UPS_C_OVERCURRENT_INDICATOR 0x0008
-#define UPS_C_PORT_RESET 0x0010
-} UPACKED usb_port_status_t;
-
-/* Device class codes */
-#define UDCLASS_IN_INTERFACE 0x00
-#define UDCLASS_COMM 0x02
-#define UDCLASS_HUB 0x09
-#define UDSUBCLASS_HUB 0x00
-#define UDPROTO_FSHUB 0x00
-#define UDPROTO_HSHUBSTT 0x01
-#define UDPROTO_HSHUBMTT 0x02
-#define UDCLASS_DIAGNOSTIC 0xdc
-#define UDCLASS_WIRELESS 0xe0
-#define UDSUBCLASS_RF 0x01
-#define UDPROTO_BLUETOOTH 0x01
-#define UDCLASS_VENDOR 0xff
-
-/* 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 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 UIPROTO_MOUSE 2
-
-#define UICLASS_PHYSICAL 0x05
-
-#define UICLASS_IMAGE 0x06
-
-#define UICLASS_PRINTER 0x07
-#define UISUBCLASS_PRINTER 1
-#define UIPROTO_PRINTER_UNI 1
-#define UIPROTO_PRINTER_BI 2
-#define UIPROTO_PRINTER_1284 3
-
-#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_OLD 2 /* Not in the spec anymore */
-#define UIPROTO_MASS_BBB 80 /* 'P' for the Iomega Zip drive */
-
-#define UICLASS_HUB 0x09
-#define UISUBCLASS_HUB 0
-#define UIPROTO_FSHUB 0
-#define UIPROTO_HSHUBSTT 0 /* Yes, same as previous */
-#define UIPROTO_HSHUBMTT 1
-
-#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_SMARTCARD 0x0b
-
-/*#define UICLASS_FIRM_UPD 0x0c*/
-
-#define UICLASS_SECURITY 0x0d
-
-#define UICLASS_DIAGNOSTIC 0xdc
-
-#define UICLASS_WIRELESS 0xe0
-#define UISUBCLASS_RF 0x01
-#define UIPROTO_BLUETOOTH 0x01
-
-#define UICLASS_APPL_SPEC 0xfe
-#define UISUBCLASS_FIRMWARE_DOWNLOAD 1
-#define UISUBCLASS_IRDA 2
-#define UIPROTO_IRDA 0
-
-#define UICLASS_VENDOR 0xff
-#define UISUBCLASS_XBOX360_CONTROLLER 0x5d
-#define UIPROTO_XBOX360_GAMEPAD 0x01
-
-
-#define USB_HUB_MAX_DEPTH 5
-
-/*
- * Minimum time a device needs to be powered down to go through
- * a power cycle. XXX Are these time in the spec?
- */
-#define USB_POWER_DOWN_TIME 200 /* ms */
-#define USB_PORT_POWER_DOWN_TIME 100 /* ms */
-
-#if 0
-/* These are the values from the spec. */
-#define USB_PORT_RESET_DELAY 10 /* ms */
-#define USB_PORT_ROOT_RESET_DELAY 50 /* ms */
-#define USB_PORT_RESET_RECOVERY 10 /* ms */
-#define USB_PORT_POWERUP_DELAY 100 /* ms */
-#define USB_SET_ADDRESS_SETTLE 2 /* ms */
-#define USB_RESUME_DELAY (20*5) /* ms */
-#define USB_RESUME_WAIT 10 /* ms */
-#define USB_RESUME_RECOVERY 10 /* ms */
-#define USB_EXTRA_POWER_UP_TIME 0 /* ms */
-#else
-/* Allow for marginal (i.e. non-conforming) devices. */
-#define USB_PORT_RESET_DELAY 50 /* ms */
-#define USB_PORT_ROOT_RESET_DELAY 250 /* ms */
-#define USB_PORT_RESET_RECOVERY 250 /* ms */
-#define USB_PORT_POWERUP_DELAY 300 /* ms */
-#define USB_SET_ADDRESS_SETTLE 10 /* ms */
-#define USB_RESUME_DELAY (50*5) /* ms */
-#define USB_RESUME_WAIT 50 /* ms */
-#define USB_RESUME_RECOVERY 50 /* ms */
-#define USB_EXTRA_POWER_UP_TIME 20 /* ms */
-#endif
-
-#define USB_MIN_POWER 100 /* mA */
-#define USB_MAX_POWER 500 /* mA */
-
-#define USB_BUS_RESET_DELAY 100 /* ms XXX?*/
-
-
-#define USB_UNCONFIG_NO 0
-#define USB_UNCONFIG_INDEX (-1)
-
-/*** ioctl() related stuff ***/
-
-struct usb_ctl_request {
- int ucr_addr;
- usb_device_request_t ucr_request;
- void *ucr_data;
- int ucr_flags;
-#define USBD_SHORT_XFER_OK 0x04 /* allow short reads */
- int ucr_actlen; /* actual length transferred */
-};
-
-struct usb_alt_interface {
- int uai_config_index;
- int uai_interface_index;
- int uai_alt_no;
-};
-
-#define USB_CURRENT_CONFIG_INDEX (-1)
-#define USB_CURRENT_ALT_INDEX (-1)
-
-struct usb_config_desc {
- int ucd_config_index;
- usb_config_descriptor_t ucd_desc;
-};
-
-struct usb_interface_desc {
- int uid_config_index;
- int uid_interface_index;
- int uid_alt_index;
- usb_interface_descriptor_t uid_desc;
-};
-
-struct usb_endpoint_desc {
- int ued_config_index;
- int ued_interface_index;
- int ued_alt_index;
- int ued_endpoint_index;
- usb_endpoint_descriptor_t ued_desc;
-};
-
-struct usb_full_desc {
- int ufd_config_index;
- u_int ufd_size;
- u_char *ufd_data;
-};
-
-struct usb_string_desc {
- int usd_string_index;
- int usd_language_id;
- usb_string_descriptor_t usd_desc;
-};
-
-struct usb_ctl_report_desc {
- int ucrd_size;
- u_char ucrd_data[1024]; /* filled data size will vary */
-};
-
-typedef struct { u_int32_t cookie; } usb_event_cookie_t;
-
-#define USB_MAX_DEVNAMES 4
-#define USB_MAX_DEVNAMELEN 16
-struct usb_device_info {
- u_int8_t udi_bus;
- u_int8_t udi_addr; /* device address */
- usb_event_cookie_t udi_cookie;
- char udi_product[USB_MAX_STRING_LEN];
- char udi_vendor[USB_MAX_STRING_LEN];
- char udi_release[8];
- u_int16_t udi_productNo;
- u_int16_t udi_vendorNo;
- u_int16_t udi_releaseNo;
- u_int8_t udi_class;
- u_int8_t udi_subclass;
- u_int8_t udi_protocol;
- u_int8_t udi_config;
- u_int8_t udi_speed;
-#define USB_SPEED_LOW 1
-#define USB_SPEED_FULL 2
-#define USB_SPEED_HIGH 3
- int udi_power; /* power consumption in mA, 0 if selfpowered */
- int udi_nports;
- char udi_devnames[USB_MAX_DEVNAMES][USB_MAX_DEVNAMELEN];
- u_int8_t udi_ports[16];/* hub only: addresses of devices on ports */
-#define USB_PORT_ENABLED 0xff
-#define USB_PORT_SUSPENDED 0xfe
-#define USB_PORT_POWERED 0xfd
-#define USB_PORT_DISABLED 0xfc
-};
-
-struct usb_ctl_report {
- int ucr_report;
- u_char ucr_data[1024]; /* filled data size will vary */
-};
-
-struct usb_device_stats {
- u_long uds_requests[4]; /* indexed by transfer type UE_* */
-};
-
-/* Events that can be read from /dev/usb */
-struct usb_event {
- int ue_type;
-#define USB_EVENT_CTRLR_ATTACH 1
-#define USB_EVENT_CTRLR_DETACH 2
-#define USB_EVENT_DEVICE_ATTACH 3
-#define USB_EVENT_DEVICE_DETACH 4
-#define USB_EVENT_DRIVER_ATTACH 5
-#define USB_EVENT_DRIVER_DETACH 6
-#define USB_EVENT_IS_ATTACH(n) ((n) == USB_EVENT_CTRLR_ATTACH || (n) == USB_EVENT_DEVICE_ATTACH || (n) == USB_EVENT_DRIVER_ATTACH)
-#define USB_EVENT_IS_DETACH(n) ((n) == USB_EVENT_CTRLR_DETACH || (n) == USB_EVENT_DEVICE_DETACH || (n) == USB_EVENT_DRIVER_DETACH)
- struct timespec ue_time;
- union {
- struct {
- int ue_bus;
- } ue_ctrlr;
- struct usb_device_info ue_device;
- struct {
- usb_event_cookie_t ue_cookie;
- char ue_devname[16];
- } ue_driver;
- } u;
-};
-
-/* USB controller */
-#define USB_REQUEST _IOWR('U', 1, struct usb_ctl_request)
-#define USB_SETDEBUG _IOW ('U', 2, int)
-#define USB_DISCOVER _IO ('U', 3)
-#define USB_DEVICEINFO _IOWR('U', 4, struct usb_device_info)
-#define USB_DEVICESTATS _IOR ('U', 5, struct usb_device_stats)
-
-/* Generic HID device */
-#define USB_GET_REPORT_DESC _IOR ('U', 21, struct usb_ctl_report_desc)
-#define USB_SET_IMMED _IOW ('U', 22, int)
-#define USB_GET_REPORT _IOWR('U', 23, struct usb_ctl_report)
-#define USB_SET_REPORT _IOW ('U', 24, struct usb_ctl_report)
-#define USB_GET_REPORT_ID _IOR ('U', 25, int)
-
-/* Generic USB device */
-#define USB_GET_CONFIG _IOR ('U', 100, int)
-#define USB_SET_CONFIG _IOW ('U', 101, int)
-#define USB_GET_ALTINTERFACE _IOWR('U', 102, struct usb_alt_interface)
-#define USB_SET_ALTINTERFACE _IOWR('U', 103, struct usb_alt_interface)
-#define USB_GET_NO_ALT _IOWR('U', 104, struct usb_alt_interface)
-#define USB_GET_DEVICE_DESC _IOR ('U', 105, usb_device_descriptor_t)
-#define USB_GET_CONFIG_DESC _IOWR('U', 106, struct usb_config_desc)
-#define USB_GET_INTERFACE_DESC _IOWR('U', 107, struct usb_interface_desc)
-#define USB_GET_ENDPOINT_DESC _IOWR('U', 108, struct usb_endpoint_desc)
-#define USB_GET_FULL_DESC _IOWR('U', 109, struct usb_full_desc)
-#define USB_GET_STRING_DESC _IOWR('U', 110, struct usb_string_desc)
-#define USB_DO_REQUEST _IOWR('U', 111, struct usb_ctl_request)
-#define USB_GET_DEVICEINFO _IOR ('U', 112, struct usb_device_info)
-#define USB_SET_SHORT_XFER _IOW ('U', 113, int)
-#define USB_SET_TIMEOUT _IOW ('U', 114, int)
-#define USB_RESET_DEVICE _IO ('U', 115)
-
-/* Modem device */
-#define USB_GET_CM_OVER_DATA _IOR ('U', 130, int)
-#define USB_SET_CM_OVER_DATA _IOW ('U', 131, int)
-
-#endif /* _USB_H_ */
diff --git a/sys/dev/usb/usb_ethersubr.c b/sys/dev/usb/usb_ethersubr.c
deleted file mode 100644
index d0a3b83..0000000
--- a/sys/dev/usb/usb_ethersubr.c
+++ /dev/null
@@ -1,283 +0,0 @@
-/*-
- * Copyright (c) 1997, 1998, 1999, 2000
- * Bill Paul <wpaul@ee.columbia.edu>. 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * Callbacks in the USB code operate at splusb() (actually splbio()
- * in FreeBSD). However adding packets to the input queues has to be
- * done at splimp(). It is conceivable that this arrangement could
- * trigger a condition where the splimp() is ignored and the input
- * queues could get trampled in spite of our best effors to prevent
- * it. To work around this, we implement a special input queue for
- * USB ethernet adapter drivers. Rather than passing the frames directly
- * to ether_input(), we pass them here, then schedule a soft interrupt
- * to hand them to ether_input() later, outside of the USB interrupt
- * context.
- *
- * It's questional as to whether this code should be expanded to
- * handle other kinds of devices, or handle USB transfer callbacks
- * in general. Right now, I need USB network interfaces to work
- * properly.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/sockio.h>
-#include <sys/mbuf.h>
-#include <sys/malloc.h>
-#include <sys/socket.h>
-#include <sys/taskqueue.h>
-
-#include <net/if.h>
-#include <net/if_types.h>
-#include <net/if_arp.h>
-#include <net/ethernet.h>
-#include <net/netisr.h>
-#include <net/bpf.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usb_ethersubr.h>
-
-static struct ifqueue usbq_rx;
-static struct ifqueue usbq_tx;
-static int mtx_inited = 0;
-
-static void usbintr (void);
-
-static void
-usbintr(void)
-{
- struct mbuf *m;
- struct usb_qdat *q;
- struct ifnet *ifp;
-
- mtx_lock(&Giant);
-
- /* Check the RX queue */
- while(1) {
- IF_DEQUEUE(&usbq_rx, m);
- if (m == NULL)
- break;
- q = (struct usb_qdat *)m->m_pkthdr.rcvif;
- ifp = q->ifp;
- m->m_pkthdr.rcvif = ifp;
- (*ifp->if_input)(ifp, m);
-
- /* Re-arm the receiver */
- (*q->if_rxstart)(ifp);
- if (ifp->if_snd.ifq_head != NULL)
- (*ifp->if_start)(ifp);
- }
-
- /* Check the TX queue */
- while(1) {
- IF_DEQUEUE(&usbq_tx, m);
- if (m == NULL)
- break;
- ifp = m->m_pkthdr.rcvif;
- m_freem(m);
- if (ifp->if_snd.ifq_head != NULL)
- (*ifp->if_start)(ifp);
- }
-
- mtx_unlock(&Giant);
-
- return;
-}
-
-void
-usb_register_netisr(void)
-{
- if (mtx_inited)
- return;
- netisr_register(NETISR_USB, (netisr_t *)usbintr, NULL,
- NETISR_FORCEQUEUE);
- mtx_init(&usbq_tx.ifq_mtx, "usbq_tx_mtx", NULL, MTX_DEF);
- mtx_init(&usbq_rx.ifq_mtx, "usbq_rx_mtx", NULL, MTX_DEF);
- mtx_inited++;
- return;
-}
-
-/*
- * Must be called at splusb() (actually splbio()). This should be
- * the case when called from a transfer callback routine.
- */
-void
-usb_ether_input(m)
- struct mbuf *m;
-{
- IF_ENQUEUE(&usbq_rx, m);
- schednetisr(NETISR_USB);
-
- return;
-}
-
-void
-usb_tx_done(m)
- struct mbuf *m;
-{
- IF_ENQUEUE(&usbq_tx, m);
- schednetisr(NETISR_USB);
-
- return;
-}
-
-struct mbuf *
-usb_ether_newbuf(void)
-{
- struct mbuf *m_new;
-
- m_new = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
- if (m_new == NULL)
- return (NULL);
- m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
-
- m_adj(m_new, ETHER_ALIGN);
- return (m_new);
-}
-
-int
-usb_ether_rx_list_init(void *sc, struct ue_cdata *cd,
- usbd_device_handle ue_udev)
-{
- struct ue_chain *c;
- int i;
-
- for (i = 0; i < UE_RX_LIST_CNT; i++) {
- c = &cd->ue_rx_chain[i];
- c->ue_sc = sc;
- c->ue_idx = i;
- c->ue_mbuf = usb_ether_newbuf();
- if (c->ue_mbuf == NULL)
- return (ENOBUFS);
- if (c->ue_xfer == NULL) {
- c->ue_xfer = usbd_alloc_xfer(ue_udev);
- if (c->ue_xfer == NULL)
- return (ENOBUFS);
- c->ue_buf = usbd_alloc_buffer(c->ue_xfer, UE_BUFSZ);
- if (c->ue_buf == NULL)
- return (ENOBUFS);
- }
- }
-
- return (0);
-}
-
-int
-usb_ether_tx_list_init(void *sc, struct ue_cdata *cd,
- usbd_device_handle ue_udev)
-{
- struct ue_chain *c;
- int i;
-
- for (i = 0; i < UE_TX_LIST_CNT; i++) {
- c = &cd->ue_tx_chain[i];
- c->ue_sc = sc;
- c->ue_idx = i;
- c->ue_mbuf = NULL;
- if (c->ue_xfer == NULL) {
- c->ue_xfer = usbd_alloc_xfer(ue_udev);
- if (c->ue_xfer == NULL)
- return (ENOBUFS);
- c->ue_buf = usbd_alloc_buffer(c->ue_xfer, UE_BUFSZ);
- if (c->ue_buf == NULL)
- return (ENOBUFS);
- }
- }
-
- return (0);
-}
-
-void
-usb_ether_rx_list_free(struct ue_cdata *cd)
-{
- int i;
-
- for (i = 0; i < UE_RX_LIST_CNT; i++) {
- if (cd->ue_rx_chain[i].ue_mbuf != NULL) {
- m_freem(cd->ue_rx_chain[i].ue_mbuf);
- cd->ue_rx_chain[i].ue_mbuf = NULL;
- }
- if (cd->ue_rx_chain[i].ue_xfer != NULL) {
- usbd_free_xfer(cd->ue_rx_chain[i].ue_xfer);
- cd->ue_rx_chain[i].ue_xfer = NULL;
- }
- }
-}
-
-void
-usb_ether_tx_list_free(struct ue_cdata *cd)
-{
- int i;
-
- for (i = 0; i < UE_RX_LIST_CNT; i++) {
- if (cd->ue_tx_chain[i].ue_mbuf != NULL) {
- m_freem(cd->ue_tx_chain[i].ue_mbuf);
- cd->ue_tx_chain[i].ue_mbuf = NULL;
- }
- if (cd->ue_tx_chain[i].ue_xfer != NULL) {
- usbd_free_xfer(cd->ue_tx_chain[i].ue_xfer);
- cd->ue_tx_chain[i].ue_xfer = NULL;
- }
- }
-}
-
-void
-usb_ether_task_init(device_t dev, int flags, struct usb_taskqueue *tq)
-{
-
- /* nothing for now. */
-}
-
-void
-usb_ether_task_enqueue(struct usb_taskqueue *tq, struct task *task)
-{
-
- taskqueue_enqueue(taskqueue_thread, task);
-}
-
-void
-usb_ether_task_drain(struct usb_taskqueue *tq, struct task *task)
-{
-
- taskqueue_drain(taskqueue_thread, task);
-}
-
-void
-usb_ether_task_destroy(struct usb_taskqueue *tq)
-{
-
- /* nothing for now */
-
-}
diff --git a/sys/dev/usb/usb_ethersubr.h b/sys/dev/usb/usb_ethersubr.h
deleted file mode 100644
index f3d2e34..0000000
--- a/sys/dev/usb/usb_ethersubr.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*-
- * Copyright (c) 1997, 1998, 1999, 2000
- * Bill Paul <wpaul@ee.columbia.edu>. 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$
- */
-
-#ifndef _USB_ETHERSUBR_H_
-#define _USB_ETHERSUBR_H_
-
-#include <sys/bus.h>
-#include <sys/module.h>
-
-#include <dev/usb/usbdi.h>
-
-#define UE_TX_LIST_CNT 1
-#define UE_RX_LIST_CNT 1
-#define UE_BUFSZ 1536
-
-struct usb_qdat {
- struct ifnet *ifp;
- void (*if_rxstart) (struct ifnet *);
-};
-
-struct ue_chain {
- void *ue_sc;
- usbd_xfer_handle ue_xfer;
- char *ue_buf;
- struct mbuf *ue_mbuf;
- int ue_idx;
- usbd_status ue_status;
-};
-
-struct ue_cdata {
- struct ue_chain ue_tx_chain[UE_TX_LIST_CNT];
- struct ue_chain ue_rx_chain[UE_RX_LIST_CNT];
- void *ue_ibuf;
- int ue_tx_prod;
- int ue_tx_cons;
- int ue_tx_cnt;
- int ue_rx_prod;
-};
-
-void usb_register_netisr (void);
-void usb_ether_input (struct mbuf *);
-void usb_tx_done (struct mbuf *);
-struct mbuf *usb_ether_newbuf (void);
-int usb_ether_rx_list_init (void *, struct ue_cdata *,
- usbd_device_handle);
-int usb_ether_tx_list_init (void *, struct ue_cdata *,
- usbd_device_handle);
-void usb_ether_rx_list_free (struct ue_cdata *);
-void usb_ether_tx_list_free (struct ue_cdata *);
-
-struct usb_taskqueue {
- int dummy;
-};
-
-void usb_ether_task_init(device_t, int, struct usb_taskqueue *);
-void usb_ether_task_enqueue(struct usb_taskqueue *, struct task *);
-void usb_ether_task_drain(struct usb_taskqueue *, struct task *);
-void usb_ether_task_destroy(struct usb_taskqueue *);
-
-#endif /* _USB_ETHERSUBR_H_ */
diff --git a/sys/dev/usb/usb_if.m b/sys/dev/usb/usb_if.m
deleted file mode 100644
index b04c8a4..0000000
--- a/sys/dev/usb/usb_if.m
+++ /dev/null
@@ -1,42 +0,0 @@
-#-
-# Copyright (c) 1992-1998 Nick Hibma <n_hibma@freebsd.org>
-# 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,
-# without modification, immediately at the beginning of the file.
-# 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. The name of the author may not be used to endorse or promote products
-# derived from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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$
-#
-
-# USB interface description
-#
-
-#include <sys/bus.h>
-
-INTERFACE usb;
-
-# The device should start probing for new drivers again
-#
-METHOD int reconfigure {
- device_t dev;
-};
diff --git a/sys/dev/usb/usb_mem.c b/sys/dev/usb/usb_mem.c
deleted file mode 100644
index bbb0bf6..0000000
--- a/sys/dev/usb/usb_mem.c
+++ /dev/null
@@ -1,297 +0,0 @@
-/* $NetBSD: usb_mem.c,v 1.26 2003/02/01 06:23:40 thorpej Exp $ */
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) 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.
- */
-
-/*
- * USB DMA memory allocation.
- * We need to allocate a lot of small (many 8 byte, some larger)
- * memory blocks that can be used for DMA. Using the bus_dma
- * routines directly would incur large overheads in space and time.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/malloc.h>
-#include <sys/kernel.h>
-#include <sys/endian.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/queue.h>
-
-#include <machine/bus.h>
-#include <machine/endian.h>
-
-#ifdef DIAGNOSTIC
-#include <sys/proc.h>
-#endif
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdivar.h> /* just for usb_dma_t */
-#include <dev/usb/usb_mem.h>
-
-#ifdef USB_DEBUG
-#define DPRINTF(x) if (usbdebug) printf x
-#define DPRINTFN(n,x) if (usbdebug>(n)) printf x
-extern int usbdebug;
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-#define USB_MEM_SMALL 64
-#define USB_MEM_CHUNKS (PAGE_SIZE / USB_MEM_SMALL)
-#define USB_MEM_BLOCK (USB_MEM_SMALL * USB_MEM_CHUNKS)
-
-/* This struct is overlayed on free fragments. */
-struct usb_frag_dma {
- usb_dma_block_t *block;
- u_int offs;
- LIST_ENTRY(usb_frag_dma) next;
-};
-
-static bus_dmamap_callback_t usbmem_callback;
-static usbd_status usb_block_allocmem(bus_dma_tag_t, size_t, size_t,
- usb_dma_block_t **);
-static void usb_block_freemem(usb_dma_block_t *);
-
-static LIST_HEAD(, usb_dma_block) usb_blk_freelist =
- LIST_HEAD_INITIALIZER(usb_blk_freelist);
-static int usb_blk_nfree = 0;
-/* XXX should have different free list for different tags (for speed) */
-static LIST_HEAD(, usb_frag_dma) usb_frag_freelist =
- LIST_HEAD_INITIALIZER(usb_frag_freelist);
-
-static void
-usbmem_callback(void *arg, bus_dma_segment_t *segs, int nseg, int error)
-{
- int i;
- usb_dma_block_t *p = arg;
-
- if (error == EFBIG) {
- printf("usb: mapping to large\n");
- return;
- }
-
- p->nsegs = nseg;
- for (i = 0; i < nseg && i < sizeof p->segs / sizeof *p->segs; i++)
- p->segs[i] = segs[i];
-}
-
-static usbd_status
-usb_block_allocmem(bus_dma_tag_t tag, size_t size, size_t align,
- usb_dma_block_t **dmap)
-{
- usb_dma_block_t *p;
- int s;
-
- DPRINTFN(5, ("usb_block_allocmem: size=%lu align=%lu\n",
- (u_long)size, (u_long)align));
-
-#ifdef DIAGNOSTIC
- if (!curproc) {
- printf("usb_block_allocmem: in interrupt context, size=%lu\n",
- (unsigned long) size);
- }
-#endif
-
- s = splusb();
- /* First check the free list. */
- for (p = LIST_FIRST(&usb_blk_freelist); p; p = LIST_NEXT(p, next)) {
- if (p->tag == tag && p->size >= size && p->size < size * 2 &&
- p->align >= align) {
- LIST_REMOVE(p, next);
- usb_blk_nfree--;
- splx(s);
- *dmap = p;
- DPRINTFN(6,("usb_block_allocmem: free list size=%lu\n",
- (u_long)p->size));
- return (USBD_NORMAL_COMPLETION);
- }
- }
- splx(s);
-
-#ifdef DIAGNOSTIC
- if (!curproc) {
- printf("usb_block_allocmem: in interrupt context, failed\n");
- return (USBD_NOMEM);
- }
-#endif
-
- DPRINTFN(6, ("usb_block_allocmem: no free\n"));
- p = malloc(sizeof *p, M_USB, M_NOWAIT);
- if (p == NULL)
- return (USBD_NOMEM);
-
- if (bus_dma_tag_create(tag, align, 0,
- BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
- size, sizeof(p->segs) / sizeof(p->segs[0]), size,
- 0, NULL, NULL, &p->tag) == ENOMEM)
- {
- goto free;
- }
-
- p->size = size;
- p->align = align;
- if (bus_dmamem_alloc(p->tag, &p->kaddr,
- BUS_DMA_NOWAIT|BUS_DMA_COHERENT, &p->map))
- goto tagfree;
-
- if (bus_dmamap_load(p->tag, p->map, p->kaddr, p->size,
- usbmem_callback, p, 0))
- goto memfree;
-
- /* XXX - override the tag, ok since we never free it */
- p->tag = tag;
- *dmap = p;
- return (USBD_NORMAL_COMPLETION);
-
- /*
- * XXX - do we need to _unload? is the order of _free and _destroy
- * correct?
- */
-memfree:
- bus_dmamem_free(p->tag, p->kaddr, p->map);
-tagfree:
- bus_dma_tag_destroy(p->tag);
-free:
- free(p, M_USB);
- return (USBD_NOMEM);
-}
-
-/*
- * Do not free the memory unconditionally since we might be called
- * from an interrupt context and that is BAD.
- * XXX when should we really free?
- */
-static void
-usb_block_freemem(usb_dma_block_t *p)
-{
- int s;
-
- 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);
-}
-
-usbd_status
-usb_allocmem(usbd_bus_handle bus, size_t size, size_t align, usb_dma_t *p)
-{
- bus_dma_tag_t tag = bus->parent_dmatag;
- usbd_status err;
- struct usb_frag_dma *f;
- usb_dma_block_t *b;
- int i;
- int s;
-
- /* compat w/ Net/OpenBSD */
- if (align == 0)
- align = 1;
-
- /* If the request is large then just use a full block. */
- if (size > USB_MEM_SMALL || align > USB_MEM_SMALL) {
- DPRINTFN(1, ("usb_allocmem: large alloc %d\n", (int)size));
- size = (size + USB_MEM_BLOCK - 1) & ~(USB_MEM_BLOCK - 1);
- err = usb_block_allocmem(tag, size, align, &p->block);
- if (!err) {
- p->block->fullblock = 1;
- p->offs = 0;
- p->len = size;
- }
- return (err);
- }
-
- s = splusb();
- /* Check for free fragments. */
- for (f = LIST_FIRST(&usb_frag_freelist); f; f = LIST_NEXT(f, next))
- if (f->block->tag == tag)
- break;
- if (f == NULL) {
- DPRINTFN(1, ("usb_allocmem: adding fragments\n"));
- err = usb_block_allocmem(tag, USB_MEM_BLOCK, USB_MEM_SMALL,&b);
- if (err) {
- splx(s);
- return (err);
- }
- b->fullblock = 0;
- /* XXX - override the tag, ok since we never free it */
- b->tag = tag;
- KASSERT(sizeof *f <= USB_MEM_SMALL, ("USB_MEM_SMALL(%d) is too small for struct usb_frag_dma(%zd)\n",
- USB_MEM_SMALL, sizeof *f));
- for (i = 0; i < USB_MEM_BLOCK; i += USB_MEM_SMALL) {
- f = (struct usb_frag_dma *)((char *)b->kaddr + i);
- f->block = b;
- f->offs = i;
- LIST_INSERT_HEAD(&usb_frag_freelist, f, next);
- }
- f = LIST_FIRST(&usb_frag_freelist);
- }
- p->block = f->block;
- p->offs = f->offs;
- p->len = USB_MEM_SMALL;
- LIST_REMOVE(f, next);
- splx(s);
- DPRINTFN(5, ("usb_allocmem: use frag=%p size=%d\n", f, (int)size));
- return (USBD_NORMAL_COMPLETION);
-}
-
-void
-usb_freemem(usbd_bus_handle bus, usb_dma_t *p)
-{
- struct usb_frag_dma *f;
- int s;
-
- if (p->block->fullblock) {
- DPRINTFN(1, ("usb_freemem: large free\n"));
- usb_block_freemem(p->block);
- return;
- }
- f = KERNADDR(p, 0);
- f->block = p->block;
- f->offs = p->offs;
- s = splusb();
- LIST_INSERT_HEAD(&usb_frag_freelist, f, next);
- splx(s);
- DPRINTFN(5, ("usb_freemem: frag=%p\n", f));
-}
diff --git a/sys/dev/usb/usb_mem.h b/sys/dev/usb/usb_mem.h
deleted file mode 100644
index b8f0a14..0000000
--- a/sys/dev/usb/usb_mem.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* $NetBSD: usb_mem.h,v 1.18 2002/05/28 17:45:17 augustss Exp $ */
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) 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.
- */
-
-typedef struct usb_dma_block {
- bus_dma_tag_t tag;
- bus_dmamap_t map;
- void *kaddr;
- bus_dma_segment_t segs[1];
- int nsegs;
- size_t size;
- size_t align;
- int fullblock;
- LIST_ENTRY(usb_dma_block) next;
-} usb_dma_block_t;
-
-#define DMAADDR(dma, o) ((dma)->block->segs[0].ds_addr + (dma)->offs + (o))
-#define KERNADDR(dma, o) \
- ((void *)((char *)((dma)->block->kaddr) + (dma)->offs + (o)))
-
-usbd_status usb_allocmem(usbd_bus_handle,size_t,size_t, usb_dma_t *);
-void usb_freemem(usbd_bus_handle, usb_dma_t *);
diff --git a/sys/dev/usb/usb_port.h b/sys/dev/usb/usb_port.h
deleted file mode 100644
index fd92d7b..0000000
--- a/sys/dev/usb/usb_port.h
+++ /dev/null
@@ -1,200 +0,0 @@
-/* $OpenBSD: usb_port.h,v 1.18 2000/09/06 22:42:10 rahnds Exp $ */
-/* $NetBSD: usb_port.h,v 1.54 2002/03/28 21:49:19 ichiro Exp $ */
-/* $FreeBSD$ */
-
-/* Also already merged from NetBSD:
- * $NetBSD: usb_port.h,v 1.57 2002/09/27 20:42:01 thorpej Exp $
- * $NetBSD: usb_port.h,v 1.58 2002/10/01 01:25:26 thorpej 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 (lennart@augustsson.net) 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.
- */
-
-#ifndef _USB_PORT_H
-#define _USB_PORT_H
-
-/*
- * Macro's to cope with the differences between operating systems.
- */
-
-/*
- * FreeBSD
- */
-
-/* We don't use the soft interrupt code in FreeBSD. */
-#if 0
-#define USB_USE_SOFTINTR
-#endif
-
-#define Static static
-
-#define device_ptr_t device_t
-#define USBBASEDEVICE device_t
-#define USBDEV(bdev) (bdev)
-#define USBDEVNAME(bdev) device_get_nameunit(bdev)
-#define USBDEVPTRNAME(bdev) device_get_nameunit(bdev)
-#define USBDEVUNIT(bdev) device_get_unit(bdev)
-#define USBGETSOFTC(bdev) (device_get_softc(bdev))
-
-#define DECLARE_USB_DMA_T \
- struct usb_dma_block; \
- typedef struct { \
- struct usb_dma_block *block; \
- u_int offs; \
- u_int len; \
- } usb_dma_t
-
-typedef struct thread *usb_proc_ptr;
-
-#define uio_procp uio_td
-
-#define usb_kthread_create1(f, s, p, a0, a1) \
- kproc_create((f), (s), (p), RFHIGHPID, 0, (a0), (a1))
-#define usb_kthread_create2(f, s, p, a0) \
- kproc_create((f), (s), (p), RFHIGHPID, 0, (a0))
-#define usb_kthread_create kproc_create
-
-#define config_pending_incr()
-#define config_pending_decr()
-
-typedef struct callout usb_callout_t;
-#define usb_callout_init(h) callout_init(&(h), 0)
-#define usb_callout(h, t, f, d) callout_reset(&(h), (t), (f), (d))
-#define usb_uncallout(h, f, d) callout_stop(&(h))
-#define usb_uncallout_drain(h, f, d) callout_drain(&(h))
-
-#define clalloc(p, s, x) (clist_alloc_cblocks((p), (s), (s)), 0)
-#define clfree(p) clist_free_cblocks((p))
-
-#define config_detach(dev, flag) \
- do { \
- device_detach(dev); \
- free(device_get_ivars(dev), M_USB); \
- device_delete_child(device_get_parent(dev), dev); \
- } while (0);
-
-typedef struct malloc_type *usb_malloc_type;
-
-#define USB_DECLARE_DRIVER_INIT(dname, init...) \
-static device_probe_t __CONCAT(dname,_match); \
-static device_attach_t __CONCAT(dname,_attach); \
-static device_detach_t __CONCAT(dname,_detach); \
-\
-static devclass_t __CONCAT(dname,_devclass); \
-\
-static device_method_t __CONCAT(dname,_methods)[] = { \
- DEVMETHOD(device_probe, __CONCAT(dname,_match)), \
- DEVMETHOD(device_attach, __CONCAT(dname,_attach)), \
- DEVMETHOD(device_detach, __CONCAT(dname,_detach)), \
- init, \
- {0,0} \
-}; \
-\
-static driver_t __CONCAT(dname,_driver) = { \
- #dname, \
- __CONCAT(dname,_methods), \
- sizeof(struct __CONCAT(dname,_softc)) \
-}; \
-MODULE_DEPEND(dname, usb, 1, 1, 1)
-
-
-#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)
-
-#define USB_MATCH_START(dname, uaa) \
- struct usb_attach_arg *uaa = device_get_ivars(self)
-
-#define USB_MATCH_SETUP \
- sc->sc_dev = self
-
-#define USB_ATTACH(dname) \
-static int \
-__CONCAT(dname,_attach)(device_t self)
-
-#define USB_ATTACH_START(dname, sc, uaa) \
- struct __CONCAT(dname,_softc) *sc = device_get_softc(self); \
- struct usb_attach_arg *uaa = device_get_ivars(self)
-
-/* Returns from attach */
-#define USB_ATTACH_ERROR_RETURN return ENXIO
-#define USB_ATTACH_SUCCESS_RETURN return 0
-
-#define USB_ATTACH_SETUP \
- sc->sc_dev = self; \
-
-#define USB_DETACH(dname) \
-static int \
-__CONCAT(dname,_detach)(device_t self)
-
-#define USB_DETACH_START(dname, sc) \
- struct __CONCAT(dname,_softc) *sc = device_get_softc(self)
-
-#define USB_GET_SC_OPEN(dname, unit, sc) \
- sc = devclass_get_softc(__CONCAT(dname,_devclass), unit); \
- if (sc == NULL) \
- return (ENXIO)
-
-#define USB_GET_SC(dname, unit, sc) \
- sc = devclass_get_softc(__CONCAT(dname,_devclass), unit)
-
-#define USB_DO_ATTACH(dev, bdev, parent, args, print, sub) \
- (device_probe_and_attach((bdev)) == 0 ? (bdev) : 0)
-
-/* conversion from one type of queue to the other */
-#define SIMPLEQ_REMOVE_HEAD STAILQ_REMOVE_HEAD
-#define SIMPLEQ_INSERT_HEAD STAILQ_INSERT_HEAD
-#define SIMPLEQ_INSERT_TAIL STAILQ_INSERT_TAIL
-#define SIMPLEQ_NEXT STAILQ_NEXT
-#define SIMPLEQ_FIRST STAILQ_FIRST
-#define SIMPLEQ_HEAD STAILQ_HEAD
-#define SIMPLEQ_EMPTY STAILQ_EMPTY
-#define SIMPLEQ_FOREACH STAILQ_FOREACH
-#define SIMPLEQ_INIT STAILQ_INIT
-#define SIMPLEQ_HEAD_INITIALIZER STAILQ_HEAD_INITIALIZER
-#define SIMPLEQ_ENTRY STAILQ_ENTRY
-
-#include <sys/syslog.h>
-/*
-#define logprintf(args...) log(LOG_DEBUG, args)
-*/
-#define logprintf printf
-
-#endif /* _USB_PORT_H */
diff --git a/sys/dev/usb/usb_quirks.c b/sys/dev/usb/usb_quirks.c
deleted file mode 100644
index 2771bb7..0000000
--- a/sys/dev/usb/usb_quirks.c
+++ /dev/null
@@ -1,153 +0,0 @@
-/* $NetBSD: usb_quirks.c,v 1.50 2004/06/23 02:30:52 mycroft 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 (lennart@augustsson.net) 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-
-#include <dev/usb/usb.h>
-
-#include "usbdevs.h"
-#include <dev/usb/usb_quirks.h>
-
-#ifdef USB_DEBUG
-extern int usbdebug;
-#endif
-
-#define ANY 0xffff
-
-static const struct usbd_quirk_entry {
- u_int16_t idVendor;
- u_int16_t idProduct;
- u_int16_t bcdDevice;
- struct usbd_quirks quirks;
-} usb_quirks[] = {
- { USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORT4,
- 0x094, { UQ_SWAP_UNICODE}},
- { USB_VENDOR_DALLAS, USB_PRODUCT_DALLAS_J6502, 0x0a2, { UQ_BAD_ADC }},
- { USB_VENDOR_DALLAS, USB_PRODUCT_DALLAS_J6502, 0x0a2, { UQ_AU_NO_XU }},
- { 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_ALCOR2, USB_PRODUCT_ALCOR2_KBD_HUB, 0x001, { UQ_SPUR_BUT_UP }},
- { USB_VENDOR_MCT, USB_PRODUCT_MCT_HUB0100, 0x102, { UQ_BUS_POWERED }},
- { USB_VENDOR_MCT, USB_PRODUCT_MCT_USB232, 0x102, { UQ_BUS_POWERED }},
- { USB_VENDOR_TI, USB_PRODUCT_TI_UTUSB41, 0x110, { UQ_POWER_CLAIM }},
- { USB_VENDOR_TELEX, USB_PRODUCT_TELEX_MIC1, 0x009, { UQ_AU_NO_FRAC }},
- { USB_VENDOR_SILICONPORTALS, USB_PRODUCT_SILICONPORTALS_YAPPHONE,
- 0x100, { UQ_AU_INP_ASYNC }},
- { USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_UN53B, ANY, { UQ_NO_STRINGS }},
- /* XXX These should have a revision number, but I don't know what they are. */
- { USB_VENDOR_HP, USB_PRODUCT_HP_895C, ANY, { UQ_BROKEN_BIDIR }},
- { USB_VENDOR_HP, USB_PRODUCT_HP_880C, ANY, { UQ_BROKEN_BIDIR }},
- { USB_VENDOR_HP, USB_PRODUCT_HP_815C, ANY, { UQ_BROKEN_BIDIR }},
- { USB_VENDOR_HP, USB_PRODUCT_HP_810C, ANY, { UQ_BROKEN_BIDIR }},
- { USB_VENDOR_HP, USB_PRODUCT_HP_830C, ANY, { UQ_BROKEN_BIDIR }},
- { USB_VENDOR_HP, USB_PRODUCT_HP_1220C, ANY, { UQ_BROKEN_BIDIR }},
- { USB_VENDOR_XEROX, USB_PRODUCT_XEROX_WCM15, ANY, { UQ_BROKEN_BIDIR }},
- /* MS keyboards do weird things */
- { USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_WLNOTEBOOK,
- ANY, { UQ_MS_BAD_CLASS | UQ_MS_LEADING_BYTE }},
- { USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_WLNOTEBOOK2,
- ANY, { UQ_MS_BAD_CLASS | UQ_MS_LEADING_BYTE }},
- { USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_WLINTELLIMOUSE,
- ANY, { UQ_MS_LEADING_BYTE }},
- { USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_COMFORT3000,
- ANY, { UQ_MS_BAD_CLASS | UQ_MS_LEADING_BYTE }},
- { USB_VENDOR_SONY, USB_PRODUCT_SONY_RF_RECEIVER,
- ANY,{ UQ_MS_BAD_CLASS }},
-
- /* Devices which should be ignored by uhid */
- { USB_VENDOR_APC, USB_PRODUCT_APC_UPS,
- ANY, { UQ_HID_IGNORE }},
- { USB_VENDOR_ASUS, USB_PRODUCT_ASUS_LCM,
- ANY, { UQ_HID_IGNORE }},
- { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F6C550AVR,
- ANY, { UQ_HID_IGNORE }},
- { USB_VENDOR_CYBERPOWER, USB_PRODUCT_CYBERPOWER_1500CAVRLCD,
- ANY, { UQ_HID_IGNORE }},
- { USB_VENDOR_DELORME, USB_PRODUCT_DELORME_EARTHMATE,
- ANY, { UQ_HID_IGNORE }},
- { USB_VENDOR_ITUNERNET, USB_PRODUCT_ITUNERNET_USBLCD2X20,
- ANY, { UQ_HID_IGNORE }},
- { USB_VENDOR_MGE, USB_PRODUCT_MGE_UPS1,
- ANY, { UQ_HID_IGNORE }},
- { USB_VENDOR_MGE, USB_PRODUCT_MGE_UPS2,
- ANY, { UQ_HID_IGNORE }},
- { USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPHONE,
- ANY, { UQ_HID_IGNORE }},
- { USB_VENDOR_APPLE, USB_PRODUCT_APPLE_IPHONE_3G,
- ANY, { UQ_HID_IGNORE }},
-
- /* Devices which should be ignored by both ukbd and uhid */
- { USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_WISPY1A,
- ANY, { UQ_KBD_IGNORE }},
- { USB_VENDOR_METAGEEK, USB_PRODUCT_METAGEEK_WISPY1B,
- ANY, { UQ_KBD_IGNORE }},
- { USB_VENDOR_METAGEEK, USB_PRODUCT_METAGEEK_WISPY24X,
- ANY, { UQ_KBD_IGNORE }},
- { 0, 0, 0, { 0 } }
-};
-
-const struct usbd_quirks usbd_no_quirk = { 0 };
-
-const struct usbd_quirks *
-usbd_find_quirk(usb_device_descriptor_t *d)
-{
- const struct usbd_quirk_entry *t;
- u_int16_t vendor = UGETW(d->idVendor);
- u_int16_t product = UGETW(d->idProduct);
- u_int16_t revision = UGETW(d->bcdDevice);
-
- for (t = usb_quirks; t->idVendor != 0; t++) {
- if (t->idVendor == vendor &&
- t->idProduct == product &&
- (t->bcdDevice == ANY || t->bcdDevice == revision))
- break;
- }
-#ifdef USB_DEBUG
- if (usbdebug && t->quirks.uq_flags)
- printf("usbd_find_quirk 0x%04x/0x%04x/%x: %d\n",
- UGETW(d->idVendor), UGETW(d->idProduct),
- UGETW(d->bcdDevice), t->quirks.uq_flags);
-#endif
- return (&t->quirks);
-}
diff --git a/sys/dev/usb/usb_quirks.h b/sys/dev/usb/usb_quirks.h
deleted file mode 100644
index 16e2f3f..0000000
--- a/sys/dev/usb/usb_quirks.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* $NetBSD: usb_quirks.h,v 1.20 2001/04/15 09:38:01 augustss Exp $ */
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) 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.
- */
-
-struct usbd_quirks {
- u_int32_t uq_flags; /* Device problems: */
-#define UQ_SWAP_UNICODE 0x00000002 /* has some Unicode strings swapped. */
-#define UQ_MS_REVZ 0x00000004 /* mouse has Z-axis reversed */
-#define UQ_NO_STRINGS 0x00000008 /* string descriptors are broken. */
-#define UQ_BAD_ADC 0x00000010 /* bad audio spec version number. */
-#define UQ_BUS_POWERED 0x00000020 /* device is bus powered, despite claim */
-#define UQ_BAD_AUDIO 0x00000040 /* device claims audio class, but isn't */
-#define UQ_SPUR_BUT_UP 0x00000080 /* spurious mouse button up events */
-#define UQ_AU_NO_XU 0x00000100 /* audio device has broken extension unit */
-#define UQ_POWER_CLAIM 0x00000200 /* hub lies about power status */
-#define UQ_AU_NO_FRAC 0x00000400 /* don't adjust for fractional samples */
-#define UQ_AU_INP_ASYNC 0x00000800 /* input is async despite claim of adaptive */
-#define UQ_BROKEN_BIDIR 0x00002000 /* printer has broken bidir mode */
-#define UQ_OPEN_CLEARSTALL 0x04000 /* device needs clear endpoint stall */
-#define UQ_HID_IGNORE 0x00008000 /* device should be ignored by hid class */
-#define UQ_KBD_IGNORE 0x00018000 /* device should be ignored by both kbd and hid class */
-#define UQ_MS_BAD_CLASS 0x00020000 /* doesn't identify properly */
-#define UQ_MS_LEADING_BYTE 0x40000 /* mouse sends an unknown leading byte. */
-};
-
-extern const struct usbd_quirks usbd_no_quirk;
-
-const struct usbd_quirks *usbd_find_quirk(usb_device_descriptor_t *);
diff --git a/sys/dev/usb/usb_subr.c b/sys/dev/usb/usb_subr.c
deleted file mode 100644
index 29d044c..0000000
--- a/sys/dev/usb/usb_subr.c
+++ /dev/null
@@ -1,1388 +0,0 @@
-/* $NetBSD: usb_subr.c,v 1.99 2002/07/11 21:14:34 augustss Exp $ */
-
-/* Also already have from NetBSD:
- * $NetBSD: usb_subr.c,v 1.102 2003/01/01 16:21:50 augustss Exp $
- * $NetBSD: usb_subr.c,v 1.103 2003/01/10 11:19:13 augustss Exp $
- * $NetBSD: usb_subr.c,v 1.111 2004/03/15 10:35:04 augustss Exp $
- * $NetBSD: usb_subr.c,v 1.114 2004/06/23 02:30:52 mycroft Exp $
- * $NetBSD: usb_subr.c,v 1.115 2004/06/23 05:23:19 mycroft Exp $
- * $NetBSD: usb_subr.c,v 1.116 2004/06/23 06:27:54 mycroft Exp $
- * $NetBSD: usb_subr.c,v 1.119 2004/10/23 13:26:33 augustss Exp $
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) 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.
- */
-
-#include "opt_usb.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/proc.h>
-#include <sys/sysctl.h>
-
-#include <machine/bus.h>
-
-#include <dev/usb/usb.h>
-
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include <dev/usb/usbdivar.h>
-#include "usbdevs.h"
-#include <dev/usb/usb_quirks.h>
-
-#define delay(d) DELAY(d)
-
-#ifdef USB_DEBUG
-#define DPRINTF(x) if (usbdebug) printf x
-#define DPRINTFN(n,x) if (usbdebug>(n)) printf x
-extern int usbdebug;
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-static usbd_status usbd_set_config(usbd_device_handle, int);
-static void usbd_devinfo_vp(usbd_device_handle, char *, char *, int);
-static int usbd_getnewaddr(usbd_bus_handle bus);
-static void usbd_free_iface_data(usbd_device_handle dev, int ifcno);
-static void usbd_kill_pipe(usbd_pipe_handle);
-static usbd_status usbd_probe_and_attach(device_t parent,
- usbd_device_handle dev, int port, int addr);
-
-static u_int32_t usb_cookie_no = 0;
-
-#ifdef USBVERBOSE
-typedef u_int16_t usb_vendor_id_t;
-typedef u_int16_t usb_product_id_t;
-
-/*
- * Descriptions of of known vendors and devices ("products").
- */
-struct usb_knowndev {
- usb_vendor_id_t vendor;
- usb_product_id_t product;
- int flags;
- char *vendorname, *productname;
-};
-#define USB_KNOWNDEV_NOPROD 0x01 /* match on vendor only */
-
-#include "usbdevs_data.h"
-#endif /* USBVERBOSE */
-
-static const char * const usbd_error_strs[] = {
- "NORMAL_COMPLETION",
- "IN_PROGRESS",
- "PENDING_REQUESTS",
- "NOT_STARTED",
- "INVAL",
- "NOMEM",
- "CANCELLED",
- "BAD_ADDRESS",
- "IN_USE",
- "NO_ADDR",
- "SET_ADDR_FAILED",
- "NO_POWER",
- "TOO_DEEP",
- "IOERROR",
- "NOT_CONFIGURED",
- "TIMEOUT",
- "SHORT_XFER",
- "STALLED",
- "INTERRUPTED",
- "XXX",
-};
-
-const char *
-usbd_errstr(usbd_status err)
-{
- static char buffer[5];
-
- if (err < USBD_ERROR_MAX) {
- return usbd_error_strs[err];
- } else {
- snprintf(buffer, sizeof buffer, "%d", err);
- return buffer;
- }
-}
-
-usbd_status
-usbd_get_string_desc(usbd_device_handle dev, int sindex, int langid,
- usb_string_descriptor_t *sdesc, int *sizep)
-{
- usb_device_request_t req;
- usbd_status err;
- int actlen;
-
- req.bmRequestType = UT_READ_DEVICE;
- req.bRequest = UR_GET_DESCRIPTOR;
- USETW2(req.wValue, UDESC_STRING, sindex);
- USETW(req.wIndex, langid);
- USETW(req.wLength, 2); /* only size byte first */
- err = usbd_do_request_flags(dev, &req, sdesc, USBD_SHORT_XFER_OK,
- &actlen, USBD_DEFAULT_TIMEOUT);
- if (err)
- return (err);
-
- if (actlen < 2)
- return (USBD_SHORT_XFER);
-
- USETW(req.wLength, sdesc->bLength); /* the whole string */
- err = usbd_do_request_flags(dev, &req, sdesc, USBD_SHORT_XFER_OK,
- &actlen, USBD_DEFAULT_TIMEOUT);
- if (err)
- return (err);
-
- if (actlen != sdesc->bLength) {
- DPRINTFN(-1, ("usbd_get_string_desc: expected %d, got %d\n",
- sdesc->bLength, actlen));
- }
-
- *sizep = actlen;
- return (USBD_NORMAL_COMPLETION);
-}
-
-static void
-usbd_trim_spaces(char *p)
-{
- char *q, *e;
-
- if (p == NULL)
- return;
- q = e = p;
- while (*q == ' ') /* skip leading spaces */
- q++;
- while ((*p = *q++)) /* copy string */
- if (*p++ != ' ') /* remember last non-space */
- e = p;
- *e = 0; /* kill trailing spaces */
-}
-
-static void
-usbd_devinfo_vp(usbd_device_handle dev, char *v, char *p, int usedev)
-{
- usb_device_descriptor_t *udd = &dev->ddesc;
- char *vendor = 0, *product = 0;
-#ifdef USBVERBOSE
- const struct usb_knowndev *kdp;
-#endif
-
- if (dev == NULL) {
- v[0] = p[0] = '\0';
- return;
- }
-
- if (usedev) {
- if (usbd_get_string(dev, udd->iManufacturer, v,
- USB_MAX_STRING_LEN))
- vendor = NULL;
- else
- vendor = v;
- usbd_trim_spaces(vendor);
- if (usbd_get_string(dev, udd->iProduct, p,
- USB_MAX_STRING_LEN))
- product = NULL;
- else
- product = p;
- usbd_trim_spaces(product);
- if (vendor && !*vendor)
- vendor = NULL;
- if (product && !*product)
- product = NULL;
- } else {
- vendor = NULL;
- product = NULL;
- }
-#ifdef USBVERBOSE
- if (vendor == NULL || product == NULL) {
- for(kdp = usb_knowndevs;
- kdp->vendorname != NULL;
- kdp++) {
- if (kdp->vendor == UGETW(udd->idVendor) &&
- (kdp->product == UGETW(udd->idProduct) ||
- (kdp->flags & USB_KNOWNDEV_NOPROD) != 0))
- break;
- }
- if (kdp->vendorname != NULL) {
- if (vendor == NULL)
- vendor = kdp->vendorname;
- if (product == NULL)
- product = (kdp->flags & USB_KNOWNDEV_NOPROD) == 0 ?
- kdp->productname : NULL;
- }
- }
-#endif
- if (vendor != NULL && *vendor)
- strcpy(v, vendor);
- else
- sprintf(v, "vendor 0x%04x", UGETW(udd->idVendor));
- if (product != NULL && *product)
- strcpy(p, product);
- else
- sprintf(p, "product 0x%04x", UGETW(udd->idProduct));
-}
-
-int
-usbd_printBCD(char *cp, int bcd)
-{
- return (sprintf(cp, "%x.%02x", bcd >> 8, bcd & 0xff));
-}
-
-void
-usbd_devinfo(usbd_device_handle dev, int showclass, char *cp)
-{
- usb_device_descriptor_t *udd = &dev->ddesc;
- usbd_interface_handle iface;
- char vendor[USB_MAX_STRING_LEN];
- char product[USB_MAX_STRING_LEN];
- int bcdDevice, bcdUSB;
- usb_interface_descriptor_t *id;
-
- usbd_devinfo_vp(dev, vendor, product, 1);
- cp += sprintf(cp, "%s %s", vendor, product);
- if (showclass & USBD_SHOW_DEVICE_CLASS)
- cp += sprintf(cp, ", class %d/%d",
- udd->bDeviceClass, udd->bDeviceSubClass);
- bcdUSB = UGETW(udd->bcdUSB);
- bcdDevice = UGETW(udd->bcdDevice);
- cp += sprintf(cp, ", rev ");
- cp += usbd_printBCD(cp, bcdUSB);
- *cp++ = '/';
- cp += usbd_printBCD(cp, bcdDevice);
- cp += sprintf(cp, ", addr %d", dev->address);
- if (showclass & USBD_SHOW_INTERFACE_CLASS)
- {
- /* fetch the interface handle for the first interface */
- (void)usbd_device2interface_handle(dev, 0, &iface);
- id = usbd_get_interface_descriptor(iface);
- cp += sprintf(cp, ", iclass %d/%d",
- id->bInterfaceClass, id->bInterfaceSubClass);
- }
- *cp = 0;
-}
-
-/* Delay for a certain number of ms */
-void
-usb_delay_ms(usbd_bus_handle bus, u_int ms)
-{
- /* Wait at least two clock ticks so we know the time has passed. */
- if (bus->use_polling || cold)
- delay((ms+1) * 1000);
- else
- pause("usbdly", (ms*hz+999)/1000 + 1);
-}
-
-/* Delay given a device handle. */
-void
-usbd_delay_ms(usbd_device_handle dev, u_int ms)
-{
- usb_delay_ms(dev->bus, ms);
-}
-
-usbd_status
-usbd_reset_port(usbd_device_handle dev, int port, usb_port_status_t *ps)
-{
- usbd_status err;
- int n;
-
- err = usbd_set_port_feature(dev, port, UHF_PORT_RESET);
- DPRINTFN(1,("usbd_reset_port: port %d reset done, error=%s\n",
- port, usbd_errstr(err)));
- if (err)
- return (err);
- n = 10;
- do {
- /* Wait for device to recover from reset. */
- usbd_delay_ms(dev, USB_PORT_RESET_DELAY);
- err = usbd_get_port_status(dev, port, ps);
- if (err) {
- DPRINTF(("usbd_reset_port: get status failed %d\n",
- err));
- return (err);
- }
- /* If the device disappeared, just give up. */
- if (!(UGETW(ps->wPortStatus) & UPS_CURRENT_CONNECT_STATUS))
- return (USBD_NORMAL_COMPLETION);
- } while ((UGETW(ps->wPortChange) & UPS_C_PORT_RESET) == 0 && --n > 0);
- if (n == 0)
- return (USBD_TIMEOUT);
- 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",
- err));
-#endif
-
- /* Wait for the device to recover from reset. */
- usbd_delay_ms(dev, USB_PORT_RESET_RECOVERY);
- return (err);
-}
-
-usb_interface_descriptor_t *
-usbd_find_idesc(usb_config_descriptor_t *cd, int ifaceidx, int altidx)
-{
- char *p = (char *)cd;
- char *end = p + UGETW(cd->wTotalLength);
- usb_interface_descriptor_t *d;
- int curidx, lastidx, curaidx = 0;
-
- for (curidx = lastidx = -1; p < end; ) {
- d = (usb_interface_descriptor_t *)p;
- DPRINTFN(4,("usbd_find_idesc: idx=%d(%d) altidx=%d(%d) len=%d "
- "type=%d\n",
- ifaceidx, curidx, altidx, curaidx,
- d->bLength, d->bDescriptorType));
- if (d->bLength == 0) /* bad descriptor */
- break;
- p += d->bLength;
- if (p <= end && d->bDescriptorType == UDESC_INTERFACE) {
- if (d->bInterfaceNumber != lastidx) {
- lastidx = d->bInterfaceNumber;
- curidx++;
- curaidx = 0;
- } else
- curaidx++;
- if (ifaceidx == curidx && altidx == curaidx)
- return (d);
- }
- }
- return (NULL);
-}
-
-usb_endpoint_descriptor_t *
-usbd_find_edesc(usb_config_descriptor_t *cd, int ifaceidx, int altidx,
- int endptidx)
-{
- char *p = (char *)cd;
- char *end = p + UGETW(cd->wTotalLength);
- usb_interface_descriptor_t *d;
- usb_endpoint_descriptor_t *e;
- int curidx;
-
- d = usbd_find_idesc(cd, ifaceidx, altidx);
- if (d == NULL)
- return (NULL);
- if (endptidx >= d->bNumEndpoints) /* quick exit */
- return (NULL);
-
- curidx = -1;
- for (p = (char *)d + d->bLength; p < end; ) {
- e = (usb_endpoint_descriptor_t *)p;
- if (e->bLength == 0) /* bad descriptor */
- break;
- p += e->bLength;
- if (p <= end && e->bDescriptorType == UDESC_INTERFACE)
- return (NULL);
- if (p <= end && e->bDescriptorType == UDESC_ENDPOINT) {
- curidx++;
- if (curidx == endptidx)
- return (e);
- }
- }
- return (NULL);
-}
-
-usbd_status
-usbd_fill_iface_data(usbd_device_handle dev, int ifaceidx, int altidx)
-{
- usbd_interface_handle ifc = &dev->ifaces[ifaceidx];
- usb_interface_descriptor_t *idesc;
- char *p, *end;
- int endpt, nendpt;
-
- DPRINTFN(4,("usbd_fill_iface_data: ifaceidx=%d altidx=%d\n",
- ifaceidx, altidx));
- idesc = usbd_find_idesc(dev->cdesc, ifaceidx, altidx);
- if (idesc == NULL)
- return (USBD_INVAL);
- ifc->device = dev;
- ifc->idesc = idesc;
- ifc->index = ifaceidx;
- ifc->altindex = altidx;
- nendpt = ifc->idesc->bNumEndpoints;
- DPRINTFN(4,("usbd_fill_iface_data: found idesc nendpt=%d\n", nendpt));
- if (nendpt != 0) {
- ifc->endpoints = malloc(nendpt * sizeof(struct usbd_endpoint),
- M_USB, M_NOWAIT);
- if (ifc->endpoints == NULL)
- return (USBD_NOMEM);
- } else
- ifc->endpoints = NULL;
- ifc->priv = NULL;
- p = (char *)ifc->idesc + ifc->idesc->bLength;
- end = (char *)dev->cdesc + UGETW(dev->cdesc->wTotalLength);
-#define ed ((usb_endpoint_descriptor_t *)p)
- for (endpt = 0; endpt < nendpt; endpt++) {
- DPRINTFN(10,("usbd_fill_iface_data: endpt=%d\n", endpt));
- for (; p < end; p += ed->bLength) {
- DPRINTFN(10,("usbd_fill_iface_data: p=%p end=%p "
- "len=%d type=%d\n",
- p, end, ed->bLength, ed->bDescriptorType));
- if (p + ed->bLength <= end && ed->bLength != 0 &&
- ed->bDescriptorType == UDESC_ENDPOINT)
- goto found;
- if (ed->bLength == 0 ||
- ed->bDescriptorType == UDESC_INTERFACE)
- break;
- }
- /* passed end, or bad desc */
- printf("usbd_fill_iface_data: bad descriptor(s): %s\n",
- ed->bLength == 0 ? "0 length" :
- ed->bDescriptorType == UDESC_INTERFACE ? "iface desc":
- "out of data");
- goto bad;
- found:
- ifc->endpoints[endpt].edesc = ed;
- if (dev->speed == USB_SPEED_HIGH) {
- u_int mps;
- /* Control and bulk endpoints have max packet limits. */
- switch (UE_GET_XFERTYPE(ed->bmAttributes)) {
- case UE_CONTROL:
- mps = USB_2_MAX_CTRL_PACKET;
- goto check;
- case UE_BULK:
- mps = USB_2_MAX_BULK_PACKET;
- check:
- if (UGETW(ed->wMaxPacketSize) != mps) {
- USETW(ed->wMaxPacketSize, mps);
-#ifdef DIAGNOSTIC
- printf("usbd_fill_iface_data: bad max "
- "packet size\n");
-#endif
- }
- break;
- default:
- break;
- }
- }
- ifc->endpoints[endpt].refcnt = 0;
- ifc->endpoints[endpt].savedtoggle = 0;
- p += ed->bLength;
- }
-#undef ed
- LIST_INIT(&ifc->pipes);
- return (USBD_NORMAL_COMPLETION);
-
- bad:
- if (ifc->endpoints != NULL) {
- free(ifc->endpoints, M_USB);
- ifc->endpoints = NULL;
- }
- return (USBD_INVAL);
-}
-
-void
-usbd_free_iface_data(usbd_device_handle dev, int ifcno)
-{
- usbd_interface_handle ifc = &dev->ifaces[ifcno];
- if (ifc->endpoints)
- free(ifc->endpoints, M_USB);
-}
-
-static usbd_status
-usbd_set_config(usbd_device_handle dev, int conf)
-{
- usb_device_request_t req;
-
- req.bmRequestType = UT_WRITE_DEVICE;
- req.bRequest = UR_SET_CONFIG;
- USETW(req.wValue, conf);
- USETW(req.wIndex, 0);
- USETW(req.wLength, 0);
- return (usbd_do_request(dev, &req, 0));
-}
-
-usbd_status
-usbd_set_config_no(usbd_device_handle dev, int no, int msg)
-{
- int index;
- usb_config_descriptor_t cd;
- usbd_status err;
-
- if (no == USB_UNCONFIG_NO)
- return (usbd_set_config_index(dev, USB_UNCONFIG_INDEX, msg));
-
- DPRINTFN(5,("usbd_set_config_no: %d\n", no));
- /* Figure out what config index to use. */
- for (index = 0; index < dev->ddesc.bNumConfigurations; index++) {
- err = usbd_get_config_desc(dev, index, &cd);
- if (err)
- return (err);
- if (cd.bConfigurationValue == no)
- return (usbd_set_config_index(dev, index, msg));
- }
- return (USBD_INVAL);
-}
-
-usbd_status
-usbd_set_config_index(usbd_device_handle dev, int index, int msg)
-{
- usb_status_t ds;
- usb_config_descriptor_t cd, *cdp;
- usbd_status err;
- int i, ifcidx, nifc, len, selfpowered, power;
-
- DPRINTFN(5,("usbd_set_config_index: dev=%p index=%d\n", dev, index));
-
- if (dev->config != USB_UNCONFIG_NO) {
- nifc = dev->cdesc->bNumInterface;
-
- /* Check that all interfaces are idle */
- for (ifcidx = 0; ifcidx < nifc; ifcidx++) {
- if (LIST_EMPTY(&dev->ifaces[ifcidx].pipes))
- continue;
- DPRINTF(("usbd_set_config_index: open pipes exist\n"));
- return (USBD_IN_USE);
- }
-
- DPRINTF(("usbd_set_config_index: free old config\n"));
- /* Free all configuration data structures. */
- for (ifcidx = 0; ifcidx < nifc; ifcidx++)
- usbd_free_iface_data(dev, ifcidx);
- free(dev->ifaces, M_USB);
- free(dev->cdesc, M_USB);
- dev->ifaces = NULL;
- dev->cdesc = NULL;
- dev->config = USB_UNCONFIG_NO;
- }
-
- if (index == USB_UNCONFIG_INDEX) {
- /* We are unconfiguring the device, so leave unallocated. */
- DPRINTF(("usbd_set_config_index: set config 0\n"));
- err = usbd_set_config(dev, USB_UNCONFIG_NO);
- if (err)
- DPRINTF(("usbd_set_config_index: setting config=0 "
- "failed, error=%s\n", usbd_errstr(err)));
- return (err);
- }
-
- /* Get the short descriptor. */
- err = usbd_get_config_desc(dev, index, &cd);
- if (err)
- return (err);
- len = UGETW(cd.wTotalLength);
- cdp = malloc(len, M_USB, M_NOWAIT);
- if (cdp == NULL)
- return (USBD_NOMEM);
-
- /* Get the full descriptor. Try a few times for slow devices. */
- for (i = 0; i < 3; i++) {
- err = usbd_get_desc(dev, UDESC_CONFIG, index, len, cdp);
- if (!err)
- break;
- usbd_delay_ms(dev, 200);
- }
- if (err)
- goto bad;
- if (cdp->bDescriptorType != UDESC_CONFIG) {
- DPRINTFN(-1,("usbd_set_config_index: bad desc %d\n",
- cdp->bDescriptorType));
- err = USBD_INVAL;
- goto bad;
- }
-
- /* Figure out if the device is self or bus powered. */
- selfpowered = 0;
- if (!(dev->quirks->uq_flags & UQ_BUS_POWERED) &&
- (cdp->bmAttributes & UC_SELF_POWERED)) {
- /* May be self powered. */
- if (cdp->bmAttributes & UC_BUS_POWERED) {
- /* Must ask device. */
- if (dev->quirks->uq_flags & UQ_POWER_CLAIM) {
- /*
- * Hub claims to be self powered, but isn't.
- * It seems that the power status can be
- * determined by the hub characteristics.
- */
- usb_hub_descriptor_t hd;
- usb_device_request_t req;
- req.bmRequestType = UT_READ_CLASS_DEVICE;
- req.bRequest = UR_GET_DESCRIPTOR;
- USETW(req.wValue, 0);
- USETW(req.wIndex, 0);
- USETW(req.wLength, USB_HUB_DESCRIPTOR_SIZE);
- err = usbd_do_request(dev, &req, &hd);
- if (!err &&
- (UGETW(hd.wHubCharacteristics) &
- UHD_PWR_INDIVIDUAL))
- selfpowered = 1;
- DPRINTF(("usbd_set_config_index: charac=0x%04x"
- ", error=%s\n",
- UGETW(hd.wHubCharacteristics),
- usbd_errstr(err)));
- } else {
- err = usbd_get_device_status(dev, &ds);
- if (!err &&
- (UGETW(ds.wStatus) & UDS_SELF_POWERED))
- selfpowered = 1;
- DPRINTF(("usbd_set_config_index: status=0x%04x"
- ", error=%s\n",
- UGETW(ds.wStatus), usbd_errstr(err)));
- }
- } else
- selfpowered = 1;
- }
- DPRINTF(("usbd_set_config_index: (addr %d) cno=%d attr=0x%02x, "
- "selfpowered=%d, power=%d\n",
- cdp->bConfigurationValue, dev->address, cdp->bmAttributes,
- selfpowered, cdp->bMaxPower * 2));
-
- /* Check if we have enough power. */
-#ifdef USB_DEBUG
- if (dev->powersrc == NULL) {
- DPRINTF(("usbd_set_config_index: No power source?\n"));
- return (USBD_IOERROR);
- }
-#endif
- power = cdp->bMaxPower * 2;
- if (power > dev->powersrc->power) {
- DPRINTF(("power exceeded %d %d\n", power,dev->powersrc->power));
- /* XXX print nicer message. */
- if (msg)
- device_printf(dev->bus->bdev,
- "device addr %d (config %d) exceeds "
- "power budget, %d mA > %d mA\n",
- dev->address, cdp->bConfigurationValue,
- power, dev->powersrc->power);
- err = USBD_NO_POWER;
- goto bad;
- }
- dev->power = power;
- dev->self_powered = selfpowered;
-
- /* Set the actual configuration value. */
- DPRINTF(("usbd_set_config_index: set config %d\n",
- cdp->bConfigurationValue));
- err = usbd_set_config(dev, cdp->bConfigurationValue);
- if (err) {
- DPRINTF(("usbd_set_config_index: setting config=%d failed, "
- "error=%s\n",
- cdp->bConfigurationValue, usbd_errstr(err)));
- goto bad;
- }
-
- /* Allocate and fill interface data. */
- nifc = cdp->bNumInterface;
- dev->ifaces = malloc(nifc * sizeof(struct usbd_interface),
- M_USB, M_NOWAIT);
- if (dev->ifaces == NULL) {
- err = USBD_NOMEM;
- goto bad;
- }
- DPRINTFN(5,("usbd_set_config_index: dev=%p cdesc=%p\n", dev, cdp));
- dev->cdesc = cdp;
- dev->config = cdp->bConfigurationValue;
- for (ifcidx = 0; ifcidx < nifc; ifcidx++) {
- err = usbd_fill_iface_data(dev, ifcidx, 0);
- if (err) {
- while (--ifcidx >= 0)
- usbd_free_iface_data(dev, ifcidx);
- goto bad;
- }
- }
-
- return (USBD_NORMAL_COMPLETION);
-
- bad:
- free(cdp, M_USB);
- return (err);
-}
-
-/* XXX add function for alternate settings */
-
-usbd_status
-usbd_setup_pipe(usbd_device_handle dev, usbd_interface_handle iface,
- struct usbd_endpoint *ep, int ival, usbd_pipe_handle *pipe)
-{
- usbd_pipe_handle p;
- usbd_status err;
-
- DPRINTFN(1,("usbd_setup_pipe: dev=%p iface=%p ep=%p pipe=%p\n",
- dev, iface, ep, pipe));
- p = malloc(dev->bus->pipe_size, M_USB, M_NOWAIT);
- if (p == NULL)
- return (USBD_NOMEM);
- p->device = dev;
- p->iface = iface;
- p->endpoint = ep;
- ep->refcnt++;
- p->refcnt = 1;
- p->intrxfer = 0;
- p->running = 0;
- p->aborting = 0;
- p->repeat = 0;
- p->interval = ival;
- STAILQ_INIT(&p->queue);
- err = dev->bus->methods->open_pipe(p);
- if (err) {
- DPRINTFN(-1,("usbd_setup_pipe: endpoint=0x%x failed, error="
- "%s\n",
- ep->edesc->bEndpointAddress, usbd_errstr(err)));
- free(p, M_USB);
- return (err);
- }
-
- if (dev->quirks->uq_flags & UQ_OPEN_CLEARSTALL) {
- /* Clear any stall and make sure DATA0 toggle will be used next. */
- if (UE_GET_ADDR(ep->edesc->bEndpointAddress) != USB_CONTROL_ENDPOINT) {
- err = usbd_clear_endpoint_stall(p);
- if (err && err != USBD_STALLED && err != USBD_TIMEOUT) {
- printf("usbd_setup_pipe: failed to start "
- "endpoint, %s\n", usbd_errstr(err));
- return (err);
- }
- }
- }
-
- *pipe = p;
- return (USBD_NORMAL_COMPLETION);
-}
-
-/* Abort the device control pipe. */
-void
-usbd_kill_pipe(usbd_pipe_handle pipe)
-{
- usbd_abort_pipe(pipe);
- pipe->methods->close(pipe);
- pipe->endpoint->refcnt--;
- free(pipe, M_USB);
-}
-
-int
-usbd_getnewaddr(usbd_bus_handle bus)
-{
- int addr;
-
- for (addr = 1; addr < USB_MAX_DEVICES; addr++)
- if (bus->devices[addr] == 0)
- return (addr);
- return (-1);
-}
-
-
-usbd_status
-usbd_probe_and_attach(device_t parent, usbd_device_handle dev,
- int port, int addr)
-{
- struct usb_attach_arg uaa;
- usb_device_descriptor_t *dd = &dev->ddesc;
- int found, i, confi, nifaces;
- usbd_status err;
- device_t *tmpdv;
- usbd_interface_handle ifaces[256]; /* 256 is the absolute max */
- char *devinfo;
-
- /* XXX FreeBSD may leak resources on failure cases -- fixme */
- device_t bdev;
- struct usb_attach_arg *uaap;
-
- devinfo = malloc(1024, M_USB, M_NOWAIT);
- if (devinfo == NULL) {
- device_printf(parent, "Can't allocate memory for probe string\n");
- return (USBD_NOMEM);
- }
- bdev = device_add_child(parent, NULL, -1);
- if (!bdev) {
- free(devinfo, M_USB);
- device_printf(parent, "Device creation failed\n");
- return (USBD_INVAL);
- }
- uaap = malloc(sizeof(uaa), M_USB, M_NOWAIT);
- if (uaap == NULL) {
- free(devinfo, M_USB);
- return (USBD_INVAL);
- }
- device_set_ivars(bdev, uaap);
- uaa.device = dev;
- uaa.iface = NULL;
- uaa.ifaces = NULL;
- uaa.nifaces = 0;
- uaa.usegeneric = 0;
- uaa.port = port;
- uaa.configno = UHUB_UNK_CONFIGURATION;
- uaa.ifaceno = UHUB_UNK_INTERFACE;
- uaa.vendor = UGETW(dd->idVendor);
- uaa.product = UGETW(dd->idProduct);
- uaa.release = UGETW(dd->bcdDevice);
- uaa.matchlvl = 0;
-
- /* First try with device specific drivers. */
- DPRINTF(("usbd_probe_and_attach: trying device specific drivers\n"));
-
- dev->ifacenums = NULL;
- dev->subdevs = malloc(2 * sizeof(device_t), M_USB, M_NOWAIT);
- if (dev->subdevs == NULL) {
- free(devinfo, M_USB);
- return (USBD_NOMEM);
- }
- dev->subdevs[0] = bdev;
- dev->subdevs[1] = 0;
- *uaap = uaa;
- usbd_devinfo(dev, 1, devinfo);
- device_set_desc_copy(bdev, devinfo);
- if (device_probe_and_attach(bdev) == 0) {
- free(devinfo, M_USB);
- return (USBD_NORMAL_COMPLETION);
- }
-
- /*
- * Free subdevs so we can reallocate it larger for the number of
- * interfaces
- */
- tmpdv = dev->subdevs;
- dev->subdevs = NULL;
- free(tmpdv, M_USB);
- DPRINTF(("usbd_probe_and_attach: no device specific driver found\n"));
-
- DPRINTF(("usbd_probe_and_attach: looping over %d configurations\n",
- dd->bNumConfigurations));
- /* Next try with interface drivers. */
- for (confi = 0; confi < dd->bNumConfigurations; confi++) {
- DPRINTFN(1,("usbd_probe_and_attach: trying config idx=%d\n",
- confi));
- err = usbd_set_config_index(dev, confi, 1);
- if (err) {
-#ifdef USB_DEBUG
- DPRINTF(("%s: port %d, set config at addr %d failed, "
- "error=%s\n", device_get_nameunit(parent), port,
- addr, usbd_errstr(err)));
-#else
- printf("%s: port %d, set config at addr %d failed\n",
- device_get_nameunit(parent), port, addr);
-#endif
- free(devinfo, M_USB);
- return (err);
- }
- nifaces = dev->cdesc->bNumInterface;
- uaa.configno = dev->cdesc->bConfigurationValue;
- for (i = 0; i < nifaces; i++)
- ifaces[i] = &dev->ifaces[i];
- uaa.ifaces = ifaces;
- uaa.nifaces = nifaces;
- dev->subdevs = malloc((nifaces+1) * sizeof(device_t), M_USB,M_NOWAIT);
- if (dev->subdevs == NULL) {
- free(devinfo, M_USB);
- return (USBD_NOMEM);
- }
- dev->ifacenums = malloc((nifaces) * sizeof(*dev->ifacenums),
- M_USB,M_NOWAIT);
- if (dev->ifacenums == NULL) {
- free(devinfo, M_USB);
- return (USBD_NOMEM);
- }
-
- found = 0;
- for (i = 0; i < nifaces; i++) {
- if (ifaces[i] == NULL)
- continue; /* interface already claimed */
- uaa.iface = ifaces[i];
- uaa.ifaceno = ifaces[i]->idesc->bInterfaceNumber;
- dev->subdevs[found] = bdev;
- dev->subdevs[found + 1] = 0;
- dev->ifacenums[found] = i;
- *uaap = uaa;
- usbd_devinfo(dev, 1, devinfo);
- device_set_desc_copy(bdev, devinfo);
- if (device_probe_and_attach(bdev) == 0) {
- ifaces[i] = NULL; /* consumed */
- found++;
- /* create another child for the next iface */
- bdev = device_add_child(parent, NULL, -1);
- if (!bdev) {
- device_printf(parent,
- "Device add failed\n");
- free(devinfo, M_USB);
- return (USBD_NORMAL_COMPLETION);
- }
- uaap = malloc(sizeof(uaa), M_USB, M_NOWAIT);
- if (uaap == NULL) {
- free(devinfo, M_USB);
- return (USBD_NOMEM);
- }
- device_set_ivars(bdev, uaap);
- } else {
- dev->subdevs[found] = 0;
- }
- }
- if (found != 0) {
- /* remove the last created child. It is unused */
- free(uaap, M_USB);
- free(devinfo, M_USB);
- device_delete_child(parent, bdev);
- /* free(uaap, M_USB); */ /* May be needed? xxx */
- return (USBD_NORMAL_COMPLETION);
- }
- tmpdv = dev->subdevs;
- dev->subdevs = NULL;
- free(tmpdv, M_USB);
- free(dev->ifacenums, M_USB);
- dev->ifacenums = NULL;
- }
- /* No interfaces were attached in any of the configurations. */
-
- if (dd->bNumConfigurations > 1) /* don't change if only 1 config */
- usbd_set_config_index(dev, 0, 0);
-
- DPRINTF(("usbd_probe_and_attach: no interface drivers found\n"));
-
- /* Finally try the generic driver. */
- uaa.iface = NULL;
- uaa.usegeneric = 1;
- uaa.configno = UHUB_UNK_CONFIGURATION;
- uaa.ifaceno = UHUB_UNK_INTERFACE;
- dev->subdevs = malloc(2 * sizeof(device_t), M_USB, M_NOWAIT);
- if (dev->subdevs == 0) {
- free(devinfo, M_USB);
- return (USBD_NOMEM);
- }
- dev->subdevs[0] = bdev;
- dev->subdevs[1] = 0;
- *uaap = uaa;
- usbd_devinfo(dev, 1, devinfo);
- device_set_desc_copy(bdev, devinfo);
- free(devinfo, M_USB);
- if (device_probe_and_attach(bdev) == 0)
- return (USBD_NORMAL_COMPLETION);
-
- /*
- * The generic attach failed, but leave the device as it is.
- * We just did not find any drivers, that's all. The device is
- * fully operational and not harming anyone.
- */
- DPRINTF(("usbd_probe_and_attach: generic attach failed\n"));
- return (USBD_NORMAL_COMPLETION);
-}
-
-
-/*
- * Called when a new device has been put in the powered state,
- * but not yet in the addressed state.
- * Get initial descriptor, set the address, get full descriptor,
- * and attach a driver.
- */
-usbd_status
-usbd_new_device(device_t parent, usbd_bus_handle bus, int depth,
- int speed, int port, struct usbd_port *up)
-{
- usbd_device_handle dev, adev;
- struct usbd_device *hub;
- usb_device_descriptor_t *dd;
- usb_port_status_t ps;
- usbd_status err;
- int addr;
- int i;
- int p;
-
- DPRINTF(("usbd_new_device bus=%p port=%d depth=%d speed=%d\n",
- bus, port, depth, speed));
- addr = usbd_getnewaddr(bus);
- if (addr < 0) {
- device_printf(bus->bdev, "No free USB addresses\n");
- return (USBD_NO_ADDR);
- }
-
- dev = malloc(sizeof *dev, M_USB, M_NOWAIT|M_ZERO);
- if (dev == NULL)
- return (USBD_NOMEM);
-
- dev->bus = bus;
-
- /* Set up default endpoint handle. */
- dev->def_ep.edesc = &dev->def_ep_desc;
-
- /* Set up default endpoint descriptor. */
- dev->def_ep_desc.bLength = USB_ENDPOINT_DESCRIPTOR_SIZE;
- dev->def_ep_desc.bDescriptorType = UDESC_ENDPOINT;
- dev->def_ep_desc.bEndpointAddress = USB_CONTROL_ENDPOINT;
- dev->def_ep_desc.bmAttributes = UE_CONTROL;
- USETW(dev->def_ep_desc.wMaxPacketSize, USB_MAX_IPACKET);
- dev->def_ep_desc.bInterval = 0;
-
- dev->quirks = &usbd_no_quirk;
- dev->address = USB_START_ADDR;
- dev->ddesc.bMaxPacketSize = 0;
- dev->depth = depth;
- dev->powersrc = up;
- dev->myhub = up->parent;
-
- up->device = dev;
-
- if (up->parent && speed > up->parent->speed) {
-#ifdef USB_DEBUG
- printf("%s: maxium speed of attached "
- "device, %d, is higher than speed "
- "of parent HUB, %d.\n",
- __FUNCTION__, speed, up->parent->speed);
-#endif
- /*
- * Reduce the speed, otherwise we won't setup the
- * proper transfer methods.
- */
- speed = up->parent->speed;
- }
-
- /* Locate port on upstream high speed hub */
- for (adev = dev, hub = up->parent;
- hub != NULL && hub->speed != USB_SPEED_HIGH;
- adev = hub, hub = hub->myhub)
- ;
- if (hub) {
- for (p = 0; p < hub->hub->hubdesc.bNbrPorts; p++) {
- if (hub->hub->ports[p].device == adev) {
- dev->myhsport = &hub->hub->ports[p];
- goto found;
- }
- }
- panic("usbd_new_device: cannot find HS port\n");
- found:
- DPRINTFN(1,("usbd_new_device: high speed port %d\n", p));
- } else {
- dev->myhsport = NULL;
- }
- dev->speed = speed;
- dev->langid = USBD_NOLANG;
- dev->cookie.cookie = ++usb_cookie_no;
-
- /* Establish the default pipe. */
- err = usbd_setup_pipe(dev, 0, &dev->def_ep, USBD_DEFAULT_INTERVAL,
- &dev->default_pipe);
- if (err) {
- usbd_remove_device(dev, up);
- return (err);
- }
-
- dd = &dev->ddesc;
- /* Try a few times in case the device is slow (i.e. outside specs.) */
- DPRINTFN(5,("usbd_new_device: setting device address=%d\n", addr));
- for (i = 0; i < 15; i++) {
- /* Get the first 8 bytes of the device descriptor. */
- err = usbd_get_desc(dev, UDESC_DEVICE, 0, USB_MAX_IPACKET, dd);
- if (!err)
- break;
- usbd_delay_ms(dev, 200);
- if ((i & 3) == 3) {
- DPRINTFN(-1,("usb_new_device: set address %d "
- "failed - trying a port reset\n", addr));
- usbd_reset_port(up->parent, port, &ps);
- }
-
- }
- if (err) {
- DPRINTFN(-1, ("usbd_new_device: addr=%d, getting first desc "
- "failed\n", addr));
- usbd_remove_device(dev, up);
- return (err);
- }
-
- if (speed == USB_SPEED_HIGH) {
- /* Max packet size must be 64 (sec 5.5.3). */
- if (dd->bMaxPacketSize != USB_2_MAX_CTRL_PACKET) {
-#ifdef DIAGNOSTIC
- printf("usbd_new_device: addr=%d bad max packet size\n",
- addr);
-#endif
- dd->bMaxPacketSize = USB_2_MAX_CTRL_PACKET;
- }
- }
-
- DPRINTF(("usbd_new_device: adding unit addr=%d, rev=%02x, class=%d, "
- "subclass=%d, protocol=%d, maxpacket=%d, len=%d, speed=%d\n",
- addr,UGETW(dd->bcdUSB), dd->bDeviceClass, dd->bDeviceSubClass,
- dd->bDeviceProtocol, dd->bMaxPacketSize, dd->bLength,
- dev->speed));
-
- if (dd->bDescriptorType != UDESC_DEVICE) {
- /* Illegal device descriptor */
- DPRINTFN(-1,("usbd_new_device: illegal descriptor %d\n",
- dd->bDescriptorType));
- usbd_remove_device(dev, up);
- return (USBD_INVAL);
- }
-
- if (dd->bLength < USB_DEVICE_DESCRIPTOR_SIZE) {
- DPRINTFN(-1,("usbd_new_device: bad length %d\n", dd->bLength));
- usbd_remove_device(dev, up);
- return (USBD_INVAL);
- }
-
- USETW(dev->def_ep_desc.wMaxPacketSize, dd->bMaxPacketSize);
-
- /* Re-establish the default pipe with the new max packet size. */
- usbd_kill_pipe(dev->default_pipe);
- err = usbd_setup_pipe(dev, 0, &dev->def_ep, USBD_DEFAULT_INTERVAL,
- &dev->default_pipe);
- if (err) {
- usbd_remove_device(dev, up);
- return (err);
- }
-
- err = usbd_reload_device_desc(dev);
- if (err) {
- DPRINTFN(-1, ("usbd_new_device: addr=%d, getting full desc "
- "failed\n", addr));
- usbd_remove_device(dev, up);
- return (err);
- }
-
- /* Set the address */
- DPRINTFN(5,("usbd_new_device: setting device address=%d\n", addr));
- err = usbd_set_address(dev, addr);
- if (err) {
- DPRINTFN(-1,("usb_new_device: set address %d failed\n", addr));
- err = USBD_SET_ADDR_FAILED;
- usbd_remove_device(dev, up);
- return (err);
- }
-
- /* Allow device time to set new address */
- usbd_delay_ms(dev, USB_SET_ADDRESS_SETTLE);
- dev->address = addr; /* New device address now */
- bus->devices[addr] = dev;
-
- /* Re-establish the default pipe with the new address. */
- usbd_kill_pipe(dev->default_pipe);
- err = usbd_setup_pipe(dev, 0, &dev->def_ep, USBD_DEFAULT_INTERVAL,
- &dev->default_pipe);
- if (err) {
- usbd_remove_device(dev, up);
- return (err);
- }
-
- /* Assume 100mA bus powered for now. Changed when configured. */
- dev->power = USB_MIN_POWER;
- dev->self_powered = 0;
-
- DPRINTF(("usbd_new_device: new dev (addr %d), dev=%p, parent=%p\n",
- addr, dev, parent));
-
- err = usbd_probe_and_attach(parent, dev, port, addr);
- if (err) {
- usbd_remove_device(dev, up);
- return (err);
- }
-
- usbd_add_dev_event(USB_EVENT_DEVICE_ATTACH, dev);
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-usbd_status
-usbd_reload_device_desc(usbd_device_handle dev)
-{
- usbd_status err;
- int i;
-
- /* Get the full device descriptor. */
- for (i = 0; i < 3; ++i) {
- err = usbd_get_device_desc(dev, &dev->ddesc);
- if (!err)
- break;
- usbd_delay_ms(dev, 200);
- }
- if (err)
- return (err);
-
- /* Figure out what's wrong with this device. */
- dev->quirks = usbd_find_quirk(&dev->ddesc);
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-void
-usbd_remove_device(usbd_device_handle dev, struct usbd_port *up)
-{
- DPRINTF(("usbd_remove_device: %p\n", dev));
-
- if (dev->default_pipe != NULL)
- usbd_kill_pipe(dev->default_pipe);
- up->device = NULL;
- dev->bus->devices[dev->address] = NULL;
-
- free(dev, M_USB);
-}
-
-void
-usbd_fill_deviceinfo(usbd_device_handle dev, struct usb_device_info *di,
- int usedev)
-{
- struct usbd_port *p;
- int i, err, s;
-
- di->udi_bus = device_get_unit(dev->bus->bdev);
- di->udi_addr = dev->address;
- di->udi_cookie = dev->cookie;
- usbd_devinfo_vp(dev, di->udi_vendor, di->udi_product, usedev);
- usbd_printBCD(di->udi_release, UGETW(dev->ddesc.bcdDevice));
- di->udi_vendorNo = UGETW(dev->ddesc.idVendor);
- di->udi_productNo = UGETW(dev->ddesc.idProduct);
- di->udi_releaseNo = UGETW(dev->ddesc.bcdDevice);
- di->udi_class = dev->ddesc.bDeviceClass;
- di->udi_subclass = dev->ddesc.bDeviceSubClass;
- di->udi_protocol = dev->ddesc.bDeviceProtocol;
- di->udi_config = dev->config;
- di->udi_power = dev->self_powered ? 0 : dev->power;
- di->udi_speed = dev->speed;
-
- if (dev->subdevs != NULL) {
- for (i = 0; dev->subdevs[i] && i < USB_MAX_DEVNAMES; i++) {
- if (device_is_attached(dev->subdevs[i]))
- strlcpy(di->udi_devnames[i],
- device_get_nameunit(dev->subdevs[i]),
- USB_MAX_DEVNAMELEN);
- else
- di->udi_devnames[i][0] = 0;
- }
- } else {
- i = 0;
- }
- for (/*i is set */; i < USB_MAX_DEVNAMES; i++)
- di->udi_devnames[i][0] = 0; /* empty */
-
- if (dev->hub) {
- for (i = 0;
- i < sizeof(di->udi_ports) / sizeof(di->udi_ports[0]) &&
- i < dev->hub->hubdesc.bNbrPorts;
- i++) {
- p = &dev->hub->ports[i];
- if (p->device)
- err = p->device->address;
- else {
- s = UGETW(p->status.wPortStatus);
- if (s & UPS_PORT_ENABLED)
- err = USB_PORT_ENABLED;
- else if (s & UPS_SUSPEND)
- err = USB_PORT_SUSPENDED;
- else if (s & UPS_PORT_POWER)
- err = USB_PORT_POWERED;
- else
- err = USB_PORT_DISABLED;
- }
- di->udi_ports[i] = err;
- }
- di->udi_nports = dev->hub->hubdesc.bNbrPorts;
- } else
- di->udi_nports = 0;
-}
-
-void
-usb_free_device(usbd_device_handle dev)
-{
- int ifcidx, nifc;
-
- if (dev->default_pipe != NULL)
- usbd_kill_pipe(dev->default_pipe);
- if (dev->ifaces != NULL) {
- nifc = dev->cdesc->bNumInterface;
- for (ifcidx = 0; ifcidx < nifc; ifcidx++)
- usbd_free_iface_data(dev, ifcidx);
- free(dev->ifaces, M_USB);
- }
- if (dev->cdesc != NULL)
- free(dev->cdesc, M_USB);
- if (dev->subdevs != NULL)
- free(dev->subdevs, M_USB);
- if (dev->ifacenums != NULL)
- free(dev->ifacenums, M_USB);
- free(dev, M_USB);
-}
-
-/*
- * The general mechanism for detaching drivers works as follows: Each
- * driver is responsible for maintaining a reference count on the
- * number of outstanding references to its softc (e.g. from
- * processing hanging in a read or write). The detach method of the
- * driver decrements this counter and flags in the softc that the
- * driver is dying and then wakes any sleepers. It then sleeps on the
- * softc. Each place that can sleep must maintain the reference
- * count. When the reference count drops to -1 (0 is the normal value
- * of the reference count) the a wakeup on the softc is performed
- * signaling to the detach waiter that all references are gone.
- */
-
-/*
- * Called from process context when we discover that a port has
- * been disconnected.
- */
-void
-usb_disconnect_port(struct usbd_port *up, device_t parent)
-{
- usbd_device_handle dev = up->device;
- const char *hubname = device_get_nameunit(parent);
- int i;
-
- DPRINTFN(3,("uhub_disconnect: up=%p dev=%p port=%d\n",
- up, dev, up->portno));
-
-#ifdef DIAGNOSTIC
- if (dev == NULL) {
- printf("usb_disconnect_port: no device\n");
- return;
- }
-#endif
-
- if (dev->subdevs != NULL) {
- DPRINTFN(3,("usb_disconnect_port: disconnect subdevs\n"));
- for (i = 0; dev->subdevs[i]; i++) {
- if (!device_is_quiet(dev->subdevs[i])) {
- device_printf(dev->subdevs[i],
- "at %s", hubname);
- if (up->portno != 0)
- printf(" port %d", up->portno);
- printf(" (addr %d) disconnected\n", dev->address);
- }
-
- struct usb_attach_arg *uaap =
- device_get_ivars(dev->subdevs[i]);
- device_detach(dev->subdevs[i]);
- free(uaap, M_USB);
- device_delete_child(device_get_parent(dev->subdevs[i]),
- dev->subdevs[i]);
- dev->subdevs[i] = NULL;
- }
- }
-
- usbd_add_dev_event(USB_EVENT_DEVICE_DETACH, dev);
- dev->bus->devices[dev->address] = NULL;
- up->device = NULL;
- usb_free_device(dev);
-}
diff --git a/sys/dev/usb/usbcdc.h b/sys/dev/usb/usbcdc.h
deleted file mode 100644
index d684108..0000000
--- a/sys/dev/usb/usbcdc.h
+++ /dev/null
@@ -1,188 +0,0 @@
-/* $NetBSD: usbcdc.h,v 1.9 2004/10/23 13:24:24 augustss Exp $ */
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) 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.
- */
-
-#ifndef _USBCDC_H_
-#define _USBCDC_H_
-
-#define UDESCSUB_CDC_HEADER 0
-#define UDESCSUB_CDC_CM 1 /* Call Management */
-#define UDESCSUB_CDC_ACM 2 /* Abstract Control Model */
-#define UDESCSUB_CDC_DLM 3 /* Direct Line Management */
-#define UDESCSUB_CDC_TRF 4 /* Telephone Ringer */
-#define UDESCSUB_CDC_TCLSR 5 /* Telephone Call ... */
-#define UDESCSUB_CDC_UNION 6
-#define UDESCSUB_CDC_CS 7 /* Country Selection */
-#define UDESCSUB_CDC_TOM 8 /* Telephone Operational Modes */
-#define UDESCSUB_CDC_USBT 9 /* USB Terminal */
-#define UDESCSUB_CDC_NCT 10
-#define UDESCSUB_CDC_PUF 11
-#define UDESCSUB_CDC_EUF 12
-#define UDESCSUB_CDC_MCMF 13
-#define UDESCSUB_CDC_CCMF 14
-#define UDESCSUB_CDC_ENF 15
-#define UDESCSUB_CDC_ANF 16
-
-typedef struct {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDescriptorSubtype;
- uWord bcdCDC;
-} UPACKED usb_cdc_header_descriptor_t;
-
-typedef struct {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDescriptorSubtype;
- uByte bmCapabilities;
-#define USB_CDC_CM_DOES_CM 0x01
-#define USB_CDC_CM_OVER_DATA 0x02
- uByte bDataInterface;
-} UPACKED usb_cdc_cm_descriptor_t;
-
-typedef struct {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDescriptorSubtype;
- uByte bmCapabilities;
-#define USB_CDC_ACM_HAS_FEATURE 0x01
-#define USB_CDC_ACM_HAS_LINE 0x02
-#define USB_CDC_ACM_HAS_BREAK 0x04
-#define USB_CDC_ACM_HAS_NETWORK_CONN 0x08
-} UPACKED usb_cdc_acm_descriptor_t;
-
-typedef struct {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDescriptorSubtype;
- uByte bMasterInterface;
- uByte bSlaveInterface[1];
-} UPACKED usb_cdc_union_descriptor_t;
-
-typedef struct {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDescriptorSubtype;
- uByte iMacAddress;
- uDWord bmEthernetStatistics;
- uWord wMaxSegmentSize;
- uWord wNumberMCFikters;
- uByte bNumberPowerFilters;
-} UPACKED usb_cdc_ethernet_descriptor_t;
-
-#define UCDC_SEND_ENCAPSULATED_COMMAND 0x00
-#define UCDC_GET_ENCAPSULATED_RESPONSE 0x01
-#define UCDC_SET_COMM_FEATURE 0x02
-#define UCDC_GET_COMM_FEATURE 0x03
-#define UCDC_ABSTRACT_STATE 0x01
-#define UCDC_COUNTRY_SETTING 0x02
-#define UCDC_CLEAR_COMM_FEATURE 0x04
-#define UCDC_SET_LINE_CODING 0x20
-#define UCDC_GET_LINE_CODING 0x21
-#define UCDC_SET_CONTROL_LINE_STATE 0x22
-#define UCDC_LINE_DTR 0x0001
-#define UCDC_LINE_RTS 0x0002
-#define UCDC_SEND_BREAK 0x23
-#define UCDC_BREAK_ON 0xffff
-#define UCDC_BREAK_OFF 0x0000
-
-typedef struct {
- uWord wState;
-#define UCDC_IDLE_SETTING 0x0001
-#define UCDC_DATA_MULTIPLEXED 0x0002
-} UPACKED usb_cdc_abstract_state_t;
-#define UCDC_ABSTRACT_STATE_LENGTH 2
-
-typedef struct {
- uDWord dwDTERate;
- uByte bCharFormat;
-#define UCDC_STOP_BIT_1 0
-#define UCDC_STOP_BIT_1_5 1
-#define UCDC_STOP_BIT_2 2
- uByte bParityType;
-#define UCDC_PARITY_NONE 0
-#define UCDC_PARITY_ODD 1
-#define UCDC_PARITY_EVEN 2
-#define UCDC_PARITY_MARK 3
-#define UCDC_PARITY_SPACE 4
- uByte bDataBits;
-} UPACKED usb_cdc_line_state_t;
-#define UCDC_LINE_STATE_LENGTH 7
-
-typedef struct {
- uByte bmRequestType;
-#define UCDC_NOTIFICATION 0xa1
- uByte bNotification;
-#define UCDC_N_NETWORK_CONNECTION 0x00
-#define UCDC_N_RESPONSE_AVAILABLE 0x01
-#define UCDC_N_AUX_JACK_HOOK_STATE 0x08
-#define UCDC_N_RING_DETECT 0x09
-#define UCDC_N_SERIAL_STATE 0x20
-#define UCDC_N_CALL_STATE_CHANGED 0x28
-#define UCDC_N_LINE_STATE_CHANGED 0x29
-#define UCDC_N_CONNECTION_SPEED_CHANGE 0x2a
- uWord wValue;
- uWord wIndex;
- uWord wLength;
- uByte data[16];
-} UPACKED usb_cdc_notification_t;
-#define UCDC_NOTIFICATION_LENGTH 8
-
-/*
- * Bits set in the SERIAL STATE notifcation (first byte of data)
- */
-
-#define UCDC_N_SERIAL_OVERRUN 0x40
-#define UCDC_N_SERIAL_PARITY 0x20
-#define UCDC_N_SERIAL_FRAMING 0x10
-#define UCDC_N_SERIAL_RI 0x08
-#define UCDC_N_SERIAL_BREAK 0x04
-#define UCDC_N_SERIAL_DSR 0x02
-#define UCDC_N_SERIAL_DCD 0x01
-
-/* Serial state bit masks */
-#define UCDC_MDM_RXCARRIER 0x01
-#define UCDC_MDM_TXCARRIER 0x02
-#define UCDC_MDM_BREAK 0x04
-#define UCDC_MDM_RING 0x08
-#define UCDC_MDM_FRAMING_ERR 0x10
-#define UCDC_MDM_PARITY_ERR 0x20
-#define UCDC_MDM_OVERRUN_ERR 0x40
-
-#endif /* _USBCDC_H_ */
diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
deleted file mode 100644
index 0a3d85e..0000000
--- a/sys/dev/usb/usbdevs
+++ /dev/null
@@ -1,2527 +0,0 @@
-$FreeBSD$
-/* $NetBSD: usbdevs,v 1.392 2004/12/29 08:38:44 imp Exp $ */
-
-/*-
- * Copyright (c) 1998-2004 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) 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.
- */
-
-/*
- * List of known USB vendors
- *
- * USB.org publishes a VID list of USB-IF member companies at
- * http://www.usb.org/developers/tools
- * Note that it does not show companies that have obtained a Vendor ID
- * without becoming full members.
- *
- * Please note that these IDs do not do anything. Adding an ID here and
- * regenerating the usbdevs.h and usbdevs_data.h only makes a symbolic name
- * available to the source code and does not change any functionality, nor
- * does it make your device available to a specific driver.
- * It will however make the descriptive string available if a device does not
- * provide the string itself.
- *
- * After adding a vendor ID VNDR and a product ID PRDCT you will have the
- * following extra defines:
- * #define USB_VENDOR_VNDR 0x????
- * #define USB_PRODUCT_VNDR_PRDCT 0x????
- *
- * You may have to add these defines to the respective probe routines to
- * make the device recognised by the appropriate device driver.
- */
-
-vendor UNKNOWN1 0x0053 Unknown vendor
-vendor UNKNOWN2 0x0105 Unknown vendor
-vendor EGALAX2 0x0123 eGalax, Inc.
-vendor HUMAX 0x02ad HUMAX
-vendor LTS 0x0386 LTS
-vendor BWCT 0x03da Bernd Walter Computer Technology
-vendor AOX 0x03e8 AOX
-vendor THESYS 0x03e9 Thesys
-vendor DATABROADCAST 0x03ea Data Broadcasting
-vendor ATMEL 0x03eb Atmel
-vendor IWATSU 0x03ec Iwatsu America
-vendor MITSUMI 0x03ee Mitsumi
-vendor HP 0x03f0 Hewlett Packard
-vendor GENOA 0x03f1 Genoa
-vendor OAK 0x03f2 Oak
-vendor ADAPTEC 0x03f3 Adaptec
-vendor DIEBOLD 0x03f4 Diebold
-vendor SIEMENSELECTRO 0x03f5 Siemens Electromechanical
-vendor EPSONIMAGING 0x03f8 Epson Imaging
-vendor KEYTRONIC 0x03f9 KeyTronic
-vendor OPTI 0x03fb OPTi
-vendor ELITEGROUP 0x03fc Elitegroup
-vendor XILINX 0x03fd Xilinx
-vendor FARALLON 0x03fe Farallon Communications
-vendor NATIONAL 0x0400 National Semiconductor
-vendor NATIONALREG 0x0401 National Registry
-vendor ACERLABS 0x0402 Acer Labs
-vendor FTDI 0x0403 Future Technology Devices
-vendor NCR 0x0404 NCR
-vendor SYNOPSYS2 0x0405 Synopsys
-vendor FUJITSUICL 0x0406 Fujitsu-ICL
-vendor FUJITSU2 0x0407 Fujitsu Personal Systems
-vendor QUANTA 0x0408 Quanta
-vendor NEC 0x0409 NEC
-vendor KODAK 0x040a Eastman Kodak
-vendor WELTREND 0x040b Weltrend
-vendor VIA 0x040d VIA
-vendor MCCI 0x040e MCCI
-vendor MELCO 0x0411 Melco
-vendor LEADTEK 0x0413 Leadtek
-vendor WINBOND 0x0416 Winbond
-vendor PHOENIX 0x041a Phoenix
-vendor CREATIVE 0x041e Creative Labs
-vendor NOKIA 0x0421 Nokia
-vendor ADI 0x0422 ADI Systems
-vendor CATC 0x0423 Computer Access Technology
-vendor SMC2 0x0424 Standard Microsystems
-vendor MOTOROLA_HK 0x0425 Motorola HK
-vendor GRAVIS 0x0428 Advanced Gravis Computer
-vendor CIRRUSLOGIC 0x0429 Cirrus Logic
-vendor INNOVATIVE 0x042c Innovative Semiconductors
-vendor MOLEX 0x042f Molex
-vendor SUN 0x0430 Sun Microsystems
-vendor UNISYS 0x0432 Unisys
-vendor TAUGA 0x0436 Taugagreining HF
-vendor AMD 0x0438 Advanced Micro Devices
-vendor LEXMARK 0x043d Lexmark International
-vendor LG 0x043e LG Electronics
-vendor NANAO 0x0440 NANAO
-vendor GATEWAY 0x0443 Gateway 2000
-vendor NMB 0x0446 NMB
-vendor ALPS 0x044e Alps Electric
-vendor THRUST 0x044f Thrustmaster
-vendor TI 0x0451 Texas Instruments
-vendor ANALOGDEVICES 0x0456 Analog Devices
-vendor SIS 0x0457 Silicon Integrated Systems Corp.
-vendor KYE 0x0458 KYE Systems
-vendor DIAMOND2 0x045a Diamond (Supra)
-vendor RENESAS 0x045b Renesas
-vendor MICROSOFT 0x045e Microsoft
-vendor PRIMAX 0x0461 Primax Electronics
-vendor MGE 0x0463 MGE UPS Systems
-vendor AMP 0x0464 AMP
-vendor CHERRY 0x046a Cherry Mikroschalter
-vendor MEGATRENDS 0x046b American Megatrends
-vendor LOGITECH 0x046d Logitech
-vendor BTC 0x046e Behavior Tech. Computer
-vendor PHILIPS 0x0471 Philips
-vendor SUN2 0x0472 Sun Microsystems (offical)
-vendor SANYO 0x0474 Sanyo Electric
-vendor SEAGATE 0x0477 Seagate
-vendor CONNECTIX 0x0478 Connectix
-vendor SEMTECH 0x047a Semtech
-vendor KENSINGTON 0x047d Kensington
-vendor LUCENT 0x047e Lucent
-vendor PLANTRONICS 0x047f Plantronics
-vendor KYOCERA 0x0482 Kyocera Wireless Corp.
-vendor STMICRO 0x0483 STMicroelectronics
-vendor FOXCONN 0x0489 Foxconn
-vendor MEIZU 0x0492 Meizu Electronics
-vendor YAMAHA 0x0499 YAMAHA
-vendor COMPAQ 0x049f Compaq
-vendor HITACHI 0x04a4 Hitachi
-vendor ACERP 0x04a5 Acer Peripherals
-vendor DAVICOM 0x04a6 Davicom
-vendor VISIONEER 0x04a7 Visioneer
-vendor CANON 0x04a9 Canon
-vendor NIKON 0x04b0 Nikon
-vendor PAN 0x04b1 Pan International
-vendor IBM 0x04b3 IBM
-vendor CYPRESS 0x04b4 Cypress Semiconductor
-vendor ROHM 0x04b5 ROHM
-vendor COMPAL 0x04b7 Compal
-vendor EPSON 0x04b8 Seiko Epson
-vendor RAINBOW 0x04b9 Rainbow Technologies
-vendor IODATA 0x04bb I-O Data
-vendor TDK 0x04bf TDK
-vendor 3COMUSR 0x04c1 U.S. Robotics
-vendor METHODE 0x04c2 Methode Electronics Far East
-vendor MAXISWITCH 0x04c3 Maxi Switch
-vendor LOCKHEEDMER 0x04c4 Lockheed Martin Energy Research
-vendor FUJITSU 0x04c5 Fujitsu
-vendor TOSHIBAAM 0x04c6 Toshiba America
-vendor MICROMACRO 0x04c7 Micro Macro Technologies
-vendor KONICA 0x04c8 Konica
-vendor LITEON 0x04ca Lite-On Technology
-vendor FUJIPHOTO 0x04cb Fuji Photo Film
-vendor PHILIPSSEMI 0x04cc Philips Semiconductors
-vendor TATUNG 0x04cd Tatung Co. Of America
-vendor SCANLOGIC 0x04ce ScanLogic
-vendor MYSON 0x04cf Myson Technology
-vendor DIGI2 0x04d0 Digi
-vendor ITTCANON 0x04d1 ITT Canon
-vendor ALTEC 0x04d2 Altec Lansing
-vendor LSI 0x04d4 LSI
-vendor MENTORGRAPHICS 0x04d6 Mentor Graphics
-vendor ITUNERNET 0x04d8 I-Tuner Networks
-vendor HOLTEK 0x04d9 Holtek Semiconductor, Inc.
-vendor PANASONIC 0x04da Panasonic (Matsushita)
-vendor HUANHSIN 0x04dc Huan Hsin
-vendor SHARP 0x04dd Sharp
-vendor IIYAMA 0x04e1 Iiyama
-vendor SHUTTLE 0x04e6 Shuttle Technology
-vendor ELO 0x04e7 Elo TouchSystems
-vendor SAMSUNG 0x04e8 Samsung Electronics
-vendor NORTHSTAR 0x04eb Northstar
-vendor TOKYOELECTRON 0x04ec Tokyo Electron
-vendor ANNABOOKS 0x04ed Annabooks
-vendor JVC 0x04f1 JVC
-vendor CHICONY 0x04f2 Chicony Electronics
-vendor ELAN 0x04f3 Elan
-vendor NEWNEX 0x04f7 Newnex
-vendor BROTHER 0x04f9 Brother Industries
-vendor DALLAS 0x04fa Dallas Semiconductor
-vendor AIPTEK2 0x04fc AIPTEK International
-vendor PFU 0x04fe PFU
-vendor FUJIKURA 0x0501 Fujikura/DDK
-vendor ACER 0x0502 Acer
-vendor 3COM 0x0506 3Com
-vendor HOSIDEN 0x0507 Hosiden Corporation
-vendor AZTECH 0x0509 Aztech Systems
-vendor BELKIN 0x050d Belkin Components
-vendor KAWATSU 0x050f Kawatsu Semiconductor
-vendor FCI 0x0514 FCI
-vendor LONGWELL 0x0516 Longwell
-vendor COMPOSITE 0x0518 Composite
-vendor STAR 0x0519 Star Micronics
-vendor APC 0x051d American Power Conversion
-vendor SCIATLANTA 0x051e Scientific Atlanta
-vendor TSM 0x0520 TSM
-vendor CONNECTEK 0x0522 Advanced Connectek USA
-vendor NETCHIP 0x0525 NetChip Technology
-vendor ALTRA 0x0527 ALTRA
-vendor ATI 0x0528 ATI Technologies
-vendor AKS 0x0529 Aladdin Knowledge Systems
-vendor TEKOM 0x052b Tekom
-vendor CANONDEV 0x052c Canon
-vendor WACOMTECH 0x0531 Wacom
-vendor INVENTEC 0x0537 Inventec
-vendor SHYHSHIUN 0x0539 Shyh Shiun Terminals
-vendor PREHWERKE 0x053a Preh Werke Gmbh & Co. KG
-vendor SYNOPSYS 0x053f Synopsys
-vendor UNIACCESS 0x0540 Universal Access
-vendor VIEWSONIC 0x0543 ViewSonic
-vendor XIRLINK 0x0545 Xirlink
-vendor ANCHOR 0x0547 Anchor Chips
-vendor SONY 0x054c Sony
-vendor FUJIXEROX 0x0550 Fuji Xerox
-vendor VISION 0x0553 VLSI Vision
-vendor ASAHIKASEI 0x0556 Asahi Kasei Microsystems
-vendor ATEN 0x0557 ATEN International
-vendor SAMSUNG2 0x055d Samsung Electronics
-vendor MUSTEK 0x055f Mustek Systems
-vendor TELEX 0x0562 Telex Communications
-vendor CHINON 0x0564 Chinon
-vendor PERACOM 0x0565 Peracom Networks
-vendor ALCOR2 0x0566 Alcor Micro
-vendor XYRATEX 0x0567 Xyratex
-vendor WACOM 0x056a WACOM
-vendor ETEK 0x056c e-TEK Labs
-vendor EIZO 0x056d EIZO
-vendor ELECOM 0x056e Elecom
-vendor CONEXANT 0x0572 Conexant
-vendor HAUPPAUGE 0x0573 Hauppauge Computer Works
-vendor BAFO 0x0576 BAFO/Quality Computer Accessories
-vendor YEDATA 0x057b Y-E Data
-vendor AVM 0x057c AVM
-vendor QUICKSHOT 0x057f Quickshot
-vendor ROLAND 0x0582 Roland
-vendor ROCKFIRE 0x0583 Rockfire
-vendor RATOC 0x0584 RATOC Systems
-vendor ZYXEL 0x0586 ZyXEL Communication
-vendor INFINEON 0x058b Infineon
-vendor MICREL 0x058d Micrel
-vendor ALCOR 0x058f Alcor Micro
-vendor OMRON 0x0590 OMRON
-vendor ZORAN 0x0595 Zoran Microelectronics
-vendor NIIGATA 0x0598 Niigata
-vendor IOMEGA 0x059b Iomega
-vendor ATREND 0x059c A-Trend Technology
-vendor AID 0x059d Advanced Input Devices
-vendor LACIE 0x059f LaCie
-vendor FUJIFILM 0x05a2 Fuji Film
-vendor ARC 0x05a3 ARC
-vendor ORTEK 0x05a4 Ortek
-vendor BOSE 0x05a7 Bose
-vendor OMNIVISION 0x05a9 OmniVision
-vendor INSYSTEM 0x05ab In-System Design
-vendor APPLE 0x05ac Apple Computer
-vendor YCCABLE 0x05ad Y.C. Cable
-vendor DIGITALPERSONA 0x05ba DigitalPersona
-vendor 3G 0x05bc 3G Green Green Globe
-vendor RAFI 0x05bd RAFI
-vendor TYCO 0x05be Tyco
-vendor KAWASAKI 0x05c1 Kawasaki
-vendor DIGI 0x05c5 Digi International
-vendor QUALCOMM2 0x05c6 Qualcomm
-vendor QTRONIX 0x05c7 Qtronix
-vendor FOXLINK 0x05c8 Foxlink
-vendor RICOH 0x05ca Ricoh
-vendor ELSA 0x05cc ELSA
-vendor SCIWORX 0x05ce sci-worx
-vendor BRAINBOXES 0x05d1 Brainboxes Limited
-vendor ULTIMA 0x05d8 Ultima
-vendor AXIOHM 0x05d9 Axiohm Transaction Solutions
-vendor MICROTEK 0x05da Microtek
-vendor SUNTAC 0x05db SUN Corporation
-vendor LEXAR 0x05dc Lexar Media
-vendor ADDTRON 0x05dd Addtron
-vendor SYMBOL 0x05e0 Symbol Technologies
-vendor SYNTEK 0x05e1 Syntek
-vendor GENESYS 0x05e3 Genesys Logic
-vendor FUJI 0x05e5 Fuji Electric
-vendor KEITHLEY 0x05e6 Keithley Instruments
-vendor EIZONANAO 0x05e7 EIZO Nanao
-vendor KLSI 0x05e9 Kawasaki LSI
-vendor FFC 0x05eb FFC
-vendor ANKO 0x05ef Anko Electronic
-vendor PIENGINEERING 0x05f3 P.I. Engineering
-vendor AOC 0x05f6 AOC International
-vendor CHIC 0x05fe Chic Technology
-vendor BARCO 0x0600 Barco Display Systems
-vendor BRIDGE 0x0607 Bridge Information
-vendor SOLIDYEAR 0x060b Solid Year
-vendor BIORAD 0x0614 Bio-Rad Laboratories
-vendor MACALLY 0x0618 Macally
-vendor ACTLABS 0x061c Act Labs
-vendor ALARIS 0x0620 Alaris
-vendor APEX 0x0624 Apex
-vendor CREATIVE3 0x062a Creative Labs
-vendor VIVITAR 0x0636 Vivitar
-vendor GUNZE 0x0637 Gunze Electronics USA
-vendor AVISION 0x0638 Avision
-vendor TEAC 0x0644 TEAC
-vendor SGI 0x065e Silicon Graphics
-vendor SANWASUPPLY 0x0663 Sanwa Supply
-vendor LINKSYS 0x066b Linksys
-vendor ACERSA 0x066e Acer Semiconductor America
-vendor SIGMATEL 0x066f Sigmatel
-vendor DRAYTEK 0x0675 DrayTek
-vendor AIWA 0x0677 Aiwa
-vendor ACARD 0x0678 ACARD Technology
-vendor PROLIFIC 0x067b Prolific Technology
-vendor SIEMENS 0x067c Siemens
-vendor AVANCELOGIC 0x0680 Avance Logic
-vendor SIEMENS2 0x0681 Siemens
-vendor MINOLTA 0x0686 Minolta
-vendor CHPRODUCTS 0x068e CH Products
-vendor HAGIWARA 0x0693 Hagiwara Sys-Com
-vendor CTX 0x0698 Chuntex
-vendor ASKEY 0x069a Askey Computer
-vendor SAITEK 0x06a3 Saitek
-vendor ALCATELT 0x06b9 Alcatel Telecom
-vendor AGFA 0x06bd AGFA-Gevaert
-vendor ASIAMD 0x06be Asia Microelectronic Development
-vendor BIZLINK 0x06c4 Bizlink International
-vendor KEYSPAN 0x06cd Keyspan / InnoSys Inc.
-vendor AASHIMA 0x06d6 Aashima Technology
-vendor MULTITECH 0x06e0 MultiTech
-vendor ADS 0x06e1 ADS Technologies
-vendor ALCATELM 0x06e4 Alcatel Microelectronics
-vendor SIRIUS 0x06ea Sirius Technologies
-vendor GUILLEMOT 0x06f8 Guillemot
-vendor BOSTON 0x06fd Boston Acoustics
-vendor SMC 0x0707 Standard Microsystems
-vendor PUTERCOM 0x0708 Putercom
-vendor MCT 0x0711 MCT
-vendor IMATION 0x0718 Imation
-vendor SONYERICSSON 0x0731 Sony Ericsson
-vendor EICON 0x0734 Eicon Networks
-vendor SYNTECH 0x0745 Syntech Information
-vendor DIGITALSTREAM 0x074e Digital Stream
-vendor AUREAL 0x0755 Aureal Semiconductor
-vendor MIDIMAN 0x0763 Midiman
-vendor CYBERPOWER 0x0764 Cyber Power Systems, Inc.
-vendor SURECOM 0x0769 Surecom Technology
-vendor LINKSYS2 0x077b Linksys
-vendor GRIFFIN 0x077d Griffin Technology
-vendor SANDISK 0x0781 SanDisk
-vendor JENOPTIK 0x0784 Jenoptik
-vendor LOGITEC 0x0789 Logitec
-vendor BRIMAX 0x078e Brimax
-vendor AXIS 0x0792 Axis Communications
-vendor ABL 0x0794 ABL Electronics
-vendor SAGEM 0x079b Sagem
-vendor SUNCOMM 0x079c Sun Communications, Inc.
-vendor ALFADATA 0x079d Alfadata Computer
-vendor NATIONALTECH 0x07a2 National Technical Systems
-vendor ONNTO 0x07a3 Onnto
-vendor BE 0x07a4 Be
-vendor ADMTEK 0x07a6 ADMtek
-vendor COREGA 0x07aa Corega
-vendor FREECOM 0x07ab Freecom
-vendor MICROTECH 0x07af Microtech
-vendor GENERALINSTMNTS 0x07b2 General Instruments (Motorola)
-vendor OLYMPUS 0x07b4 Olympus
-vendor ABOCOM 0x07b8 AboCom Systems
-vendor KEISOKUGIKEN 0x07c1 Keisokugiken
-vendor ONSPEC 0x07c4 OnSpec
-vendor APG 0x07c5 APG Cash Drawer
-vendor BUG 0x07c8 B.U.G.
-vendor ALLIEDTELESYN 0x07c9 Allied Telesyn International
-vendor AVERMEDIA 0x07ca AVerMedia Technologies
-vendor SIIG 0x07cc SIIG
-vendor CASIO 0x07cf CASIO
-vendor DLINK2 0x07d1 D-Link
-vendor APTIO 0x07d2 Aptio Products
-vendor ARASAN 0x07da Arasan Chip Systems
-vendor ALLIEDCABLE 0x07e6 Allied Cable
-vendor STSN 0x07ef STSN
-vendor CENTURY 0x07f7 Century Corp
-vendor ZOOM 0x0803 Zoom Telephonics
-vendor PCS 0x0810 Personal Communication Systems
-vendor BROADLOGIC 0x0827 BroadLogic
-vendor HANDSPRING 0x082d Handspring
-vendor PALM 0x0830 Palm Computing
-vendor SOURCENEXT 0x0833 SOURCENEXT
-vendor ACTIONSTAR 0x0835 Action Star Enterprise
-vendor SAMSUNG_TECHWIN 0x0839 Samsung Techwin
-vendor ACCTON 0x083a Accton Technology
-vendor DIAMOND 0x0841 Diamond
-vendor NETGEAR 0x0846 BayNETGEAR
-vendor TOPRE 0x0853 Topre Corporation
-vendor ACTIVEWIRE 0x0854 ActiveWire
-vendor BBELECTRONICS 0x0856 B&B Electronics
-vendor PORTGEAR 0x085a PortGear
-vendor NETGEAR2 0x0864 Netgear
-vendor SYSTEMTALKS 0x086e System Talks
-vendor METRICOM 0x0870 Metricom
-vendor ADESSOKBTEK 0x087c ADESSO/Kbtek America
-vendor JATON 0x087d Jaton
-vendor APT 0x0880 APT Technologies
-vendor BOCARESEARCH 0x0885 Boca Research
-vendor ANDREA 0x08a8 Andrea Electronics
-vendor BURRBROWN 0x08bb Burr-Brown Japan
-vendor 2WIRE 0x08c8 2Wire
-vendor AIPTEK 0x08ca AIPTEK International
-vendor SMARTBRIDGES 0x08d1 SmartBridges
-vendor BILLIONTON 0x08dd Billionton Systems
-vendor EXTENDED 0x08e9 Extended Systems
-vendor MSYSTEMS 0x08ec M-Systems
-vendor AUTHENTEC 0x08ff AuthenTec
-vendor AUDIOTECHNICA 0x0909 Audio-Technica
-vendor TRUMPION 0x090a Trumpion Microelectronics
-vendor FEIYA 0x090c Feiya
-vendor ALATION 0x0910 Alation Systems
-vendor GLOBESPAN 0x0915 Globespan
-vendor CONCORDCAMERA 0x0919 Concord Camera
-vendor GARMIN 0x091e Garmin International
-vendor GOHUBS 0x0921 GoHubs
-vendor XEROX 0x0924 Xerox
-vendor BIOMETRIC 0x0929 American Biometric Company
-vendor TOSHIBA 0x0930 Toshiba
-vendor PLEXTOR 0x093b Plextor
-vendor INTREPIDCS 0x093c Intrepid
-vendor YANO 0x094f Yano
-vendor KINGSTON 0x0951 Kingston Technology
-vendor BLUEWATER 0x0956 BlueWater Systems
-vendor AGILENT 0x0957 Agilent Technologies
-vendor GUDE 0x0959 Gude ADS
-vendor PORTSMITH 0x095a Portsmith
-vendor ACERW 0x0967 Acer
-vendor ADIRONDACK 0x0976 Adirondack Wire & Cable
-vendor BECKHOFF 0x0978 Beckhoff
-vendor MINDSATWORK 0x097a Minds At Work
-vendor POINTCHIPS 0x09a6 PointChips
-vendor INTERSIL 0x09aa Intersil
-vendor ALTIUS 0x09b3 Altius Solutions
-vendor ARRIS 0x09c1 Arris Interactive
-vendor ACTIVCARD 0x09c3 ACTIVCARD
-vendor ACTISYS 0x09c4 ACTiSYS
-vendor NOVATEL2 0x09d7 Novatel Wireless
-vendor AFOURTECH 0x09da A-FOUR TECH
-vendor AIMEX 0x09dc AIMEX
-vendor ADDONICS 0x09df Addonics Technologies
-vendor AKAI 0x09e8 AKAI professional M.I.
-vendor ARESCOM 0x09f5 ARESCOM
-vendor BAY 0x09f9 Bay Associates
-vendor ALTERA 0x09fb Altera
-vendor CSR 0x0a12 Cambridge Silicon Radio
-vendor TREK 0x0a16 Trek Technology
-vendor ASAHIOPTICAL 0x0a17 Asahi Optical
-vendor BOCASYSTEMS 0x0a43 Boca Systems
-vendor SHANTOU 0x0a46 ShanTou
-vendor MEDIAGEAR 0x0a48 MediaGear
-vendor BROADCOM 0x0a5c Broadcom
-vendor GREENHOUSE 0x0a6b GREENHOUSE
-vendor GEOCAST 0x0a79 Geocast Network Systems
-vendor IDQUANTIQUE 0x0aba id Quantique
-vendor ZYDAS 0x0ace Zydas Technology Corporation
-vendor NEODIO 0x0aec Neodio
-vendor OPTION 0x0af0 Option N.V:
-vendor ASUS 0x0b05 ASUSTeK Computer
-vendor TODOS 0x0b0c Todos Data System
-vendor SIIG2 0x0b39 SIIG
-vendor TEKRAM 0x0b3b Tekram Technology
-vendor HAL 0x0b41 HAL Corporation
-vendor EMS 0x0b43 EMS Production
-vendor NEC2 0x0b62 NEC
-vendor ATI2 0x0b6f ATI
-vendor ZEEVO 0x0b7a Zeevo, Inc.
-vendor KURUSUGAWA 0x0b7e Kurusugawa Electronics, Inc.
-vendor ASIX 0x0b95 ASIX Electronics
-vendor O2MICRO 0x0b97 O2 Micro, Inc.
-vendor USR 0x0baf U.S. Robotics
-vendor AMBIT 0x0bb2 Ambit Microsystems
-vendor HTC 0x0bb4 HTC
-vendor REALTEK 0x0bda Realtek
-vendor ADDONICS2 0x0bf6 Addonics Technology
-vendor FSC 0x0bf8 Fujitsu Siemens Computers
-vendor AGATE 0x0c08 Agate Technologies
-vendor DMI 0x0c0b DMI
-vendor CHICONY2 0x0c45 Chicony
-vendor SEALEVEL 0x0c52 Sealevel System
-vendor LUWEN 0x0c76 Luwen
-vendor KYOCERA2 0x0c88 Kyocera Wireless Corp.
-vendor ZCOM 0x0cde Z-Com
-vendor ATHEROS2 0x0cf3 Atheros Communications
-vendor TANGTOP 0x0d3d Tangtop
-vendor SMC3 0x0d5c Standard Microsystems
-vendor ADDON 0x0d7d Add-on Technology
-vendor ACDC 0x0d7e American Computer & Digital Components
-vendor ABC 0x0d8c ABC
-vendor CONCEPTRONIC 0x0d8e Conceptronic
-vendor SKANHEX 0x0d96 Skanhex Technology, Inc.
-vendor MSI 0x0db0 Micro Star International
-vendor ELCON 0x0db7 ELCON Systemtechnik
-vendor NETAC 0x0dd8 Netac
-vendor SITECOMEU 0x0df6 Sitecom Europe
-vendor MOBILEACTION 0x0df7 Mobile Action
-vendor SPEEDDRAGON 0x0e55 Speed Dragon Multimedia
-vendor HAWKING 0x0e66 Hawking
-vendor FOSSIL 0x0e67 Fossil, Inc
-vendor GMATE 0x0e7e G.Mate, Inc
-vendor OTI 0x0ea0 Ours Technology
-vendor YISO 0x0eab Yiso Wireless Co.
-vendor PILOTECH 0x0eaf Pilotech
-vendor NOVATECH 0x0eb0 NovaTech
-vendor ITEGNO 0x0eba iTegno
-vendor WINMAXGROUP 0x0ed1 WinMaxGroup
-vendor TOD 0x0ede TOD
-vendor EGALAX 0x0eef eGalax, Inc.
-vendor AIRPRIME 0x0f3d AirPrime, Inc.
-vendor MICROTUNE 0x0f4d Microtune
-vendor VTECH 0x0f88 VTech
-vendor FALCOM 0x0f94 Falcom Wireless Communications GmbH
-vendor RIM 0x0fca Research In Motion
-vendor DYNASTREAM 0x0fcf Dynastream Innovations
-vendor QUALCOMM 0x1004 Qualcomm
-vendor DESKNOTE 0x1019 Desknote
-vendor GIGABYTE 0x1044 GIGABYTE
-vendor WESTERN 0x1058 Western Digital
-vendor MOTOROLA 0x1063 Motorola
-vendor CCYU 0x1065 CCYU Technology
-vendor CURITEL 0x106c Curitel Communications Inc
-vendor SILABS2 0x10a6 SILABS2
-vendor USI 0x10ab USI
-vendor PLX 0x10b5 PLX
-vendor ASANTE 0x10bd Asante
-vendor SILABS 0x10c4 Silicon Labs
-vendor ANALOG 0x1110 Analog Devices
-vendor TENX 0x1130 Ten X Technology, Inc.
-vendor ISSC 0x1131 Integrated System Solution Corp.
-vendor JRC 0x1145 Japan Radio Company
-vendor SPHAIRON 0x114b Sphairon Access Systems GmbH
-vendor DELORME 0x1163 DeLorme
-vendor SERVERWORKS 0x1166 ServerWorks
-vendor ACERCM 0x1189 Acer Communications & Multimedia
-vendor SIERRA 0x1199 Sierra Wireless
-vendor TOPFIELD 0x11db Topfield Co., Ltd
-vendor SIEMENS3 0x11f5 Siemens
-vendor PROLIFIC2 0x11f6 Prolific
-vendor ALCATEL 0x11f7 Alcatel
-vendor UNKNOWN3 0x1233 Unknown vendor
-vendor TSUNAMI 0x1241 Tsunami
-vendor PHEENET 0x124a Pheenet
-vendor TARGUS 0x1267 Targus
-vendor TWINMOS 0x126f TwinMOS
-vendor TENDA 0x1286 Tenda
-vendor CREATIVE2 0x1292 Creative Labs
-vendor BELKIN2 0x1293 Belkin Components
-vendor CYBERTAN 0x129b CyberTAN Technology
-vendor HUAWEI 0x12d1 Huawei Technologies
-vendor ARANEUS 0x12d8 Araneus Information Systems
-vendor TAPWAVE 0x12ef Tapwave
-vendor AINCOMM 0x12fd Aincomm
-vendor MOBILITY 0x1342 Mobility
-vendor DICKSMITH 0x1371 Dick Smith Electronics
-vendor NETGEAR3 0x1385 Netgear
-vendor BALTECH 0x13ad Baltech
-vendor CISCOLINKSYS 0x13b1 Cisco-Linksys
-vendor SHARK 0x13d2 Shark
-vendor NOVATEL 0x1410 Novatel Wireless
-vendor MERLIN 0x1416 Merlin
-vendor WISTRONNEWEB 0x1435 Wistron NeWeb
-vendor RADIOSHACK 0x1453 Radio Shack
-vendor HUAWEI3COM 0x1472 Huawei-3Com
-vendor SILICOM 0x1485 Silicom
-vendor RALINK 0x148f Ralink Technology
-vendor IMAGINATION 0x149a Imagination Technologies
-vendor CONCEPTRONIC2 0x14b2 Conceptronic
-vendor PLANEX3 0x14ea Planex Communications
-vendor SILICONPORTALS 0x1527 Silicon Portals
-vendor UBIQUAM 0x1529 UBIQUAM Co., Ltd.
-vendor UBLOX 0x1546 U-blox
-vendor PNY 0x154b PNY
-vendor OQO 0x1557 OQO
-vendor UMEDIA 0x157e U-MEDIA Communications
-vendor FIBERLINE 0x1582 Fiberline
-vendor SPARKLAN 0x15a9 SparkLAN
-vendor SOHOWARE 0x15e8 SOHOware
-vendor UMAX 0x1606 UMAX Data Systems
-vendor INSIDEOUT 0x1608 Inside Out Networks
-vendor GOODWAY 0x1631 Good Way Technology
-vendor ENTREGA 0x1645 Entrega
-vendor ACTIONTEC 0x1668 Actiontec Electronics
-vendor ATHEROS 0x168c Atheros Communications
-vendor GIGASET 0x1690 Gigaset
-vendor GLOBALSUN 0x16ab Global Sun Technology
-vendor ANYDATA 0x16d5 AnyDATA Corporation
-vendor JABLOTRON 0x16d6 Jablotron
-vendor CMOTECH 0x16d8 C-motech
-vendor AXESSTEL 0x1726 Axesstel Co., Ltd.
-vendor LINKSYS4 0x1737 Linksys
-vendor SENAO 0x1740 Senao
-vendor METAGEEK 0x1781 MetaGeek
-vendor AMIT 0x18c5 AMIT
-vendor QCOM 0x18e8 Qcom
-vendor LINKSYS3 0x1915 Linksys
-vendor QUALCOMMINC 0x19d2 Qualcomm, Incorporated
-vendor STELERA 0x1a8d Stelera Wireless
-vendor DRESDENELEKTRONIK 0x1cf1 dresden elektronik
-vendor DLINK 0x2001 D-Link
-vendor PLANEX2 0x2019 Planex Communications
-vendor ERICSSON 0x2282 Ericsson
-vendor MOTOROLA2 0x22b8 Motorola
-vendor TRIPPLITE 0x2478 Tripp-Lite
-vendor HIROSE 0x2631 Hirose Electric
-vendor NHJ 0x2770 NHJ
-vendor PLANEX 0x2c02 Planex Communications
-vendor VIDZMEDIA 0x3275 VidzMedia Pte Ltd
-vendor AEI 0x3334 AEI
-vendor HANK 0x3353 Hank Connection
-vendor PQI 0x3538 PQI
-vendor DAISY 0x3579 Daisy Technology
-vendor NI 0x3923 National Instruments
-vendor MICRONET 0x3980 Micronet Communications
-vendor IODATA2 0x40bb I-O Data
-vendor IRIVER 0x4102 iRiver
-vendor DELL 0x413c Dell
-vendor WCH 0x4348 QinHeng Electronics
-vendor ACEECA 0x4766 Aceeca
-vendor AVERATEC 0x50c2 Averatec
-vendor SWEEX 0x5173 Sweex
-vendor ONSPEC2 0x55aa OnSpec Electronic Inc.
-vendor ZINWELL 0x5a57 Zinwell
-vendor SITECOM 0x6189 Sitecom
-vendor ARKMICRO 0x6547 Arkmicro Technologies Inc.
-vendor 3COM2 0x6891 3Com
-vendor INTEL 0x8086 Intel
-vendor SITECOM2 0x9016 Sitecom
-vendor MOSCHIP 0x9710 MosChip Semiconductor
-vendor 3COM3 0xa727 3Com
-vendor HP2 0xf003 Hewlett Packard
-vendor USRP 0xfffe GNU Radio USRP
-
-/*
- * List of known products. Grouped by vendor.
- */
-
-/* 3Com products */
-product 3COM HOMECONN 0x009d HomeConnect Camera
-product 3COM 3CREB96 0x00a0 Bluetooth USB Adapter
-product 3COM 3C19250 0x03e8 3C19250 Ethernet Adapter
-product 3COM 3CRSHEW696 0x0a01 3CRSHEW696 Wireless Adapter
-product 3COM 3C460 0x11f8 HomeConnect 3C460
-product 3COM USR56K 0x3021 U.S.Robotics 56000 Voice FaxModem Pro
-product 3COM 3C460B 0x4601 HomeConnect 3C460B
-product 3COM2 3CRUSB10075 0xa727 3CRUSB10075
-product 3COM3 AR5523_1 0x6893 AR5523
-product 3COM3 AR5523_2 0x6895 AR5523
-product 3COM3 AR5523_3 0x6897 AR5523
-
-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
-
-/* AboCom products */
-product ABOCOM XX1 0x110c XX1
-product ABOCOM XX2 0x200c XX2
-product ABOCOM URE450 0x4000 URE450 Ethernet Adapter
-product ABOCOM UFE1000 0x4002 UFE1000 Fast Ethernet Adapter
-product ABOCOM DSB650TX_PNA 0x4003 1/10/100 Ethernet Adapter
-product ABOCOM XX4 0x4004 XX4
-product ABOCOM XX5 0x4007 XX5
-product ABOCOM XX6 0x400b XX6
-product ABOCOM XX7 0x400c XX7
-product ABOCOM RTL8151 0x401a RTL8151
-product ABOCOM XX8 0x4102 XX8
-product ABOCOM XX9 0x4104 XX9
-product ABOCOM UF200 0x420a UF200 Ethernet
-product ABOCOM WL54 0x6001 WL54
-product ABOCOM XX10 0xabc1 XX10
-product ABOCOM BWU613 0xb000 BWU613
-product ABOCOM HWU54DM 0xb21b HWU54DM
-product ABOCOM RT2573_2 0xb21c RT2573
-product ABOCOM RT2573_3 0xb21d RT2573
-product ABOCOM RT2573_4 0xb21e RT2573
-product ABOCOM WUG2700 0xb21f WUG2700
-
-/* Accton products */
-product ACCTON USB320_EC 0x1046 USB320-EC Ethernet Adapter
-product ACCTON 2664W 0x3501 2664W
-product ACCTON 111 0x3503 T-Sinus 111 Wireless Adapter
-product ACCTON SMCWUSBG 0x4505 SMCWUSB-G
-product ACCTON PRISM_GT 0x4521 PrismGT USB 2.0 WLAN
-product ACCTON SS1001 0x5046 SpeedStream Ethernet Adapter
-product ACCTON ZD1211B 0xe501 ZD1211B
-
-/* Aceeca products */
-product ACEECA MEZ1000 0x0001 MEZ1000 RDA
-
-/* Acer Communications & Multimedia (oemd by Surecom) */
-product ACERCM EP1427X2 0x0893 EP-1427X-2 Ethernet Adapter
-
-/* Acer Labs products */
-product ACERLABS M5632 0x5632 USB 2.0 Data Link
-
-/* Acer Peripherals, Inc. products */
-product ACERP ACERSCAN_C310U 0x12a6 Acerscan C310U
-product ACERP ACERSCAN_320U 0x2022 Acerscan 320U
-product ACERP ACERSCAN_640U 0x2040 Acerscan 640U
-product ACERP ACERSCAN_620U 0x2060 Acerscan 620U
-product ACERP ACERSCAN_4300U 0x20b0 Benq 3300U/4300U
-product ACERP ACERSCAN_640BT 0x20be Acerscan 640BT
-product ACERP ACERSCAN_1240U 0x20c0 Acerscan 1240U
-product ACERP ATAPI 0x6003 ATA/ATAPI Adapter
-product ACERP AWL300 0x9000 AWL300 Wireless Adapter
-product ACERP AWL400 0x9001 AWL400 Wireless Adapter
-
-/* Acer Warp products */
-product ACERW WARPLINK 0x0204 Warplink
-
-/* Actiontec, Inc. products */
-product ACTIONTEC PRISM_25 0x0408 Prism2.5 Wireless Adapter
-product ACTIONTEC PRISM_25A 0x0421 Prism2.5 Wireless Adapter A
-product ACTIONTEC FREELAN 0x6106 ROPEX FreeLan 802.11b
-product ACTIONTEC UAT1 0x7605 UAT1 Wireless Ethernet Adapter
-
-/* ACTiSYS products */
-product ACTISYS IR2000U 0x0011 ACT-IR2000U FIR
-
-/* ActiveWire, Inc. products */
-product ACTIVEWIRE IOBOARD 0x0100 I/O Board
-product ACTIVEWIRE IOBOARD_FW1 0x0101 I/O Board, rev. 1 firmware
-
-/* Adaptec products */
-product ADAPTEC AWN8020 0x0020 AWN-8020 WLAN
-
-/* Addtron products */
-product ADDTRON AWU120 0xff31 AWU-120
-
-/* ADMtek products */
-product ADMTEK PEGASUSII_4 0x07c2 AN986A Ethernet
-product ADMTEK PEGASUS 0x0986 AN986 Ethernet
-product ADMTEK PEGASUSII 0x8511 AN8511 Ethernet
-product ADMTEK PEGASUSII_2 0x8513 AN8513 Ethernet
-product ADMTEK PEGASUSII_3 0x8515 AN8515 Ethernet
-
-/* ADDON products */
-/* PNY OEMs these */
-product ADDON ATTACHE 0x1300 USB 2.0 Flash Drive
-product ADDON ATTACHE 0x1300 USB 2.0 Flash Drive
-product ADDON A256MB 0x1400 Attache 256MB USB 2.0 Flash Drive
-product ADDON DISKPRO512 0x1420 USB 2.0 Flash Drive (DANE-ELEC zMate 512MB USB flash drive)
-
-/* Addonics products */
-product ADDONICS2 CABLE_205 0xa001 Cable 205
-
-/* ADS products */
-product ADS UBS10BT 0x0008 UBS-10BT Ethernet
-product ADS UBS10BTX 0x0009 UBS-10BT Ethernet
-
-/* AEI products */
-product AEI FASTETHERNET 0x1701 Fast Ethernet
-
-/* Agate Technologies products */
-product AGATE QDRIVE 0x0378 Q-Drive
-
-/* AGFA products */
-product AGFA SNAPSCAN1212U 0x0001 SnapScan 1212U
-product AGFA SNAPSCAN1236U 0x0002 SnapScan 1236U
-product AGFA SNAPSCANTOUCH 0x0100 SnapScan Touch
-product AGFA SNAPSCAN1212U2 0x2061 SnapScan 1212U
-product AGFA SNAPSCANE40 0x208d SnapScan e40
-product AGFA SNAPSCANE50 0x208f SnapScan e50
-product AGFA SNAPSCANE20 0x2091 SnapScan e20
-product AGFA SNAPSCANE25 0x2095 SnapScan e25
-product AGFA SNAPSCANE26 0x2097 SnapScan e26
-product AGFA SNAPSCANE52 0x20fd SnapScan e52
-
-/* Ain Communication Technology products */
-product AINCOMM AWU2000B 0x1001 AWU2000B Wireless Adapter
-
-/* AIPTEK products */
-product AIPTEK POCKETCAM3M 0x2011 PocketCAM 3Mega
-product AIPTEK2 PENCAM_MEGA_1_3 0x504a PenCam Mega 1.3
-
-/* AirPrime products */
-product AIRPRIME PC5220 0x0112 CDMA Wireless PC Card
-
-/* AKS products */
-product AKS USBHASP 0x0001 USB-HASP 0.06
-
-/* Alcor Micro, Inc. products */
-product ALCOR2 KBD_HUB 0x2802 Kbd Hub
-
-product ALCOR TRANSCEND 0x6387 Transcend JetFlash Drive
-product ALCOR MA_KBD_HUB 0x9213 MacAlly Kbd Hub
-product ALCOR AU9814 0x9215 AU9814 Hub
-product ALCOR UMCR_9361 0x9361 USB Multimedia Card Reader
-product ALCOR SM_KBD 0x9410 MicroConnectors/StrongMan Keyboard
-product ALCOR NEC_KBD_HUB 0x9472 NEC Kbd Hub
-
-/* Altec Lansing products */
-product ALTEC ADA70 0x0070 ADA70 Speakers
-product ALTEC ASC495 0xff05 ASC495 Speakers
-
-/* Allied Telesyn International products */
-product ALLIEDTELESYN ATUSB100 0xb100 AT-USB100
-
-/* American Power Conversion products */
-product APC UPS 0x0002 Uninterruptible Power Supply
-
-/* Ambit Microsystems products */
-product AMBIT WLAN 0x0302 WLAN
-product AMBIT NTL_250 0x6098 NTL 250 cable modem
-
-/* AMIT products */
-product AMIT CGWLUSB2GO 0x0002 CG-WLUSB2GO
-
-/* Anchor products */
-product ANCHOR EZUSB 0x2131 EZUSB
-product ANCHOR EZLINK 0x2720 EZLINK
-
-/* AnyData products */
-product ANYDATA ADU_E100X 0x6501 CDMA 2000 1xRTT/EV-DO USB Modem
-product ANYDATA ADU_500A 0x6502 CDMA 2000 EV-DO USB Modem
-
-/* AOX, Inc. products */
-product AOX USB101 0x0008 Ethernet
-
-/* American Power Conversion products */
-product APC UPS 0x0002 Uninterruptible Power Supply
-
-/* Apple Computer products */
-product APPLE EXT_KBD 0x020c Apple Extended USB Keyboard
-product APPLE OPTMOUSE 0x0302 Optical mouse
-product APPLE MIGHTYMOUSE 0x0304 Mighty Mouse
-product APPLE EXT_KBD_HUB 0x1003 Hub in Apple Extended USB Keyboard
-product APPLE SPEAKERS 0x1101 Speakers
-product APPLE IPOD 0x1201 iPod
-product APPLE IPOD2G 0x1202 iPod 2G
-product APPLE IPOD3G 0x1203 iPod 3G
-product APPLE IPOD_04 0x1204 iPod '04'
-product APPLE IPODMINI 0x1205 iPod Mini
-product APPLE IPOD_06 0x1206 iPod '06'
-product APPLE IPOD_07 0x1207 iPod '07'
-product APPLE IPOD_08 0x1208 iPod '08'
-product APPLE IPODVIDEO 0x1209 iPod Video
-product APPLE IPODNANO 0x120a iPod Nano
-product APPLE IPHONE 0x1290 iPhone
-product APPLE IPHONE_3G 0x1292 iPhone 3G
-product APPLE ETHERNET 0x1402 Ethernet A1277
-
-/* Arkmicro Technologies */
-product ARKMICRO ARK3116 0x0232 ARK3116 Serial
-
-/* Asahi Optical products */
-product ASAHIOPTICAL OPTIO230 0x0004 Digital camera
-product ASAHIOPTICAL OPTIO330 0x0006 Digital camera
-
-/* Asante products */
-product ASANTE EA 0x1427 Ethernet
-
-/* ASIX Electronics products */
-product ASIX AX88172 0x1720 10/100 Ethernet
-product ASIX AX88178 0x1780 AX88178
-product ASIX AX88772 0x7720 AX88772
-
-/* ASUS products */
-product ASUS WL167G 0x1707 WL-167g Wireless Adapter
-product ASUS WL159G 0x170c WL-159g
-product ASUS A9T_WIFI 0x171b A9T wireless
-product ASUS RT2573_1 0x1723 RT2573
-product ASUS RT2573_2 0x1724 RT2573
-product ASUS LCM 0x1726 LCM display
-product ASUS P535 0x420f ASUS P535 PDA
-
-/* ATen products */
-product ATEN UC1284 0x2001 Parallel printer
-product ATEN UC10T 0x2002 10Mbps Ethernet
-product ATEN UC110T 0x2007 UC-110T Ethernet
-product ATEN UC232A 0x2008 Serial
-product ATEN UC210T 0x2009 UC-210T Ethernet
-product ATEN DSB650C 0x4000 DSB-650C
-
-/* Atheros Communications products */
-product ATHEROS AR5523 0x0001 AR5523
-product ATHEROS AR5523_NF 0x0002 AR5523 (no firmware)
-product ATHEROS2 AR5523_1 0x0001 AR5523
-product ATHEROS2 AR5523_1_NF 0x0002 AR5523 (no firmware)
-product ATHEROS2 AR5523_2 0x0003 AR5523
-product ATHEROS2 AR5523_2_NF 0x0004 AR5523 (no firmware)
-product ATHEROS2 AR5523_3 0x0005 AR5523
-product ATHEROS2 AR5523_3_NF 0x0006 AR5523 (no firmware)
-
-/* Atmel Comp. products */
-product ATMEL UHB124 0x3301 UHB124 hub
-product ATMEL DWL120 0x7603 DWL-120 Wireless Adapter
-product ATMEL BW002 0x7605 BW002 Wireless Adapter
-product ATMEL WL1130USB 0x7613 WL-1130 USB
-product ATMEL AT76C505A 0x7614 AT76c505a Wireless Adapter
-
-/* Avision products */
-product AVISION 1200U 0x0268 1200U scanner
-
-/* Axesstel products */
-product AXESSTEL DATAMODEM 0x1000 Data Modem
-
-/* Baltech products */
-product BALTECH CARDREADER 0x9999 Card reader
-
-/* B&B Electronics products */
-product BBELECTRONICS USOTL4 0xAC01 RS-422/485
-
-/* Belkin products */
-/*product BELKIN F5U111 0x???? F5U111 Ethernet*/
-product BELKIN F5D6050 0x0050 F5D6050 802.11b Wireless Adapter
-product BELKIN FBT001V 0x0081 FBT001v2 Bluetooth
-product BELKIN FBT003V 0x0084 FBT003v2 Bluetooth
-product BELKIN F5U103 0x0103 F5U103 Serial
-product BELKIN F5U109 0x0109 F5U109 Serial
-product BELKIN USB2SCSI 0x0115 USB to SCSI
-product BELKIN F8T012 0x0121 F8T012xx1 Bluetooth USB Adapter
-product BELKIN USB2LAN 0x0121 USB to LAN
-product BELKIN F5U208 0x0208 F5U208 VideoBus II
-product BELKIN F5U237 0x0237 F5U237 USB 2.0 7-Port Hub
-product BELKIN F5U257 0x0257 F5U257 Serial
-product BELKIN F5U409 0x0409 F5U409 Serial
-product BELKIN F6C550AVR 0x0551 F6C550-AVR UPS
-product BELKIN F5U120 0x1203 F5U120-PC Hub
-product BELKIN ZD1211B 0x4050 ZD1211B
-product BELKIN F5D5055 0x5055 F5D5055
-product BELKIN F5D7050 0x7050 F5D7050 Wireless Adapter
-product BELKIN F5D7051 0x7051 F5D7051 54g USB Network Adapter
-product BELKIN F5D7050A 0x705a F5D7050A Wireless Adapter
-/* Also sold as 'Ativa 802.11g wireless card' */
-product BELKIN F5D7050_V4000 0x705c F5D7050 v4000 Wireless Adapter
-product BELKIN F5D9050V3 0x905b F5D9050 ver 3 Wireless Adapter
-product BELKIN2 F5U002 0x0002 F5U002 Parallel printer
-
-/* Billionton products */
-product BILLIONTON USB100 0x0986 USB100N 10/100 FastEthernet
-product BILLIONTON USBLP100 0x0987 USB100LP
-product BILLIONTON USBEL100 0x0988 USB100EL
-product BILLIONTON USBE100 0x8511 USBE100
-product BILLIONTON USB2AR 0x90ff USB2AR Ethernet
-
-/* Broadcom products */
-product BROADCOM BCM2033 0x2033 BCM2033 Bluetooth USB dongle
-
-/* Brother Industries products */
-product BROTHER HL1050 0x0002 HL-1050 laser printer
-
-/* Behavior Technology Computer products */
-product BTC BTC7932 0x6782 Keyboard with mouse port
-
-/* Canon, Inc. products */
-product CANON N656U 0x2206 CanoScan N656U
-product CANON N1220U 0x2207 CanoScan N1220U
-product CANON D660U 0x2208 CanoScan D660U
-product CANON N676U 0x220d CanoScan N676U
-product CANON N1240U 0x220e CanoScan N1240U
-product CANON LIDE25 0x2220 CanoScan LIDE 25
-product CANON S10 0x3041 PowerShot S10
-product CANON S100 0x3045 PowerShot S100
-product CANON S200 0x3065 PowerShot S200
-product CANON REBELXT 0x30ef Digital Rebel XT
-
-/* CATC products */
-product CATC NETMATE 0x000a Netmate Ethernet
-product CATC NETMATE2 0x000c Netmate2 Ethernet
-product CATC CHIEF 0x000d USB Chief Bus & Protocol Analyzer
-product CATC ANDROMEDA 0x1237 Andromeda hub
-
-/* CASIO products */
-product CASIO QV_DIGICAM 0x1001 QV DigiCam
-product CASIO EXS880 0x1105 Exilim EX-S880
-product CASIO BE300 0x2002 BE-300 PDA
-product CASIO NAMELAND 0x4001 CASIO Nameland EZ-USB
-
-/* CCYU products */
-product CCYU ED1064 0x2136 EasyDisk ED1064
-
-/* Century products */
-product CENTURY EX35QUAT 0x011e Century USB Disk Enclosure
-
-/* Cherry products */
-product CHERRY MY3000KBD 0x0001 My3000 keyboard
-product CHERRY MY3000HUB 0x0003 My3000 hub
-product CHERRY CYBOARD 0x0004 CyBoard Keyboard
-
-/* Chic Technology products */
-product CHIC MOUSE1 0x0001 mouse
-product CHIC CYPRESS 0x0003 Cypress USB Mouse
-
-/* Chicony products */
-product CHICONY KB8933 0x0001 KB-8933 keyboard
-product CHICONY2 TWINKLECAM 0x600d TwinkleCam USB camera
-
-/* CH Products */
-product CHPRODUCTS PROTHROTTLE 0x00f1 Pro Throttle
-product CHPRODUCTS PROPEDALS 0x00f2 Pro Pedals
-product CHPRODUCTS FIGHTERSTICK 0x00f3 Fighterstick
-product CHPRODUCTS FLIGHTYOKE 0x00ff Flight Sim Yoke
-
-/* Cisco-Linksys products */
-product CISCOLINKSYS WUSB54G 0x000d WUSB54G Wireless Adapter
-product CISCOLINKSYS WUSB54GP 0x0011 WUSB54GP Wireless Adapter
-product CISCOLINKSYS USB200MV2 0x0018 USB200M v2
-product CISCOLINKSYS HU200TS 0x001a HU200TS Wireless Adapter
-product CISCOLINKSYS WUSB54GC 0x0020 WUSB54GC
-product CISCOLINKSYS WUSB54GR 0x0023 WUSB54GR
-product CISCOLINKSYS WUSBF54G 0x0024 WUSBF54G
-
-/* CMOTECH products */
-product CMOTECH CNU510 0x5141 CDMA Technologies USB modem
-product CMOTECH CNU550 0x5543 CDMA 2000 1xRTT/1xEVDO USB modem
-product CMOTECH CGU628 0x6006 CGU-628
-product CMOTECH CDMA_MODEM1 0x6280 CDMA Technologies USB modem
-product CMOTECH DISK 0xf000 disk mode
-
-/* Compaq products */
-product COMPAQ IPAQPOCKETPC 0x0003 iPAQ PocketPC
-product COMPAQ PJB100 0x504a Personal Jukebox PJB100
-product COMPAQ IPAQLINUX 0x505a iPAQ Linux
-
-/* Composite Corp products looks the same as "TANGTOP" */
-product COMPOSITE USBPS2 0x0001 USB to PS2 Adaptor
-
-/* Conceptronic products */
-product CONCEPTRONIC PRISM_GT 0x3762 PrismGT USB 2.0 WLAN
-product CONCEPTRONIC C11U 0x7100 C11U
-product CONCEPTRONIC WL210 0x7110 WL-210
-product CONCEPTRONIC AR5523_1 0x7801 AR5523
-product CONCEPTRONIC AR5523_1_NF 0x7802 AR5523 (no firmware)
-product CONCEPTRONIC AR5523_2 0x7811 AR5523
-product CONCEPTRONIC AR5523_2_NF 0x7812 AR5523 (no firmware)
-product CONCEPTRONIC2 C54RU 0x3c02 C54RU WLAN
-product CONCEPTRONIC2 C54RU2 0x3c22 C54RU
-
-/* Connectix products */
-product CONNECTIX QUICKCAM 0x0001 QuickCam
-
-/* Corega products */
-product COREGA ETHER_USB_T 0x0001 Ether USB-T
-product COREGA FETHER_USB_TX 0x0004 FEther USB-TX
-product COREGA WLAN_USB_USB_11 0x000c WirelessLAN USB-11
-product COREGA FETHER_USB_TXS 0x000d FEther USB-TXS
-product COREGA WLANUSB 0x0012 Wireless LAN Stick-11
-product COREGA FETHER_USB2_TX 0x0017 FEther USB2-TX
-product COREGA WLUSB_11_KEY 0x001a ULUSB-11 Key
-product COREGA CGWLUSB2GL 0x002d CG-WLUSB2GL
-product COREGA CGWLUSB2GPX 0x002e CG-WLUSB2GPX
-product COREGA WLUSB_11_STICK 0x7613 WLAN USB Stick 11
-product COREGA FETHER_USB_TXC 0x9601 FEther USB-TXC
-
-/* Creative products */
-product CREATIVE NOMAD_II 0x1002 Nomad II MP3 player
-product CREATIVE NOMAD_IIMG 0x4004 Nomad II MG
-product CREATIVE NOMAD 0x4106 Nomad
-product CREATIVE2 VOIP_BLASTER 0x0258 Voip Blaster
-product CREATIVE3 OPTICAL_MOUSE 0x0001 Notebook Optical Mouse
-
-/* Cambridge Silicon Radio Ltd. products */
-product CSR BT_DONGLE 0x0001 Bluetooth USB dongle
-product CSR CSRDFU 0xffff USB Bluetooth Device in DFU State
-
-/* CTX products */
-product CTX EX1300 0x9999 Ex1300 hub
-
-/* Curitel products */
-product CURITEL HX550C 0x1101 CDMA 2000 1xRTT USB modem (HX-550C)
-product CURITEL HX57XB 0x2101 CDMA 2000 1xRTT USB modem (HX-570/575B/PR-600)
-product CURITEL PC5740 0x3701 Broadband Wireless modem
-
-/* CyberPower products */
-product CYBERPOWER 1500CAVRLCD 0x0501 1500CAVRLCD
-
-/* CyberTAN Technology products */
-product CYBERTAN TG54USB 0x1666 TG54USB
-
-/* Cypress Semiconductor products */
-product CYPRESS MOUSE 0x0001 mouse
-product CYPRESS THERMO 0x0002 thermometer
-product CYPRESS WISPY1A 0x0bad MetaGeek Wi-Spy
-product CYPRESS KBDHUB 0x0101 Keyboard/Hub
-product CYPRESS FMRADIO 0x1002 FM Radio
-product CYPRESS USBRS232 0x5500 USB-RS232 Interface
-product CYPRESS SLIM_HUB 0x6560 Slim Hub
-
-/* Daisy Technology products */
-product DAISY DMC 0x6901 USB MultiMedia Reader
-
-/* Dallas Semiconductor products */
-product DALLAS J6502 0x4201 J-6502 speakers
-
-/* Dell products */
-product DELL PORT 0x0058 Port Replicator
-product DELL AIO926 0x5115 Photo AIO Printer 926
-product DELL BC02 0x8000 BC02 Bluetooth USB Adapter
-product DELL PRISM_GT_1 0x8102 PrismGT USB 2.0 WLAN
-product DELL TM350 0x8103 TrueMobile 350 Bluetooth USB Adapter
-product DELL PRISM_GT_2 0x8104 PrismGT USB 2.0 WLAN
-product DELL U740 0x8135 Dell U740 CDMA
-
-/* Delorme Paublishing products */
-product DELORME EARTHMATE 0x0100 Earthmate GPS
-
-/* Desknote products */
-product DESKNOTE UCR_61S2B 0x0c55 UCR-61S2B
-
-/* Diamond products */
-product DIAMOND RIO500USB 0x0001 Rio 500 USB
-
-/* Dick Smith Electronics (really C-Net) products */
-product DICKSMITH RT2573 0x9022 RT2573
-product DICKSMITH CWD854F 0x9032 C-Net CWD-854 rev F
-
-/* Digi International products */
-product DIGI ACCELEPORT2 0x0002 AccelePort USB 2
-product DIGI ACCELEPORT4 0x0004 AccelePort USB 4
-product DIGI ACCELEPORT8 0x0008 AccelePort USB 8
-
-/* D-Link products */
-/*product DLINK DSBS25 0x0100 DSB-S25 serial*/
-product DLINK DUBE100 0x1a00 10/100 Ethernet
-product DLINK DSB650TX4 0x200c 10/100 Ethernet
-product DLINK DWL120E 0x3200 DWL-120 rev E
-product DLINK DWL122 0x3700 DWL-122
-product DLINK DWLG120 0x3701 DWL-G120
-product DLINK DWL120F 0x3702 DWL-120 rev F
-product DLINK DWLAG132 0x3a00 DWL-AG132
-product DLINK DWLAG132_NF 0x3a01 DWL-AG132 (no firmware)
-product DLINK DWLG132 0x3a02 DWL-G132
-product DLINK DWLG132_NF 0x3a03 DWL-G132 (no firmware)
-product DLINK DWLAG122 0x3a04 DWL-AG122
-product DLINK DWLAG122_NF 0x3a05 DWL-AG122 (no firmware)
-product DLINK DWLG122 0x3c00 DWL-G122 b1 Wireless Adapter
-product DLINK DUBE100B1 0x3c05 DUB-E100 rev B1
-product DLINK DSB650C 0x4000 10Mbps Ethernet
-product DLINK DSB650TX1 0x4001 10/100 Ethernet
-product DLINK DSB650TX 0x4002 10/100 Ethernet
-product DLINK DSB650TX_PNA 0x4003 1/10/100 Ethernet
-product DLINK DSB650TX3 0x400b 10/100 Ethernet
-product DLINK DSB650TX2 0x4102 10/100 Ethernet
-product DLINK DSB650 0xabc1 10/100 Ethernet
-product DLINK2 DWLG122C1 0x3c03 DWL-G122 c1
-product DLINK2 WUA1340 0x3c04 WUA-1340
-product DLINK2 DWA111 0x3c06 DWA-111
-product DLINK2 DWA110 0x3c07 DWA-110
-
-/* DMI products */
-product DMI CFSM_RW 0xa109 CF/SM Reader/Writer
-
-/* DrayTek products */
-product DRAYTEK VIGOR550 0x0550 Vigor550
-
-/* dresden elektronik products */
-product DRESDENELEKTRONIK SENSORTERMINALBOARD 0x0001 SensorTerminalBoard
-
-/* Dynastream Innovations */
-product DYNASTREAM ANTDEVBOARD 0x1003 ANT dev board
-
-/* EIZO products */
-product EIZO HUB 0x0000 hub
-product EIZO MONITOR 0x0001 monitor
-
-/* ELCON Systemtechnik products */
-product ELCON PLAN 0x0002 Goldpfeil P-LAN
-
-/* Elecom products */
-product ELECOM MOUSE29UO 0x0002 mouse 29UO
-product ELECOM LDUSBTX0 0x200c LD-USB/TX
-product ELECOM LDUSBTX1 0x4002 LD-USB/TX
-product ELECOM LDUSBLTX 0x4005 LD-USBL/TX
-product ELECOM LDUSBTX2 0x400b LD-USB/TX
-product ELECOM LDUSB20 0x4010 LD-USB20
-product ELECOM UCSGT 0x5003 UC-SGT
-product ELECOM UCSGT0 0x5004 UC-SGT
-product ELECOM LDUSBTX3 0xabc1 LD-USB/TX
-
-/* Elsa products */
-product ELSA MODEM1 0x2265 ELSA Modem Board
-product ELSA USB2ETHERNET 0x3000 Microlink USB2Ethernet
-
-/* EMS products */
-product EMS DUAL_SHOOTER 0x0003 PSX gun controller converter
-
-/* Entrega products */
-product ENTREGA 1S 0x0001 1S serial
-product ENTREGA 2S 0x0002 2S serial
-product ENTREGA 1S25 0x0003 1S25 serial
-product ENTREGA 4S 0x0004 4S serial
-product ENTREGA E45 0x0005 E45 Ethernet
-product ENTREGA CENTRONICS 0x0006 Parallel Port
-product ENTREGA XX1 0x0008 Ethernet
-product ENTREGA 1S9 0x0093 1S9 serial
-product ENTREGA EZUSB 0x8000 EZ-USB
-/*product ENTREGA SERIAL 0x8001 DB25 Serial*/
-product ENTREGA 2U4S 0x8004 2U4S serial/usb hub
-product ENTREGA XX2 0x8005 Ethernet
-/*product ENTREGA SERIAL_DB9 0x8093 DB9 Serial*/
-
-/* Epson products */
-product EPSON PRINTER1 0x0001 USB Printer
-product EPSON PRINTER2 0x0002 ISD USB Smart Cable for Mac
-product EPSON PRINTER3 0x0003 ISD USB Smart Cable
-product EPSON PRINTER5 0x0005 USB Printer
-product EPSON 636 0x0101 Perfection 636U / 636Photo scanner
-product EPSON 610 0x0103 Perfection 610 scanner
-product EPSON 1200 0x0104 Perfection 1200U / 1200Photo scanner
-product EPSON 1600 0x0107 Expression 1600 scanner
-product EPSON 1640 0x010a Perfection 1640SU scanner
-product EPSON 1240 0x010b Perfection 1240U / 1240Photo scanner
-product EPSON 640U 0x010c Perfection 640U scanner
-product EPSON 1250 0x010f Perfection 1250U / 1250Photo scanner
-product EPSON 1650 0x0110 Perfection 1650 scanner
-product EPSON GT9700F 0x0112 GT-9700F scanner
-product EPSON GT9300UF 0x011b GT-9300UF scanner
-product EPSON 3200 0x011c Perfection 3200 scanner
-product EPSON 1260 0x011d Perfection 1260 scanner
-product EPSON 1660 0x011e Perfection 1660 scanner
-product EPSON 1670 0x011f Perfection 1670 scanner
-product EPSON 1270 0x0120 Perfection 1270 scanner
-product EPSON 2480 0x0121 Perfection 2480 scanner
-product EPSON 3590 0x0122 Perfection 3590 scanner
-product EPSON 4990 0x012a Perfection 4990 Photo scanner
-product EPSON STYLUS_875DC 0x0601 Stylus Photo 875DC Card Reader
-product EPSON STYLUS_895 0x0602 Stylus Photo 895 Card Reader
-product EPSON CX5400 0x0808 CX5400 scanner
-product EPSON 3500 0x080e CX-3500/3600/3650 MFP
-product EPSON RX425 0x080f Stylus Photo RX425 scanner
-product EPSON DX3800 0x0818 CX3700/CX3800/DX38x0 MFP scanner
-product EPSON 4800 0x0819 CX4700/CX4800/DX48x0 MFP scanner
-product EPSON 4200 0x0820 CX4100/CX4200/DX4200 MFP scanner
-product EPSON 5000 0x082b CX4900/CX5000/DX50x0 MFP scanner
-product EPSON 6000 0x082e CX5900/CX6000/DX60x0 MFP scanner
-product EPSON DX4000 0x082f DX4000 MFP scanner
-product EPSON DX7400 0x0838 CX7300/CX7400/DX7400 MFP scanner
-product EPSON DX8400 0x0839 CX8300/CX8400/DX8400 MFP scanner
-product EPSON SX100 0x0841 SX100/NX100 MFP scanner
-product EPSON NX300 0x0848 NX300 MFP scanner
-product EPSON SX200 0x0849 SX200/SX205 MFP scanner
-product EPSON SX400 0x084a SX400/NX400/TX400 MFP scanner
-
-/* e-TEK Labs products */
-product ETEK 1COM 0x8007 Serial
-
-/* Extended Systems products */
-product EXTENDED XTNDACCESS 0x0100 XTNDAccess IrDA
-
-/* FEIYA products */
-product FEIYA 5IN1 0x1132 5-in-1 Card Reader
-
-/* Fiberline */
-product FIBERLINE WL430U 0x6003 WL-430U
-
-/* Fossil, Inc products */
-product FOSSIL WRISTPDA 0x0002 Wrist PDA
-
-/* Freecom products */
-product FREECOM DVD 0xfc01 DVD drive
-
-/* Fujitsu Siemens Computers products */
-product FSC E5400 0x1009 PrismGT USB 2.0 WLAN
-
-/* Future Technology Devices products */
-product FTDI SERIAL_8U100AX 0x8372 8U100AX Serial
-product FTDI SERIAL_8U232AM 0x6001 8U232AM Serial
-product FTDI SERIAL_2232C 0x6010 FT2232C Dual port Serial
-/* Gude Analog- und Digitalsysteme products also uses FTDI's id: */
-product FTDI TACTRIX_OPENPORT_13M 0xcc48 OpenPort 1.3 Mitsubishi
-product FTDI TACTRIX_OPENPORT_13S 0xcc49 OpenPort 1.3 Subaru
-product FTDI TACTRIX_OPENPORT_13U 0xcc4a OpenPort 1.3 Universal
-product FTDI EISCOU 0xe888 Expert ISDN Control USB
-product FTDI UOPTBR 0xe889 USB-RS232 OptoBridge
-product FTDI EMCU2D 0xe88a Expert mouseCLOCK USB II
-product FTDI PCMSFU 0xe88b Precision Clock MSF USB
-product FTDI EMCU2H 0xe88c Expert mouseCLOCK USB II HBG
-product FTDI MAXSTREAM 0xee18 Maxstream PKG-U
-product FTDI USBSERIAL 0xfa00 Matrix Orbital USB Serial
-product FTDI MX2_3 0xfa01 Matrix Orbital MX2 or MX3
-product FTDI MX4_5 0xfa02 Matrix Orbital MX4 or MX5
-product FTDI LK202 0xfa03 Matrix Orbital VK/LK202 Family
-product FTDI LK204 0xfa04 Matrix Orbital VK/LK204 Family
-product FTDI CFA_632 0xfc08 Crystalfontz CFA-632 USB LCD
-product FTDI CFA_634 0xfc09 Crystalfontz CFA-634 USB LCD
-product FTDI CFA_633 0xfc0b Crystalfontz CFA-633 USB LCD
-product FTDI CFA_631 0xfc0c Crystalfontz CFA-631 USB LCD
-product FTDI CFA_635 0xfc0d Crystalfontz CFA-635 USB LCD
-product FTDI SEMC_DSS20 0xfc82 SEMC DSS-20 SyncStation
-
-/* Fuji photo products */
-product FUJIPHOTO MASS0100 0x0100 Mass Storage
-
-/* Fujitsu protducts */
-product FUJITSU AH_F401U 0x105b AH-F401U Air H device
-
-/* Garmin products */
-product GARMIN IQUE_3600 0x0004 iQue 3600
-
-/* General Instruments (Motorola) products */
-product GENERALINSTMNTS SB5100 0x5100 SURFboard SB5100 Cable modem
-
-/* Genesys Logic products */
-product GENESYS GL620USB 0x0501 GL620USB Host-Host interface
-product GENESYS GL650 0x0604 GL650 Hub
-product GENESYS GL641USB 0x0700 GL641USB CompactFlash Card Reader
-product GENESYS GL641USB2IDE_2 0x0701 GL641USB USB-IDE Bridge No 2
-product GENESYS GL641USB2IDE 0x0702 GL641USB USB-IDE Bridge
-product GENESYS GL641USB_2 0x0760 GL641USB 6-in-1 Card Reader
-
-/* GIGABYTE products */
-product GIGABYTE GN54G 0x8001 GN-54G
-product GIGABYTE GNBR402W 0x8002 GN-BR402W
-product GIGABYTE GNWLBM101 0x8003 GN-WLBM101
-product GIGABYTE GNWBKG 0x8007 GN-WBKG
-product GIGABYTE GNWB01GS 0x8008 GN-WB01GS
-product GIGABYTE GNWI05GS 0x800a GN-WI05GS
-
-/* Gigaset products */
-product GIGASET WLAN 0x0701 WLAN
-product GIGASET SMCWUSBTG 0x0710 SMCWUSBT-G
-product GIGASET SMCWUSBTG_NF 0x0711 SMCWUSBT-G (no firmware)
-product GIGASET AR5523 0x0712 AR5523
-product GIGASET AR5523_NF 0x0713 AR5523 (no firmware)
-product GIGASET RT2573 0x0722 RT2573
-
-/* Global Sun Technology product */
-product GLOBALSUN AR5523_1 0x7801 AR5523
-product GLOBALSUN AR5523_1_NF 0x7802 AR5523 (no firmware)
-product GLOBALSUN AR5523_2 0x7811 AR5523
-product GLOBALSUN AR5523_2_NF 0x7812 AR5523 (no firmware)
-
-/* Globespan products */
-product GLOBESPAN PRISM_GT_1 0x2000 PrismGT USB 2.0 WLAN
-product GLOBESPAN PRISM_GT_2 0x2002 PrismGT USB 2.0 WLAN
-
-/* G.Mate, Inc products */
-product GMATE YP3X00 0x1001 YP3X00 PDA
-
-/* GoHubs products */
-product GOHUBS GOCOM232 0x1001 GoCOM232 Serial
-
-/* Good Way Technology products */
-product GOODWAY GWUSB2E 0x6200 GWUSB2E
-product GOODWAY RT2573 0xc019 RT2573
-
-/* Gravis products */
-product GRAVIS GAMEPADPRO 0x4001 GamePad Pro
-
-/* GREENHOUSE products */
-product GREENHOUSE KANA21 0x0001 CF-writer with MP3
-
-/* Griffin Technology */
-product GRIFFIN IMATE 0x0405 iMate, ADB Adapter
-
-/* Guillemot Corporation */
-product GUILLEMOT DALEADER 0xa300 DA Leader
-product GUILLEMOT HWGUSB254 0xe000 HWGUSB2-54 WLAN
-product GUILLEMOT HWGUSB254LB 0xe010 HWGUSB2-54-LB
-product GUILLEMOT HWGUSB254V2AP 0xe020 HWGUSB2-54V2-AP
-
-/* Hagiwara products */
-product HAGIWARA FGSM 0x0002 FlashGate SmartMedia Card Reader
-product HAGIWARA FGCF 0x0003 FlashGate CompactFlash Card Reader
-product HAGIWARA FG 0x0005 FlashGate
-
-/* HAL Corporation products */
-product HAL IMR001 0x0011 Crossam2+USB IR commander
-
-/* Handspring, Inc. */
-product HANDSPRING VISOR 0x0100 Handspring Visor
-product HANDSPRING TREO 0x0200 Handspring Treo
-product HANDSPRING TREO600 0x0300 Handspring Treo 600
-
-/* Hauppauge Computer Works */
-product HAUPPAUGE WINTV_USB_FM 0x4d12 WinTV USB FM
-
-/* Hawking Technologies products */
-product HAWKING UF100 0x400c 10/100 USB Ethernet
-
-/* Hitachi, Ltd. products */
-product HITACHI DVDCAM_DZ_MV100A 0x0004 DVD-CAM DZ-MV100A Camcorder
-product HITACHI DVDCAM_USB 0x001e DVDCAM USB HS Interface
-
-/* HP products */
-product HP 895C 0x0004 DeskJet 895C
-product HP 4100C 0x0101 Scanjet 4100C
-product HP S20 0x0102 Photosmart S20
-product HP 880C 0x0104 DeskJet 880C
-product HP 4200C 0x0105 ScanJet 4200C
-product HP CDWRITERPLUS 0x0107 CD-Writer Plus
-product HP KBDHUB 0x010c Multimedia Keyboard Hub
-product HP G55XI 0x0111 OfficeJet G55xi
-product HP HN210W 0x011c HN210W 802.11b WLAN
-product HP 49GPLUS 0x0121 49g+ graphing calculator
-product HP 6200C 0x0201 ScanJet 6200C
-product HP S20b 0x0202 PhotoSmart S20
-product HP 815C 0x0204 DeskJet 815C
-product HP 3300C 0x0205 ScanJet 3300C
-product HP CDW8200 0x0207 CD-Writer Plus 8200e
-product HP MMKEYB 0x020c Multimedia keyboard
-product HP 1220C 0x0212 DeskJet 1220C
-product HP 810C 0x0304 DeskJet 810C/812C
-product HP 4300C 0x0305 Scanjet 4300C
-product HP CDW4E 0x0307 CD-Writer+ CD-4e
-product HP G85XI 0x0311 OfficeJet G85xi
-product HP 1200 0x0317 LaserJet 1200
-product HP 5200C 0x0401 Scanjet 5200C
-product HP 830C 0x0404 DeskJet 830C
-product HP 3400CSE 0x0405 ScanJet 3400cse
-product HP 6300C 0x0601 Scanjet 6300C
-product HP 840C 0x0604 DeskJet 840c
-product HP 2200C 0x0605 ScanJet 2200C
-product HP 5300C 0x0701 Scanjet 5300C
-product HP 4400C 0x0705 Scanjet 4400C
-product HP 4470C 0x0805 Scanjet 4470C
-product HP 82x0C 0x0b01 Scanjet 82x0C
-product HP 2300D 0x0b17 Laserjet 2300d
-product HP 970CSE 0x1004 Deskjet 970Cse
-product HP 5400C 0x1005 Scanjet 5400C
-product HP 2215 0x1016 iPAQ 22xx/Jornada 548
-product HP 568J 0x1116 Jornada 568
-product HP 930C 0x1204 DeskJet 930c
-product HP P2000U 0x1801 Inkjet P-2000U
-product HP 640C 0x2004 DeskJet 640c
-product HP 4670V 0x3005 ScanJet 4670v
-product HP P1100 0x3102 Photosmart P1100
-product HP OJ4215 0x3d11 OfficeJet 4215
-product HP HN210E 0x811c Ethernet HN210E
-product HP2 C500 0x6002 PhotoSmart C500
-product HP HS2300 0x1e1d hs2300 HSDPA (aka MC8775)
-
-/* HTC products */
-product HTC WINMOBILE 0x00ce HTC USB Sync
-product HTC PPC6700MODEM 0x00cf PPC6700 Modem
-product HTC SMARTPHONE 0x0a51 SmartPhone USB Sync
-
-/* HUAWEI products */
-product HUAWEI MOBILE 0x1001 Huawei Mobile
-product HUAWEI E220 0x1003 Huawei HSDPA modem
-
-/* HUAWEI 3com products */
-product HUAWEI3COM WUB320G 0x0009 Aolynk WUB320g
-
-/* IBM Corporation */
-product IBM USBCDROMDRIVE 0x4427 USB CD-ROM Drive
-
-/* Imagination Technologies products */
-product IMAGINATION DBX1 0x2107 DBX1 DSP core
-
-/* Inside Out Networks products */
-product INSIDEOUT EDGEPORT4 0x0001 EdgePort/4 serial ports
-
-/* In-System products */
-product INSYSTEM F5U002 0x0002 Parallel printer
-product INSYSTEM ATAPI 0x0031 ATAPI Adapter
-product INSYSTEM ISD110 0x0200 IDE Adapter ISD110
-product INSYSTEM ISD105 0x0202 IDE Adapter ISD105
-product INSYSTEM USBCABLE 0x081a USB cable
-product INSYSTEM STORAGE_V2 0x5701 USB Storage Adapter V2
-
-/* Intel products */
-product INTEL EASYPC_CAMERA 0x0110 Easy PC Camera
-product INTEL TESTBOARD 0x9890 82930 test board
-
-/* Intersil products */
-product INTERSIL PRISM_GT 0x1000 PrismGT USB 2.0 WLAN
-product INTERSIL PRISM_2X 0x3642 Prism2.x or Atmel WLAN
-
-/* Interpid Control Systems products */
-product INTREPIDCS VALUECAN 0x0601 ValueCAN CAN bus interface
-product INTREPIDCS NEOVI 0x0701 NeoVI Blue vehicle bus interface
-
-/* I/O DATA products */
-product IODATA IU_CD2 0x0204 DVD Multi-plus unit iU-CD2
-product IODATA DVR_UEH8 0x0206 DVD Multi-plus unit DVR-UEH8
-product IODATA USBSSMRW 0x0314 USB-SSMRW SD-card
-product IODATA USBSDRW 0x031e USB-SDRW SD-card
-product IODATA USBETT 0x0901 USB ETT
-product IODATA USBETTX 0x0904 USB ETTX
-product IODATA USBETTXS 0x0913 USB ETTX
-product IODATA USBWNB11A 0x0919 USB WN-B11
-product IODATA USBWNB11 0x0922 USB Airport WN-B11
-product IODATA ETGUS2 0x0930 ETG-US2
-product IODATA USBRSAQ 0x0a03 Serial USB-RSAQ1
-product IODATA2 USB2SC 0x0a09 USB2.0-SCSI Bridge USB2-SC
-
-/* Iomega products */
-product IOMEGA ZIP100 0x0001 Zip 100
-product IOMEGA ZIP250 0x0030 Zip 250
-
-/* Ituner networks products */
-product ITUNERNET USBLCD2X20 0x0002 USB-LCD 2x20
-product ITUNERNET USBLCD4X20 0xc001 USB-LCD 4x20
-
-/* Jablotron products */
-product JABLOTRON PC60B 0x0001 PC-60B
-
-/* Jaton products */
-product JATON EDA 0x5704 Ethernet
-
-/* JVC products */
-product JVC GR_DX95 0x000a GR-DX95
-product JVC MP_PRX1 0x3008 MP-PRX1 Ethernet
-
-/* JRC products */
-product JRC AH_J3001V_J3002V 0x0001 AirH PHONE AH-J3001V/J3002V
-
-/* Kawatsu products */
-product KAWATSU MH4000P 0x0003 MiniHub 4000P
-
-/* Keisokugiken Corp. products */
-product KEISOKUGIKEN USBDAQ 0x0068 HKS-0200 USBDAQ
-
-/* Kensington products */
-product KENSINGTON ORBIT 0x1003 Orbit USB/PS2 trackball
-product KENSINGTON TURBOBALL 0x1005 TurboBall
-
-/* Keyspan products */
-product KEYSPAN USA28_NF 0x0101 USA-28 serial Adapter (no firmware)
-product KEYSPAN USA28X_NF 0x0102 USA-28X serial Adapter (no firmware)
-product KEYSPAN USA19_NF 0x0103 USA-19 serial Adapter (no firmware)
-product KEYSPAN USA18_NF 0x0104 USA-18 serial Adapter (no firmware)
-product KEYSPAN USA18X_NF 0x0105 USA-18X serial Adapter (no firmware)
-product KEYSPAN USA19W_NF 0x0106 USA-19W serial Adapter (no firmware)
-product KEYSPAN USA19 0x0107 USA-19 serial Adapter
-product KEYSPAN USA19W 0x0108 USA-19W serial Adapter
-product KEYSPAN USA49W_NF 0x0109 USA-49W serial Adapter (no firmware)
-product KEYSPAN USA49W 0x010a USA-49W serial Adapter
-product KEYSPAN USA19QI_NF 0x010b USA-19QI serial Adapter (no firmware)
-product KEYSPAN USA19QI 0x010c USA-19QI serial Adapter
-product KEYSPAN USA19Q_NF 0x010d USA-19Q serial Adapter (no firmware)
-product KEYSPAN USA19Q 0x010e USA-19Q serial Adapter
-product KEYSPAN USA28 0x010f USA-28 serial Adapter
-product KEYSPAN USA28XXB 0x0110 USA-28X/XB serial Adapter
-product KEYSPAN USA18 0x0111 USA-18 serial Adapter
-product KEYSPAN USA18X 0x0112 USA-18X serial Adapter
-product KEYSPAN USA28XB_NF 0x0113 USA-28XB serial Adapter (no firmware)
-product KEYSPAN USA28XA_NF 0x0114 USA-28XB serial Adapter (no firmware)
-product KEYSPAN USA28XA 0x0115 USA-28XA serial Adapter
-product KEYSPAN USA18XA_NF 0x0116 USA-18XA serial Adapter (no firmware)
-product KEYSPAN USA18XA 0x0117 USA-18XA serial Adapter
-product KEYSPAN USA19QW_NF 0x0118 USA-19WQ serial Adapter (no firmware)
-product KEYSPAN USA19QW 0x0119 USA-19WQ serial Adapter
-product KEYSPAN USA19HA 0x0121 USA-19HS serial Adapter
-product KEYSPAN UIA10 0x0201 UIA-10 remote control
-product KEYSPAN UIA11 0x0202 UIA-11 remote control
-
-/* Kingston products */
-product KINGSTON XX1 0x0008 Ethernet
-product KINGSTON KNU101TX 0x000a KNU101TX USB Ethernet
-
-/* Kawasaki products */
-product KLSI DUH3E10BT 0x0008 USB Ethernet
-product KLSI DUH3E10BTN 0x0009 USB Ethernet
-
-/* 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
-product KYE VIVIDPRO 0x2001 ColorPage Vivid-Pro scanner
-
-/* Kyocera products */
-product KYOCERA FINECAM_S3X 0x0100 Finecam S3x
-product KYOCERA FINECAM_S4 0x0101 Finecam S4
-product KYOCERA FINECAM_S5 0x0103 Finecam S5
-product KYOCERA FINECAM_L3 0x0105 Finecam L3
-product KYOCERA AHK3001V 0x0203 AH-K3001V
-product KYOCERA2 CDMA_MSM_K 0x17da Qualcomm Kyocera CDMA Technologies MSM
-
-/* LaCie products */
-product LACIE HD 0xa601 Hard Disk
-product LACIE CDRW 0xa602 CD R/W
-
-/* Lexar products */
-product LEXAR JUMPSHOT 0x0001 jumpSHOT CompactFlash Reader
-product LEXAR CF_READER 0xb002 USB CF Reader
-
-/* Lexmark products */
-product LEXMARK S2450 0x0009 Optra S 2450
-
-/* Linksys products */
-product LINKSYS MAUSB2 0x0105 Camedia MAUSB-2
-product LINKSYS USB10TX1 0x200c USB10TX
-product LINKSYS USB10T 0x2202 USB10T Ethernet
-product LINKSYS USB100TX 0x2203 USB100TX Ethernet
-product LINKSYS USB100H1 0x2204 USB100H1 Ethernet/HPNA
-product LINKSYS USB10TA 0x2206 USB10TA Ethernet
-product LINKSYS USB10TX2 0x400b USB10TX
-product LINKSYS2 WUSB11 0x2219 WUSB11 Wireless Adapter
-product LINKSYS2 USB200M 0x2226 USB 2.0 10/100 Ethernet
-product LINKSYS3 WUSB11v28 0x2233 WUSB11 v2.8 Wireless Adapter
-product LINKSYS4 USB1000 0x0039 USB1000
-
-/* Logitech products */
-product LOGITECH M2452 0x0203 M2452 keyboard
-product LOGITECH M4848 0x0301 M4848 mouse
-product LOGITECH PAGESCAN 0x040f PageScan
-product LOGITECH QUICKCAMWEB 0x0801 QuickCam Web
-product LOGITECH QUICKCAMPRO 0x0810 QuickCam Pro
-product LOGITECH QUICKCAMEXP 0x0840 QuickCam Express
-product LOGITECH QUICKCAM 0x0850 QuickCam
-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 BD58 0xc00c BD58 mouse
-product LOGITECH UN58A 0xc030 iFeel Mouse
-product LOGITECH UN53B 0xc032 iFeel MouseMan
-product LOGITECH WMPAD 0xc208 WingMan GamePad Extreme
-product LOGITECH WMRPAD 0xc20a WingMan RumblePad
-product LOGITECH WMJOY 0xc281 WingMan Force joystick
-product LOGITECH BB13 0xc401 USB-PS/2 Trackball
-product LOGITECH RK53 0xc501 Cordless mouse
-product LOGITECH RB6 0xc503 Cordless keyboard
-product LOGITECH MX700 0xc506 Cordless optical mouse
-product LOGITECH QUICKCAMPRO2 0xd001 QuickCam Pro
-
-/* Logitec Corp. products */
-product LOGITEC LDR_H443SU2 0x0033 DVD Multi-plus unit LDR-H443SU2
-product LOGITEC LDR_H443U2 0x00b3 DVD Multi-plus unit LDR-H443U2
-
-/* Lucent products */
-product LUCENT EVALKIT 0x1001 USS-720 evaluation kit
-
-/* Luwen products */
-product LUWEN EASYDISK 0x0005 EasyDisc
-
-/* Macally products */
-product MACALLY MOUSE1 0x0101 mouse
-
-/* MCT Corp. */
-product MCT HUB0100 0x0100 Hub
-product MCT DU_H3SP_USB232 0x0200 D-Link DU-H3SP USB BAY Hub
-product MCT USB232 0x0210 USB-232 Interface
-product MCT SITECOM_USB232 0x0230 Sitecom USB-232 Products
-
-/* Meizu Electronics */
-product MEIZU M6_SL 0x0140 MiniPlayer M6 (SL)
-
-/* Melco, Inc products */
-product MELCO LUATX1 0x0001 LUA-TX Ethernet
-product MELCO LUATX5 0x0005 LUA-TX Ethernet
-product MELCO LUA2TX5 0x0009 LUA2-TX Ethernet
-product MELCO LUAKTX 0x0012 LUA-KTX Ethernet
-product MELCO DUBPXXG 0x001c USB-IDE Bridge: DUB-PxxG
-product MELCO LUAU2KTX 0x003d LUA-U2-KTX Ethernet
-product MELCO KG54YB 0x005e WLI-U2-KG54-YB WLAN
-product MELCO KG54 0x0066 WLI-U2-KG54 WLAN
-product MELCO KG54AI 0x0067 WLI-U2-KG54-AI WLAN
-product MELCO NINWIFI 0x008b Nintendo Wi-Fi
-product MELCO PCOPRS1 0x00b3 PC-OP-RS1 RemoteStation
-product MELCO SG54HP 0x00d8 WLI-U2-SG54HP
-product MELCO G54HP 0x00d9 WLI-U2-G54HP
-product MELCO KG54L 0x00da WLI-U2-KG54L
-product MELCO SG54HG 0x00f4 WLI-U2-SG54HG
-
-/* Merlin products */
-product MERLIN V620 0x1110 Merlin V620
-
-/* MetaGeek products */
-product METAGEEK WISPY1B 0x083e MetaGeek Wi-Spy
-product METAGEEK WISPY24X 0x083f MetaGeek Wi-Spy 2.4x
-
-/* Metricom products */
-product METRICOM RICOCHET_GS 0x0001 Ricochet GS
-
-/* MGE UPS Systems */
-product MGE UPS1 0x0001 MGE UPS SYSTEMS PROTECTIONCENTER 1
-product MGE UPS2 0xffff MGE UPS SYSTEMS PROTECTIONCENTER 2
-
-/* Micro Star International products */
-product MSI BT_DONGLE 0x1967 Bluetooth USB dongle
-product MSI UB11B 0x6823 UB11B
-product MSI RT2570 0x6861 RT2570
-product MSI RT2570_2 0x6865 RT2570
-product MSI RT2570_3 0x6869 RT2570
-product MSI RT2573_1 0x6874 RT2573
-product MSI RT2573_2 0x6877 RT2573
-product MSI RT2573_3 0xa861 RT2573
-product MSI RT2573_4 0xa874 RT2573
-
-/* 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 INETPRO 0x001c Internet Keyboard Pro
-product MICROSOFT TBEXPLORER 0x0024 Trackball Explorer
-product MICROSOFT INTELLIEYE 0x0025 IntelliEye mouse
-product MICROSOFT INETPRO2 0x002b Internet Keyboard Pro
-product MICROSOFT MN510 0x006e MN510 Wireless
-product MICROSOFT MN110 0x007a 10/100 USB NIC
-product MICROSOFT WLINTELLIMOUSE 0x008c Wireless Optical IntelliMouse
-product MICROSOFT WLNOTEBOOK 0x00b9 Wireless Optical Mouse (Model 1023)
-product MICROSOFT COMFORT3000 0x00d1 Comfort Optical Mouse 3000 (Model 1043)
-product MICROSOFT WLNOTEBOOK2 0x00e1 Wireless Optical Mouse 3000 (Model 1056)
-product MICROSOFT WLNOTEBOOK3 0x00d2 Wireless Optical Mouse 3000 (Model 1049)
-product MICROSOFT WLUSBMOUSE 0x00b9 Wireless USB Mouse
-product MICROSOFT XBOX360 0x0292 XBOX 360 WLAN
-
-/* Microtech products */
-product MICROTECH SCSIDB25 0x0004 USB-SCSI-DB25
-product MICROTECH SCSIHD50 0x0005 USB-SCSI-HD50
-product MICROTECH DPCM 0x0006 USB CameraMate
-product MICROTECH FREECOM 0xfc01 Freecom USB-IDE
-
-/* Microtek products */
-product MICROTEK 336CX 0x0094 Phantom 336CX - C3 scanner
-product MICROTEK X6U 0x0099 ScanMaker X6 - X6U
-product MICROTEK C6 0x009a Phantom C6 scanner
-product MICROTEK 336CX2 0x00a0 Phantom 336CX - C3 scanner
-product MICROTEK V6USL 0x00a3 ScanMaker V6USL
-product MICROTEK V6USL2 0x80a3 ScanMaker V6USL
-product MICROTEK V6UL 0x80ac ScanMaker V6UL
-
-/* Microtune, Inc. products */
-product MICROTUNE BT_DONGLE 0x1000 Bluetooth USB dongle
-
-/* Midiman products */
-product MIDIMAN MIDISPORT2X2 0x1001 Midisport 2x2
-
-/* MindsAtWork products */
-product MINDSATWORK WALLET 0x0001 Digital Wallet
-
-/* Minolta Co., Ltd. */
-product MINOLTA 2300 0x4001 Dimage 2300
-product MINOLTA S304 0x4007 Dimage S304
-product MINOLTA X 0x4009 Dimage X
-product MINOLTA 5400 0x400e Dimage 5400
-product MINOLTA F300 0x4011 Dimage F300
-product MINOLTA E223 0x4017 Dimage E223
-
-/* Mitsumi products */
-product MITSUMI CDRRW 0x0000 CD-R/RW Drive
-product MITSUMI BT_DONGLE 0x641f Bluetooth USB dongle
-product MITSUMI FDD 0x6901 USB FDD
-
-/* Mobility products */
-product MOBILITY EA 0x0204 Ethernet
-product MOBILITY EASIDOCK 0x0304 EasiDock Ethernet
-
-/* MosChip products */
-product MOSCHIP MCS7703 0x7703 MCS7703 Serial Port Adapter
-product MOSCHIP MCS7830 0x7830 MCS7830 Ethernet
-
-/* Motorola products */
-product MOTOROLA MC141555 0x1555 MC141555 hub controller
-product MOTOROLA SB4100 0x4100 SB4100 USB Cable Modem
-product MOTOROLA2 A41XV32X 0x2a22 A41x/V32x Mobile Phones
-product MOTOROLA2 E398 0x4810 E398 Mobile Phone
-product MOTOROLA2 USBLAN 0x600c USBLAN
-product MOTOROLA2 USBLAN2 0x6027 USBLAN
-
-/* MultiTech products */
-product MULTITECH ATLAS 0xf101 MT5634ZBA-USB modem
-
-/* Mustek products */
-product MUSTEK 1200CU 0x0001 1200 CU scanner
-product MUSTEK 600CU 0x0002 600 CU scanner
-product MUSTEK 1200USB 0x0003 1200 USB scanner
-product MUSTEK 1200UB 0x0006 1200 UB scanner
-product MUSTEK 1200USBPLUS 0x0007 1200 USB Plus scanner
-product MUSTEK 1200CUPLUS 0x0008 1200 CU Plus scanner
-product MUSTEK BEARPAW1200F 0x0010 BearPaw 1200F scanner
-product MUSTEK BEARPAW1200TA 0x021e BearPaw 1200TA scanner
-product MUSTEK 600USB 0x0873 600 USB scanner
-product MUSTEK MDC800 0xa800 MDC-800 digital camera
-
-/* M-Systems products */
-product MSYSTEMS DISKONKEY 0x0010 DiskOnKey
-product MSYSTEMS DISKONKEY2 0x0011 DiskOnKey
-
-/* Myson products */
-product MYSON HEDEN 0x8818 USB-IDE
-product MYSON STARREADER 0x9920 USB flash card adapter
-
-/* National Semiconductor */
-product NATIONAL BEARPAW1200 0x1000 BearPaw 1200
-product NATIONAL BEARPAW2400 0x1001 BearPaw 2400
-
-/* NEC products */
-product NEC HUB 0x55aa hub
-product NEC HUB_B 0x55ab hub
-
-/* NEODIO products */
-product NEODIO ND3260 0x3260 8-in-1 Multi-format Flash Controller
-product NEODIO ND5010 0x5010 Multi-format Flash Controller
-
-/* Netac products */
-product NETAC CF_CARD 0x1060 USB-CF-Card
-product NETAC ONLYDISK 0x0003 OnlyDisk
-
-/* NetChip Technology Products */
-product NETCHIP TURBOCONNECT 0x1080 Turbo-Connect
-product NETCHIP CLIK_40 0xa140 USB Clik! 40
-product NETCHIP ETHERNETGADGET 0xa4a2 Linux Ethernet/RNDIS gadget on pxa210/25x/26x
-
-/* Netgear products */
-product NETGEAR EA101 0x1001 Ethernet
-product NETGEAR EA101X 0x1002 Ethernet
-product NETGEAR FA101 0x1020 Ethernet 10/100, USB1.1
-product NETGEAR FA120 0x1040 USB 2.0 Ethernet
-product NETGEAR WG111V2_2 0x4240 PrismGT USB 2.0 WLAN
-product NETGEAR WG111U 0x4300 WG111U
-product NETGEAR WG111U_NF 0x4301 WG111U (no firmware)
-product NETGEAR WG111V2 0x6a00 WG111V2
-product NETGEAR2 MA101 0x4100 MA101
-product NETGEAR2 MA101B 0x4102 MA101 Rev B
-product NETGEAR3 WG111T 0x4250 WG111T
-product NETGEAR3 WG111T_NF 0x4251 WG111T (no firmware)
-product NETGEAR3 WPN111 0x5f00 WPN111
-product NETGEAR3 WPN111_NF 0x5f01 WPN111 (no firmware)
-
-/* Nikon products */
-product NIKON E990 0x0102 Digital Camera E990
-product NIKON LS40 0x4000 CoolScan LS40 ED
-product NIKON D300 0x041a Digital Camera D300
-
-/* NovaTech Products */
-product NOVATECH NV902 0x9020 NovaTech NV-902W
-product NOVATECH RT2573 0x9021 RT2573
-
-/* Novatel Wireless products */
-product NOVATEL V640 0x1100 Merlin V620
-product NOVATEL CDMA_MODEM 0x1110 Novatel Wireless Merlin CDMA
-product NOVATEL V620 0x1110 Merlin V620
-product NOVATEL V740 0x1120 Merlin V740
-product NOVATEL V720 0x1130 Merlin V720
-product NOVATEL U740 0x1400 Merlin U740
-product NOVATEL U740_2 0x1410 Merlin U740
-product NOVATEL U870 0x1420 Merlin U870
-product NOVATEL XU870 0x1430 Merlin XU870
-product NOVATEL X950D 0x1450 Merlin X950D
-product NOVATEL ES620 0x2100 ES620 CDMA
-product NOVATEL U720 0x2110 Merlin U720
-product NOVATEL U727 0x4100 Merlin U727 CDMA
-product NOVATEL MC950D 0x4400 Novatel MC950D HSUPA
-product NOVATEL ZEROCD 0x5010 Novatel ZeroCD
-product NOVATEL ZEROCD2 0x5030 Novatel ZeroCD
-product NOVATEL U760 0x6000 Novatel U760
-product NOVATEL2 FLEXPACKGPS 0x0100 NovAtel FlexPack GPS receiver
-
-/* Merlin products */
-product MERLIN V620 0x1110 Merlin V620
-
-/* Olympus products */
-product OLYMPUS C1 0x0102 C-1 Digital Camera
-product OLYMPUS C700 0x0105 C-700 Ultra Zoom
-
-/* OmniVision Technologies, Inc. products */
-product OMNIVISION OV511 0x0511 OV511 Camera
-product OMNIVISION OV511PLUS 0xa511 OV511+ Camera
-
-/* OnSpec Electronic, Inc. */
-product ONSPEC SDS_HOTFIND_D 0x0400 SDS-infrared.com Hotfind-D Infrared Camera
-product ONSPEC MDCFE_B_CF_READER 0xa000 MDCFE-B USB CF Reader
-product ONSPEC CFMS_RW 0xa001 SIIG/Datafab Memory Stick+CF Reader/Writer
-product ONSPEC READER 0xa003 Datafab-based Reader
-product ONSPEC CFSM_READER 0xa005 PNY/Datafab CF+SM Reader
-product ONSPEC CFSM_READER2 0xa006 Simple Tech/Datafab CF+SM Reader
-product ONSPEC MDSM_B_READER 0xa103 MDSM-B reader
-product ONSPEC CFSM_COMBO 0xa109 USB to CF + SM Combo (LC1)
-product ONSPEC UCF100 0xa400 FlashLink UCF-100 CompactFlash Reader
-product ONSPEC2 IMAGEMATE_SDDR55 0xa103 ImageMate SDDR55
-
-/* Option products */
-product OPTION VODAFONEMC3G 0x5000 Vodafone Mobile Connect 3G datacard
-product OPTION GT3G 0x6000 GlobeTrotter 3G datacard
-product OPTION GT3GQUAD 0x6300 GlobeTrotter 3G QUAD datacard
-product OPTION GT3GPLUS 0x6600 GlobeTrotter 3G+ datacard
-product OPTION GTICON322 0xd033 GlobeTrotter Icon322 storage
-product OPTION GTMAX36 0x6701 GlobeTrotter Max 3.6 Modem
-product OPTION GTMAXHSUPA 0x7001 GlobeTrotter HSUPA
-
-/* OQO */
-product OQO WIFI01 0x0002 model 01 WiFi interface
-product OQO BT01 0x0003 model 01 Bluetooth interface
-product OQO ETHER01PLUS 0x7720 model 01+ Ethernet
-product OQO ETHER01 0x8150 model 01 Ethernet interface
-
-/* Palm Computing, Inc. product */
-product PALM SERIAL 0x0080 USB Serial
-product PALM M500 0x0001 Palm m500
-product PALM M505 0x0002 Palm m505
-product PALM M515 0x0003 Palm m515
-product PALM I705 0x0020 Palm i705
-product PALM TUNGSTEN_Z 0x0031 Palm Tungsten Z
-product PALM M125 0x0040 Palm m125
-product PALM M130 0x0050 Palm m130
-product PALM TUNGSTEN_T 0x0060 Palm Tungsten T
-product PALM ZIRE31 0x0061 Palm Zire 31
-product PALM ZIRE 0x0070 Palm Zire
-
-/* Panasonic products */
-product PANASONIC LS120CAM 0x0901 LS-120 Camera
-product PANASONIC KXL840AN 0x0d01 CD-R Drive KXL-840AN
-product PANASONIC KXLRW32AN 0x0d09 CD-R Drive KXL-RW32AN
-product PANASONIC KXLCB20AN 0x0d0a CD-R Drive KXL-CB20AN
-product PANASONIC KXLCB35AN 0x0d0e DVD-ROM & CD-R/RW
-product PANASONIC SDCAAE 0x1b00 MultiMediaCard
-
-/* Peracom products */
-product PERACOM SERIAL1 0x0001 Serial
-product PERACOM ENET 0x0002 Ethernet
-product PERACOM ENET3 0x0003 At Home Ethernet
-product PERACOM ENET2 0x0005 Ethernet
-
-/* 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 PCA646VC 0x0303 PCA646VC PC Camera
-product PHILIPS PCVC680K 0x0308 PCVC680K Vesta Pro PC Camera
-product PHILIPS DSS150 0x0471 DSS 150 Digital Speaker System
-product PHILIPS SNU5600 0x1236 SNU5600
-product PHILIPS UM10016 0x1552 ISP 1581 Hi-Speed USB MPEG2 Encoder Reference Kit
-product PHILIPS DIVAUSB 0x1801 DIVA USB mp3 player
-
-/* Philips Semiconductor products */
-product PHILIPSSEMI HUB1122 0x1122 hub
-
-/* P.I. Engineering products */
-product PIENGINEERING PS2USB 0x020b PS2 to Mac USB Adapter
-
-/* Planex Communications products */
-product PLANEX GW_US11H 0x14ea GW-US11H WLAN
-product PLANEX2 GW_US11S 0x3220 GW-US11S WLAN
-product PLANEX2 GW_US54GXS 0x5303 GW-US54GXS WLAN
-product PLANEX2 GWUS54HP 0xab01 GW-US54HP
-product PLANEX2 GWUS54MINI2 0xab50 GW-US54Mini2
-product PLANEX2 GWUS54SG 0xc002 GW-US54SG
-product PLANEX2 GWUS54GZL 0xc007 GW-US54GZL
-product PLANEX2 GWUS54GD 0xed01 GW-US54GD
-product PLANEX2 GWUSMM 0xed02 GW-USMM
-product PLANEX3 GWUS54GZ 0xab10 GW-US54GZ
-product PLANEX3 GU1000T 0xab11 GU-1000T
-product PLANEX3 GWUS54MINI 0xab13 GW-US54Mini
-
-/* Plextor Corp. */
-product PLEXTOR 40_12_40U 0x0011 PlexWriter 40/12/40U
-
-/* PLX products */
-product PLX TESTBOARD 0x9060 test board
-
-/* PNY products */
-product PNY ATTACHE2 0x0010 USB 2.0 Flash Drive
-
-/* PortGear products */
-product PORTGEAR EA8 0x0008 Ethernet
-product PORTGEAR EA9 0x0009 Ethernet
-
-/* Portsmith products */
-product PORTSMITH EEA 0x3003 Express Ethernet
-
-/* Primax products */
-product PRIMAX G2X300 0x0300 G2-200 scanner
-product PRIMAX G2E300 0x0301 G2E-300 scanner
-product PRIMAX G2300 0x0302 G2-300 scanner
-product PRIMAX G2E3002 0x0303 G2E-300 scanner
-product PRIMAX 9600 0x0340 Colorado USB 9600 scanner
-product PRIMAX 600U 0x0341 Colorado 600u scanner
-product PRIMAX 6200 0x0345 Visioneer 6200 scanner
-product PRIMAX 19200 0x0360 Colorado USB 19200 scanner
-product PRIMAX 1200U 0x0361 Colorado 1200u scanner
-product PRIMAX G600 0x0380 G2-600 scanner
-product PRIMAX 636I 0x0381 ReadyScan 636i
-product PRIMAX G2600 0x0382 G2-600 scanner
-product PRIMAX G2E600 0x0383 G2E-600 scanner
-product PRIMAX COMFORT 0x4d01 Comfort
-product PRIMAX MOUSEINABOX 0x4d02 Mouse-in-a-Box
-product PRIMAX PCGAUMS1 0x4d04 Sony PCGA-UMS1
-
-/* Prolific products */
-product PROLIFIC PL2301 0x0000 PL2301 Host-Host interface
-product PROLIFIC PL2302 0x0001 PL2302 Host-Host interface
-product PROLIFIC RSAQ2 0x04bb PL2303 Serial (IODATA USB-RSAQ2)
-product PROLIFIC PL2303 0x2303 PL2303 Serial (ATEN/IOGEAR UC232A)
-product PROLIFIC PL2305 0x2305 Parallel printer
-product PROLIFIC ATAPI4 0x2307 ATAPI-4 Controller
-product PROLIFIC PL2501 0x2501 PL2501 Host-Host interface
-product PROLIFIC PHAROS 0xaaa0 Prolific Pharos
-product PROLIFIC RSAQ3 0xaaa2 PL2303 Serial Adapter (IODATA USB-RSAQ3)
-product PROLIFIC2 WSIM 0x2001 Willcom WSIM
-
-/* Putercom products */
-product PUTERCOM UPA100 0x047e USB-1284 BRIDGE
-
-/* Qcom products */
-product QCOM RT2573 0x6196 RT2573
-product QCOM RT2573_2 0x6229 RT2573
-
-/* Qualcomm products */
-product QUALCOMM CDMA_MSM 0x6000 CDMA Technologies MSM phone
-product QUALCOMM2 RWT_FCT 0x3100 RWT FCT-CDMA 2000 1xRTT modem
-product QUALCOMM2 CDMA_MSM 0x3196 CDMA Technologies MSM modem
-product QUALCOMMINC CDMA_MSM 0x0001 CDMA Technologies MSM modem
-product QUALCOMMINC ZTE_STOR 0x2000 USB ZTE Storage
-product QUALCOMMINC AC8700 0xfffe CDMA 1xEVDO USB modem
-
-/* Qtronix products */
-product QTRONIX 980N 0x2011 Scorpion-980N keyboard
-
-/* Quickshot products */
-product QUICKSHOT STRIKEPAD 0x6238 USB StrikePad
-
-/* Radio Shack */
-product RADIOSHACK USBCABLE 0x4026 USB to Serial Cable
-
-/* Rainbow Technologies products */
-product RAINBOW IKEY2000 0x1200 i-Key 2000
-
-/* Ralink Technology products */
-product RALINK RT2570 0x1706 RT2500USB Wireless Adapter
-product RALINK RT2570_2 0x2570 RT2500USB Wireless Adapter
-product RALINK RT2573 0x2573 RT2501USB Wireless Adapter
-product RALINK RT2671 0x2671 RT2601USB Wireless Adapter
-product RALINK RT2570_3 0x9020 RT2500USB Wireless Adapter
-product RALINK RT2573_2 0x9021 RT2501USB Wireless Adapter
-
-/* ReakTek products */
-/* Green House and CompUSA OEM this part */
-product REALTEK USBKR100 0x8150 USBKR100 USB Ethernet
-product REALTEK RTL8187 0x8187 RTL8187 Wireless Adapter
-
-/* Ricoh products */
-product RICOH VGPVCC2 0x1830 VGP-VCC2 Camera
-product RICOH VGPVCC3 0x1832 VGP-VCC3 Camera
-product RICOH VGPVCC2_2 0x1833 VGP-VCC2 Camera
-product RICOH VGPVCC2_3 0x1834 VGP-VCC2 Camera
-product RICOH VGPVCC7 0x183a VGP-VCC7 Camera
-product RICOH VGPVCC8 0x183b VGP-VCC8 Camera
-
-/* Roland products */
-product ROLAND UM1 0x0009 UM-1 MIDI I/F
-product ROLAND UM880N 0x0014 EDIROL UM-880 MIDI I/F (native)
-product ROLAND UM880G 0x0015 EDIROL UM-880 MIDI I/F (generic)
-
-/* Rockfire products */
-product ROCKFIRE GAMEPAD 0x2033 gamepad 203USB
-
-/* RATOC Systems products */
-product RATOC REXUSB60 0xb000 REX-USB60
-
-/* Sagem products */
-product SAGEM USBSERIAL 0x0027 USB-Serial Controller
-product SAGEM XG760A 0x004a XG-760A
-product SAGEM XG76NA 0x0062 XG-76NA
-
-/* Samsung products */
-product SAMSUNG ML6060 0x3008 ML-6060 laser printer
-product SAMSUNG YP_U2 0x5050 YP-U2 MP3 Player
-product SAMSUNG I500 0x6601 I500 Palm USB Phone
-
-/* Samsung Techwin products */
-product SAMSUNG_TECHWIN DIGIMAX_410 0x000a Digimax 410
-
-/* SanDisk products */
-product SANDISK SDDR05A 0x0001 ImageMate SDDR-05a
-product SANDISK SDDR31 0x0002 ImageMate SDDR-31
-product SANDISK SDDR05 0x0005 ImageMate SDDR-05
-product SANDISK SDDR12 0x0100 ImageMate SDDR-12
-product SANDISK SDDR09 0x0200 ImageMate SDDR-09
-product SANDISK SDDR75 0x0810 ImageMate SDDR-75
-product SANDISK SDCZ2_256 0x7104 Cruzer Mini 256MB
-product SANDISK SDCZ4_128 0x7112 Cruzer Micro 128MB
-product SANDISK SDCZ4_256 0x7113 Cruzer Micro 256MB
-
-/* Sanyo Electric products */
-product SANYO SCP4900 0x0701 Sanyo SCP-4900 USB Phone
-
-/* ScanLogic products */
-product SCANLOGIC SL11R 0x0002 SL11R IDE Adapter
-product SCANLOGIC 336CX 0x0300 Phantom 336CX - C3 scanner
-
-/* Senao products */
-product SENAO NUB8301 0x2000 NUB-8301
-
-/* ShanTou products */
-product SHANTOU ST268 0x0268 ST268
-product SHANTOU DM9601 0x9601 DM 9601
-
-/* Shark products */
-product SHARK PA 0x0400 Pocket Adapter
-
-/* Sharp products */
-product SHARP SL5500 0x8004 Zaurus SL-5500 PDA
-product SHARP SLA300 0x8005 Zaurus SL-A300 PDA
-product SHARP SL5600 0x8006 Zaurus SL-5600 PDA
-product SHARP SLC700 0x8007 Zaurus SL-C700 PDA
-product SHARP SLC750 0x9031 Zaurus SL-C750 PDA
-product SHARP WZERO3ES 0x9123 W-ZERO3 ES Smartphone
-
-/* Shuttle Technology products */
-product SHUTTLE EUSB 0x0001 E-USB Bridge
-product SHUTTLE EUSCSI 0x0002 eUSCSI Bridge
-product SHUTTLE SDDR09 0x0003 ImageMate SDDR09
-product SHUTTLE EUSBCFSM 0x0005 eUSB SmartMedia / CompactFlash Adapter
-product SHUTTLE ZIOMMC 0x0006 eUSB MultiMediaCard Adapter
-product SHUTTLE HIFD 0x0007 Sony Hifd
-product SHUTTLE EUSBATAPI 0x0009 eUSB ATA/ATAPI Adapter
-product SHUTTLE CF 0x000a eUSB CompactFlash Adapter
-product SHUTTLE EUSCSI_B 0x000b eUSCSI Bridge
-product SHUTTLE EUSCSI_C 0x000c eUSCSI Bridge
-product SHUTTLE CDRW 0x0101 CD-RW Device
-product SHUTTLE EUSBORCA 0x0325 eUSB ORCA Quad Reader
-
-/* Siemens products */
-product SIEMENS SPEEDSTREAM 0x1001 SpeedStream
-product SIEMENS SPEEDSTREAM22 0x1022 SpeedStream 1022
-product SIEMENS2 WLL013 0x001b WLL013
-product SIEMENS2 ES75 0x0034 GSM module MC35
-product SIEMENS2 WL54G 0x3c06 54g USB Network Adapter
-product SIEMENS3 SX1 0x0001 SX1
-product SIEMENS3 X65 0x0003 X65
-product SIEMENS3 X75 0x0004 X75
-
-/* Sierra Wireless products */
-product SIERRA AIRCARD580 0x0112 Sierra Wireless AirCard 580
-product SIERRA AIRCARD595 0x0019 Sierra Wireless AirCard 595
-product SIERRA AC595U 0x0120 Sierra Wireless AirCard 595U
-product SIERRA AC597E 0x0021 Sierra Wireless AirCard 597E
-product SIERRA C597 0x0023 Sierra Wireless Compass 597
-product SIERRA AC875 0x6820 Sierra Wireless AirCard 875
-product SIERRA AC880 0x6850 Sierra Wireless AirCard 880
-product SIERRA AC881 0x6851 Sierra Wireless AirCard 881
-product SIERRA AC880E 0x6852 Sierra Wireless AirCard 880E
-product SIERRA AC881E 0x6853 Sierra Wireless AirCard 881E
-product SIERRA AC880U 0x6855 Sierra Wireless AirCard 880U
-product SIERRA AC881U 0x6856 Sierra Wireless AirCard 881U
-product SIERRA AC885U 0x6880 Sierra Wireless AirCard 885U
-product SIERRA EM5625 0x0017 EM5625
-product SIERRA MC5720 0x0218 MC5720 Wireless Modem
-product SIERRA MC5720_2 0x0018 MC5720
-product SIERRA MC5725 0x0020 MC5725
-product SIERRA MINI5725 0x0220 Sierra Wireless miniPCI 5275
-product SIERRA MC8755_2 0x6802 MC8755
-product SIERRA MC8765 0x6803 MC8765
-product SIERRA MC8755 0x6804 MC8755
-product SIERRA AC875U 0x6812 AC875U HSDPA USB Modem
-product SIERRA MC8755_3 0x6813 MC8755 HSDPA
-product SIERRA MC8775_2 0x6815 MC8775
-product SIERRA AIRCARD875 0x6820 Aircard 875 HSDPA
-product SIERRA MC8780 0x6832 MC8780
-product SIERRA MC8781 0x6833 MC8781
-product SIERRA TRUINSTALL 0x0fff Aircard Tru Installer
-
-/* Sigmatel products */
-product SIGMATEL I_BEAD100 0x8008 i-Bead 100 MP3 Player
-
-/* SIIG products */
-/* Also: Omnidirectional Control Technology products */
-product SIIG DIGIFILMREADER 0x0004 DigiFilm-Combo Reader
-product SIIG WINTERREADER 0x0330 WINTERREADER Reader
-product SIIG2 USBTOETHER 0x0109 USB TO Ethernet
-product SIIG2 US2308 0x0421 Serial
-
-/* Silicom products */
-product SILICOM U2E 0x0001 U2E
-product SILICOM GPE 0x0002 Psion Gold Port Ethernet
-
-/* SI Labs */
-product SILABS POLOLU 0x803b Pololu Serial
-product SILABS ARGUSISP 0x8066 Argussoft ISP
-product SILABS CRUMB128 0x807a Crumb128 board
-product SILABS DEGREE 0x80ca Degree Controls Inc
-product SILABS TRAQMATE 0x80ed Track Systems Traqmate
-product SILABS SUUNTO 0x80f6 Suunto Sports Instrument
-product SILABS BURNSIDE 0x813d Burnside Telecon Deskmobile
-product SILABS HELICOM 0x815e Helicomm IP-Link 1220-DVM
-product SILABS CP2102 0xea60 SILABS USB UART
-product SILABS LIPOWSKY_JTAG 0x81c8 Lipowsky Baby-JTAG
-product SILABS LIPOWSKY_LIN 0x81e2 Lipowsky Baby-LIN
-product SILABS LIPOWSKY_HARP 0x8218 Lipowsky HARP-1
-product SILABS CP2102 0xea60 SILABS USB UARTa
-product SILABS CP210X_2 0xea61 CP210x Serial
-product SILABS2 DCU11CLONE 0xaa26 DCU-11 clone
-
-/* Silicon Portals Inc. */
-product SILICONPORTALS YAPPH_NF 0x0200 YAP Phone (no firmware)
-product SILICONPORTALS YAPPHONE 0x0201 YAP Phone
-
-/* Sirius Technologies products */
-product SIRIUS ROADSTER 0x0001 NetComm Roadster II 56 USB
-
-/* Sitecom products */
-product SITECOM LN029 0x182d USB 2.0 Ethernet
-product SITECOM SERIAL 0x2068 USB to serial cable (v2)
-product SITECOM2 WL022 0x182d WL-022
-
-/* Sitecom Europe products */
-product SITECOMEU LN028 0x061c LN-028
-product SITECOMEU WL113 0x9071 WL-113
-product SITECOMEU ZD1211B 0x9075 ZD1211B
-product SITECOMEU WL172 0x90ac WL-172
-product SITECOMEU WL113R2 0x9712 WL-113 rev 2
-
-/* Skanhex Technology products */
-product SKANHEX MD_7425 0x410a MD 7425 Camera
-product SKANHEX SX_520Z 0x5200 SX 520z Camera
-
-/* SmartBridges products */
-product SMARTBRIDGES SMARTLINK 0x0001 SmartLink USB Ethernet
-product SMARTBRIDGES SMARTNIC 0x0003 smartNIC 2 PnP Ethernet
-
-/* SMC products */
-product SMC 2102USB 0x0100 10Mbps Ethernet
-product SMC 2202USB 0x0200 10/100 Ethernet
-product SMC 2206USB 0x0201 EZ Connect USB Ethernet
-product SMC 2862WG 0xee13 EZ Connect Wireless Adapter
-product SMC2 2020HUB 0x2020 USB Hub
-product SMC3 2662WUSB 0xa002 2662W-AR Wireless
-
-/* SOHOware products */
-product SOHOWARE NUB100 0x9100 10/100 USB Ethernet
-product SOHOWARE NUB110 0x9110 10/100 USB Ethernet
-
-/* SOLID YEAR products */
-product SOLIDYEAR KEYBOARD 0x2101 Solid Year USB keyboard
-
-/* SONY products */
-product SONY DSC 0x0010 DSC cameras
-product SONY MS_NW_MS7 0x0025 Memorystick NW-MS7
-product SONY PORTABLE_HDD_V2 0x002b Portable USB Harddrive V2
-product SONY MSACUS1 0x002d Memorystick MSAC-US1
-product SONY HANDYCAM 0x002e Handycam
-product SONY MSC 0x0032 MSC memory stick slot
-product SONY CLIE_35 0x0038 Sony Clie v3.5
-product SONY MS_PEG_N760C 0x0058 PEG N760c Memorystick
-product SONY CLIE_40 0x0066 Sony Clie v4.0
-product SONY MS_MSC_U03 0x0069 Memorystick MSC-U03
-product SONY CLIE_40_MS 0x006d Sony Clie v4.0 Memory Stick slot
-product SONY CLIE_S360 0x0095 Sony Clie s360
-product SONY CLIE_41_MS 0x0099 Sony Clie v4.1 Memory Stick slot
-product SONY CLIE_41 0x009a Sony Clie v4.1
-product SONY CLIE_NX60 0x00da Sony Clie nx60
-product SONY CLIE_TH55 0x0144 Sony Clie th55
-product SONY CLIE_TJ37 0x0169 Sony Clie tj37
-product SONY RF_RECEIVER 0x01db Sony RF mouse/kbd Receiver VGP-WRC1
-
-/* Sony Ericsson products */
-product SONYERICSSON DCU10 0x0528 USB Cable
-
-/* SOURCENEXT products */
-product SOURCENEXT KEIKAI8 0x039f KeikaiDenwa 8
-product SOURCENEXT KEIKAI8_CHG 0x012e KeikaiDenwa 8 with charger
-
-/* SparkLAN products */
-product SPARKLAN RT2573 0x0004 RT2573
-
-/* Sphairon Access Systems GmbH products */
-product SPHAIRON UB801R 0x0110 UB801R
-
-/* Stelera Wireless products */
-product STELERA ZEROCD 0x1000 Zerocd Installer
-product STELERA C105 0x1002 Stelera/Bandrish C105 USB
-
-/* STMicroelectronics products */
-product STMICRO BIOCPU 0x2016 Biometric Coprocessor
-product STMICRO COMMUNICATOR 0x7554 USB Communicator
-
-/* STSN products */
-product STSN STSN0001 0x0001 Internet Access Device
-
-/* SUN Corporation products */
-product SUNTAC DS96L 0x0003 SUNTAC U-Cable type D2
-product SUNTAC PS64P1 0x0005 SUNTAC U-Cable type P1
-product SUNTAC VS10U 0x0009 SUNTAC Slipper U
-product SUNTAC IS96U 0x000a SUNTAC Ir-Trinity
-product SUNTAC AS64LX 0x000b SUNTAC U-Cable type A3
-product SUNTAC AS144L4 0x0011 SUNTAC U-Cable type A4
-
-/* Sun Microsystems products */
-product SUN KEYBOARD 0x0005 Type 6 USB keyboard
-/* XXX The above is a North American PC style keyboard possibly */
-product SUN MOUSE 0x0100 Type 6 USB mouse
-
-/* Supra products */
-product DIAMOND2 SUPRAEXPRESS56K 0x07da Supra Express 56K modem
-product DIAMOND2 SUPRA2890 0x0b4a SupraMax 2890 56K Modem
-product DIAMOND2 RIO600USB 0x5001 Rio 600 USB
-product DIAMOND2 RIO800USB 0x5002 Rio 800 USB
-
-/* Surecom Technology products */
-product SURECOM RT2570 0x11f3 RT2570
-product SURECOM RT2573 0x31f3 RT2573
-
-/* Sweex products */
-product SWEEX ZD1211 0x1809 ZD1211
-
-/* System TALKS, Inc. */
-product SYSTEMTALKS SGCX2UL 0x1920 SGC-X2UL
-
-/* Tapwave products */
-product TAPWAVE ZODIAC 0x0100 Zodiac
-
-/* Taugagreining products */
-product TAUGA CAMERAMATE 0x0005 CameraMate (DPCM_USB)
-
-/* TDK products */
-product TDK UPA9664 0x0115 USB-PDC Adapter UPA9664
-product TDK UCA1464 0x0116 USB-cdmaOne Adapter UCA1464
-product TDK UHA6400 0x0117 USB-PHS Adapter UHA6400
-product TDK UPA6400 0x0118 USB-PHS Adapter UPA6400
-product TDK BT_DONGLE 0x0309 Bluetooth USB dongle
-
-/* TEAC products */
-product TEAC FD05PUB 0x0000 FD-05PUB floppy
-
-/* Tekram Technology products */
-product TEKRAM QUICKWLAN 0x1630 QuickWLAN
-product TEKRAM ZD1211_1 0x5630 ZD1211
-product TEKRAM ZD1211_2 0x6630 ZD1211
-
-/* Telex Communications products */
-product TELEX MIC1 0x0001 Enhanced USB Microphone
-
-/* Ten X Technology, Inc. */
-product TENX UAUDIO0 0xf211 USB audio headset
-
-/* Texas Intel products */
-product TI UTUSB41 0x1446 UT-USB41 hub
-product TI TUSB2046 0x2046 TUSB2046 hub
-
-/* Thrustmaster products */
-product THRUST FUSION_PAD 0xa0a3 Fusion Digital Gamepad
-
-/* Topre Corporation products */
-product TOPRE HHKB 0x0100 HHKB Professional
-
-/* Toshiba Corporation products */
-product TOSHIBA POCKETPC_E740 0x0706 PocketPC e740
-
-/* Trek Technology products */
-product TREK THUMBDRIVE 0x1111 ThumbDrive
-product TREK MEMKEY 0x8888 IBM USB Memory Key
-product TREK THUMBDRIVE_8MB 0x9988 ThumbDrive_8MB
-
-/* Tripp-Lite products */
-product TRIPPLITE U209 0x2008 Serial
-
-/* Trumpion products */
-product TRUMPION T33520 0x1001 T33520 USB Flash Card Controller
-product TRUMPION C3310 0x1100 Comotron C3310 MP3 player
-product TRUMPION MP3 0x1200 MP3 player
-
-/* TwinMOS */
-product TWINMOS G240 0xa006 G240
-product TWINMOS MDIV 0x1325 Memory Disk IV
-
-/* Ubiquam products */
-product UBIQUAM UALL 0x3100 CDMA 1xRTT USB Modem (U-100/105/200/300/520)
-
-/* Ultima products */
-product ULTIMA 1200UBPLUS 0x4002 1200 UB Plus scanner
-
-/* UMAX products */
-product UMAX ASTRA1236U 0x0002 Astra 1236U Scanner
-product UMAX ASTRA1220U 0x0010 Astra 1220U Scanner
-product UMAX ASTRA2000U 0x0030 Astra 2000U Scanner
-product UMAX ASTRA2100U 0x0130 Astra 2100U Scanner
-product UMAX ASTRA2200U 0x0230 Astra 2200U Scanner
-product UMAX ASTRA3400 0x0060 Astra 3400 Scanner
-
-/* U-MEDIA Communications products */
-product UMEDIA TEW444UBEU 0x3006 TEW-444UB EU
-product UMEDIA TEW444UBEU_NF 0x3007 TEW-444UB EU (no firmware)
-product UMEDIA TEW429UB_A 0x300a TEW-429UB_A
-product UMEDIA TEW429UB 0x300b TEW-429UB
-product UMEDIA TEW429UBC1 0x300d TEW-429UB C1
-product UMEDIA ALL0298V2 0x3204 ALL0298 v2
-product UMEDIA AR5523_2 0x3205 AR5523
-product UMEDIA AR5523_2_NF 0x3206 AR5523 (no firmware)
-
-/* Universal Access products */
-product UNIACCESS PANACHE 0x0101 Panache Surf USB ISDN Adapter
-
-/* U.S. Robotics products */
-product USR USR5423 0x0121 USR5423 WLAN
-
-/* VIA Technologies products */
-product VIA USB2IDEBRIDGE 0x6204 USB 2.0 IDE Bridge
-
-/* USI products */
-product USI MC60 0x10c5 MC60 Serial
-
-/* VidzMedia products */
-product VIDZMEDIA MONSTERTV 0x4fb1 MonsterTV P2H
-
-/* Vision products */
-product VISION VC6452V002 0x0002 CPiA Camera
-
-/* Visioneer products */
-product VISIONEER 7600 0x0211 OneTouch 7600
-product VISIONEER 5300 0x0221 OneTouch 5300
-product VISIONEER 3000 0x0224 Scanport 3000
-product VISIONEER 6100 0x0231 OneTouch 6100
-product VISIONEER 6200 0x0311 OneTouch 6200
-product VISIONEER 8100 0x0321 OneTouch 8100
-product VISIONEER 8600 0x0331 OneTouch 8600
-
-/* Vivitar products */
-product VIVITAR 35XX 0x0003 Vivicam 35Xx
-
-/* VTech products */
-product VTECH RT2570 0x3012 RT2570
-product VTECH ZD1211B 0x3014 ZD1211B
-
-/* Wacom products */
-product WACOM CT0405U 0x0000 CT-0405-U Tablet
-product WACOM GRAPHIRE 0x0010 Graphire
-product WACOM GRAPHIRE3_4X5 0x0013 Graphire 3 4x5
-product WACOM INTUOSA5 0x0021 Intuos A5
-product WACOM GD0912U 0x0022 Intuos 9x12 Graphics Tablet
-/* WCH products*/
-product WCH CH341SER 0x5523 CH341/CH340 USB-Serial Bridge
-/* Western Digital products */
-product WESTERN COMBO 0x0200 Firewire USB Combo
-product WESTERN EXTHDD 0x0400 External HDD
-product WESTERN HUB 0x0500 USB HUB
-product WESTERN MYBOOK 0x0901 MyBook External HDD
-
-/* Windbond Electronics */
-product WINBOND UH104 0x5518 4-port USB Hub
-
-/* WinMaxGroup products */
-product WINMAXGROUP FLASH64MC 0x6660 USB Flash Disk 64M-C
-
-/* Wistron NeWeb products */
-product WISTRONNEWEB UR045G 0x0427 PrismGT USB 2.0 WLAN
-product WISTRONNEWEB UR055G 0x0711 UR055G
-product WISTRONNEWEB AR5523_1 0x0826 AR5523
-product WISTRONNEWEB AR5523_1_NF 0x0827 AR5523 (no firmware)
-product WISTRONNEWEB AR5523_2 0x082a AR5523
-product WISTRONNEWEB AR5523_2_NF 0x0829 AR5523 (no firmware)
-
-/* Xerox products */
-product XEROX WCM15 0xffef WorkCenter M15
-
-/* Xirlink products */
-product XIRLINK PCCAM 0x8080 IBM PC Camera
-
-/* Xyratex products */
-product XYRATEX PRISM_GT_1 0x2000 PrismGT USB 2.0 WLAN
-product XYRATEX PRISM_GT_2 0x2002 PrismGT USB 2.0 WLAN
-
-/* Y-E Data products */
-product YEDATA FLASHBUSTERU 0x0000 Flashbuster-U
-
-/* Yamaha products */
-product YAMAHA UX256 0x1000 UX256 MIDI I/F
-product YAMAHA UX96 0x1008 UX96 MIDI I/F
-product YAMAHA RTA54I 0x4000 NetVolante RTA54i Broadband&ISDN Router
-product YAMAHA RTA55I 0x4004 NetVolante RTA55i Broadband VoIP Router
-product YAMAHA RTW65B 0x4001 NetVolante RTW65b Broadband Wireless Router
-product YAMAHA RTW65I 0x4002 NetVolante RTW65i Broadband&ISDN Wireless Router
-
-/* Yano products */
-product YANO U640MO 0x0101 U640MO-03
-product YANO FW800HD 0x05fc METALWEAR-HDD
-
-/* Yiso Wireless Co. products */
-product YISO C893 0xc893 CDMA 2000 1xEVDO PC Card
-
-/* Z-Com products */
-product ZCOM M4Y750 0x0001 M4Y-750
-product ZCOM XI725 0x0002 XI-725/726
-product ZCOM XI735 0x0005 XI-735
-product ZCOM XG703A 0x0008 PrismGT USB 2.0 WLAN
-product ZCOM ZD1211 0x0011 ZD1211
-product ZCOM AR5523 0x0012 AR5523
-product ZCOM AR5523_NF 0x0013 AR5523 driver (no firmware)
-product ZCOM ZD1211B 0x001a ZD1211B
-
-/* Zinwell products */
-product ZINWELL RT2570 0x0260 RT2570
-
-/* Zoom Telephonics, Inc. products */
-product ZOOM 2986L 0x9700 2986L Fax modem
-
-/* Zoran Microelectronics products */
-product ZORAN EX20DSC 0x4343 Digital Camera EX-20 DSC
-
-/* Zydas Technology Corporation products */
-product ZYDAS ZD1211 0x1211 ZD1211 WLAN abg
-product ZYDAS ZD1211B 0x1215 ZD1211B
-
-/* ZyXEL Communication Co. products */
-product ZYXEL OMNI56K 0x1500 Omni 56K Plus
-product ZYXEL 980N 0x2011 Scorpion-980N keyboard
-product ZYXEL ZYAIRG220 0x3401 ZyAIR G-220
-product ZYXEL G200V2 0x3407 G-200 v2
-product ZYXEL AG225H 0x3409 AG-225H
-product ZYXEL M202 0x340a M-202
-product ZYXEL G220V2 0x340f G-220 v2
-product ZYXEL G202 0x3410 G-202
diff --git a/sys/dev/usb/usbdi.c b/sys/dev/usb/usbdi.c
deleted file mode 100644
index a733bbf..0000000
--- a/sys/dev/usb/usbdi.c
+++ /dev/null
@@ -1,1383 +0,0 @@
-/* $NetBSD: usbdi.c,v 1.106 2004/10/24 12:52:40 augustss Exp $ */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) 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.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include "usb_if.h"
-#if defined(DIAGNOSTIC) && defined(__i386__)
-#include <machine/cpu.h>
-#endif
-#include <sys/malloc.h>
-#include <sys/proc.h>
-
-#include <machine/bus.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include <dev/usb/usbdivar.h>
-#include <dev/usb/usb_mem.h>
-#include <dev/usb/usb_quirks.h>
-
-#include "usb_if.h"
-#define delay(d) DELAY(d)
-
-#ifdef USB_DEBUG
-#define DPRINTF(x) if (usbdebug) printf x
-#define DPRINTFN(n,x) if (usbdebug>(n)) printf x
-extern int usbdebug;
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-static usbd_status usbd_ar_pipe(usbd_pipe_handle pipe);
-static void usbd_do_request_async_cb
- (usbd_xfer_handle, usbd_private_handle, usbd_status);
-static void usbd_start_next(usbd_pipe_handle pipe);
-static usbd_status usbd_open_pipe_ival
- (usbd_interface_handle, u_int8_t, u_int8_t, usbd_pipe_handle *, int);
-static int usbd_xfer_isread(usbd_xfer_handle xfer);
-static void usbd_start_transfer(void *arg, bus_dma_segment_t *segs, int nseg,
- int error);
-static void usbd_alloc_callback(void *arg, bus_dma_segment_t *segs, int nseg,
- int error);
-
-static int usbd_nbuses = 0;
-
-void
-usbd_init(void)
-{
- usbd_nbuses++;
-}
-
-void
-usbd_finish(void)
-{
- --usbd_nbuses;
-}
-
-static __inline int
-usbd_xfer_isread(usbd_xfer_handle xfer)
-{
- if (xfer->rqflags & URQ_REQUEST)
- return (xfer->request.bmRequestType & UT_READ);
- else
- return (xfer->pipe->endpoint->edesc->bEndpointAddress &
- UE_DIR_IN);
-}
-
-#ifdef USB_DEBUG
-void
-usbd_dump_iface(struct usbd_interface *iface)
-{
- printf("usbd_dump_iface: iface=%p\n", iface);
- if (iface == NULL)
- return;
- printf(" device=%p idesc=%p index=%d altindex=%d priv=%p\n",
- iface->device, iface->idesc, iface->index, iface->altindex,
- iface->priv);
-}
-
-void
-usbd_dump_device(struct usbd_device *dev)
-{
- printf("usbd_dump_device: dev=%p\n", dev);
- if (dev == NULL)
- return;
- printf(" bus=%p default_pipe=%p\n", dev->bus, dev->default_pipe);
- printf(" address=%d config=%d depth=%d speed=%d self_powered=%d "
- "power=%d langid=%d\n",
- dev->address, dev->config, dev->depth, dev->speed,
- dev->self_powered, dev->power, dev->langid);
-}
-
-void
-usbd_dump_endpoint(struct usbd_endpoint *endp)
-{
- printf("usbd_dump_endpoint: endp=%p\n", endp);
- if (endp == NULL)
- return;
- printf(" edesc=%p refcnt=%d\n", endp->edesc, endp->refcnt);
- if (endp->edesc)
- printf(" bEndpointAddress=0x%02x\n",
- endp->edesc->bEndpointAddress);
-}
-
-void
-usbd_dump_queue(usbd_pipe_handle pipe)
-{
- usbd_xfer_handle xfer;
-
- printf("usbd_dump_queue: pipe=%p\n", pipe);
- STAILQ_FOREACH(xfer, &pipe->queue, next) {
- printf(" xfer=%p\n", xfer);
- }
-}
-
-void
-usbd_dump_pipe(usbd_pipe_handle pipe)
-{
- printf("usbd_dump_pipe: pipe=%p\n", pipe);
- if (pipe == NULL)
- return;
- usbd_dump_iface(pipe->iface);
- usbd_dump_device(pipe->device);
- usbd_dump_endpoint(pipe->endpoint);
- printf(" (usbd_dump_pipe:)\n refcnt=%d running=%d aborting=%d\n",
- pipe->refcnt, pipe->running, pipe->aborting);
- printf(" intrxfer=%p, repeat=%d, interval=%d\n",
- pipe->intrxfer, pipe->repeat, pipe->interval);
-}
-#endif
-
-usbd_status
-usbd_open_pipe(usbd_interface_handle iface, u_int8_t address,
- u_int8_t flags, usbd_pipe_handle *pipe)
-{
- return (usbd_open_pipe_ival(iface, address, flags, pipe,
- USBD_DEFAULT_INTERVAL));
-}
-
-usbd_status
-usbd_open_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;
- int i;
-
- DPRINTFN(3,("usbd_open_pipe: iface=%p address=0x%x flags=0x%x\n",
- iface, address, flags));
-
- for (i = 0; i < iface->idesc->bNumEndpoints; i++) {
- ep = &iface->endpoints[i];
- if (ep->edesc == NULL)
- return (USBD_IOERROR);
- if (ep->edesc->bEndpointAddress == address)
- goto found;
- }
- return (USBD_BAD_ADDRESS);
- found:
- if ((flags & USBD_EXCLUSIVE_USE) && ep->refcnt != 0)
- return (USBD_IN_USE);
- err = usbd_setup_pipe(iface->device, iface, ep, ival, &p);
- if (err)
- return (err);
- LIST_INSERT_HEAD(&iface->pipes, p, next);
- *pipe = p;
- return (USBD_NORMAL_COMPLETION);
-}
-
-usbd_status
-usbd_open_pipe_intr(usbd_interface_handle iface, u_int8_t address,
- u_int8_t flags, usbd_pipe_handle *pipe,
- usbd_private_handle priv, void *buffer, u_int32_t len,
- usbd_callback cb, int ival)
-{
- usbd_status err;
- usbd_xfer_handle xfer;
- usbd_pipe_handle ipipe;
-
- 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,
- &ipipe, ival);
- if (err)
- return (err);
- xfer = usbd_alloc_xfer(iface->device);
- if (xfer == NULL) {
- err = USBD_NOMEM;
- goto bad1;
- }
- usbd_setup_xfer(xfer, ipipe, priv, buffer, len, flags,
- USBD_NO_TIMEOUT, cb);
- ipipe->intrxfer = xfer;
- ipipe->repeat = 1;
- *pipe = ipipe;
- err = usbd_transfer(xfer);
- if (err != USBD_IN_PROGRESS && err)
- goto bad2;
- return (USBD_NORMAL_COMPLETION);
-
- bad2:
- ipipe->intrxfer = NULL;
- ipipe->repeat = 0;
- usbd_free_xfer(xfer);
- bad1:
- usbd_close_pipe(ipipe);
- return (err);
-}
-
-usbd_status
-usbd_close_pipe(usbd_pipe_handle pipe)
-{
-#ifdef DIAGNOSTIC
- if (pipe == NULL) {
- printf("usbd_close_pipe: pipe==NULL\n");
- return (USBD_NORMAL_COMPLETION);
- }
-#endif
-
- if (--pipe->refcnt != 0)
- return (USBD_NORMAL_COMPLETION);
- if (! STAILQ_EMPTY(&pipe->queue))
- return (USBD_PENDING_REQUESTS);
- LIST_REMOVE(pipe, next);
- pipe->endpoint->refcnt--;
- pipe->methods->close(pipe);
- if (pipe->intrxfer != NULL)
- usbd_free_xfer(pipe->intrxfer);
- free(pipe, M_USB);
- return (USBD_NORMAL_COMPLETION);
-}
-
-usbd_status
-usbd_transfer(usbd_xfer_handle xfer)
-{
- usbd_pipe_handle pipe = xfer->pipe;
- struct usb_dma_mapping *dmap = &xfer->dmamap;
- usbd_status err;
- u_int size;
- int s;
-
- DPRINTFN(5,("%s: xfer=%p, flags=0x%b, rqflags=0x%b, "
- "length=%d, buffer=%p, allocbuf=%p, pipe=%p, running=%d\n",
- __func__, xfer, xfer->flags, USBD_BITS, xfer->rqflags, URQ_BITS,
- xfer->length, xfer->buffer, xfer->allocbuf, pipe, pipe->running));
-#ifdef USB_DEBUG
- if (usbdebug > 5)
- usbd_dump_queue(pipe);
-#endif
- xfer->done = 0;
-
- if (pipe->aborting)
- return (USBD_CANCELLED);
-
- size = xfer->length;
- /* If there is no buffer, allocate one. */
- if (!(xfer->rqflags & URQ_DEV_DMABUF) && size != 0) {
- bus_dma_tag_t tag = pipe->device->bus->buffer_dmatag;
-
-#ifdef DIAGNOSTIC
- if (xfer->rqflags & URQ_AUTO_DMABUF)
- printf("usbd_transfer: has old buffer!\n");
-#endif
- err = bus_dmamap_create(tag, 0, &dmap->map);
- if (err)
- return (USBD_NOMEM);
-
- xfer->rqflags |= URQ_AUTO_DMABUF;
- err = bus_dmamap_load(tag, dmap->map, xfer->buffer, size,
- usbd_start_transfer, xfer, 0);
- if (err != 0 && err != EINPROGRESS) {
- xfer->rqflags &= ~URQ_AUTO_DMABUF;
- bus_dmamap_destroy(tag, dmap->map);
- return (USBD_INVAL);
- }
- } else if (size != 0) {
- usbd_start_transfer(xfer, dmap->segs, dmap->nsegs, 0);
- } else {
- usbd_start_transfer(xfer, NULL, 0, 0);
- }
-
- if (!(xfer->flags & USBD_SYNCHRONOUS))
- return (xfer->done ? USBD_NORMAL_COMPLETION : USBD_IN_PROGRESS);
-
- /* Sync transfer, wait for completion. */
- s = splusb();
- while (!xfer->done) {
- if (pipe->device->bus->use_polling)
- panic("usbd_transfer: not done");
- tsleep(xfer, PRIBIO, "usbsyn", 0);
- }
- splx(s);
- return (xfer->status);
-}
-
-static void
-usbd_start_transfer(void *arg, bus_dma_segment_t *segs, int nseg, int error)
-{
- usbd_xfer_handle xfer = arg;
- usbd_pipe_handle pipe = xfer->pipe;
- struct usb_dma_mapping *dmap = &xfer->dmamap;
- bus_dma_tag_t tag = pipe->device->bus->buffer_dmatag;
- int err, i;
-
- if (error != 0) {
- KASSERT(xfer->rqflags & URQ_AUTO_DMABUF,
- ("usbd_start_transfer: error with non-auto buf"));
- if (nseg > 0)
- bus_dmamap_unload(tag, dmap->map);
- bus_dmamap_destroy(tag, dmap->map);
- /* XXX */
- usb_insert_transfer(xfer);
- xfer->status = USBD_IOERROR;
- usb_transfer_complete(xfer);
- return;
- }
-
- if (segs != dmap->segs) {
- for (i = 0; i < nseg; i++)
- dmap->segs[i] = segs[i];
- }
- dmap->nsegs = nseg;
-
- if (nseg > 0) {
- if (!usbd_xfer_isread(xfer)) {
- /*
- * Copy data if it is not already in the correct
- * buffer.
- */
- if (!(xfer->flags & USBD_NO_COPY) &&
- xfer->allocbuf != NULL &&
- xfer->buffer != xfer->allocbuf)
- memcpy(xfer->allocbuf, xfer->buffer,
- xfer->length);
- bus_dmamap_sync(tag, dmap->map, BUS_DMASYNC_PREWRITE);
- } else if (xfer->rqflags & URQ_REQUEST) {
- /*
- * Even if we have no data portion we still need to
- * sync the dmamap for the request data in the SETUP
- * packet.
- */
- bus_dmamap_sync(tag, dmap->map,
- BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
- } else
- bus_dmamap_sync(tag, dmap->map, BUS_DMASYNC_PREREAD);
- }
- err = pipe->methods->transfer(xfer);
- if (err != USBD_IN_PROGRESS && err) {
- if (xfer->rqflags & URQ_AUTO_DMABUF) {
- bus_dmamap_unload(tag, dmap->map);
- bus_dmamap_destroy(tag, dmap->map);
- xfer->rqflags &= ~URQ_AUTO_DMABUF;
- }
- xfer->status = err;
- usb_transfer_complete(xfer);
- return;
- }
-}
-
-/* Like usbd_transfer(), but waits for completion. */
-usbd_status
-usbd_sync_transfer(usbd_xfer_handle xfer)
-{
- xfer->flags |= USBD_SYNCHRONOUS;
- return (usbd_transfer(xfer));
-}
-
-struct usbd_allocstate {
- usbd_xfer_handle xfer;
- int done;
- int error;
- int waiting;
-};
-
-void *
-usbd_alloc_buffer(usbd_xfer_handle xfer, u_int32_t size)
-{
- struct usbd_allocstate allocstate;
- struct usb_dma_mapping *dmap = &xfer->dmamap;
- bus_dma_tag_t tag = xfer->device->bus->buffer_dmatag;
- void *buf;
- usbd_status err;
- int error, s;
-
- KASSERT((xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF)) == 0,
- ("usbd_alloc_buffer: xfer already has a buffer"));
- err = bus_dmamap_create(tag, 0, &dmap->map);
- if (err)
- return (NULL);
- buf = malloc(size, M_USB, M_WAITOK);
-
- allocstate.xfer = xfer;
- allocstate.done = 0;
- allocstate.error = 0;
- allocstate.waiting = 0;
- error = bus_dmamap_load(tag, dmap->map, buf, size, usbd_alloc_callback,
- &allocstate, 0);
- if (error && error != EINPROGRESS) {
- bus_dmamap_destroy(tag, dmap->map);
- free(buf, M_USB);
- return (NULL);
- }
- if (error == EINPROGRESS) {
- /* Wait for completion. */
- s = splusb();
- allocstate.waiting = 1;
- while (!allocstate.done)
- tsleep(&allocstate, PRIBIO, "usbdab", 0);
- splx(s);
- error = allocstate.error;
- }
- if (error) {
- bus_dmamap_unload(tag, dmap->map);
- bus_dmamap_destroy(tag, dmap->map);
- free(buf, M_USB);
- return (NULL);
- }
-
- xfer->allocbuf = buf;
- xfer->rqflags |= URQ_DEV_DMABUF;
- return (buf);
-}
-
-void
-usbd_free_buffer(usbd_xfer_handle xfer)
-{
- struct usb_dma_mapping *dmap = &xfer->dmamap;
- bus_dma_tag_t tag = xfer->device->bus->buffer_dmatag;
-
- KASSERT((xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF)) ==
- URQ_DEV_DMABUF, ("usbd_free_buffer: no/auto buffer"));
-
- xfer->rqflags &= ~URQ_DEV_DMABUF;
- bus_dmamap_unload(tag, dmap->map);
- bus_dmamap_destroy(tag, dmap->map);
- free(xfer->allocbuf, M_USB);
- xfer->allocbuf = NULL;
-}
-
-void *
-usbd_get_buffer(usbd_xfer_handle xfer)
-{
- if (!(xfer->rqflags & URQ_DEV_DMABUF))
- return (NULL);
- return (xfer->allocbuf);
-}
-
-static void
-usbd_alloc_callback(void *arg, bus_dma_segment_t *segs, int nseg, int error)
-{
- struct usbd_allocstate *allocstate = arg;
- usbd_xfer_handle xfer = allocstate->xfer;
- struct usb_dma_mapping *dmap = &xfer->dmamap;
- int i;
-
- allocstate->error = error;
- if (error == 0) {
- for (i = 0; i < nseg; i++)
- dmap->segs[i] = segs[i];
- dmap->nsegs = nseg;
- }
- allocstate->done = 1;
- if (allocstate->waiting)
- wakeup(&allocstate);
-}
-
-usbd_xfer_handle
-usbd_alloc_xfer(usbd_device_handle dev)
-{
- usbd_xfer_handle xfer;
-
- xfer = dev->bus->methods->allocx(dev->bus);
- if (xfer == NULL)
- return (NULL);
- xfer->device = dev;
- callout_init(&xfer->timeout_handle, 0);
- DPRINTFN(5,("usbd_alloc_xfer() = %p\n", xfer));
- return (xfer);
-}
-
-usbd_status
-usbd_free_xfer(usbd_xfer_handle xfer)
-{
- DPRINTFN(5,("usbd_free_xfer: %p\n", xfer));
- if (xfer->rqflags & URQ_DEV_DMABUF)
- usbd_free_buffer(xfer);
-/* XXX Does FreeBSD need to do something similar? */
-#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);
-}
-
-void
-usbd_setup_xfer(usbd_xfer_handle xfer, usbd_pipe_handle pipe,
- usbd_private_handle priv, void *buffer, u_int32_t length,
- u_int16_t flags, u_int32_t timeout,
- usbd_callback callback)
-{
- xfer->pipe = pipe;
- xfer->priv = priv;
- xfer->buffer = buffer;
- xfer->length = length;
- xfer->actlen = 0;
- xfer->flags = flags;
- xfer->timeout = timeout;
- xfer->status = USBD_NOT_STARTED;
- xfer->callback = callback;
- xfer->rqflags &= ~URQ_REQUEST;
- xfer->nframes = 0;
-}
-
-void
-usbd_setup_default_xfer(usbd_xfer_handle xfer, usbd_device_handle dev,
- 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 callback)
-{
- xfer->pipe = dev->default_pipe;
- xfer->priv = priv;
- xfer->buffer = buffer;
- xfer->length = length;
- xfer->actlen = 0;
- xfer->flags = flags;
- xfer->timeout = timeout;
- xfer->status = USBD_NOT_STARTED;
- xfer->callback = callback;
- xfer->request = *req;
- xfer->rqflags |= URQ_REQUEST;
- xfer->nframes = 0;
-}
-
-void
-usbd_setup_isoc_xfer(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 callback)
-{
- int i;
-
- xfer->pipe = pipe;
- xfer->priv = priv;
- xfer->buffer = 0;
- xfer->length = 0;
- for (i = 0; i < nframes; i++)
- xfer->length += frlengths[i];
- xfer->actlen = 0;
- xfer->flags = flags;
- xfer->timeout = USBD_NO_TIMEOUT;
- xfer->status = USBD_NOT_STARTED;
- xfer->callback = callback;
- xfer->rqflags &= ~URQ_REQUEST;
- xfer->frlengths = frlengths;
- xfer->nframes = nframes;
-}
-
-void
-usbd_get_xfer_status(usbd_xfer_handle xfer, usbd_private_handle *priv,
- void **buffer, u_int32_t *count, usbd_status *status)
-{
- if (priv != NULL)
- *priv = xfer->priv;
- if (buffer != NULL)
- *buffer = xfer->buffer;
- if (count != NULL)
- *count = xfer->actlen;
- if (status != NULL)
- *status = xfer->status;
-}
-
-usb_config_descriptor_t *
-usbd_get_config_descriptor(usbd_device_handle dev)
-{
-#ifdef DIAGNOSTIC
- if (dev == NULL) {
- printf("usbd_get_config_descriptor: dev == NULL\n");
- return (NULL);
- }
-#endif
- return (dev->cdesc);
-}
-
-int
-usbd_get_speed(usbd_device_handle dev)
-{
- return (dev->speed);
-}
-
-usb_interface_descriptor_t *
-usbd_get_interface_descriptor(usbd_interface_handle iface)
-{
-#ifdef DIAGNOSTIC
- if (iface == NULL) {
- printf("usbd_get_interface_descriptor: dev == NULL\n");
- return (NULL);
- }
-#endif
- return (iface->idesc);
-}
-
-usb_device_descriptor_t *
-usbd_get_device_descriptor(usbd_device_handle dev)
-{
- return (&dev->ddesc);
-}
-
-usb_endpoint_descriptor_t *
-usbd_interface2endpoint_descriptor(usbd_interface_handle iface, u_int8_t index)
-{
- if (index >= iface->idesc->bNumEndpoints)
- return (0);
- return (iface->endpoints[index].edesc);
-}
-
-usbd_status
-usbd_abort_pipe(usbd_pipe_handle pipe)
-{
- usbd_status err;
- int s;
-
-#ifdef DIAGNOSTIC
- if (pipe == NULL) {
- printf("usbd_close_pipe: pipe==NULL\n");
- return (USBD_NORMAL_COMPLETION);
- }
-#endif
- s = splusb();
- err = usbd_ar_pipe(pipe);
- splx(s);
- return (err);
-}
-
-usbd_status
-usbd_abort_default_pipe(usbd_device_handle dev)
-{
- return (usbd_abort_pipe(dev->default_pipe));
-}
-
-usbd_status
-usbd_clear_endpoint_stall(usbd_pipe_handle pipe)
-{
- usbd_device_handle dev = pipe->device;
- usb_device_request_t req;
- usbd_status err;
-
- DPRINTFN(8, ("usbd_clear_endpoint_stall\n"));
-
- /*
- * Clearing en endpoint stall resets the endpoint toggle, so
- * do the same to the HC toggle.
- */
- pipe->methods->cleartoggle(pipe);
-
- req.bmRequestType = UT_WRITE_ENDPOINT;
- req.bRequest = UR_CLEAR_FEATURE;
- USETW(req.wValue, UF_ENDPOINT_HALT);
- USETW(req.wIndex, pipe->endpoint->edesc->bEndpointAddress);
- USETW(req.wLength, 0);
- err = usbd_do_request(dev, &req, 0);
-#if 0
-XXX should we do this?
- if (!err) {
- pipe->state = USBD_PIPE_ACTIVE;
- /* XXX activate pipe */
- }
-#endif
- return (err);
-}
-
-usbd_status
-usbd_clear_endpoint_stall_async(usbd_pipe_handle pipe)
-{
- usbd_device_handle dev = pipe->device;
- usb_device_request_t req;
- usbd_status err;
-
- pipe->methods->cleartoggle(pipe);
-
- req.bmRequestType = UT_WRITE_ENDPOINT;
- req.bRequest = UR_CLEAR_FEATURE;
- USETW(req.wValue, UF_ENDPOINT_HALT);
- USETW(req.wIndex, pipe->endpoint->edesc->bEndpointAddress);
- USETW(req.wLength, 0);
- err = usbd_do_request_async(dev, &req, 0);
- return (err);
-}
-
-void
-usbd_clear_endpoint_toggle(usbd_pipe_handle pipe)
-{
- pipe->methods->cleartoggle(pipe);
-}
-
-usbd_status
-usbd_endpoint_count(usbd_interface_handle iface, u_int8_t *count)
-{
-#ifdef DIAGNOSTIC
- if (iface == NULL || iface->idesc == NULL) {
- printf("usbd_endpoint_count: NULL pointer\n");
- return (USBD_INVAL);
- }
-#endif
- *count = iface->idesc->bNumEndpoints;
- return (USBD_NORMAL_COMPLETION);
-}
-
-usbd_status
-usbd_interface_count(usbd_device_handle dev, u_int8_t *count)
-{
- if (dev->cdesc == NULL)
- return (USBD_NOT_CONFIGURED);
- *count = dev->cdesc->bNumInterface;
- return (USBD_NORMAL_COMPLETION);
-}
-
-void
-usbd_interface2device_handle(usbd_interface_handle iface,
- usbd_device_handle *dev)
-{
- *dev = iface->device;
-}
-
-usbd_status
-usbd_device2interface_handle(usbd_device_handle dev,
- u_int8_t ifaceno, usbd_interface_handle *iface)
-{
- if (dev->cdesc == NULL)
- return (USBD_NOT_CONFIGURED);
- if (ifaceno >= dev->cdesc->bNumInterface)
- return (USBD_INVAL);
- *iface = &dev->ifaces[ifaceno];
- return (USBD_NORMAL_COMPLETION);
-}
-
-usbd_device_handle
-usbd_pipe2device_handle(usbd_pipe_handle pipe)
-{
- return (pipe->device);
-}
-
-/* XXXX use altno */
-usbd_status
-usbd_set_interface(usbd_interface_handle iface, int altidx)
-{
- usb_device_request_t req;
- usbd_status err;
- void *endpoints;
-
- if (LIST_FIRST(&iface->pipes) != 0)
- return (USBD_IN_USE);
-
- endpoints = iface->endpoints;
- err = usbd_fill_iface_data(iface->device, iface->index, altidx);
- if (err)
- return (err);
-
- /* new setting works, we can free old endpoints */
- if (endpoints != NULL)
- free(endpoints, M_USB);
-
-#ifdef DIAGNOSTIC
- if (iface->idesc == NULL) {
- printf("usbd_set_interface: NULL pointer\n");
- return (USBD_INVAL);
- }
-#endif
-
- req.bmRequestType = UT_WRITE_INTERFACE;
- req.bRequest = UR_SET_INTERFACE;
- USETW(req.wValue, iface->idesc->bAlternateSetting);
- USETW(req.wIndex, iface->idesc->bInterfaceNumber);
- USETW(req.wLength, 0);
- return (usbd_do_request(iface->device, &req, 0));
-}
-
-int
-usbd_get_no_alts(usb_config_descriptor_t *cdesc, int ifaceno)
-{
- char *p = (char *)cdesc;
- char *end = p + UGETW(cdesc->wTotalLength);
- usb_interface_descriptor_t *d;
- int n;
-
- for (n = 0; p < end; p += d->bLength) {
- d = (usb_interface_descriptor_t *)p;
- if (p + d->bLength <= end &&
- d->bDescriptorType == UDESC_INTERFACE &&
- d->bInterfaceNumber == ifaceno)
- n++;
- }
- return (n);
-}
-
-int
-usbd_get_interface_altindex(usbd_interface_handle iface)
-{
- return (iface->altindex);
-}
-
-usbd_status
-usbd_get_interface(usbd_interface_handle iface, u_int8_t *aiface)
-{
- usb_device_request_t req;
-
- req.bmRequestType = UT_READ_INTERFACE;
- req.bRequest = UR_GET_INTERFACE;
- USETW(req.wValue, 0);
- USETW(req.wIndex, iface->idesc->bInterfaceNumber);
- USETW(req.wLength, 1);
- return (usbd_do_request(iface->device, &req, aiface));
-}
-
-/*** Internal routines ***/
-
-/* Dequeue all pipe operations, called at splusb(). */
-static usbd_status
-usbd_ar_pipe(usbd_pipe_handle pipe)
-{
- usbd_xfer_handle xfer;
-
- SPLUSBCHECK;
-
- DPRINTFN(2,("usbd_ar_pipe: pipe=%p\n", pipe));
-#ifdef USB_DEBUG
- if (usbdebug > 5)
- usbd_dump_queue(pipe);
-#endif
- pipe->repeat = 0;
- pipe->aborting = 1;
- while ((xfer = STAILQ_FIRST(&pipe->queue)) != NULL) {
- DPRINTFN(2,("usbd_ar_pipe: pipe=%p xfer=%p (methods=%p)\n",
- pipe, xfer, pipe->methods));
- /* Make the HC abort it (and invoke the callback). */
- pipe->methods->abort(xfer);
- KASSERT(STAILQ_FIRST(&pipe->queue) != xfer, ("usbd_ar_pipe"));
- /* XXX only for non-0 usbd_clear_endpoint_stall(pipe); */
- }
- pipe->aborting = 0;
- return (USBD_NORMAL_COMPLETION);
-}
-
-/* Called at splusb() */
-void
-usb_transfer_complete(usbd_xfer_handle xfer)
-{
- usbd_pipe_handle pipe = xfer->pipe;
- struct usb_dma_mapping *dmap = &xfer->dmamap;
- bus_dma_tag_t tag = pipe->device->bus->buffer_dmatag;
- int sync = xfer->flags & USBD_SYNCHRONOUS;
- int erred = xfer->status == USBD_CANCELLED ||
- xfer->status == USBD_TIMEOUT;
- int repeat = pipe->repeat;
- int polling;
-
- SPLUSBCHECK;
-
- DPRINTFN(5, ("%s: pipe=%p xfer=%p status=%d actlen=%d\n",
- __func__, pipe, xfer, xfer->status, xfer->actlen));
- DPRINTFN(5,("%s: flags=0x%b, rqflags=0x%b, length=%d, buffer=%p\n",
- __func__, xfer->flags, USBD_BITS, xfer->rqflags, URQ_BITS,
- xfer->length, xfer->buffer));
-#ifdef DIAGNOSTIC
- if (xfer->busy_free != XFER_ONQU) {
- printf("usb_transfer_complete: xfer=%p not busy 0x%08x\n",
- xfer, xfer->busy_free);
- return;
- }
-#endif
-
-#ifdef DIAGNOSTIC
- if (pipe == NULL) {
- printf("usbd_transfer_cb: pipe==0, xfer=%p\n", xfer);
- return;
- }
-#endif
- polling = pipe->device->bus->use_polling;
- /* XXXX */
- if (polling)
- pipe->running = 0;
-
- if (xfer->actlen != 0 && usbd_xfer_isread(xfer)) {
- bus_dmamap_sync(tag, dmap->map, BUS_DMASYNC_POSTREAD);
- /* Copy data if it is not already in the correct buffer. */
- if (!(xfer->flags & USBD_NO_COPY) && xfer->allocbuf != NULL &&
- xfer->buffer != xfer->allocbuf)
- memcpy(xfer->buffer, xfer->allocbuf, xfer->actlen);
- }
-
- /* if we mapped the buffer in usbd_transfer() we unmap it here. */
- if (xfer->rqflags & URQ_AUTO_DMABUF) {
- if (!repeat) {
- bus_dmamap_unload(tag, dmap->map);
- bus_dmamap_destroy(tag, dmap->map);
- xfer->rqflags &= ~URQ_AUTO_DMABUF;
- }
- }
-
- if (!repeat) {
- /* Remove request from queue. */
-#ifdef DIAGNOSTIC
- xfer->busy_free = XFER_BUSY;
-#endif
- KASSERT(STAILQ_FIRST(&pipe->queue) == xfer,
- ("usb_transfer_complete: bad dequeue"));
- STAILQ_REMOVE_HEAD(&pipe->queue, next);
- }
- DPRINTFN(5,("usb_transfer_complete: repeat=%d new head=%p\n",
- repeat, STAILQ_FIRST(&pipe->queue)));
-
- /* Count completed transfers. */
- ++pipe->device->bus->stats.uds_requests
- [pipe->endpoint->edesc->bmAttributes & UE_XFERTYPE];
-
- xfer->done = 1;
- if (!xfer->status && xfer->actlen < xfer->length &&
- !(xfer->flags & USBD_SHORT_XFER_OK)) {
- DPRINTFN(-1,("usbd_transfer_cb: short transfer %d<%d\n",
- xfer->actlen, xfer->length));
- xfer->status = USBD_SHORT_XFER;
- }
-
- /*
- * For repeat operations, call the callback first, as the xfer
- * will not go away and the "done" method may modify it. Otherwise
- * reverse the order in case the callback wants to free or reuse
- * the xfer.
- */
- if (repeat) {
- if (xfer->callback)
- xfer->callback(xfer, xfer->priv, xfer->status);
- pipe->methods->done(xfer);
- } else {
- pipe->methods->done(xfer);
- if (xfer->callback)
- xfer->callback(xfer, xfer->priv, xfer->status);
- }
-
- if (sync && !polling)
- wakeup(xfer);
-
- if (!repeat) {
- /* XXX should we stop the queue on all errors? */
- if (erred && pipe->iface != NULL) /* not control pipe */
- pipe->running = 0;
- else
- usbd_start_next(pipe);
- }
-}
-
-usbd_status
-usb_insert_transfer(usbd_xfer_handle xfer)
-{
- usbd_pipe_handle pipe = xfer->pipe;
- usbd_status err;
- int s;
-
- DPRINTFN(5,("usb_insert_transfer: pipe=%p running=%d timeout=%d\n",
- pipe, pipe->running, xfer->timeout));
-#ifdef DIAGNOSTIC
- if (xfer->busy_free != XFER_BUSY) {
- printf("usb_insert_transfer: xfer=%p not busy 0x%08x\n",
- xfer, xfer->busy_free);
- return (USBD_INVAL);
- }
- xfer->busy_free = XFER_ONQU;
-#endif
- s = splusb();
- KASSERT(STAILQ_FIRST(&pipe->queue) != xfer, ("usb_insert_transfer"));
- STAILQ_INSERT_TAIL(&pipe->queue, xfer, next);
- if (pipe->running)
- err = USBD_IN_PROGRESS;
- else {
- pipe->running = 1;
- err = USBD_NORMAL_COMPLETION;
- }
- splx(s);
- return (err);
-}
-
-/* Called at splusb() */
-void
-usbd_start_next(usbd_pipe_handle pipe)
-{
- usbd_xfer_handle xfer;
- usbd_status err;
-
- SPLUSBCHECK;
-
-#ifdef DIAGNOSTIC
- if (pipe == NULL) {
- printf("usbd_start_next: pipe == NULL\n");
- return;
- }
- if (pipe->methods == NULL || pipe->methods->start == NULL) {
- printf("usbd_start_next: pipe=%p no start method\n", pipe);
- return;
- }
-#endif
-
- /* Get next request in queue. */
- xfer = STAILQ_FIRST(&pipe->queue);
- DPRINTFN(5, ("usbd_start_next: pipe=%p, xfer=%p\n", pipe, xfer));
- if (xfer == NULL) {
- pipe->running = 0;
- } else {
- err = pipe->methods->start(xfer);
- if (err != USBD_IN_PROGRESS) {
- printf("usbd_start_next: error=%d\n", err);
- pipe->running = 0;
- /* XXX do what? */
- }
- }
-}
-
-usbd_status
-usbd_do_request(usbd_device_handle dev, usb_device_request_t *req, void *data)
-{
- return (usbd_do_request_flags(dev, req, data, 0, 0,
- USBD_DEFAULT_TIMEOUT));
-}
-
-usbd_status
-usbd_do_request_flags(usbd_device_handle dev, usb_device_request_t *req,
- void *data, u_int16_t flags, int *actlen, u_int32_t timo)
-{
- return (usbd_do_request_flags_pipe(dev, dev->default_pipe, req,
- data, flags, actlen, timo));
-}
-
-usbd_status
-usbd_do_request_flags_pipe(usbd_device_handle dev, usbd_pipe_handle pipe,
- usb_device_request_t *req, void *data, u_int16_t flags, int *actlen,
- u_int32_t timeout)
-{
- usbd_xfer_handle xfer;
- usbd_status err;
-
-#ifdef DIAGNOSTIC
-/* XXX amd64 too? */
-#if defined(__i386__)
- KASSERT(curthread->td_intr_nesting_level == 0,
- ("usbd_do_request: in interrupt context"));
-#endif
- if (dev->bus->intr_context) {
- printf("usbd_do_request: not in process context\n");
- return (USBD_INVAL);
- }
-#endif
-
- xfer = usbd_alloc_xfer(dev);
- if (xfer == NULL)
- return (USBD_NOMEM);
- usbd_setup_default_xfer(xfer, dev, 0, timeout, req,
- data, UGETW(req->wLength), flags, 0);
- xfer->pipe = pipe;
- err = usbd_sync_transfer(xfer);
-#if defined(USB_DEBUG) || defined(DIAGNOSTIC)
- if (xfer->actlen > xfer->length)
- DPRINTF(("usbd_do_request: overrun addr=%d type=0x%02x req=0x"
- "%02x val=%d index=%d rlen=%d length=%d actlen=%d\n",
- dev->address, xfer->request.bmRequestType,
- xfer->request.bRequest, UGETW(xfer->request.wValue),
- UGETW(xfer->request.wIndex),
- UGETW(xfer->request.wLength),
- xfer->length, xfer->actlen));
-#endif
- if (actlen != NULL)
- *actlen = xfer->actlen;
- if (err == USBD_STALLED) {
- /*
- * The control endpoint has stalled. Control endpoints
- * should not halt, but some may do so anyway so clear
- * any halt condition.
- */
- usb_device_request_t treq;
- usb_status_t status;
- u_int16_t s;
- usbd_status nerr;
-
- treq.bmRequestType = UT_READ_ENDPOINT;
- treq.bRequest = UR_GET_STATUS;
- USETW(treq.wValue, 0);
- USETW(treq.wIndex, 0);
- USETW(treq.wLength, sizeof(usb_status_t));
- usbd_setup_default_xfer(xfer, dev, 0, USBD_DEFAULT_TIMEOUT,
- &treq, &status,sizeof(usb_status_t),
- 0, 0);
- nerr = usbd_sync_transfer(xfer);
- if (nerr)
- goto bad;
- s = UGETW(status.wStatus);
- DPRINTF(("usbd_do_request: status = 0x%04x\n", s));
- if (!(s & UES_HALT))
- goto bad;
- treq.bmRequestType = UT_WRITE_ENDPOINT;
- treq.bRequest = UR_CLEAR_FEATURE;
- USETW(treq.wValue, UF_ENDPOINT_HALT);
- USETW(treq.wIndex, 0);
- USETW(treq.wLength, 0);
- usbd_setup_default_xfer(xfer, dev, 0, USBD_DEFAULT_TIMEOUT,
- &treq, &status, 0, 0, 0);
- nerr = usbd_sync_transfer(xfer);
- if (nerr)
- goto bad;
- }
-
- bad:
- usbd_free_xfer(xfer);
- return (err);
-}
-
-void
-usbd_do_request_async_cb(usbd_xfer_handle xfer, usbd_private_handle priv,
- usbd_status status)
-{
-#if defined(USB_DEBUG) || defined(DIAGNOSTIC)
- if (xfer->actlen > xfer->length)
- DPRINTF(("usbd_do_request: overrun addr=%d type=0x%02x req=0x"
- "%02x val=%d index=%d rlen=%d length=%d actlen=%d\n",
- xfer->pipe->device->address,
- xfer->request.bmRequestType,
- xfer->request.bRequest, UGETW(xfer->request.wValue),
- UGETW(xfer->request.wIndex),
- UGETW(xfer->request.wLength),
- xfer->length, xfer->actlen));
-#endif
- usbd_free_xfer(xfer);
-}
-
-/*
- * Execute a request without waiting for completion.
- * Can be used from interrupt context.
- */
-usbd_status
-usbd_do_request_async(usbd_device_handle dev, usb_device_request_t *req,
- void *data)
-{
- usbd_xfer_handle xfer;
- usbd_status err;
-
- 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);
- err = usbd_transfer(xfer);
- if (err != USBD_IN_PROGRESS && err) {
- usbd_free_xfer(xfer);
- return (err);
- }
- return (USBD_NORMAL_COMPLETION);
-}
-
-const struct usbd_quirks *
-usbd_get_quirks(usbd_device_handle dev)
-{
-#ifdef DIAGNOSTIC
- if (dev == NULL) {
- printf("usbd_get_quirks: dev == NULL\n");
- return 0;
- }
-#endif
- return (dev->quirks);
-}
-
-/* XXX do periodic free() of free list */
-
-/*
- * Called from keyboard driver when in polling mode.
- */
-void
-usbd_dopoll(usbd_interface_handle iface)
-{
- iface->device->bus->methods->do_poll(iface->device->bus);
-}
-
-void
-usbd_set_polling(usbd_device_handle dev, int on)
-{
- if (on)
- dev->bus->use_polling++;
- else
- dev->bus->use_polling--;
- /* When polling we need to make sure there is nothing pending to do. */
- if (dev->bus->use_polling)
- dev->bus->methods->soft_intr(dev->bus);
-}
-
-usbd_status
-usbd_reset_device(usbd_device_handle dev)
-{
- usbd_device_handle parent = dev->myhub;
- struct usbd_port *up = dev->powersrc;
-
- return usbd_reset_port(parent, up->portno, &up->status);
-}
-
-
-usb_endpoint_descriptor_t *
-usbd_get_endpoint_descriptor(usbd_interface_handle iface, u_int8_t address)
-{
- struct usbd_endpoint *ep;
- int i;
-
- for (i = 0; i < iface->idesc->bNumEndpoints; i++) {
- ep = &iface->endpoints[i];
- if (ep->edesc->bEndpointAddress == address)
- return (iface->endpoints[i].edesc);
- }
- return (0);
-}
-
-/*
- * 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 continuosly tries to do I/O operations
- * this can generate a large number of messages.
- */
-int
-usbd_ratecheck(struct timeval *last)
-{
- if (last->tv_sec == time_second)
- return (0);
- last->tv_sec = time_second;
- return (1);
-}
-
-/*
- * Search for a vendor/product pair in an array. The item size is
- * given as an argument.
- */
-const struct usb_devno *
-usb_match_device(const struct usb_devno *tbl, u_int nentries, u_int sz,
- u_int16_t vendor, u_int16_t product)
-{
- while (nentries-- > 0) {
- u_int16_t tproduct = tbl->ud_product;
- if (tbl->ud_vendor == vendor &&
- (tproduct == product || tproduct == USB_PRODUCT_ANY))
- return (tbl);
- tbl = (const struct usb_devno *)((const char *)tbl + sz);
- }
- return (NULL);
-}
-
-
-void
-usb_desc_iter_init(usbd_device_handle dev, usbd_desc_iter_t *iter)
-{
- const usb_config_descriptor_t *cd = usbd_get_config_descriptor(dev);
-
- iter->cur = (const uByte *)cd;
- iter->end = (const uByte *)cd + UGETW(cd->wTotalLength);
-}
-
-const usb_descriptor_t *
-usb_desc_iter_next(usbd_desc_iter_t *iter)
-{
- const usb_descriptor_t *desc;
-
- if (iter->cur + sizeof(usb_descriptor_t) >= iter->end) {
- if (iter->cur != iter->end)
- printf("usb_desc_iter_next: bad descriptor\n");
- return NULL;
- }
- desc = (const usb_descriptor_t *)iter->cur;
- if (desc->bLength == 0) {
- printf("usb_desc_iter_next: descriptor length = 0\n");
- return NULL;
- }
- iter->cur += desc->bLength;
- if (iter->cur > iter->end) {
- printf("usb_desc_iter_next: descriptor length too large\n");
- return NULL;
- }
- return desc;
-}
-
-usbd_status
-usbd_get_string(usbd_device_handle dev, int si, char *buf, size_t len)
-{
- int swap = dev->quirks->uq_flags & UQ_SWAP_UNICODE;
- usb_string_descriptor_t us;
- char *s;
- int i, n;
- u_int16_t c;
- usbd_status err;
- int size;
-
- buf[0] = '\0';
- if (len == 0)
- return (USBD_NORMAL_COMPLETION);
- if (si == 0)
- return (USBD_INVAL);
- if (dev->quirks->uq_flags & UQ_NO_STRINGS)
- return (USBD_STALLED);
- if (dev->langid == USBD_NOLANG) {
- /* Set up default language */
- err = usbd_get_string_desc(dev, USB_LANGUAGE_TABLE, 0, &us,
- &size);
- if (err || size < 4) {
- DPRINTFN(-1,("usbd_get_string: getting lang failed, using 0\n"));
- dev->langid = 0; /* Well, just pick something then */
- } else {
- /* Pick the first language as the default. */
- dev->langid = UGETW(us.bString[0]);
- }
- }
- err = usbd_get_string_desc(dev, si, dev->langid, &us, &size);
- if (err)
- return (err);
- s = buf;
- n = size / 2 - 1;
- for (i = 0; i < n && i < len - 1; i++) {
- c = UGETW(us.bString[i]);
- /* Convert from Unicode, handle buggy strings. */
- if ((c & 0xff00) == 0)
- *s++ = c;
- else if ((c & 0x00ff) == 0 && swap)
- *s++ = c >> 8;
- else
- *s++ = '?';
- }
- *s++ = 0;
- return (USBD_NORMAL_COMPLETION);
-}
-
-int
-usbd_driver_load(module_t mod, int what, void *arg)
-{
- /* XXX should implement something like a function that removes all generic devices */
-
- return (0);
-}
diff --git a/sys/dev/usb/usbdi.h b/sys/dev/usb/usbdi.h
deleted file mode 100644
index ef59039..0000000
--- a/sys/dev/usb/usbdi.h
+++ /dev/null
@@ -1,289 +0,0 @@
-/* $NetBSD: usbdi.h,v 1.64 2004/10/23 13:26:34 augustss Exp $ */
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) 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.
- */
-
-#ifndef _USBDI_H_
-#define _USBDI_H_
-
-typedef struct usbd_bus *usbd_bus_handle;
-typedef struct usbd_device *usbd_device_handle;
-typedef struct usbd_interface *usbd_interface_handle;
-typedef struct usbd_pipe *usbd_pipe_handle;
-typedef struct usbd_xfer *usbd_xfer_handle;
-typedef void *usbd_private_handle;
-
-typedef enum { /* keep in sync with usbd_status_msgs */
- USBD_NORMAL_COMPLETION = 0, /* must be 0 */
- USBD_IN_PROGRESS, /* 1 */
- /* errors */
- USBD_PENDING_REQUESTS, /* 2 */
- USBD_NOT_STARTED, /* 3 */
- USBD_INVAL, /* 4 */
- USBD_NOMEM, /* 5 */
- USBD_CANCELLED, /* 6 */
- USBD_BAD_ADDRESS, /* 7 */
- USBD_IN_USE, /* 8 */
- USBD_NO_ADDR, /* 9 */
- USBD_SET_ADDR_FAILED, /* 10 */
- USBD_NO_POWER, /* 11 */
- USBD_TOO_DEEP, /* 12 */
- USBD_IOERROR, /* 13 */
- USBD_NOT_CONFIGURED, /* 14 */
- USBD_TIMEOUT, /* 15 */
- USBD_SHORT_XFER, /* 16 */
- USBD_STALLED, /* 17 */
- USBD_INTERRUPTED, /* 18 */
-
- USBD_ERROR_MAX /* must be last */
-} usbd_status;
-
-typedef void (*usbd_callback)(usbd_xfer_handle, usbd_private_handle,
- usbd_status);
-
-/* Open flags */
-#define USBD_EXCLUSIVE_USE 0x01
-
-/* Use default (specified by ep. desc.) interval on interrupt pipe */
-#define USBD_DEFAULT_INTERVAL (-1)
-
-/* Request flags */
-#define USBD_NO_COPY 0x01 /* do not copy data to DMA buffer */
-#define USBD_SYNCHRONOUS 0x02 /* wait for completion */
-/* in usb.h #define USBD_SHORT_XFER_OK 0x04*/ /* allow short reads */
-#define USBD_FORCE_SHORT_XFER 0x08 /* force last short packet on write */
-
-#define USBD_BITS "\20\1NO_COPY\2SYNCHRONOUS\4FORCE_SHORT_XFER"
-
-#define USBD_NO_TIMEOUT 0
-#define USBD_DEFAULT_TIMEOUT 5000 /* ms = 5 s */
-
-usbd_status usbd_open_pipe(usbd_interface_handle, u_int8_t,
- u_int8_t, usbd_pipe_handle *);
-usbd_status usbd_close_pipe(usbd_pipe_handle);
-usbd_status usbd_transfer(usbd_xfer_handle);
-usbd_xfer_handle usbd_alloc_xfer(usbd_device_handle);
-usbd_status usbd_free_xfer(usbd_xfer_handle);
-void usbd_setup_xfer(usbd_xfer_handle, usbd_pipe_handle,
- usbd_private_handle, void *,
- u_int32_t, u_int16_t, u_int32_t,
- usbd_callback);
-void usbd_setup_default_xfer(usbd_xfer_handle, usbd_device_handle,
- usbd_private_handle, u_int32_t,
- usb_device_request_t *, void *,
- u_int32_t, u_int16_t, usbd_callback);
-void usbd_setup_isoc_xfer(usbd_xfer_handle, usbd_pipe_handle,
- usbd_private_handle, u_int16_t *,
- u_int32_t, u_int16_t, usbd_callback);
-void usbd_get_xfer_status(usbd_xfer_handle, usbd_private_handle *,
- void **, u_int32_t *, usbd_status *);
-usb_endpoint_descriptor_t *usbd_interface2endpoint_descriptor
- (usbd_interface_handle, u_int8_t);
-usbd_status usbd_abort_pipe(usbd_pipe_handle);
-usbd_status usbd_abort_default_pipe(usbd_device_handle);
-usbd_status usbd_clear_endpoint_stall(usbd_pipe_handle);
-usbd_status usbd_clear_endpoint_stall_async(usbd_pipe_handle);
-void usbd_clear_endpoint_toggle(usbd_pipe_handle);
-usbd_status usbd_endpoint_count(usbd_interface_handle, u_int8_t *);
-usbd_status usbd_interface_count(usbd_device_handle, u_int8_t *);
-void usbd_interface2device_handle(usbd_interface_handle,
- usbd_device_handle *);
-usbd_status usbd_device2interface_handle(usbd_device_handle,
- u_int8_t, usbd_interface_handle *);
-
-usbd_device_handle usbd_pipe2device_handle(usbd_pipe_handle);
-void *usbd_alloc_buffer(usbd_xfer_handle, u_int32_t);
-void usbd_free_buffer(usbd_xfer_handle);
-void *usbd_get_buffer(usbd_xfer_handle);
-usbd_status usbd_sync_transfer(usbd_xfer_handle);
-usbd_status usbd_open_pipe_intr(usbd_interface_handle, u_int8_t,
- u_int8_t, usbd_pipe_handle *,
- usbd_private_handle, void *,
- u_int32_t, usbd_callback, int);
-usbd_status usbd_do_request(usbd_device_handle, usb_device_request_t *, void *);
-usbd_status usbd_do_request_async(usbd_device_handle,
- usb_device_request_t *, void *);
-usbd_status usbd_do_request_flags(usbd_device_handle, usb_device_request_t *,
- void *, u_int16_t, int*, u_int32_t);
-usbd_status usbd_do_request_flags_pipe(usbd_device_handle, usbd_pipe_handle,
- usb_device_request_t *, void *, u_int16_t, int *, u_int32_t);
-usb_interface_descriptor_t *usbd_get_interface_descriptor
- (usbd_interface_handle);
-usb_config_descriptor_t *usbd_get_config_descriptor(usbd_device_handle);
-usb_device_descriptor_t *usbd_get_device_descriptor(usbd_device_handle);
-int usbd_get_speed(usbd_device_handle);
-usbd_status usbd_set_interface(usbd_interface_handle, int);
-int usbd_get_no_alts(usb_config_descriptor_t *, int);
-usbd_status usbd_get_interface(usbd_interface_handle, u_int8_t *);
-void usbd_fill_deviceinfo(usbd_device_handle, struct usb_device_info *, int);
-int usbd_get_interface_altindex(usbd_interface_handle);
-
-usb_interface_descriptor_t *usbd_find_idesc(usb_config_descriptor_t *,
- int, int);
-usb_endpoint_descriptor_t *usbd_find_edesc(usb_config_descriptor_t *,
- int, int, int);
-
-void usbd_dopoll(usbd_interface_handle);
-void usbd_set_polling(usbd_device_handle, int);
-usbd_status usbd_reset_device(usbd_device_handle);
-
-const char *usbd_errstr(usbd_status);
-
-void usbd_add_dev_event(int, usbd_device_handle);
-void usbd_add_drv_event(int, usbd_device_handle, device_t);
-
-void usbd_devinfo(usbd_device_handle, int, char *);
-const struct usbd_quirks *usbd_get_quirks(usbd_device_handle);
-usb_endpoint_descriptor_t *usbd_get_endpoint_descriptor
- (usbd_interface_handle, u_int8_t);
-
-usbd_status usbd_reload_device_desc(usbd_device_handle);
-
-int usbd_ratecheck(struct timeval *last);
-
-usbd_status usbd_get_string(usbd_device_handle dev, int si, char *buf,
- size_t len);
-
-/* An iterator for descriptors. */
-typedef struct {
- const uByte *cur;
- const uByte *end;
-} usbd_desc_iter_t;
-void usb_desc_iter_init(usbd_device_handle dev, usbd_desc_iter_t *iter);
-const usb_descriptor_t *usb_desc_iter_next(usbd_desc_iter_t *iter);
-
-/*
- * The usb_task structs form a queue of things to run in the USB event
- * thread. Normally this is just device discovery when a connect/disconnect
- * has been detected. But it may also be used by drivers that need to
- * perform (short) tasks that must have a process context.
- */
-struct usb_task {
- TAILQ_ENTRY(usb_task) next;
- void (*fun)(void *);
- void *arg;
- int queue;
-};
-#define USB_TASKQ_HC 0
-#define USB_TASKQ_DRIVER 1
-#define USB_NUM_TASKQS 2
-#define USB_TASKQ_NAMES {"usbtask-hc", "usbtask-dr"}
-
-void usb_add_task(usbd_device_handle, struct usb_task *, int queue);
-void usb_rem_task(usbd_device_handle, struct usb_task *);
-#define usb_init_task(t, f, a) ((t)->fun = (f), (t)->arg = (a), (t)->queue = -1)
-
-struct usb_devno {
- u_int16_t ud_vendor;
- u_int16_t ud_product;
-};
-const struct usb_devno *usb_match_device(const struct usb_devno *,
- u_int, u_int, u_int16_t, u_int16_t);
-#define usb_lookup(tbl, vendor, product) \
- usb_match_device((const struct usb_devno *)(tbl), sizeof (tbl) / sizeof ((tbl)[0]), sizeof ((tbl)[0]), (vendor), (product))
-#define USB_PRODUCT_ANY 0xffff
-
-/* NetBSD attachment information */
-
-/* Attach data */
-struct usb_attach_arg {
- int port;
- int configno;
- int ifaceno;
- int vendor;
- int product;
- int release;
- int matchlvl;
- usbd_device_handle device; /* current device */
- usbd_interface_handle iface; /* current interface */
- int usegeneric;
- usbd_interface_handle *ifaces; /* all interfaces */
- int nifaces; /* number of interfaces */
-};
-
-/* FreeBSD needs values less than zero */
-#define UMATCH_VENDOR_PRODUCT_REV (-10)
-#define UMATCH_VENDOR_PRODUCT (-20)
-#define UMATCH_VENDOR_DEVCLASS_DEVPROTO (-30)
-#define UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO (-40)
-#define UMATCH_DEVCLASS_DEVSUBCLASS (-50)
-#define UMATCH_VENDOR_PRODUCT_REV_CONF_IFACE (-60)
-#define UMATCH_VENDOR_PRODUCT_CONF_IFACE (-70)
-#define UMATCH_VENDOR_IFACESUBCLASS_IFACEPROTO (-80)
-#define UMATCH_VENDOR_IFACESUBCLASS (-90)
-#define UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO (-100)
-#define UMATCH_IFACECLASS_IFACESUBCLASS (-110)
-#define UMATCH_IFACECLASS (-120)
-#define UMATCH_IFACECLASS_GENERIC (-130)
-#define UMATCH_GENERIC (-140)
-#define UMATCH_NONE (ENXIO)
-
-#define USBD_SHOW_DEVICE_CLASS 0x1
-#define USBD_SHOW_INTERFACE_CLASS 0x2
-
-struct module;
-int usbd_driver_load(struct module *mod, int what, void *arg);
-
-static inline int
-usb_get_port(device_t dev)
-{
- struct usb_attach_arg *uap = device_get_ivars(dev);
- return (uap->port);
-}
-
-static inline struct usbd_interface *
-usb_get_iface(device_t dev)
-{
- struct usb_attach_arg *uap = device_get_ivars(dev);
- return (uap->iface);
-}
-
-/* XXX Perhaps USB should have its own levels? */
-#ifdef USB_USE_SOFTINTR
-#ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
-#define splusb splsoftnet
-#else
-#define splusb splsoftclock
-#endif /* __HAVE_GENERIC_SOFT_INTERRUPTS */
-#else
-#define splusb splbio
-#endif /* USB_USE_SOFTINTR */
-#define splhardusb splbio
-#define IPL_USB IPL_BIO
-
-#endif /* _USBDI_H_ */
diff --git a/sys/dev/usb/usbdi_util.c b/sys/dev/usb/usbdi_util.c
deleted file mode 100644
index 78ea571..0000000
--- a/sys/dev/usb/usbdi_util.c
+++ /dev/null
@@ -1,539 +0,0 @@
-/* $NetBSD: usbdi_util.c,v 1.42 2004/12/03 08:53:40 augustss 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 (lennart@augustsson.net) 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/malloc.h>
-#include <sys/bus.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbhid.h>
-
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-
-#ifdef USB_DEBUG
-#define DPRINTF(x) if (usbdebug) printf x
-#define DPRINTFN(n,x) if (usbdebug>(n)) printf x
-extern int usbdebug;
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-usbd_status
-usbd_get_desc(usbd_device_handle dev, int type, int index, int len, void *desc)
-{
- usb_device_request_t req;
-
- DPRINTFN(3,("usbd_get_desc: type=%d, index=%d, len=%d\n",
- type, index, len));
-
- req.bmRequestType = UT_READ_DEVICE;
- req.bRequest = UR_GET_DESCRIPTOR;
- USETW2(req.wValue, type, index);
- USETW(req.wIndex, 0);
- USETW(req.wLength, len);
- return (usbd_do_request(dev, &req, desc));
-}
-
-usbd_status
-usbd_get_config_desc(usbd_device_handle dev, int confidx,
- usb_config_descriptor_t *d)
-{
- usbd_status err;
-
- DPRINTFN(3,("usbd_get_config_desc: confidx=%d\n", 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 "
- "len=%d type=%d\n",
- confidx, d->bLength, d->bDescriptorType));
- return (USBD_INVAL);
- }
- return (USBD_NORMAL_COMPLETION);
-}
-
-usbd_status
-usbd_get_config_desc_full(usbd_device_handle dev, int conf, void *d, int size)
-{
- DPRINTFN(3,("usbd_get_config_desc_full: conf=%d\n", conf));
- return (usbd_get_desc(dev, UDESC_CONFIG, conf, size, d));
-}
-
-usbd_status
-usbd_get_device_desc(usbd_device_handle dev, usb_device_descriptor_t *d)
-{
- DPRINTFN(3,("usbd_get_device_desc:\n"));
- return (usbd_get_desc(dev, UDESC_DEVICE,
- 0, USB_DEVICE_DESCRIPTOR_SIZE, d));
-}
-
-usbd_status
-usbd_get_device_status(usbd_device_handle dev, usb_status_t *st)
-{
- usb_device_request_t req;
-
- req.bmRequestType = UT_READ_DEVICE;
- req.bRequest = UR_GET_STATUS;
- USETW(req.wValue, 0);
- USETW(req.wIndex, 0);
- USETW(req.wLength, sizeof(usb_status_t));
- return (usbd_do_request(dev, &req, st));
-}
-
-usbd_status
-usbd_get_hub_status(usbd_device_handle dev, usb_hub_status_t *st)
-{
- usb_device_request_t req;
-
- req.bmRequestType = UT_READ_CLASS_DEVICE;
- req.bRequest = UR_GET_STATUS;
- USETW(req.wValue, 0);
- USETW(req.wIndex, 0);
- USETW(req.wLength, sizeof(usb_hub_status_t));
- return (usbd_do_request(dev, &req, st));
-}
-
-usbd_status
-usbd_set_address(usbd_device_handle dev, int addr)
-{
- usb_device_request_t req;
-
- req.bmRequestType = UT_WRITE_DEVICE;
- req.bRequest = UR_SET_ADDRESS;
- USETW(req.wValue, addr);
- USETW(req.wIndex, 0);
- USETW(req.wLength, 0);
- return usbd_do_request(dev, &req, 0);
-}
-
-usbd_status
-usbd_get_port_status(usbd_device_handle dev, int port, usb_port_status_t *ps)
-{
- usb_device_request_t req;
-
- req.bmRequestType = UT_READ_CLASS_OTHER;
- req.bRequest = UR_GET_STATUS;
- USETW(req.wValue, 0);
- USETW(req.wIndex, port);
- USETW(req.wLength, sizeof *ps);
- return (usbd_do_request(dev, &req, ps));
-}
-
-usbd_status
-usbd_clear_hub_feature(usbd_device_handle dev, int sel)
-{
- usb_device_request_t req;
-
- req.bmRequestType = UT_WRITE_CLASS_DEVICE;
- req.bRequest = UR_CLEAR_FEATURE;
- USETW(req.wValue, sel);
- USETW(req.wIndex, 0);
- USETW(req.wLength, 0);
- return (usbd_do_request(dev, &req, 0));
-}
-
-usbd_status
-usbd_set_hub_feature(usbd_device_handle dev, int sel)
-{
- usb_device_request_t req;
-
- req.bmRequestType = UT_WRITE_CLASS_DEVICE;
- req.bRequest = UR_SET_FEATURE;
- USETW(req.wValue, sel);
- USETW(req.wIndex, 0);
- USETW(req.wLength, 0);
- return (usbd_do_request(dev, &req, 0));
-}
-
-usbd_status
-usbd_clear_port_feature(usbd_device_handle dev, int port, int sel)
-{
- usb_device_request_t req;
-
- req.bmRequestType = UT_WRITE_CLASS_OTHER;
- req.bRequest = UR_CLEAR_FEATURE;
- USETW(req.wValue, sel);
- USETW(req.wIndex, port);
- USETW(req.wLength, 0);
- return (usbd_do_request(dev, &req, 0));
-}
-
-usbd_status
-usbd_set_port_feature(usbd_device_handle dev, int port, int sel)
-{
- usb_device_request_t req;
-
- req.bmRequestType = UT_WRITE_CLASS_OTHER;
- req.bRequest = UR_SET_FEATURE;
- USETW(req.wValue, sel);
- USETW(req.wIndex, port);
- USETW(req.wLength, 0);
- return (usbd_do_request(dev, &req, 0));
-}
-
-usbd_status
-usbd_get_protocol(usbd_interface_handle iface, u_int8_t *report)
-{
- usb_interface_descriptor_t *id = usbd_get_interface_descriptor(iface);
- usbd_device_handle dev;
- usb_device_request_t req;
-
- DPRINTFN(4, ("usbd_get_protocol: iface=%p, endpt=%d\n",
- iface, id->bInterfaceNumber));
- if (id == NULL)
- return (USBD_IOERROR);
- usbd_interface2device_handle(iface, &dev);
- req.bmRequestType = UT_READ_CLASS_INTERFACE;
- req.bRequest = UR_GET_PROTOCOL;
- USETW(req.wValue, 0);
- USETW(req.wIndex, id->bInterfaceNumber);
- USETW(req.wLength, 1);
- return (usbd_do_request(dev, &req, report));
-}
-
-usbd_status
-usbd_set_protocol(usbd_interface_handle iface, int report)
-{
- usb_interface_descriptor_t *id = usbd_get_interface_descriptor(iface);
- usbd_device_handle dev;
- usb_device_request_t req;
-
- DPRINTFN(4, ("usbd_set_protocol: iface=%p, report=%d, endpt=%d\n",
- iface, report, id->bInterfaceNumber));
- if (id == NULL)
- return (USBD_IOERROR);
- usbd_interface2device_handle(iface, &dev);
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UR_SET_PROTOCOL;
- USETW(req.wValue, report);
- USETW(req.wIndex, id->bInterfaceNumber);
- USETW(req.wLength, 0);
- return (usbd_do_request(dev, &req, 0));
-}
-
-usbd_status
-usbd_set_report(usbd_interface_handle iface, int type, int id, void *data,
- int len)
-{
- usb_interface_descriptor_t *ifd = usbd_get_interface_descriptor(iface);
- usbd_device_handle dev;
- usb_device_request_t req;
-
- DPRINTFN(4, ("usbd_set_report: len=%d\n", len));
- if (ifd == NULL)
- return (USBD_IOERROR);
- usbd_interface2device_handle(iface, &dev);
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UR_SET_REPORT;
- USETW2(req.wValue, type, id);
- USETW(req.wIndex, ifd->bInterfaceNumber);
- USETW(req.wLength, len);
- return (usbd_do_request(dev, &req, data));
-}
-
-usbd_status
-usbd_set_report_async(usbd_interface_handle iface, int type, int id, void *data,
- int len)
-{
- usb_interface_descriptor_t *ifd = usbd_get_interface_descriptor(iface);
- usbd_device_handle dev;
- usb_device_request_t req;
-
- DPRINTFN(4, ("usbd_set_report_async: len=%d\n", len));
- if (ifd == NULL)
- return (USBD_IOERROR);
- usbd_interface2device_handle(iface, &dev);
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UR_SET_REPORT;
- USETW2(req.wValue, type, id);
- USETW(req.wIndex, ifd->bInterfaceNumber);
- USETW(req.wLength, len);
- return (usbd_do_request_async(dev, &req, data));
-}
-
-usbd_status
-usbd_get_report(usbd_interface_handle iface, int type, int id, void *data,
- int len)
-{
- usb_interface_descriptor_t *ifd = usbd_get_interface_descriptor(iface);
- usbd_device_handle dev;
- usb_device_request_t req;
-
- DPRINTFN(4, ("usbd_get_report: len=%d\n", len));
- if (ifd == NULL)
- return (USBD_IOERROR);
- usbd_interface2device_handle(iface, &dev);
- req.bmRequestType = UT_READ_CLASS_INTERFACE;
- req.bRequest = UR_GET_REPORT;
- USETW2(req.wValue, type, id);
- USETW(req.wIndex, ifd->bInterfaceNumber);
- USETW(req.wLength, len);
- return (usbd_do_request(dev, &req, data));
-}
-
-usbd_status
-usbd_set_idle(usbd_interface_handle iface, int duration, int id)
-{
- usb_interface_descriptor_t *ifd = usbd_get_interface_descriptor(iface);
- usbd_device_handle dev;
- usb_device_request_t req;
-
- DPRINTFN(4, ("usbd_set_idle: %d %d\n", duration, id));
- if (ifd == NULL)
- return (USBD_IOERROR);
- usbd_interface2device_handle(iface, &dev);
- req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- req.bRequest = UR_SET_IDLE;
- USETW2(req.wValue, duration, id);
- USETW(req.wIndex, ifd->bInterfaceNumber);
- USETW(req.wLength, 0);
- return (usbd_do_request(dev, &req, 0));
-}
-
-usbd_status
-usbd_get_report_descriptor(usbd_device_handle dev, int ifcno,
- int size, void *d)
-{
- usb_device_request_t req;
-
- req.bmRequestType = UT_READ_INTERFACE;
- req.bRequest = UR_GET_DESCRIPTOR;
- USETW2(req.wValue, UDESC_REPORT, 0); /* report id should be 0 */
- USETW(req.wIndex, ifcno);
- USETW(req.wLength, size);
- return (usbd_do_request(dev, &req, d));
-}
-
-usb_hid_descriptor_t *
-usbd_get_hid_descriptor(usbd_interface_handle ifc)
-{
- usb_interface_descriptor_t *idesc = usbd_get_interface_descriptor(ifc);
- usbd_device_handle dev;
- usb_config_descriptor_t *cdesc;
- usb_hid_descriptor_t *hd;
- char *p, *end;
-
- if (idesc == NULL)
- return (NULL);
- usbd_interface2device_handle(ifc, &dev);
- cdesc = usbd_get_config_descriptor(dev);
-
- p = (char *)idesc + idesc->bLength;
- end = (char *)cdesc + UGETW(cdesc->wTotalLength);
-
- for (; p < end; p += hd->bLength) {
- hd = (usb_hid_descriptor_t *)p;
- if (p + hd->bLength <= end && hd->bDescriptorType == UDESC_HID)
- return (hd);
- if (hd->bDescriptorType == UDESC_INTERFACE)
- break;
- }
- return (NULL);
-}
-
-usbd_status
-usbd_read_report_desc(usbd_interface_handle ifc, void **descp, int *sizep,
- struct malloc_type *mem)
-{
- usb_interface_descriptor_t *id;
- usb_hid_descriptor_t *hid;
- usbd_device_handle dev;
- usbd_status err;
-
- usbd_interface2device_handle(ifc, &dev);
- id = usbd_get_interface_descriptor(ifc);
- if (id == NULL)
- return (USBD_INVAL);
- hid = usbd_get_hid_descriptor(ifc);
- if (hid == NULL)
- return (USBD_IOERROR);
- *sizep = UGETW(hid->descrs[0].wDescriptorLength);
- *descp = malloc(*sizep, mem, M_NOWAIT);
- if (*descp == NULL)
- return (USBD_NOMEM);
- err = usbd_get_report_descriptor(dev, id->bInterfaceNumber,
- *sizep, *descp);
- if (err) {
- free(*descp, mem);
- *descp = NULL;
- return (err);
- }
- return (USBD_NORMAL_COMPLETION);
-}
-
-usbd_status
-usbd_get_config(usbd_device_handle dev, u_int8_t *conf)
-{
- usb_device_request_t req;
-
- req.bmRequestType = UT_READ_DEVICE;
- req.bRequest = UR_GET_CONFIG;
- USETW(req.wValue, 0);
- USETW(req.wIndex, 0);
- USETW(req.wLength, 1);
- return (usbd_do_request(dev, &req, conf));
-}
-
-static void usbd_bulk_transfer_cb(usbd_xfer_handle xfer,
- usbd_private_handle priv, usbd_status status);
-static void
-usbd_bulk_transfer_cb(usbd_xfer_handle xfer, usbd_private_handle priv,
- usbd_status status)
-{
- wakeup(xfer);
-}
-
-usbd_status
-usbd_bulk_transfer(usbd_xfer_handle xfer, usbd_pipe_handle pipe,
- u_int16_t flags, u_int32_t timeout, void *buf,
- u_int32_t *size, char *lbl)
-{
- usbd_status err;
- int s, error;
-
- usbd_setup_xfer(xfer, pipe, 0, buf, *size,
- flags, timeout, usbd_bulk_transfer_cb);
- DPRINTFN(1, ("usbd_bulk_transfer: start transfer %d bytes\n", *size));
- s = splusb(); /* don't want callback until tsleep() */
- err = usbd_transfer(xfer);
- if (err != USBD_IN_PROGRESS) {
- splx(s);
- return (err);
- }
- error = tsleep((caddr_t)xfer, PZERO | PCATCH, lbl, 0);
- splx(s);
- if (error) {
- DPRINTF(("usbd_bulk_transfer: tsleep=%d\n", error));
- usbd_abort_pipe(pipe);
- return (USBD_INTERRUPTED);
- }
- usbd_get_xfer_status(xfer, NULL, NULL, size, &err);
- DPRINTFN(1,("usbd_bulk_transfer: transferred %d\n", *size));
- if (err) {
- DPRINTF(("usbd_bulk_transfer: error=%d\n", err));
- usbd_clear_endpoint_stall(pipe);
- }
- return (err);
-}
-
-static void usbd_intr_transfer_cb(usbd_xfer_handle xfer,
- usbd_private_handle priv, usbd_status status);
-static void
-usbd_intr_transfer_cb(usbd_xfer_handle xfer, usbd_private_handle priv,
- usbd_status status)
-{
- wakeup(xfer);
-}
-
-usbd_status
-usbd_intr_transfer(usbd_xfer_handle xfer, usbd_pipe_handle pipe,
- u_int16_t flags, u_int32_t timeout, void *buf,
- u_int32_t *size, char *lbl)
-{
- usbd_status err;
- int s, error;
-
- usbd_setup_xfer(xfer, pipe, 0, buf, *size,
- flags, timeout, usbd_intr_transfer_cb);
- DPRINTFN(1, ("usbd_intr_transfer: start transfer %d bytes\n", *size));
- s = splusb(); /* don't want callback until tsleep() */
- err = usbd_transfer(xfer);
- if (err != USBD_IN_PROGRESS) {
- splx(s);
- return (err);
- }
- error = tsleep(xfer, PZERO | PCATCH, lbl, 0);
- splx(s);
- if (error) {
- DPRINTF(("usbd_intr_transfer: tsleep=%d\n", error));
- usbd_abort_pipe(pipe);
- return (USBD_INTERRUPTED);
- }
- usbd_get_xfer_status(xfer, NULL, NULL, size, &err);
- DPRINTFN(1,("usbd_intr_transfer: transferred %d\n", *size));
- if (err) {
- DPRINTF(("usbd_intr_transfer: error=%d\n", err));
- usbd_clear_endpoint_stall(pipe);
- }
- return (err);
-}
-
-void
-usb_detach_wait(device_t dv)
-{
- DPRINTF(("usb_detach_wait: waiting for %s\n", device_get_nameunit(dv)));
- if (tsleep(dv, PZERO, "usbdet", hz * 60))
- printf("usb_detach_wait: %s didn't detach\n",
- device_get_nameunit(dv));
- DPRINTF(("usb_detach_wait: %s done\n", device_get_nameunit(dv)));
-}
-
-void
-usb_detach_wakeup(device_t dv)
-{
- DPRINTF(("usb_detach_wakeup: for %s\n", device_get_nameunit(dv)));
- wakeup(dv);
-}
-
-const usb_descriptor_t *
-usb_find_desc(usbd_device_handle dev, int type, int subtype)
-{
- usbd_desc_iter_t iter;
- const usb_descriptor_t *desc;
-
- usb_desc_iter_init(dev, &iter);
- for (;;) {
- desc = usb_desc_iter_next(&iter);
- if (!desc || (desc->bDescriptorType == type &&
- (subtype == USBD_SUBTYPE_ANY ||
- subtype == desc->bDescriptorSubtype)))
- break;
- }
- return desc;
-}
diff --git a/sys/dev/usb/usbdi_util.h b/sys/dev/usb/usbdi_util.h
deleted file mode 100644
index b535f0c..0000000
--- a/sys/dev/usb/usbdi_util.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/* $NetBSD: usbdi_util.h,v 1.31 2004/12/03 08:53:40 augustss Exp $ */
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) 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.
- */
-
-#ifndef _USBI_UTIL_H_
-#define _USBI_UTIL_H_
-usbd_status usbd_get_desc(usbd_device_handle dev, int type,
- int index, int len, void *desc);
-usbd_status usbd_get_config_desc(usbd_device_handle, int,
- usb_config_descriptor_t *);
-usbd_status usbd_get_config_desc_full(usbd_device_handle, int, void *, int);
-usbd_status usbd_get_device_desc(usbd_device_handle dev,
- usb_device_descriptor_t *d);
-usbd_status usbd_set_address(usbd_device_handle dev, int addr);
-usbd_status usbd_get_port_status(usbd_device_handle,
- int, usb_port_status_t *);
-usbd_status usbd_set_hub_feature(usbd_device_handle dev, int);
-usbd_status usbd_clear_hub_feature(usbd_device_handle, int);
-usbd_status usbd_set_port_feature(usbd_device_handle dev, int, int);
-usbd_status usbd_clear_port_feature(usbd_device_handle, int, int);
-usbd_status usbd_get_device_status(usbd_device_handle, usb_status_t *);
-usbd_status usbd_get_hub_status(usbd_device_handle, usb_hub_status_t *);
-usbd_status usbd_get_protocol(usbd_interface_handle dev, u_int8_t *report);
-usbd_status usbd_set_protocol(usbd_interface_handle dev, int report);
-usbd_status usbd_get_report_descriptor(usbd_device_handle dev, int ifcno,
- int size, void *d);
-struct usb_hid_descriptor *usbd_get_hid_descriptor(usbd_interface_handle ifc);
-usbd_status usbd_set_report(usbd_interface_handle iface, int type, int id,
- void *data,int len);
-usbd_status usbd_set_report_async(usbd_interface_handle iface, int type,
- int id, void *data, int len);
-usbd_status usbd_get_report(usbd_interface_handle iface, int type, int id,
- void *data, int len);
-usbd_status usbd_set_idle(usbd_interface_handle iface, int duration, int id);
-usbd_status usbd_read_report_desc(usbd_interface_handle ifc, void **descp,
- int *sizep, struct malloc_type *mem);
-usbd_status usbd_get_config(usbd_device_handle dev, u_int8_t *conf);
-usbd_status usbd_get_string_desc(usbd_device_handle dev, int sindex,
- int langid,usb_string_descriptor_t *sdesc,
- int *sizep);
-void usbd_delay_ms(usbd_device_handle, u_int);
-
-
-usbd_status usbd_set_config_no(usbd_device_handle dev, int no, int msg);
-usbd_status usbd_set_config_index(usbd_device_handle dev, int index, int msg);
-
-usbd_status usbd_bulk_transfer(usbd_xfer_handle xfer, usbd_pipe_handle pipe,
- u_int16_t flags, u_int32_t timeout, void *buf,
- u_int32_t *size, char *lbl);
-
-usbd_status usbd_intr_transfer(usbd_xfer_handle xfer, usbd_pipe_handle pipe,
- u_int16_t flags, u_int32_t timeout, void *buf,
- u_int32_t *size, char *lbl);
-
-void usb_detach_wait(device_t);
-void usb_detach_wakeup(device_t);
-
-const usb_descriptor_t *usb_find_desc(usbd_device_handle dev, int type,
- int subtype);
-#define USBD_SUBTYPE_ANY (~0)
-
-#endif /* _USBI_UTIL_H_ */
diff --git a/sys/dev/usb/usbdivar.h b/sys/dev/usb/usbdivar.h
deleted file mode 100644
index 603d691..0000000
--- a/sys/dev/usb/usbdivar.h
+++ /dev/null
@@ -1,322 +0,0 @@
-/* $NetBSD: usbdivar.h,v 1.70 2002/07/11 21:14:36 augustss Exp $ */
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) 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.
- */
-
-/* From usb_mem.h */
-struct usb_dma_block;
-typedef struct {
- struct usb_dma_block *block;
- u_int offs;
- u_int len;
-} usb_dma_t;
-
-struct usbd_xfer;
-struct usbd_pipe;
-
-struct usbd_endpoint {
- usb_endpoint_descriptor_t *edesc;
- int refcnt;
- int savedtoggle;
-};
-
-struct usbd_bus_methods {
- usbd_status (*open_pipe)(struct usbd_pipe *pipe);
- void (*soft_intr)(void *);
- void (*do_poll)(struct usbd_bus *);
- usbd_status (*allocm)(struct usbd_bus *, usb_dma_t *,
- u_int32_t bufsize);
- void (*freem)(struct usbd_bus *, usb_dma_t *);
- struct usbd_xfer * (*allocx)(struct usbd_bus *);
- void (*freex)(struct usbd_bus *, struct usbd_xfer *);
-};
-
-struct usbd_pipe_methods {
- usbd_status (*transfer)(usbd_xfer_handle xfer);
- usbd_status (*start)(usbd_xfer_handle xfer);
- void (*abort)(usbd_xfer_handle xfer);
- void (*close)(usbd_pipe_handle pipe);
- void (*cleartoggle)(usbd_pipe_handle pipe);
- void (*done)(usbd_xfer_handle xfer);
-};
-
-struct usbd_tt {
- struct usbd_hub *hub;
-};
-
-struct usbd_port {
- usb_port_status_t status;
- u_int16_t power; /* mA of current on port */
- u_int8_t portno;
- u_int8_t restartcnt;
-#define USBD_RESTART_MAX 5
- struct usbd_device *device; /* Connected device */
- struct usbd_device *parent; /* The ports hub */
- struct usbd_tt *tt; /* Transaction translator (if any) */
-};
-
-struct usbd_hub {
- usbd_status (*explore)(usbd_device_handle hub);
- void *hubsoftc;
- usb_hub_descriptor_t hubdesc;
- struct usbd_port ports[1];
-};
-
-struct usb_softc;
-
-/*****/
-
-struct usbd_bus {
- /* Filled by HC driver */
- device_t bdev; /* base device, host adapter */
- struct usbd_bus_methods *methods;
- u_int32_t pipe_size; /* size of a pipe struct */
- /* Filled by usb driver */
- struct usbd_device *root_hub;
- usbd_device_handle devices[USB_MAX_DEVICES];
- char needs_explore;/* a hub a signalled a change */
- char use_polling;
- struct usb_softc *usbctl;
- 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
-#define USBREV_2_0 4
-#define USBREV_STR { "unknown", "pre 1.0", "1.0", "1.1", "2.0" }
-
-#ifdef USB_USE_SOFTINTR
-#ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
- void *soft; /* soft interrupt cookie */
-#else
- struct callout softi;
-#endif
-#endif
-
- bus_dma_tag_t parent_dmatag; /* Base DMA tag */
- bus_dma_tag_t buffer_dmatag; /* Tag for transfer buffers */
-};
-
-struct usbd_device {
- 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 speed; /* low/full/high speed */
- 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_device *myhub; /* upstream hub */
- struct usbd_port *myhsport; /* closest high speed port */
- 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 */
- const struct usbd_quirks *quirks; /* device quirks, always set */
- struct usbd_hub *hub; /* only if this is a hub */
- device_t *subdevs; /* sub-devices, 0 terminated */
- uint8_t *ifacenums; /* sub-device interfacenumbers */
-};
-
-struct usbd_interface {
- struct usbd_device *device;
- usb_interface_descriptor_t *idesc;
- int index;
- int altindex;
- struct usbd_endpoint *endpoints;
- void *priv;
- LIST_HEAD(, usbd_pipe) pipes;
-};
-
-struct usbd_pipe {
- struct usbd_interface *iface;
- struct usbd_device *device;
- struct usbd_endpoint *endpoint;
- int refcnt;
- char running;
- char aborting;
- STAILQ_HEAD(, usbd_xfer) queue;
- LIST_ENTRY(usbd_pipe) next;
-
- usbd_xfer_handle intrxfer; /* used for repeating requests */
- char repeat;
- int interval;
-
- /* Filled by HC driver. */
- struct usbd_pipe_methods *methods;
-};
-
-#define USB_DMA_NSEG (btoc(MAXPHYS) + 1)
-
-/* DMA-capable memory buffer. */
-struct usb_dma_mapping {
- bus_dma_segment_t segs[USB_DMA_NSEG]; /* The physical segments. */
- int nsegs; /* Number of segments. */
- bus_dmamap_t map; /* DMA mapping. */
-};
-
-struct usbd_xfer {
- struct usbd_pipe *pipe;
- void *priv;
- void *buffer;
- u_int32_t length;
- u_int32_t actlen;
- u_int16_t flags;
- u_int32_t timeout;
- usbd_status status;
- usbd_callback callback;
- __volatile char done;
-#ifdef DIAGNOSTIC
- u_int32_t busy_free;
-#define XFER_FREE 0x46524545
-#define XFER_BUSY 0x42555359
-#define XFER_ONQU 0x4f4e5155
-#endif
-
- /* For control pipe */
- usb_device_request_t request;
-
- /* For isoc */
- u_int16_t *frlengths;
- int nframes;
-
- /* For memory allocation */
- struct usbd_device *device;
- struct usb_dma_mapping dmamap;
- void *allocbuf;
-
- int rqflags;
-#define URQ_REQUEST 0x01
-#define URQ_AUTO_DMABUF 0x10
-#define URQ_DEV_DMABUF 0x20
-
- STAILQ_ENTRY(usbd_xfer) next;
-
- void *hcpriv; /* private use by the HC driver */
-
- struct callout timeout_handle;
-};
-
-#define URQ_BITS "\20\1REQUEST\5AUTO_DMABUF\6DEV_DMABUF"
-
-void usbd_init(void);
-void usbd_finish(void);
-
-#ifdef USB_DEBUG
-void usbd_dump_iface(struct usbd_interface *iface);
-void usbd_dump_device(struct usbd_device *dev);
-void usbd_dump_endpoint(struct usbd_endpoint *endp);
-void usbd_dump_queue(usbd_pipe_handle pipe);
-void usbd_dump_pipe(usbd_pipe_handle pipe);
-#endif
-
-/* Routines from usb_subr.c */
-int usbctlprint(void *, const char *);
-void usb_delay_ms(usbd_bus_handle, u_int);
-usbd_status usbd_reset_port(usbd_device_handle dev,
- int port, usb_port_status_t *ps);
-usbd_status usbd_setup_pipe(usbd_device_handle dev,
- usbd_interface_handle iface,
- struct usbd_endpoint *, int,
- usbd_pipe_handle *pipe);
-usbd_status usbd_new_device(device_t parent,
- usbd_bus_handle bus, int depth,
- int lowspeed, int port,
- struct usbd_port *);
-void usbd_remove_device(usbd_device_handle, struct usbd_port *);
-int usbd_printBCD(char *cp, int bcd);
-usbd_status usbd_fill_iface_data(usbd_device_handle dev, int i, int a);
-void usb_free_device(usbd_device_handle);
-
-usbd_status usb_insert_transfer(usbd_xfer_handle xfer);
-void usb_transfer_complete(usbd_xfer_handle xfer);
-void usb_disconnect_port(struct usbd_port *up, device_t);
-
-/* Routines from usb.c */
-void usb_needs_explore(usbd_device_handle);
-void usb_schedsoftintr(struct usbd_bus *);
-
-/*
- * XXX This check is extremely bogus. Bad Bad Bad.
- */
-#if defined(DIAGNOSTIC) && 0
-#define SPLUSBCHECK \
- do { int _s = splusb(), _su = splusb(); \
- if (!cold && _s != _su) printf("SPLUSBCHECK failed 0x%x!=0x%x, %s:%d\n", \
- _s, _su, __FILE__, __LINE__); \
- splx(_s); \
- } while (0)
-#else
-#define SPLUSBCHECK
-#endif
-
-/* Locator stuff. */
-
-/* XXX these values are used to statically bind some elements in the USB tree
- * to specific driver instances. This should be somehow emulated in FreeBSD
- * but can be done later on.
- * The values are copied from the files.usb file in the NetBSD sources.
- */
-#define UHUBCF_PORT_DEFAULT -1
-#define UHUBCF_CONFIGURATION_DEFAULT -1
-#define UHUBCF_INTERFACE_DEFAULT -1
-#define UHUBCF_VENDOR_DEFAULT -1
-#define UHUBCF_PRODUCT_DEFAULT -1
-#define UHUBCF_RELEASE_DEFAULT -1
-
-#define uhubcf_port cf_loc[UHUBCF_PORT]
-#define uhubcf_configuration cf_loc[UHUBCF_CONFIGURATION]
-#define uhubcf_interface cf_loc[UHUBCF_INTERFACE]
-#define uhubcf_vendor cf_loc[UHUBCF_VENDOR]
-#define uhubcf_product cf_loc[UHUBCF_PRODUCT]
-#define uhubcf_release cf_loc[UHUBCF_RELEASE]
-#define UHUB_UNK_PORT UHUBCF_PORT_DEFAULT /* wildcarded 'port' */
-#define UHUB_UNK_CONFIGURATION UHUBCF_CONFIGURATION_DEFAULT /* wildcarded 'configuration' */
-#define UHUB_UNK_INTERFACE UHUBCF_INTERFACE_DEFAULT /* wildcarded 'interface' */
-#define UHUB_UNK_VENDOR UHUBCF_VENDOR_DEFAULT /* wildcarded 'vendor' */
-#define UHUB_UNK_PRODUCT UHUBCF_PRODUCT_DEFAULT /* wildcarded 'product' */
-#define UHUB_UNK_RELEASE UHUBCF_RELEASE_DEFAULT /* wildcarded 'release' */
-
diff --git a/sys/dev/usb/usbhid.h b/sys/dev/usb/usbhid.h
deleted file mode 100644
index 8e0ecd5..0000000
--- a/sys/dev/usb/usbhid.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/* $NetBSD: usbhid.h,v 1.9 2000/09/03 19:09:14 augustss Exp $ */
-/* $FreeBSD$ */
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) 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.
- */
-
-
-#ifndef _USBHID_H_
-#define _USBHID_H_
-
-#define UR_GET_HID_DESCRIPTOR 0x06
-#define UDESC_HID 0x21
-#define UDESC_REPORT 0x22
-#define UDESC_PHYSICAL 0x23
-#define UR_SET_HID_DESCRIPTOR 0x07
-#define UR_GET_REPORT 0x01
-#define UR_SET_REPORT 0x09
-#define UR_GET_IDLE 0x02
-#define UR_SET_IDLE 0x0a
-#define UR_GET_PROTOCOL 0x03
-#define UR_SET_PROTOCOL 0x0b
-
-typedef struct usb_hid_descriptor {
- uByte bLength;
- uByte bDescriptorType;
- uWord bcdHID;
- uByte bCountryCode;
- uByte bNumDescriptors;
- struct {
- uByte bDescriptorType;
- uWord wDescriptorLength;
- } descrs[1];
-} UPACKED usb_hid_descriptor_t;
-#define USB_HID_DESCRIPTOR_SIZE(n) (9+(n)*3)
-
-/* Usage pages */
-#define HUP_UNDEFINED 0x0000
-#define HUP_GENERIC_DESKTOP 0x0001
-#define HUP_SIMULATION 0x0002
-#define HUP_VR_CONTROLS 0x0003
-#define HUP_SPORTS_CONTROLS 0x0004
-#define HUP_GAMING_CONTROLS 0x0005
-#define HUP_KEYBOARD 0x0007
-#define HUP_LEDS 0x0008
-#define HUP_BUTTON 0x0009
-#define HUP_ORDINALS 0x000a
-#define HUP_TELEPHONY 0x000b
-#define HUP_CONSUMER 0x000c
-#define HUP_DIGITIZERS 0x000d
-#define HUP_PHYSICAL_IFACE 0x000e
-#define HUP_UNICODE 0x0010
-#define HUP_ALPHANUM_DISPLAY 0x0014
-#define HUP_MONITOR 0x0080
-#define HUP_MONITOR_ENUM_VAL 0x0081
-#define HUP_VESA_VC 0x0082
-#define HUP_VESA_CMD 0x0083
-#define HUP_POWER 0x0084
-#define HUP_BATTERY_SYSTEM 0x0085
-#define HUP_BARCODE_SCANNER 0x008b
-#define HUP_SCALE 0x008c
-#define HUP_CAMERA_CONTROL 0x0090
-#define HUP_ARCADE 0x0091
-#define HUP_MICROSOFT 0xff00
-
-/* Usages, generic desktop */
-#define HUG_POINTER 0x0001
-#define HUG_MOUSE 0x0002
-#define HUG_JOYSTICK 0x0004
-#define HUG_GAME_PAD 0x0005
-#define HUG_KEYBOARD 0x0006
-#define HUG_KEYPAD 0x0007
-#define HUG_X 0x0030
-#define HUG_Y 0x0031
-#define HUG_Z 0x0032
-#define HUG_RX 0x0033
-#define HUG_RY 0x0034
-#define HUG_RZ 0x0035
-#define HUG_SLIDER 0x0036
-#define HUG_DIAL 0x0037
-#define HUG_WHEEL 0x0038
-#define HUG_HAT_SWITCH 0x0039
-#define HUG_COUNTED_BUFFER 0x003a
-#define HUG_BYTE_COUNT 0x003b
-#define HUG_MOTION_WAKEUP 0x003c
-#define HUG_VX 0x0040
-#define HUG_VY 0x0041
-#define HUG_VZ 0x0042
-#define HUG_VBRX 0x0043
-#define HUG_VBRY 0x0044
-#define HUG_VBRZ 0x0045
-#define HUG_VNO 0x0046
-#define HUG_TWHEEL 0x0048 // M$ Wireless Intellimouse Wheel
-#define HUG_SYSTEM_CONTROL 0x0080
-#define HUG_SYSTEM_POWER_DOWN 0x0081
-#define HUG_SYSTEM_SLEEP 0x0082
-#define HUG_SYSTEM_WAKEUP 0x0083
-#define HUG_SYSTEM_CONTEXT_MENU 0x0084
-#define HUG_SYSTEM_MAIN_MENU 0x0085
-#define HUG_SYSTEM_APP_MENU 0x0086
-#define HUG_SYSTEM_MENU_HELP 0x0087
-#define HUG_SYSTEM_MENU_EXIT 0x0088
-#define HUG_SYSTEM_MENU_SELECT 0x0089
-#define HUG_SYSTEM_MENU_RIGHT 0x008a
-#define HUG_SYSTEM_MENU_LEFT 0x008b
-#define HUG_SYSTEM_MENU_UP 0x008c
-#define HUG_SYSTEM_MENU_DOWN 0x008d
-
-/* Usages Digitizers */
-#define HUD_UNDEFINED 0x0000
-#define HUD_TIP_PRESSURE 0x0030
-#define HUD_BARREL_PRESSURE 0x0031
-#define HUD_IN_RANGE 0x0032
-#define HUD_TOUCH 0x0033
-#define HUD_UNTOUCH 0x0034
-#define HUD_TAP 0x0035
-#define HUD_QUALITY 0x0036
-#define HUD_DATA_VALID 0x0037
-#define HUD_TRANSDUCER_INDEX 0x0038
-#define HUD_TABLET_FKEYS 0x0039
-#define HUD_PROGRAM_CHANGE_KEYS 0x003a
-#define HUD_BATTERY_STRENGTH 0x003b
-#define HUD_INVERT 0x003c
-#define HUD_X_TILT 0x003d
-#define HUD_Y_TILT 0x003e
-#define HUD_AZIMUTH 0x003f
-#define HUD_ALTITUDE 0x0040
-#define HUD_TWIST 0x0041
-#define HUD_TIP_SWITCH 0x0042
-#define HUD_SEC_TIP_SWITCH 0x0043
-#define HUD_BARREL_SWITCH 0x0044
-#define HUD_ERASER 0x0045
-#define HUD_TABLET_PICK 0x0046
-
-#define HID_USAGE2(p,u) (((p) << 16) | u)
-
-#define UHID_INPUT_REPORT 0x01
-#define UHID_OUTPUT_REPORT 0x02
-#define UHID_FEATURE_REPORT 0x03
-
-/* Bits in the input/output/feature items */
-#define HIO_CONST 0x001
-#define HIO_VARIABLE 0x002
-#define HIO_RELATIVE 0x004
-#define HIO_WRAP 0x008
-#define HIO_NONLINEAR 0x010
-#define HIO_NOPREF 0x020
-#define HIO_NULLSTATE 0x040
-#define HIO_VOLATILE 0x080
-#define HIO_BUFBYTES 0x100
-
-#endif /* _USBHID_H_ */
diff --git a/sys/dev/usb/uscanner.c b/sys/dev/usb/uscanner.c
deleted file mode 100644
index bff3a48..0000000
--- a/sys/dev/usb/uscanner.c
+++ /dev/null
@@ -1,723 +0,0 @@
-/* $NetBSD: uscanner.c,v 1.30 2002/07/11 21:14:36 augustss Exp$ */
-
-/* Also already merged from NetBSD:
- * $NetBSD: uscanner.c,v 1.33 2002/09/23 05:51:24 simonb Exp $
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*-
- * Copyright (c) 2000 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) at
- * Carlstedt Research & Technology
- * and Nick Hibma (n_hibma@qubesoft.com).
- *
- * 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.
- */
-
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/conf.h>
-#include <sys/fcntl.h>
-#include <sys/filio.h>
-#include <sys/tty.h>
-#include <sys/file.h>
-#include <sys/selinfo.h>
-#include <sys/proc.h>
-#include <sys/poll.h>
-#include <sys/conf.h>
-#include <sys/sysctl.h>
-#include <sys/uio.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-
-#include "usbdevs.h"
-
-#ifdef USB_DEBUG
-#define DPRINTF(x) if (uscannerdebug) printf x
-#define DPRINTFN(n,x) if (uscannerdebug>(n)) printf x
-int uscannerdebug = 0;
-SYSCTL_NODE(_hw_usb, OID_AUTO, uscanner, CTLFLAG_RW, 0, "USB uscanner");
-SYSCTL_INT(_hw_usb_uscanner, OID_AUTO, debug, CTLFLAG_RW,
- &uscannerdebug, 0, "uscanner debug level");
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-struct uscan_info {
- struct usb_devno devno;
- u_int flags;
-#define USC_KEEP_OPEN 1
-};
-
-/* Table of scanners that may work with this driver. */
-static const struct uscan_info uscanner_devs[] = {
-
- /*
- * These first two entries are duplicates of known-working units,
- * so one can patch them to test support for newer devices
- * without rebuilding the module.
- */
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_6000 }, 0 }, /* duplicate */
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_6000 }, 0 }, /* duplicate */
-
- /* Acer Peripherals */
- {{ USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_320U }, 0 },
- {{ USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_4300U }, 0 },
- {{ USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_640U }, 0 },
- {{ USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_640BT }, 0 },
- {{ USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_620U }, 0 },
- {{ USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_1240U }, 0 },
- {{ USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_C310U }, 0 },
-
- /* AGFA */
- {{ USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCAN1236U }, 0 },
- {{ USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCAN1212U }, 0 },
- {{ USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCAN1212U2 }, 0 },
- {{ USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANTOUCH }, 0 },
- {{ USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE40 }, 0 },
- {{ USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE50 }, 0 },
- {{ USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE20 }, 0 },
- {{ USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE25 }, 0 },
- {{ USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE26 }, 0 },
- {{ USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANE52 }, 0 },
-
- /* Avision */
- {{ USB_VENDOR_AVISION, USB_PRODUCT_AVISION_1200U }, 0 },
-
- /* Canon */
- {{ USB_VENDOR_CANON, USB_PRODUCT_CANON_N656U }, 0 },
- {{ USB_VENDOR_CANON, USB_PRODUCT_CANON_N676U }, 0 },
- {{ USB_VENDOR_CANON, USB_PRODUCT_CANON_N1220U }, 0 },
- {{ USB_VENDOR_CANON, USB_PRODUCT_CANON_D660U }, 0 },
- {{ USB_VENDOR_CANON, USB_PRODUCT_CANON_N1240U }, 0 },
- {{ USB_VENDOR_CANON, USB_PRODUCT_CANON_LIDE25 }, 0 },
-
- /* Kye */
- {{ USB_VENDOR_KYE, USB_PRODUCT_KYE_VIVIDPRO }, 0 },
-
- /* HP */
- {{ USB_VENDOR_HP, USB_PRODUCT_HP_2200C }, 0 },
- {{ USB_VENDOR_HP, USB_PRODUCT_HP_3300C }, 0 },
- {{ USB_VENDOR_HP, USB_PRODUCT_HP_3400CSE }, 0 },
- {{ USB_VENDOR_HP, USB_PRODUCT_HP_4100C }, 0 },
- {{ USB_VENDOR_HP, USB_PRODUCT_HP_4200C }, 0 },
- {{ USB_VENDOR_HP, USB_PRODUCT_HP_4300C }, 0 },
- {{ USB_VENDOR_HP, USB_PRODUCT_HP_4470C }, 0 },
- {{ USB_VENDOR_HP, USB_PRODUCT_HP_4670V }, 0 },
- {{ USB_VENDOR_HP, USB_PRODUCT_HP_S20 }, 0 },
- {{ USB_VENDOR_HP, USB_PRODUCT_HP_5200C }, 0 },
- {{ USB_VENDOR_HP, USB_PRODUCT_HP_5300C }, 0 },
- {{ USB_VENDOR_HP, USB_PRODUCT_HP_5400C }, 0 },
- {{ USB_VENDOR_HP, USB_PRODUCT_HP_6200C }, 0 },
- {{ USB_VENDOR_HP, USB_PRODUCT_HP_6300C }, 0 },
- {{ USB_VENDOR_HP, USB_PRODUCT_HP_82x0C }, 0 },
-
- /* Microtek */
- {{ USB_VENDOR_SCANLOGIC, USB_PRODUCT_SCANLOGIC_336CX }, 0 },
- {{ USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_X6U }, 0 },
- {{ USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_336CX }, 0 },
- {{ USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_336CX2 }, 0 },
- {{ USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_C6 }, 0 },
- {{ USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_V6USL }, 0 },
- {{ USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_V6USL2 }, 0 },
- {{ USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_V6UL }, 0 },
-
- /* Minolta */
- {{ USB_VENDOR_MINOLTA, USB_PRODUCT_MINOLTA_5400 }, 0 },
-
- /* Mustek */
- {{ USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_1200CU }, 0 },
- {{ USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_BEARPAW1200F }, 0 },
- {{ USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_BEARPAW1200TA }, 0 },
- {{ USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_600USB }, 0 },
- {{ USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_600CU }, 0 },
- {{ USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_1200USB }, 0 },
- {{ USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_1200UB }, 0 },
- {{ USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_1200USBPLUS }, 0 },
- {{ USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_1200CUPLUS }, 0 },
-
- /* National */
- {{ USB_VENDOR_NATIONAL, USB_PRODUCT_NATIONAL_BEARPAW1200 }, 0 },
- {{ USB_VENDOR_NATIONAL, USB_PRODUCT_NATIONAL_BEARPAW2400 }, 0 },
-
- /* Nikon */
- {{ USB_VENDOR_NIKON, USB_PRODUCT_NIKON_LS40 }, 0 },
-
- /* Primax */
- {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2X300 }, 0 },
- {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2E300 }, 0 },
- {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2300 }, 0 },
- {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2E3002 }, 0 },
- {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_9600 }, 0 },
- {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_600U }, 0 },
- {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_6200 }, 0 },
- {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_19200 }, 0 },
- {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_1200U }, 0 },
- {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G600 }, 0 },
- {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_636I }, 0 },
- {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2600 }, 0 },
- {{ USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2E600 }, 0 },
-
- /* Epson */
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_636 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_610 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1200 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1240 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1250 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1600 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1640 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_640U }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1650 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1660 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1670 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1260 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1270 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_RX425 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_3200 }, USC_KEEP_OPEN },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_GT9700F }, USC_KEEP_OPEN },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_GT9300UF }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_2480 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_3500 }, USC_KEEP_OPEN },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_3590 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_4200 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_4800 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_4990 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_5000 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_6000 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_CX5400 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_DX7400 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_DX8400 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_CX5400 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_DX3800 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_DX4000 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_NX300 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_SX200 }, 0 },
- {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_SX400 }, 0 },
-
- /* UMAX */
- {{ USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA1220U }, 0 },
- {{ USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA1236U }, 0 },
- {{ USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA2000U }, 0 },
- {{ USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA2100U }, 0 },
- {{ USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA2200U }, 0 },
- {{ USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA3400 }, 0 },
-
- /* Visioneer */
- {{ USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_3000 }, 0 },
- {{ USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_5300 }, 0 },
- {{ USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_7600 }, 0 },
- {{ USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_6100 }, 0 },
- {{ USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_6200 }, 0 },
- {{ USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_8100 }, 0 },
- {{ USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_8600 }, 0 },
-
- /* Ultima */
- {{ USB_VENDOR_ULTIMA, USB_PRODUCT_ULTIMA_1200UBPLUS }, 0 },
-
-};
-#define uscanner_lookup(v, p) ((const struct uscan_info *)usb_lookup(uscanner_devs, v, p))
-
-#define USCANNER_BUFFERSIZE 1024
-
-struct uscanner_softc {
- device_t sc_dev; /* base device */
- usbd_device_handle sc_udev;
- usbd_interface_handle sc_iface;
- struct cdev *dev;
-
- u_int sc_dev_flags;
-
- usbd_pipe_handle sc_bulkin_pipe;
- int sc_bulkin;
- usbd_xfer_handle sc_bulkin_xfer;
- void *sc_bulkin_buffer;
- int sc_bulkin_bufferlen;
- int sc_bulkin_datalen;
-
- usbd_pipe_handle sc_bulkout_pipe;
- int sc_bulkout;
- usbd_xfer_handle sc_bulkout_xfer;
- void *sc_bulkout_buffer;
- int sc_bulkout_bufferlen;
- int sc_bulkout_datalen;
-
- u_char sc_state;
-#define USCANNER_OPEN 0x01 /* opened */
-
- int sc_refcnt;
- u_char sc_dying;
-};
-
-d_open_t uscanneropen;
-d_close_t uscannerclose;
-d_read_t uscannerread;
-d_write_t uscannerwrite;
-d_poll_t uscannerpoll;
-
-
-static struct cdevsw uscanner_cdevsw = {
- .d_version = D_VERSION,
- .d_flags = D_NEEDGIANT,
- .d_open = uscanneropen,
- .d_close = uscannerclose,
- .d_read = uscannerread,
- .d_write = uscannerwrite,
- .d_poll = uscannerpoll,
- .d_name = "uscanner",
-};
-
-static int uscanner_do_read(struct uscanner_softc *, struct uio *, int);
-static int uscanner_do_write(struct uscanner_softc *, struct uio *, int);
-static void uscanner_do_close(struct uscanner_softc *);
-
-#define USCANNERUNIT(n) (dev2unit(n))
-
-static device_probe_t uscanner_match;
-static device_attach_t uscanner_attach;
-static device_detach_t uscanner_detach;
-
-static device_method_t uscanner_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, uscanner_match),
- DEVMETHOD(device_attach, uscanner_attach),
- DEVMETHOD(device_detach, uscanner_detach),
-
- { 0, 0 }
-};
-
-static driver_t uscanner_driver = {
- "uscanner",
- uscanner_methods,
- sizeof(struct uscanner_softc)
-};
-
-static devclass_t uscanner_devclass;
-
-static int
-uscanner_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usb_interface_descriptor_t *id;
-
- if (uaa->iface == NULL)
- return UMATCH_NONE; /* do not grab the entire device */
-
- if (uscanner_lookup(uaa->vendor, uaa->product) == NULL)
- return UMATCH_NONE; /* not in the list of known devices */
- id = usbd_get_interface_descriptor(uaa->iface);
- if (id == NULL)
- return UMATCH_NONE;
-
- /*
- * There isn't a specific UICLASS for scanners, many vendors use
- * UICLASS_VENDOR, so detecting the right interface is not so easy.
- * But certainly we can exclude PRINTER and MASS - which some
- * multifunction devices implement.
- */
- if (id->bInterfaceClass == UICLASS_PRINTER ||
- id->bInterfaceClass == UICLASS_MASS)
- return UMATCH_NONE;
-
- return UMATCH_VENDOR_PRODUCT; /* ok we found it */
-}
-
-static int
-uscanner_attach(device_t self)
-{
- struct uscanner_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usb_interface_descriptor_t *id = 0;
- usb_endpoint_descriptor_t *ed, *ed_bulkin = NULL, *ed_bulkout = NULL;
- int i;
- usbd_status err;
- int ifnum;
-
- sc->sc_dev = self;
- sc->sc_dev_flags = uscanner_lookup(uaa->vendor, uaa->product)->flags;
- sc->sc_udev = uaa->device;
-
- id = usbd_get_interface_descriptor(uaa->iface);
- ifnum = id->bInterfaceNumber;
-#if 0
- /*
- * This was in the original driver, but we cannot change the
- * configuration of the whole device while attaching only to
- * one of its interfaces. This can kill other already-attached
- * driver, and/or possibly prevent this driver from attaching
- * if an error occurs in set_config_no.
- * If a device need setting the configuration, this must be done
- * before attaching drivers to the various interfaces.
- */
- err = usbd_set_config_no(uaa->device, 1, 1); /* XXX */
- if (err) {
- printf("%s: setting config no failed\n",
- device_get_nameunit(sc->sc_dev));
- return ENXIO;
- }
-#endif
- err = usbd_device2interface_handle(sc->sc_udev, ifnum, &sc->sc_iface);
- if (!err && sc->sc_iface)
- id = usbd_get_interface_descriptor(sc->sc_iface);
- if (err || id == 0) {
- printf("%s: could not get interface descriptor, err=%d,id=%p\n",
- device_get_nameunit(sc->sc_dev), err, id);
- return ENXIO;
- }
-
- /* Find the two first bulk endpoints */
- for (i = 0 ; i < id->bNumEndpoints; i++) {
- ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
- if (ed == 0) {
- printf("%s: could not read endpoint descriptor\n",
- device_get_nameunit(sc->sc_dev));
- return ENXIO;
- }
-
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN
- && (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
- ed_bulkin = ed;
- } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT
- && (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
- ed_bulkout = ed;
- }
-
- if (ed_bulkin && ed_bulkout) /* found all we need */
- break;
- }
-
- /* Verify that we goething sensible */
- if (ed_bulkin == NULL || ed_bulkout == NULL) {
- printf("%s: bulk-in and/or bulk-out endpoint not found\n",
- device_get_nameunit(sc->sc_dev));
- return ENXIO;
- }
-
- sc->sc_bulkin = ed_bulkin->bEndpointAddress;
- sc->sc_bulkout = ed_bulkout->bEndpointAddress;
-
- /* the main device, ctrl endpoint */
- sc->dev = make_dev(&uscanner_cdevsw, device_get_unit(sc->sc_dev),
- UID_ROOT, GID_OPERATOR, 0644, "%s", device_get_nameunit(sc->sc_dev));
- usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,sc->sc_dev);
-
- return 0;
-}
-
-int
-uscanneropen(struct cdev *dev, int flag, int mode, struct thread *p)
-{
- struct uscanner_softc *sc;
- int unit = USCANNERUNIT(dev);
- usbd_status err;
-
- sc = devclass_get_softc(uscanner_devclass, unit);
- if (sc == NULL)
- return (ENXIO);
-
- DPRINTFN(5, ("uscanneropen: flag=%d, mode=%d, unit=%d\n",
- flag, mode, unit));
-
- if (sc->sc_dying)
- return (ENXIO);
-
- if (sc->sc_state & USCANNER_OPEN)
- return (EBUSY);
-
- sc->sc_state |= USCANNER_OPEN;
-
- sc->sc_bulkin_buffer = malloc(USCANNER_BUFFERSIZE, M_USBDEV, M_WAITOK);
- sc->sc_bulkout_buffer = malloc(USCANNER_BUFFERSIZE, M_USBDEV, M_WAITOK);
- /* No need to check buffers for NULL since we have WAITOK */
-
- sc->sc_bulkin_bufferlen = USCANNER_BUFFERSIZE;
- sc->sc_bulkout_bufferlen = USCANNER_BUFFERSIZE;
-
- /* We have decided on which endpoints to use, now open the pipes */
- if (sc->sc_bulkin_pipe == NULL) {
- err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkin,
- USBD_EXCLUSIVE_USE, &sc->sc_bulkin_pipe);
- if (err) {
- printf("%s: cannot open bulk-in pipe (addr %d)\n",
- device_get_nameunit(sc->sc_dev), sc->sc_bulkin);
- uscanner_do_close(sc);
- return (EIO);
- }
- }
- if (sc->sc_bulkout_pipe == NULL) {
- err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkout,
- USBD_EXCLUSIVE_USE, &sc->sc_bulkout_pipe);
- if (err) {
- printf("%s: cannot open bulk-out pipe (addr %d)\n",
- device_get_nameunit(sc->sc_dev), sc->sc_bulkout);
- uscanner_do_close(sc);
- return (EIO);
- }
- }
-
- sc->sc_bulkin_xfer = usbd_alloc_xfer(sc->sc_udev);
- if (sc->sc_bulkin_xfer == NULL) {
- uscanner_do_close(sc);
- return (ENOMEM);
- }
- sc->sc_bulkout_xfer = usbd_alloc_xfer(sc->sc_udev);
- if (sc->sc_bulkout_xfer == NULL) {
- uscanner_do_close(sc);
- return (ENOMEM);
- }
-
- return (0); /* success */
-}
-
-int
-uscannerclose(struct cdev *dev, int flag, int mode, struct thread *p)
-{
- struct uscanner_softc *sc;
-
- sc = devclass_get_softc(uscanner_devclass, USCANNERUNIT(dev));
- DPRINTFN(5, ("uscannerclose: flag=%d, mode=%d, unit=%d\n",
- flag, mode, USCANNERUNIT(dev)));
-
-#ifdef DIAGNOSTIC
- if (!(sc->sc_state & USCANNER_OPEN)) {
- printf("uscannerclose: not open\n");
- return (EINVAL);
- }
-#endif
-
- uscanner_do_close(sc);
-
- return (0);
-}
-
-void
-uscanner_do_close(struct uscanner_softc *sc)
-{
- if (sc->sc_bulkin_xfer) {
- usbd_free_xfer(sc->sc_bulkin_xfer);
- sc->sc_bulkin_xfer = NULL;
- }
- if (sc->sc_bulkout_xfer) {
- usbd_free_xfer(sc->sc_bulkout_xfer);
- sc->sc_bulkout_xfer = NULL;
- }
-
- if (!(sc->sc_dev_flags & USC_KEEP_OPEN)) {
- if (sc->sc_bulkin_pipe != NULL) {
- usbd_abort_pipe(sc->sc_bulkin_pipe);
- usbd_close_pipe(sc->sc_bulkin_pipe);
- sc->sc_bulkin_pipe = NULL;
- }
- if (sc->sc_bulkout_pipe != NULL) {
- usbd_abort_pipe(sc->sc_bulkout_pipe);
- usbd_close_pipe(sc->sc_bulkout_pipe);
- sc->sc_bulkout_pipe = NULL;
- }
- }
-
- if (sc->sc_bulkin_buffer) {
- free(sc->sc_bulkin_buffer, M_USBDEV);
- sc->sc_bulkin_buffer = NULL;
- }
- if (sc->sc_bulkout_buffer) {
- free(sc->sc_bulkout_buffer, M_USBDEV);
- sc->sc_bulkout_buffer = NULL;
- }
-
- sc->sc_state &= ~USCANNER_OPEN;
-}
-
-static int
-uscanner_do_read(struct uscanner_softc *sc, struct uio *uio, int flag)
-{
- u_int32_t n, tn;
- usbd_status err;
- int error = 0;
-
- DPRINTFN(5, ("%s: uscannerread\n", device_get_nameunit(sc->sc_dev)));
-
- if (sc->sc_dying)
- return (EIO);
-
- while ((n = min(sc->sc_bulkin_bufferlen, uio->uio_resid)) != 0) {
- DPRINTFN(1, ("uscannerread: start transfer %d bytes\n",n));
- tn = n;
-
- err = usbd_bulk_transfer(
- sc->sc_bulkin_xfer, sc->sc_bulkin_pipe,
- USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT,
- sc->sc_bulkin_buffer, &tn,
- "uscnrb");
- if (err) {
- if (err == USBD_INTERRUPTED)
- error = EINTR;
- else if (err == USBD_TIMEOUT)
- error = ETIMEDOUT;
- else
- error = EIO;
- break;
- }
- DPRINTFN(1, ("uscannerread: got %d bytes\n", tn));
- error = uiomove(sc->sc_bulkin_buffer, tn, uio);
- if (error || tn < n)
- break;
- }
-
- return (error);
-}
-
-int
-uscannerread(struct cdev *dev, struct uio *uio, int flag)
-{
- struct uscanner_softc *sc;
- int error;
-
- sc = devclass_get_softc(uscanner_devclass, USCANNERUNIT(dev));
- sc->sc_refcnt++;
- error = uscanner_do_read(sc, uio, flag);
- if (--sc->sc_refcnt < 0)
- usb_detach_wakeup(sc->sc_dev);
-
- return (error);
-}
-
-static int
-uscanner_do_write(struct uscanner_softc *sc, struct uio *uio, int flag)
-{
- u_int32_t n;
- int error = 0;
- usbd_status err;
-
- DPRINTFN(5, ("%s: uscanner_do_write\n", device_get_nameunit(sc->sc_dev)));
-
- if (sc->sc_dying)
- return (EIO);
-
- while ((n = min(sc->sc_bulkout_bufferlen, uio->uio_resid)) != 0) {
- error = uiomove(sc->sc_bulkout_buffer, n, uio);
- if (error)
- break;
- DPRINTFN(1, ("uscanner_do_write: transfer %d bytes\n", n));
- err = usbd_bulk_transfer(
- sc->sc_bulkout_xfer, sc->sc_bulkout_pipe,
- 0, USBD_NO_TIMEOUT,
- sc->sc_bulkout_buffer, &n,
- "uscnwb");
- if (err) {
- if (err == USBD_INTERRUPTED)
- error = EINTR;
- else
- error = EIO;
- break;
- }
- }
-
- return (error);
-}
-
-int
-uscannerwrite(struct cdev *dev, struct uio *uio, int flag)
-{
- struct uscanner_softc *sc;
- int error;
-
- sc = devclass_get_softc(uscanner_devclass, USCANNERUNIT(dev));
- sc->sc_refcnt++;
- error = uscanner_do_write(sc, uio, flag);
- if (--sc->sc_refcnt < 0)
- usb_detach_wakeup(sc->sc_dev);
- return (error);
-}
-
-static int
-uscanner_detach(device_t self)
-{
- struct uscanner_softc *sc = device_get_softc(self);
- int s;
-
- DPRINTF(("uscanner_detach: sc=%p\n", sc));
-
- sc->sc_dying = 1;
- sc->sc_dev_flags = 0; /* make close really close device */
-
- /* Abort all pipes. Causes processes waiting for transfer to wake. */
- if (sc->sc_bulkin_pipe != NULL)
- usbd_abort_pipe(sc->sc_bulkin_pipe);
- if (sc->sc_bulkout_pipe != NULL)
- usbd_abort_pipe(sc->sc_bulkout_pipe);
-
- s = splusb();
- if (--sc->sc_refcnt >= 0) {
- /* Wait for processes to go away. */
- usb_detach_wait(sc->sc_dev);
- }
- splx(s);
-
- /* destroy the device for the control endpoint */
- destroy_dev(sc->dev);
- usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev);
-
- return (0);
-}
-
-int
-uscannerpoll(struct cdev *dev, int events, struct thread *p)
-{
- struct uscanner_softc *sc;
- int revents = 0;
-
- sc = devclass_get_softc(uscanner_devclass, USCANNERUNIT(dev));
- if (sc->sc_dying)
- return (EIO);
-
- /*
- * We have no easy way of determining if a read will
- * yield any data or a write will happen.
- * Pretend they will.
- */
- revents |= events &
- (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM);
-
- return (revents);
-}
-
-MODULE_DEPEND(uscanner, usb, 1, 1, 1);
-DRIVER_MODULE(uscanner, uhub, uscanner_driver, uscanner_devclass, usbd_driver_load, 0);
diff --git a/sys/dev/usb/uslcom.c b/sys/dev/usb/uslcom.c
deleted file mode 100644
index edb13c5..0000000
--- a/sys/dev/usb/uslcom.c
+++ /dev/null
@@ -1,419 +0,0 @@
-/* $FreeBSD$ */
-/* $OpenBSD: uslcom.c,v 1.17 2007/11/24 10:52:12 jsg Exp $ */
-
-/*
- * Copyright (c) 2006 Jonathan Gray <jsg@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/conf.h>
-#include <sys/bus.h>
-#include <sys/tty.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbcdc.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-
-#include "usbdevs.h"
-#include <dev/usb/ucomvar.h>
-
-#ifdef USLCOM_DEBUG
-#define DPRINTFN(n, x) do { if (uslcomdebug > (n)) printf x; } while (0)
-int uslcomdebug = 1;
-#else
-#define DPRINTFN(n, x)
-#endif
-#define DPRINTF(x) DPRINTFN(0, x)
-
-#define USLCOMBUFSZ 256
-#define USLCOM_CONFIG_NO 0
-#define USLCOM_IFACE_NO 0
-
-#define USLCOM_SET_DATA_BITS(x) (x << 8)
-
-#define USLCOM_WRITE 0x41
-#define USLCOM_READ 0xc1
-
-#define USLCOM_UART 0x00
-#define USLCOM_BAUD_RATE 0x01
-#define USLCOM_DATA 0x03
-#define USLCOM_BREAK 0x05
-#define USLCOM_CTRL 0x07
-
-#define USLCOM_UART_DISABLE 0x00
-#define USLCOM_UART_ENABLE 0x01
-
-#define USLCOM_CTRL_DTR_ON 0x0001
-#define USLCOM_CTRL_DTR_SET 0x0100
-#define USLCOM_CTRL_RTS_ON 0x0002
-#define USLCOM_CTRL_RTS_SET 0x0200
-#define USLCOM_CTRL_CTS 0x0010
-#define USLCOM_CTRL_DSR 0x0020
-#define USLCOM_CTRL_DCD 0x0080
-
-
-#define USLCOM_BAUD_REF 0x384000
-
-#define USLCOM_STOP_BITS_1 0x00
-#define USLCOM_STOP_BITS_2 0x02
-
-#define USLCOM_PARITY_NONE 0x00
-#define USLCOM_PARITY_ODD 0x10
-#define USLCOM_PARITY_EVEN 0x20
-
-#define USLCOM_BREAK_OFF 0x00
-#define USLCOM_BREAK_ON 0x01
-
-
-struct uslcom_softc {
- struct ucom_softc sc_ucom;
- device_t sc_dev;
- usbd_device_handle sc_udev;
-
- u_char sc_msr;
- u_char sc_lsr;
-
- u_char sc_dying;
-};
-
-void uslcom_get_status(void *, int portno, u_char *lsr, u_char *msr);
-void uslcom_set(void *, int, int, int);
-int uslcom_param(void *, int, struct termios *);
-int uslcom_open(void *sc, int portno);
-void uslcom_close(void *, int);
-void uslcom_break(void *sc, int portno, int onoff);
-
-struct ucom_callback uslcom_callback = {
- uslcom_get_status,
- uslcom_set,
- uslcom_param,
- NULL,
- uslcom_open,
- uslcom_close,
- NULL,
- NULL,
-};
-
-static const struct usb_devno uslcom_devs[] = {
- { USB_VENDOR_BALTECH, USB_PRODUCT_BALTECH_CARDREADER },
- { USB_VENDOR_DYNASTREAM, USB_PRODUCT_DYNASTREAM_ANTDEVBOARD },
- { USB_VENDOR_JABLOTRON, USB_PRODUCT_JABLOTRON_PC60B },
- { USB_VENDOR_SILABS, USB_PRODUCT_SILABS_ARGUSISP },
- { USB_VENDOR_SILABS, USB_PRODUCT_SILABS_CRUMB128 },
- { USB_VENDOR_SILABS, USB_PRODUCT_SILABS_DEGREE },
- { USB_VENDOR_SILABS, USB_PRODUCT_SILABS_BURNSIDE },
- { USB_VENDOR_SILABS, USB_PRODUCT_SILABS_HELICOM },
- { USB_VENDOR_SILABS, USB_PRODUCT_SILABS_LIPOWSKY_HARP },
- { USB_VENDOR_SILABS, USB_PRODUCT_SILABS_LIPOWSKY_JTAG },
- { USB_VENDOR_SILABS, USB_PRODUCT_SILABS_LIPOWSKY_LIN },
- { USB_VENDOR_SILABS, USB_PRODUCT_SILABS_POLOLU },
- { USB_VENDOR_SILABS, USB_PRODUCT_SILABS_CP2102 },
- { USB_VENDOR_SILABS, USB_PRODUCT_SILABS_CP210X_2 },
- { USB_VENDOR_SILABS, USB_PRODUCT_SILABS_SUUNTO },
- { USB_VENDOR_SILABS, USB_PRODUCT_SILABS_TRAQMATE },
- { USB_VENDOR_SILABS2, USB_PRODUCT_SILABS2_DCU11CLONE },
- { USB_VENDOR_USI, USB_PRODUCT_USI_MC60 }
-};
-
-static device_probe_t uslcom_match;
-static device_attach_t uslcom_attach;
-static device_detach_t uslcom_detach;
-
-static device_method_t uslcom_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, uslcom_match),
- DEVMETHOD(device_attach, uslcom_attach),
- DEVMETHOD(device_detach, uslcom_detach),
- { 0, 0 }
-};
-
-static driver_t uslcom_driver = {
- "ucom",
- uslcom_methods,
- sizeof (struct uslcom_softc)
-};
-
-DRIVER_MODULE(uslcom, uhub, uslcom_driver, ucom_devclass, usbd_driver_load, 0);
-MODULE_DEPEND(uslcom, usb, 1, 1, 1);
-MODULE_DEPEND(uslcom, ucom, UCOM_MINVER, UCOM_PREFVER, UCOM_MAXVER);
-MODULE_VERSION(uslcom, 1);
-
-static int
-uslcom_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
-
- if (uaa->iface != NULL)
- return UMATCH_NONE;
-
- return (usb_lookup(uslcom_devs, uaa->vendor, uaa->product) != NULL) ?
- UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
-}
-
-static int
-uslcom_attach(device_t self)
-{
- struct uslcom_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usbd_device_handle dev = uaa->device;
- struct ucom_softc* ucom;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
- usbd_status error;
- int i;
-
- ucom = &sc->sc_ucom;
- ucom->sc_dev = self;
- ucom->sc_udev = dev;
- ucom->sc_iface = uaa->iface;
-
- sc->sc_dev = self;
- sc->sc_udev = uaa->device;
-
- if (usbd_set_config_index(sc->sc_udev, USLCOM_CONFIG_NO, 1) != 0) {
- device_printf(self, "could not set configuration no\n");
- sc->sc_dying = 1;
- return ENXIO;
- }
-
- /* get the first interface handle */
- error = usbd_device2interface_handle(sc->sc_udev, USLCOM_IFACE_NO,
- &ucom->sc_iface);
- if (error != 0) {
- device_printf(self, "could not get interface handle\n");
- sc->sc_dying = 1;
- return ENXIO;
- }
-
- id = usbd_get_interface_descriptor(ucom->sc_iface);
-
- ucom->sc_bulkin_no = ucom->sc_bulkout_no = -1;
- for (i = 0; i < id->bNumEndpoints; i++) {
- ed = usbd_interface2endpoint_descriptor(ucom->sc_iface, i);
- if (ed == NULL) {
- device_printf(self, "no endpoint descriptor found for %d\n",
- i);
- sc->sc_dying = 1;
- return ENXIO;
- }
-
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
- ucom->sc_bulkin_no = ed->bEndpointAddress;
- else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
- ucom->sc_bulkout_no = ed->bEndpointAddress;
- }
-
- if (ucom->sc_bulkin_no == -1 || ucom->sc_bulkout_no == -1) {
- device_printf(self, "missing endpoint\n");
- sc->sc_dying = 1;
- return ENXIO;
- }
-
- ucom->sc_parent = sc;
- ucom->sc_portno = UCOM_UNK_PORTNO;
- /* bulkin, bulkout set above */
- ucom->sc_ibufsize = USLCOMBUFSZ;
- ucom->sc_obufsize = USLCOMBUFSZ;
- ucom->sc_ibufsizepad = USLCOMBUFSZ;
- ucom->sc_opkthdrlen = 0;
- ucom->sc_callback = &uslcom_callback;
-
- DPRINTF(("uslcom: in = 0x%x, out = 0x%x\n",
- ucom->sc_bulkin_no, ucom->sc_bulkout_no));
-
- ucom_attach(&sc->sc_ucom);
- return 0;
-}
-
-static int
-uslcom_detach(device_t self)
-{
- struct uslcom_softc *sc = device_get_softc(self);
-
- sc->sc_dying = 1;
- return ucom_detach(&sc->sc_ucom);
-}
-
-int
-uslcom_open(void *vsc, int portno)
-{
- struct uslcom_softc *sc = vsc;
- usb_device_request_t req;
- usbd_status err;
-
- if (sc->sc_dying)
- return (EIO);
-
- req.bmRequestType = USLCOM_WRITE;
- req.bRequest = USLCOM_UART;
- USETW(req.wValue, USLCOM_UART_ENABLE);
- USETW(req.wIndex, portno);
- USETW(req.wLength, 0);
- err = usbd_do_request(sc->sc_udev, &req, NULL);
- if (err)
- return (EIO);
-
- return (0);
-}
-
-void
-uslcom_close(void *vsc, int portno)
-{
- struct uslcom_softc *sc = vsc;
- usb_device_request_t req;
-
- if (sc->sc_dying)
- return;
-
- req.bmRequestType = USLCOM_WRITE;
- req.bRequest = USLCOM_UART;
- USETW(req.wValue, USLCOM_UART_DISABLE);
- USETW(req.wIndex, portno);
- USETW(req.wLength, 0);
- usbd_do_request(sc->sc_udev, &req, NULL);
-}
-
-void
-uslcom_set(void *vsc, int portno, int reg, int onoff)
-{
- struct uslcom_softc *sc = vsc;
- usb_device_request_t req;
- int ctl;
-
- switch (reg) {
- case UCOM_SET_DTR:
- ctl = onoff ? USLCOM_CTRL_DTR_ON : 0;
- ctl |= USLCOM_CTRL_DTR_SET;
- break;
- case UCOM_SET_RTS:
- ctl = onoff ? USLCOM_CTRL_RTS_ON : 0;
- ctl |= USLCOM_CTRL_RTS_SET;
- break;
- case UCOM_SET_BREAK:
- uslcom_break(sc, portno, onoff);
- return;
- default:
- return;
- }
- req.bmRequestType = USLCOM_WRITE;
- req.bRequest = USLCOM_CTRL;
- USETW(req.wValue, ctl);
- USETW(req.wIndex, portno);
- USETW(req.wLength, 0);
- usbd_do_request(sc->sc_udev, &req, NULL);
-}
-
-int
-uslcom_param(void *vsc, int portno, struct termios *t)
-{
- struct uslcom_softc *sc = (struct uslcom_softc *)vsc;
- usbd_status err;
- usb_device_request_t req;
- int data;
-
- if (t->c_ospeed <= 0 || t->c_ospeed > 921600)
- return (EINVAL);
-
- req.bmRequestType = USLCOM_WRITE;
- req.bRequest = USLCOM_BAUD_RATE;
- USETW(req.wValue, USLCOM_BAUD_REF / t->c_ospeed);
- USETW(req.wIndex, portno);
- USETW(req.wLength, 0);
- err = usbd_do_request(sc->sc_udev, &req, NULL);
- if (err)
- return (EIO);
-
- if (ISSET(t->c_cflag, CSTOPB))
- data = USLCOM_STOP_BITS_2;
- else
- data = USLCOM_STOP_BITS_1;
- if (ISSET(t->c_cflag, PARENB)) {
- if (ISSET(t->c_cflag, PARODD))
- data |= USLCOM_PARITY_ODD;
- else
- data |= USLCOM_PARITY_EVEN;
- } else
- data |= USLCOM_PARITY_NONE;
- switch (ISSET(t->c_cflag, CSIZE)) {
- case CS5:
- data |= USLCOM_SET_DATA_BITS(5);
- break;
- case CS6:
- data |= USLCOM_SET_DATA_BITS(6);
- break;
- case CS7:
- data |= USLCOM_SET_DATA_BITS(7);
- break;
- case CS8:
- data |= USLCOM_SET_DATA_BITS(8);
- break;
- }
-
- req.bmRequestType = USLCOM_WRITE;
- req.bRequest = USLCOM_DATA;
- USETW(req.wValue, data);
- USETW(req.wIndex, portno);
- USETW(req.wLength, 0);
- err = usbd_do_request(sc->sc_udev, &req, NULL);
- if (err)
- return (EIO);
-
-#if 0
- /* XXX flow control */
- if (ISSET(t->c_cflag, CRTSCTS))
- /* rts/cts flow ctl */
- } else if (ISSET(t->c_iflag, IXON|IXOFF)) {
- /* xon/xoff flow ctl */
- } else {
- /* disable flow ctl */
- }
-#endif
-
- return (0);
-}
-
-void
-uslcom_get_status(void *vsc, int portno, u_char *lsr, u_char *msr)
-{
- struct uslcom_softc *sc = vsc;
-
- if (msr != NULL)
- *msr = sc->sc_msr;
- if (lsr != NULL)
- *lsr = sc->sc_lsr;
-}
-
-void
-uslcom_break(void *vsc, int portno, int onoff)
-{
- struct uslcom_softc *sc = vsc;
- usb_device_request_t req;
- int brk = onoff ? USLCOM_BREAK_ON : USLCOM_BREAK_OFF;
-
- req.bmRequestType = USLCOM_WRITE;
- req.bRequest = USLCOM_BREAK;
- USETW(req.wValue, brk);
- USETW(req.wIndex, portno);
- USETW(req.wLength, 0);
- usbd_do_request(sc->sc_udev, &req, NULL);
-}
diff --git a/sys/dev/usb/uvisor.c b/sys/dev/usb/uvisor.c
deleted file mode 100644
index 6c4470e..0000000
--- a/sys/dev/usb/uvisor.c
+++ /dev/null
@@ -1,639 +0,0 @@
-/* $NetBSD: uvisor.c,v 1.9 2001/01/23 14:04:14 augustss Exp $ */
-/* $FreeBSD$ */
-
-/* Also already merged from NetBSD:
- * $NetBSD: uvisor.c,v 1.12 2001/11/13 06:24:57 lukem Exp $
- * $NetBSD: uvisor.c,v 1.13 2002/02/11 15:11:49 augustss Exp $
- * $NetBSD: uvisor.c,v 1.14 2002/02/27 23:00:03 augustss Exp $
- * $NetBSD: uvisor.c,v 1.15 2002/06/16 15:01:31 augustss Exp $
- * $NetBSD: uvisor.c,v 1.16 2002/07/11 21:14:36 augustss Exp $
- * $NetBSD: uvisor.c,v 1.17 2002/08/13 11:38:15 augustss Exp $
- * $NetBSD: uvisor.c,v 1.18 2003/02/05 00:50:14 augustss Exp $
- * $NetBSD: uvisor.c,v 1.19 2003/02/07 18:12:37 augustss Exp $
- * $NetBSD: uvisor.c,v 1.20 2003/04/11 01:30:10 simonb Exp $
- */
-
-
-/*-
- * Copyright (c) 2000 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Lennart Augustsson (lennart@augustsson.net) 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.
- */
-
-/*
- * Handspring Visor (Palmpilot compatible PDA) driver
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/conf.h>
-#include <sys/tty.h>
-#include <sys/sysctl.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbhid.h>
-
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include "usbdevs.h"
-
-#include <dev/usb/ucomvar.h>
-
-#ifdef USB_DEBUG
-#define DPRINTF(x) if (uvisordebug) printf x
-#define DPRINTFN(n,x) if (uvisordebug>(n)) printf x
-int uvisordebug = 0;
-SYSCTL_NODE(_hw_usb, OID_AUTO, uvisor, CTLFLAG_RW, 0, "USB uvisor");
-SYSCTL_INT(_hw_usb_uvisor, OID_AUTO, debug, CTLFLAG_RW,
- &uvisordebug, 0, "uvisor debug level");
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-#define UVISOR_CONFIG_INDEX 0
-#define UVISOR_IFACE_INDEX 0
-#define UVISOR_MODVER 1
-
-/* From the Linux driver */
-/*
- * UVISOR_REQUEST_BYTES_AVAILABLE asks the visor for the number of bytes that
- * are available to be transfered to the host for the specified endpoint.
- * Currently this is not used, and always returns 0x0001
- */
-#define UVISOR_REQUEST_BYTES_AVAILABLE 0x01
-
-/*
- * UVISOR_CLOSE_NOTIFICATION is set to the device to notify it that the host
- * is now closing the pipe. An empty packet is sent in response.
- */
-#define UVISOR_CLOSE_NOTIFICATION 0x02
-
-/*
- * UVISOR_GET_CONNECTION_INFORMATION is sent by the host during enumeration to
- * get the endpoints used by the connection.
- */
-#define UVISOR_GET_CONNECTION_INFORMATION 0x03
-
-
-/*
- * UVISOR_GET_CONNECTION_INFORMATION returns data in the following format
- */
-#define UVISOR_MAX_CONN 8
-struct uvisor_connection_info {
- uWord num_ports;
- struct {
- uByte port_function_id;
- uByte port;
- } connections[UVISOR_MAX_CONN];
-};
-#define UVISOR_CONNECTION_INFO_SIZE 18
-
-/* struct uvisor_connection_info.connection[x].port defines: */
-#define UVISOR_ENDPOINT_1 0x01
-#define UVISOR_ENDPOINT_2 0x02
-
-/* struct uvisor_connection_info.connection[x].port_function_id defines: */
-#define UVISOR_FUNCTION_GENERIC 0x00
-#define UVISOR_FUNCTION_DEBUGGER 0x01
-#define UVISOR_FUNCTION_HOTSYNC 0x02
-#define UVISOR_FUNCTION_CONSOLE 0x03
-#define UVISOR_FUNCTION_REMOTE_FILE_SYS 0x04
-
-/*
- * Unknown PalmOS stuff.
- */
-#define UVISOR_GET_PALM_INFORMATION 0x04
-#define UVISOR_GET_PALM_INFORMATION_LEN 0x44
-
-struct uvisor_palm_connection_info {
- uByte num_ports;
- uByte endpoint_numbers_different;
- uWord reserved1;
- struct {
- uDWord port_function_id;
- uByte port;
- uByte end_point_info;
- uWord reserved;
- } connections[UVISOR_MAX_CONN];
-};
-
-
-/*
- * Crank down UVISORBUFSIZE from 1024 to 64 to avoid a problem where
- * the Palm device and the USB host controller deadlock. The USB host
- * controller is expecting an early-end-of-transmission packet with 0
- * data, and the Palm doesn't send one because it's already
- * communicated the amount of data it's going to send in a header
- * (which ucom/uvisor are oblivious to). This is the problem that has
- * been known on the pilot-link lists as the "[Free]BSD USB problem",
- * but not understood.
- */
-#define UVISORIBUFSIZE 64
-#define UVISOROBUFSIZE 1024
-
-struct uvisor_softc {
- struct ucom_softc sc_ucom;
- u_int16_t sc_flags;
-};
-
-static usbd_status uvisor_init(struct uvisor_softc *);
-
-/*static usbd_status clie_3_5_init(struct uvisor_softc *);*/
-
-static void uvisor_close(void *, int);
-
-struct ucom_callback uvisor_callback = {
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- uvisor_close,
- NULL,
- NULL,
-};
-
-static device_probe_t uvisor_match;
-static device_attach_t uvisor_attach;
-static device_detach_t uvisor_detach;
-static device_method_t uvisor_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, uvisor_match),
- DEVMETHOD(device_attach, uvisor_attach),
- DEVMETHOD(device_detach, uvisor_detach),
- { 0, 0 }
-};
-
-
-static driver_t uvisor_driver = {
- "ucom",
- uvisor_methods,
- sizeof (struct uvisor_softc)
-};
-
-DRIVER_MODULE(uvisor, uhub, uvisor_driver, ucom_devclass, usbd_driver_load, 0);
-MODULE_DEPEND(uvisor, usb, 1, 1, 1);
-MODULE_DEPEND(uvisor, ucom, UCOM_MINVER, UCOM_PREFVER, UCOM_MAXVER);
-MODULE_VERSION(uvisor, UVISOR_MODVER);
-
-struct uvisor_type {
- struct usb_devno uv_dev;
- u_int16_t uv_flags;
-#define PALM4 0x0001
-#define VISOR 0x0002
-#define PALM35 0x0004
-};
-static const struct uvisor_type uvisor_devs[] = {
- {{ USB_VENDOR_ACEECA, USB_PRODUCT_ACEECA_MEZ1000 }, PALM4 },
- {{ USB_VENDOR_GARMIN, USB_PRODUCT_GARMIN_IQUE_3600 }, PALM4 },
- {{ USB_VENDOR_FOSSIL, USB_PRODUCT_FOSSIL_WRISTPDA }, PALM4 },
- {{ USB_VENDOR_HANDSPRING, USB_PRODUCT_HANDSPRING_VISOR }, VISOR },
- {{ USB_VENDOR_HANDSPRING, USB_PRODUCT_HANDSPRING_TREO }, PALM4 },
- {{ USB_VENDOR_HANDSPRING, USB_PRODUCT_HANDSPRING_TREO600 }, PALM4 },
- {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_M500 }, PALM4 },
- {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_M505 }, PALM4 },
- {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_M515 }, PALM4 },
- {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_I705 }, PALM4 },
- {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_M125 }, PALM4 },
- {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_M130 }, PALM4 },
- {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_TUNGSTEN_Z }, PALM4 },
- {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_TUNGSTEN_T }, PALM4 },
- {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_ZIRE }, PALM4 },
- {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_ZIRE31 }, PALM4 },
- {{ USB_VENDOR_SAMSUNG, USB_PRODUCT_SAMSUNG_I500 }, PALM4 },
- {{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_40 }, 0 },
- {{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_41 }, PALM4 },
- {{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_S360 }, PALM4 },
- {{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_NX60 }, PALM4 },
- {{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_35 }, PALM35 },
-/* {{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_25 }, PALM4 },*/
-/* {{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_TH55 }, PALM4 }, */ /* See PR 80935 */
- {{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_TJ37 }, PALM4 },
- {{ USB_VENDOR_TAPWAVE, USB_PRODUCT_TAPWAVE_ZODIAC }, PALM4 },
-};
-#define uvisor_lookup(v, p) ((const struct uvisor_type *)usb_lookup(uvisor_devs, v, p))
-
-
-static int
-uvisor_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
-
- if (uaa->iface != NULL)
- return (UMATCH_NONE);
-
- DPRINTFN(20,("uvisor: vendor=0x%x, product=0x%x\n",
- uaa->vendor, uaa->product));
-
- return (uvisor_lookup(uaa->vendor, uaa->product) != NULL ?
- UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
-}
-
-static int
-uvisor_attach(device_t self)
-{
- struct uvisor_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usbd_device_handle dev = uaa->device;
- usbd_interface_handle iface;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
- int i;
- usbd_status err;
- struct ucom_softc *ucom;
-
- ucom = &sc->sc_ucom;
- ucom->sc_dev = self;
- ucom->sc_udev = dev;
- ucom->sc_iface = uaa->iface;
-
- DPRINTFN(10,("\nuvisor_attach: sc=%p\n", sc));
-
- /* Move the device into the configured state. */
- err = usbd_set_config_index(dev, UVISOR_CONFIG_INDEX, 1);
- if (err) {
- device_printf(self, "failed to set configuration, err=%s\n",
- usbd_errstr(err));
- goto bad;
- }
-
- err = usbd_device2interface_handle(dev, UVISOR_IFACE_INDEX, &iface);
- if (err) {
- device_printf(self, "failed to get interface, err=%s\n",
- usbd_errstr(err));
- goto bad;
- }
-
- sc->sc_flags = uvisor_lookup(uaa->vendor, uaa->product)->uv_flags;
-
- id = usbd_get_interface_descriptor(iface);
-
- ucom->sc_udev = dev;
- ucom->sc_iface = iface;
-
- ucom->sc_bulkin_no = ucom->sc_bulkout_no = -1;
- for (i = 0; i < id->bNumEndpoints; i++) {
- int addr, dir, attr;
- ed = usbd_interface2endpoint_descriptor(iface, i);
- if (ed == NULL) {
- device_printf(self,
- "could not read endpoint descriptor: %s\n",
- usbd_errstr(err));
- goto bad;
- }
-
- addr = ed->bEndpointAddress;
- dir = UE_GET_DIR(ed->bEndpointAddress);
- attr = ed->bmAttributes & UE_XFERTYPE;
- if (dir == UE_DIR_IN && attr == UE_BULK)
- ucom->sc_bulkin_no = addr;
- else if (dir == UE_DIR_OUT && attr == UE_BULK)
- ucom->sc_bulkout_no = addr;
- else {
- device_printf(self, "unexpected endpoint\n");
- goto bad;
- }
- }
- if (ucom->sc_bulkin_no == -1) {
- device_printf(self, "Could not find data bulk in\n");
- goto bad;
- }
- if (ucom->sc_bulkout_no == -1) {
- device_printf(self, "Could not find data bulk out\n");
- goto bad;
- }
-
- ucom->sc_parent = sc;
- ucom->sc_portno = UCOM_UNK_PORTNO;
- /* bulkin, bulkout set above */
- ucom->sc_ibufsize = UVISORIBUFSIZE;
- ucom->sc_obufsize = UVISOROBUFSIZE;
- ucom->sc_ibufsizepad = UVISORIBUFSIZE;
- ucom->sc_opkthdrlen = 0;
- ucom->sc_callback = &uvisor_callback;
-
-#if 0
- if (uaa->vendor == USB_VENDOR_SONY &&
- uaa->product == USB_PRODUCT_SONY_CLIE_35)
- err = clie_3_5_init(sc);
- else
-#endif
- err = uvisor_init(sc);
-
- if (err) {
- device_printf(ucom->sc_dev, "init failed, %s\n",
- usbd_errstr(err));
- goto bad;
- }
-
- usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, ucom->sc_udev,
- ucom->sc_dev);
-
- DPRINTF(("uvisor: in=0x%x out=0x%x\n", ucom->sc_bulkin_no, ucom->sc_bulkout_no));
- ucom_attach(&sc->sc_ucom);
-
- return 0;
-
-bad:
- DPRINTF(("uvisor_attach: ATTACH ERROR\n"));
- ucom->sc_dying = 1;
- return ENXIO;
-}
-
-#if 0
-
-int
-uvisor_activate(device_t self, enum devact act)
-{
- struct uvisor_softc *sc = (struct uvisor_softc *)self;
- int rv = 0;
-
- switch (act) {
- case DVACT_ACTIVATE:
- return (EOPNOTSUPP);
- break;
-
- case DVACT_DEACTIVATE:
- if (sc->sc_subdev != NULL)
- rv = config_deactivate(sc->sc_subdev);
- sc->sc_dying = 1;
- break;
- }
- return (rv);
-}
-
-#endif
-
-static int
-uvisor_detach(device_t self)
-{
- struct uvisor_softc *sc = device_get_softc(self);
- int rv = 0;
-
- DPRINTF(("uvisor_detach: sc=%p\n", sc));
- sc->sc_ucom.sc_dying = 1;
- rv = ucom_detach(&sc->sc_ucom);
-
- usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_ucom.sc_udev,
- sc->sc_ucom.sc_dev);
-
- return (rv);
-}
-
-usbd_status
-uvisor_init(struct uvisor_softc *sc)
-{
- usbd_status err;
- usb_device_request_t req;
- struct uvisor_connection_info coninfo;
- struct uvisor_palm_connection_info pconinfo;
- int actlen;
- uWord avail;
- char buffer[256];
-
- if (sc->sc_flags & VISOR) {
- DPRINTF(("uvisor_init: getting connection info\n"));
- req.bmRequestType = UT_READ_VENDOR_ENDPOINT;
- req.bRequest = UVISOR_GET_CONNECTION_INFORMATION;
- USETW(req.wValue, 0);
- USETW(req.wIndex, 0);
- USETW(req.wLength, UVISOR_CONNECTION_INFO_SIZE);
- err = usbd_do_request_flags(sc->sc_ucom.sc_udev, &req, &coninfo,
- USBD_SHORT_XFER_OK, &actlen,
- USBD_DEFAULT_TIMEOUT);
- if (err)
- return (err);
- }
-#ifdef USB_DEBUG
- {
- int i, np;
- char *string;
-
- np = UGETW(coninfo.num_ports);
- device_printf(sc->sc_ucom.sc_dev, "Number of ports: %d\n", np);
- for (i = 0; i < np; ++i) {
- switch (coninfo.connections[i].port_function_id) {
- case UVISOR_FUNCTION_GENERIC:
- string = "Generic";
- break;
- case UVISOR_FUNCTION_DEBUGGER:
- string = "Debugger";
- break;
- case UVISOR_FUNCTION_HOTSYNC:
- string = "HotSync";
- break;
- case UVISOR_FUNCTION_REMOTE_FILE_SYS:
- string = "Remote File System";
- break;
- default:
- string = "unknown";
- break;
- }
- device_printf(sc->sc_ucom.sc_dev,
- "port %d, is for %s\n",
- coninfo.connections[i].port, string);
- }
- }
-#endif
-
- if (sc->sc_flags & PALM4) {
- int port;
- /* Palm OS 4.0 Hack */
- req.bmRequestType = UT_READ_VENDOR_ENDPOINT;
- req.bRequest = UVISOR_GET_PALM_INFORMATION;
- USETW(req.wValue, 0);
- USETW(req.wIndex, 0);
- USETW(req.wLength, UVISOR_GET_PALM_INFORMATION_LEN);
- err = usbd_do_request_flags(sc->sc_ucom.sc_udev, &req, &pconinfo,
- USBD_SHORT_XFER_OK, &actlen,
- USBD_DEFAULT_TIMEOUT);
- if (err)
- return (err);
-
- if (pconinfo.endpoint_numbers_different) {
- port = pconinfo.connections[0].end_point_info;
- sc->sc_ucom.sc_bulkin_no = (port >> 4) | UE_DIR_IN;
- sc->sc_ucom.sc_bulkout_no = (port & 0xf) | UE_DIR_OUT;
- } else {
- port = pconinfo.connections[0].port;
- sc->sc_ucom.sc_bulkin_no = port | UE_DIR_IN;
- sc->sc_ucom.sc_bulkout_no = port | UE_DIR_OUT;
- }
-#if 0
- req.bmRequestType = UT_READ_VENDOR_ENDPOINT;
- req.bRequest = UVISOR_GET_PALM_INFORMATION;
- USETW(req.wValue, 0);
- USETW(req.wIndex, 0);
- USETW(req.wLength, UVISOR_GET_PALM_INFORMATION_LEN);
- err = usbd_do_request(sc->sc_ucom.sc_udev, &req, buffer);
- if (err)
- return (err);
-#endif
- }
-
- if (sc->sc_flags & PALM35) {
- /* get the config number */
- DPRINTF(("clie_3_5_init: getting config info\n"));
- req.bmRequestType = UT_READ;
- req.bRequest = UR_GET_CONFIG;
- USETW(req.wValue, 0);
- USETW(req.wIndex, 0);
- USETW(req.wLength, 1);
- err = usbd_do_request(sc->sc_ucom.sc_udev, &req, buffer);
- if (err)
- return (err);
-
- /* get the interface number */
- DPRINTF(("clie_3_5_init: get the interface number\n"));
- req.bmRequestType = UT_READ_DEVICE;
- req.bRequest = UR_GET_INTERFACE;
- USETW(req.wValue, 0);
- USETW(req.wIndex, 0);
- USETW(req.wLength, 1);
- err = usbd_do_request(sc->sc_ucom.sc_udev, &req, buffer);
- if (err)
- return (err);
- }
-
- DPRINTF(("uvisor_init: getting available bytes\n"));
- req.bmRequestType = UT_READ_VENDOR_ENDPOINT;
- req.bRequest = UVISOR_REQUEST_BYTES_AVAILABLE;
- USETW(req.wValue, 0);
- USETW(req.wIndex, 5);
- USETW(req.wLength, sizeof avail);
- err = usbd_do_request(sc->sc_ucom.sc_udev, &req, &avail);
- if (err)
- return (err);
- DPRINTF(("uvisor_init: avail=%d\n", UGETW(avail)));
-
- DPRINTF(("uvisor_init: done\n"));
- return (err);
-}
-
-#if 0
-usbd_status
-clie_3_5_init(struct uvisor_softc *sc)
-{
- usbd_status err;
- usb_device_request_t req;
- char buffer[256];
-
- /*
- * Note that PEG-300 series devices expect the following two calls.
- */
-
- /* get the config number */
- DPRINTF(("clie_3_5_init: getting config info\n"));
- req.bmRequestType = UT_READ;
- req.bRequest = UR_GET_CONFIG;
- USETW(req.wValue, 0);
- USETW(req.wIndex, 0);
- USETW(req.wLength, 1);
- err = usbd_do_request(sc->sc_ucom.sc_udev, &req, buffer);
- if (err)
- return (err);
-
- /* get the interface number */
- DPRINTF(("clie_3_5_init: get the interface number\n"));
- req.bmRequestType = UT_READ_DEVICE;
- req.bRequest = UR_GET_INTERFACE;
- USETW(req.wValue, 0);
- USETW(req.wIndex, 0);
- USETW(req.wLength, 1);
- err = usbd_do_request(sc->sc_ucom.sc_udev, &req, buffer);
- if (err)
- return (err);
-
-#ifdef USB_DEBUG
- {
- struct uvisor_connection_info coninfo;
- int i, np;
- char *string;
-
- np = UGETW(coninfo.num_ports);
- DPRINTF(("%s: Number of ports: %d\n", device_get_nameunit(sc->sc_ucom.sc_dev), np));
- for (i = 0; i < np; ++i) {
- switch (coninfo.connections[i].port_function_id) {
- case UVISOR_FUNCTION_GENERIC:
- string = "Generic";
- break;
- case UVISOR_FUNCTION_DEBUGGER:
- string = "Debugger";
- break;
- case UVISOR_FUNCTION_HOTSYNC:
- string = "HotSync";
- break;
- case UVISOR_FUNCTION_REMOTE_FILE_SYS:
- string = "Remote File System";
- break;
- default:
- string = "unknown";
- break;
- }
- DPRINTF(("%s: port %d, is for %s\n",
- device_get_nameunit(sc->sc_ucom.sc_dev), coninfo.connections[i].port,
- string));
- }
- }
-#endif
-
- DPRINTF(("clie_3_5_init: done\n"));
- return (err);
-}
-#endif
-
-void
-uvisor_close(void *addr, int portno)
-{
- struct uvisor_softc *sc = addr;
- usb_device_request_t req;
- struct uvisor_connection_info coninfo; /* XXX ? */
- int actlen;
-
- if (sc->sc_ucom.sc_dying)
- return;
-
- req.bmRequestType = UT_READ_VENDOR_ENDPOINT; /* XXX read? */
- req.bRequest = UVISOR_CLOSE_NOTIFICATION;
- USETW(req.wValue, 0);
- USETW(req.wIndex, 0);
- USETW(req.wLength, UVISOR_CONNECTION_INFO_SIZE);
- (void)usbd_do_request_flags(sc->sc_ucom.sc_udev, &req, &coninfo,
- USBD_SHORT_XFER_OK, &actlen,
- USBD_DEFAULT_TIMEOUT);
-}
diff --git a/sys/dev/usb/uvscom.c b/sys/dev/usb/uvscom.c
deleted file mode 100644
index ac311f7..0000000
--- a/sys/dev/usb/uvscom.c
+++ /dev/null
@@ -1,906 +0,0 @@
-/* $NetBSD: usb/uvscom.c,v 1.1 2002/03/19 15:08:42 augustss Exp $ */
-/*-
- * Copyright (c) 2001-2003, 2005 Shunsuke Akiyama <akiyama@jp.FreeBSD.org>.
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * uvscom: SUNTAC Slipper U VS-10U driver.
- * Slipper U is a PC Card to USB converter for data communication card
- * adapter. It supports DDI Pocket's Air H" C@rd, C@rd H" 64, NTT's P-in,
- * P-in m@ater and various data communication card adapters.
- */
-
-#include "opt_uvscom.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/fcntl.h>
-#include <sys/conf.h>
-#include <sys/serial.h>
-#include <sys/tty.h>
-#include <sys/file.h>
-#include <sys/bus.h>
-#include <sys/ioccom.h>
-#include <sys/selinfo.h>
-#include <sys/proc.h>
-#include <sys/poll.h>
-#include <sys/sysctl.h>
-#include <sys/taskqueue.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbcdc.h>
-
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include "usbdevs.h"
-#include <dev/usb/usb_quirks.h>
-
-#include <dev/usb/ucomvar.h>
-
-SYSCTL_NODE(_hw_usb, OID_AUTO, uvscom, CTLFLAG_RW, 0, "USB uvscom");
-#ifdef USB_DEBUG
-static int uvscomdebug = 0;
-SYSCTL_INT(_hw_usb_uvscom, OID_AUTO, debug, CTLFLAG_RW,
- &uvscomdebug, 0, "uvscom debug level");
-
-#define DPRINTFN(n, x) do { \
- if (uvscomdebug > (n)) \
- printf x; \
- } while (0)
-#else
-#define DPRINTFN(n, x)
-#endif
-#define DPRINTF(x) DPRINTFN(0, x)
-
-#define UVSCOM_MODVER 1 /* module version */
-
-#define UVSCOM_CONFIG_INDEX 0
-#define UVSCOM_IFACE_INDEX 0
-
-#ifndef UVSCOM_INTR_INTERVAL
-#define UVSCOM_INTR_INTERVAL 100 /* mS */
-#endif
-
-#define UVSCOM_UNIT_WAIT 5
-
-/* Request */
-#define UVSCOM_SET_SPEED 0x10
-#define UVSCOM_LINE_CTL 0x11
-#define UVSCOM_SET_PARAM 0x12
-#define UVSCOM_READ_STATUS 0xd0
-#define UVSCOM_SHUTDOWN 0xe0
-
-/* UVSCOM_SET_SPEED parameters */
-#define UVSCOM_SPEED_150BPS 0x00
-#define UVSCOM_SPEED_300BPS 0x01
-#define UVSCOM_SPEED_600BPS 0x02
-#define UVSCOM_SPEED_1200BPS 0x03
-#define UVSCOM_SPEED_2400BPS 0x04
-#define UVSCOM_SPEED_4800BPS 0x05
-#define UVSCOM_SPEED_9600BPS 0x06
-#define UVSCOM_SPEED_19200BPS 0x07
-#define UVSCOM_SPEED_38400BPS 0x08
-#define UVSCOM_SPEED_57600BPS 0x09
-#define UVSCOM_SPEED_115200BPS 0x0a
-
-/* UVSCOM_LINE_CTL parameters */
-#define UVSCOM_BREAK 0x40
-#define UVSCOM_RTS 0x02
-#define UVSCOM_DTR 0x01
-#define UVSCOM_LINE_INIT 0x08
-
-/* UVSCOM_SET_PARAM parameters */
-#define UVSCOM_DATA_MASK 0x03
-#define UVSCOM_DATA_BIT_8 0x03
-#define UVSCOM_DATA_BIT_7 0x02
-#define UVSCOM_DATA_BIT_6 0x01
-#define UVSCOM_DATA_BIT_5 0x00
-
-#define UVSCOM_STOP_MASK 0x04
-#define UVSCOM_STOP_BIT_2 0x04
-#define UVSCOM_STOP_BIT_1 0x00
-
-#define UVSCOM_PARITY_MASK 0x18
-#define UVSCOM_PARITY_EVEN 0x18
-#if 0
-#define UVSCOM_PARITY_UNK 0x10
-#endif
-#define UVSCOM_PARITY_ODD 0x08
-#define UVSCOM_PARITY_NONE 0x00
-
-/* Status bits */
-#define UVSCOM_TXRDY 0x04
-#define UVSCOM_RXRDY 0x01
-
-#define UVSCOM_DCD 0x08
-#define UVSCOM_NOCARD 0x04
-#define UVSCOM_DSR 0x02
-#define UVSCOM_CTS 0x01
-#define UVSCOM_USTAT_MASK (UVSCOM_NOCARD | UVSCOM_DSR | UVSCOM_CTS)
-
-struct uvscom_softc {
- struct ucom_softc sc_ucom;
-
- int sc_iface_number;/* interface number */
-
- usbd_interface_handle sc_intr_iface; /* interrupt interface */
- int sc_intr_number; /* interrupt number */
- usbd_pipe_handle sc_intr_pipe; /* interrupt pipe */
- u_char *sc_intr_buf; /* interrupt buffer */
- int sc_isize;
-
- u_char sc_dtr; /* current DTR state */
- u_char sc_rts; /* current RTS state */
-
- u_char sc_lsr; /* Local status register */
- u_char sc_msr; /* uvscom status register */
-
- uint16_t sc_lcr; /* Line control */
- u_char sc_usr; /* unit status */
-
- struct task sc_task;
-};
-
-/*
- * These are the maximum number of bytes transferred per frame.
- * The output buffer size cannot be increased due to the size encoding.
- */
-#define UVSCOMIBUFSIZE 512
-#define UVSCOMOBUFSIZE 64
-
-#ifndef UVSCOM_DEFAULT_OPKTSIZE
-#define UVSCOM_DEFAULT_OPKTSIZE 8
-#endif
-
-static usbd_status uvscom_shutdown(struct uvscom_softc *);
-static usbd_status uvscom_reset(struct uvscom_softc *);
-static usbd_status uvscom_set_line_coding(struct uvscom_softc *,
- uint16_t, uint16_t);
-static usbd_status uvscom_set_line(struct uvscom_softc *, uint16_t);
-static usbd_status uvscom_set_crtscts(struct uvscom_softc *);
-static void uvscom_get_status(void *, int, u_char *, u_char *);
-static void uvscom_dtr(struct uvscom_softc *, int);
-static void uvscom_rts(struct uvscom_softc *, int);
-static void uvscom_break(struct uvscom_softc *, int);
-
-static void uvscom_set(void *, int, int, int);
-static void uvscom_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
-static int uvscom_param(void *, int, struct termios *);
-static int uvscom_open(void *, int);
-static void uvscom_close(void *, int);
-static void uvscom_notify(void *, int);
-
-struct ucom_callback uvscom_callback = {
- uvscom_get_status,
- uvscom_set,
- uvscom_param,
- NULL,
- uvscom_open,
- uvscom_close,
- NULL,
- NULL
-};
-
-static const struct usb_devno uvscom_devs [] = {
- /* SUNTAC U-Cable type A4 */
- { USB_VENDOR_SUNTAC, USB_PRODUCT_SUNTAC_AS144L4 },
- /* SUNTAC U-Cable type D2 */
- { USB_VENDOR_SUNTAC, USB_PRODUCT_SUNTAC_DS96L },
- /* SUNTAC Ir-Trinity */
- { USB_VENDOR_SUNTAC, USB_PRODUCT_SUNTAC_IS96U },
- /* SUNTAC U-Cable type P1 */
- { USB_VENDOR_SUNTAC, USB_PRODUCT_SUNTAC_PS64P1 },
- /* SUNTAC Slipper U */
- { USB_VENDOR_SUNTAC, USB_PRODUCT_SUNTAC_VS10U },
-};
-#define uvscom_lookup(v, p) usb_lookup(uvscom_devs, v, p)
-
-static device_probe_t uvscom_match;
-static device_attach_t uvscom_attach;
-static device_detach_t uvscom_detach;
-
-static device_method_t uvscom_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, uvscom_match),
- DEVMETHOD(device_attach, uvscom_attach),
- DEVMETHOD(device_detach, uvscom_detach),
- { 0, 0 }
-};
-
-static driver_t uvscom_driver = {
- "ucom",
- uvscom_methods,
- sizeof (struct uvscom_softc)
-};
-
-DRIVER_MODULE(uvscom, uhub, uvscom_driver, ucom_devclass, usbd_driver_load, 0);
-MODULE_DEPEND(uvscom, usb, 1, 1, 1);
-MODULE_DEPEND(uvscom, ucom, UCOM_MINVER, UCOM_PREFVER, UCOM_MAXVER);
-MODULE_VERSION(uvscom, UVSCOM_MODVER);
-
-static int uvscomobufsiz = UVSCOM_DEFAULT_OPKTSIZE;
-static int uvscominterval = UVSCOM_INTR_INTERVAL;
-
-static int
-sysctl_hw_usb_uvscom_opktsize(SYSCTL_HANDLER_ARGS)
-{
- int err, val;
-
- val = uvscomobufsiz;
- err = sysctl_handle_int(oidp, &val, 0, req);
- if (err != 0 || req->newptr == NULL)
- return (err);
- if (0 < val && val <= UVSCOMOBUFSIZE)
- uvscomobufsiz = val;
- else
- err = EINVAL;
-
- return (err);
-}
-
-static int
-sysctl_hw_usb_uvscom_interval(SYSCTL_HANDLER_ARGS)
-{
- int err, val;
-
- val = uvscominterval;
- err = sysctl_handle_int(oidp, &val, 0, req);
- if (err != 0 || req->newptr == NULL)
- return (err);
- if (0 < val && val <= 1000)
- uvscominterval = val;
- else
- err = EINVAL;
-
- return (err);
-}
-
-SYSCTL_PROC(_hw_usb_uvscom, OID_AUTO, opktsize, CTLTYPE_INT | CTLFLAG_RW,
- 0, sizeof(int), sysctl_hw_usb_uvscom_opktsize,
- "I", "uvscom output packet size");
-SYSCTL_PROC(_hw_usb_uvscom, OID_AUTO, interval, CTLTYPE_INT | CTLFLAG_RW,
- 0, sizeof(int), sysctl_hw_usb_uvscom_interval,
- "I", "uvscom interrpt pipe interval");
-
-static int
-uvscom_match(device_t self)
-{
- struct usb_attach_arg *uaa = device_get_ivars(self);
-
- if (uaa->iface != NULL)
- return (UMATCH_NONE);
-
- return (uvscom_lookup(uaa->vendor, uaa->product) != NULL ?
- UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
-}
-
-static int
-uvscom_attach(device_t self)
-{
- struct uvscom_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
- usbd_device_handle dev = uaa->device;
- struct ucom_softc *ucom;
- usb_config_descriptor_t *cdesc;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
- usbd_status err;
- int i;
-
- ucom = &sc->sc_ucom;
- ucom->sc_dev = self;
- ucom->sc_udev = dev;
- ucom->sc_iface = uaa->iface;
-
- DPRINTF(("uvscom attach: sc = %p\n", sc));
-
- /* initialize endpoints */
- ucom->sc_bulkin_no = ucom->sc_bulkout_no = -1;
- sc->sc_intr_number = -1;
- sc->sc_intr_pipe = NULL;
-
- /* Move the device into the configured state. */
- err = usbd_set_config_index(dev, UVSCOM_CONFIG_INDEX, 1);
- if (err) {
- device_printf(self, "failed to set configuration, err=%s\n",
- usbd_errstr(err));
- goto error;
- }
-
- /* get the config descriptor */
- cdesc = usbd_get_config_descriptor(ucom->sc_udev);
-
- if (cdesc == NULL) {
- device_printf(self, "failed to get configuration descriptor\n");
- goto error;
- }
-
- /* get the common interface */
- err = usbd_device2interface_handle(dev, UVSCOM_IFACE_INDEX,
- &ucom->sc_iface);
- if (err) {
- device_printf(self, "failed to get interface, err=%s\n",
- usbd_errstr(err));
- goto error;
- }
-
- id = usbd_get_interface_descriptor(ucom->sc_iface);
- sc->sc_iface_number = id->bInterfaceNumber;
-
- /* Find endpoints */
- for (i = 0; i < id->bNumEndpoints; i++) {
- ed = usbd_interface2endpoint_descriptor(ucom->sc_iface, i);
- if (ed == NULL) {
- device_printf(self, "no endpoint descriptor for %d\n",
- i);
- goto error;
- }
-
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
- ucom->sc_bulkin_no = ed->bEndpointAddress;
- } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
- ucom->sc_bulkout_no = ed->bEndpointAddress;
- } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
- sc->sc_intr_number = ed->bEndpointAddress;
- sc->sc_isize = UGETW(ed->wMaxPacketSize);
- }
- }
-
- if (ucom->sc_bulkin_no == -1) {
- device_printf(self, "Could not find data bulk in\n");
- goto error;
- }
- if (ucom->sc_bulkout_no == -1) {
- device_printf(self, "Could not find data bulk out\n");
- goto error;
- }
- if (sc->sc_intr_number == -1) {
- device_printf(self, "Could not find interrupt in\n");
- goto error;
- }
-
- sc->sc_dtr = sc->sc_rts = 0;
- sc->sc_lcr = UVSCOM_LINE_INIT;
-
- ucom->sc_parent = sc;
- ucom->sc_portno = UCOM_UNK_PORTNO;
- /* bulkin, bulkout set above */
- ucom->sc_ibufsize = UVSCOMIBUFSIZE;
- ucom->sc_obufsize = uvscomobufsiz;
- ucom->sc_ibufsizepad = UVSCOMIBUFSIZE;
- ucom->sc_opkthdrlen = 0;
- ucom->sc_callback = &uvscom_callback;
-
- err = uvscom_reset(sc);
-
- if (err) {
- device_printf(self, "reset failed, %s\n", usbd_errstr(err));
- goto error;
- }
-
- DPRINTF(("uvscom: in = 0x%x out = 0x%x intr = 0x%x\n",
- ucom->sc_bulkin_no, ucom->sc_bulkout_no, sc->sc_intr_number));
-
- TASK_INIT(&sc->sc_task, 0, uvscom_notify, sc);
- ucom_attach(&sc->sc_ucom);
- return 0;
-
-error:
- ucom->sc_dying = 1;
- return ENXIO;
-}
-
-static int
-uvscom_detach(device_t self)
-{
- struct uvscom_softc *sc = device_get_softc(self);
- int rv = 0;
-
- DPRINTF(("uvscom_detach: sc = %p\n", sc));
-
- sc->sc_ucom.sc_dying = 1;
-
- if (sc->sc_intr_pipe != NULL) {
- usbd_abort_pipe(sc->sc_intr_pipe);
- usbd_close_pipe(sc->sc_intr_pipe);
- free(sc->sc_intr_buf, M_USBDEV);
- sc->sc_intr_pipe = NULL;
- }
-
- rv = ucom_detach(&sc->sc_ucom);
-
- return (rv);
-}
-
-static usbd_status
-uvscom_readstat(struct uvscom_softc *sc)
-{
- usb_device_request_t req;
- usbd_status err;
- uint16_t r;
-
- DPRINTF(("%s: send readstat\n", device_get_nameunit(sc->sc_ucom.sc_dev)));
-
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = UVSCOM_READ_STATUS;
- USETW(req.wValue, 0);
- USETW(req.wIndex, 0);
- USETW(req.wLength, 2);
-
- err = usbd_do_request(sc->sc_ucom.sc_udev, &req, &r);
- if (err) {
- device_printf(sc->sc_ucom.sc_dev, "uvscom_readstat: %s\n",
- usbd_errstr(err));
- return (err);
- }
-
- DPRINTF(("%s: uvscom_readstat: r = %d\n",
- device_get_nameunit(sc->sc_ucom.sc_dev), r));
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-static usbd_status
-uvscom_shutdown(struct uvscom_softc *sc)
-{
- usb_device_request_t req;
- usbd_status err;
-
- DPRINTF(("%s: send shutdown\n", device_get_nameunit(sc->sc_ucom.sc_dev)));
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = UVSCOM_SHUTDOWN;
- USETW(req.wValue, 0);
- USETW(req.wIndex, 0);
- USETW(req.wLength, 0);
-
- err = usbd_do_request(sc->sc_ucom.sc_udev, &req, NULL);
- if (err) {
- device_printf(sc->sc_ucom.sc_dev, "uvscom_shutdown: %s\n",
- usbd_errstr(err));
- return (err);
- }
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-static usbd_status
-uvscom_reset(struct uvscom_softc *sc)
-{
- DPRINTF(("%s: uvscom_reset\n", device_get_nameunit(sc->sc_ucom.sc_dev)));
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-static usbd_status
-uvscom_set_crtscts(struct uvscom_softc *sc)
-{
- DPRINTF(("%s: uvscom_set_crtscts\n", device_get_nameunit(sc->sc_ucom.sc_dev)));
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-static usbd_status
-uvscom_set_line(struct uvscom_softc *sc, uint16_t line)
-{
- usb_device_request_t req;
- usbd_status err;
-
- DPRINTF(("%s: uvscom_set_line: %04x\n",
- device_get_nameunit(sc->sc_ucom.sc_dev), line));
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = UVSCOM_LINE_CTL;
- USETW(req.wValue, line);
- USETW(req.wIndex, 0);
- USETW(req.wLength, 0);
-
- err = usbd_do_request(sc->sc_ucom.sc_udev, &req, NULL);
- if (err) {
- device_printf(sc->sc_ucom.sc_dev, "uvscom_set_line: %s\n",
- usbd_errstr(err));
- return (err);
- }
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-static usbd_status
-uvscom_set_line_coding(struct uvscom_softc *sc, uint16_t lsp, uint16_t ls)
-{
- usb_device_request_t req;
- usbd_status err;
-
- DPRINTF(("%s: uvscom_set_line_coding: %02x %02x\n",
- device_get_nameunit(sc->sc_ucom.sc_dev), lsp, ls));
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = UVSCOM_SET_SPEED;
- USETW(req.wValue, lsp);
- USETW(req.wIndex, 0);
- USETW(req.wLength, 0);
-
- err = usbd_do_request(sc->sc_ucom.sc_udev, &req, NULL);
- if (err) {
- device_printf(sc->sc_ucom.sc_dev, "uvscom_set_line_coding: %s\n",
- usbd_errstr(err));
- return (err);
- }
-
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = UVSCOM_SET_PARAM;
- USETW(req.wValue, ls);
- USETW(req.wIndex, 0);
- USETW(req.wLength, 0);
-
- err = usbd_do_request(sc->sc_ucom.sc_udev, &req, NULL);
- if (err) {
- device_printf(sc->sc_ucom.sc_dev, "uvscom_set_line_coding: %s\n",
- usbd_errstr(err));
- return (err);
- }
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-static void
-uvscom_dtr(struct uvscom_softc *sc, int onoff)
-{
- DPRINTF(("%s: uvscom_dtr: onoff = %d\n",
- device_get_nameunit(sc->sc_ucom.sc_dev), onoff));
-
- if (sc->sc_dtr == onoff)
- return; /* no change */
-
- sc->sc_dtr = onoff;
-
- if (onoff)
- SET(sc->sc_lcr, UVSCOM_DTR);
- else
- CLR(sc->sc_lcr, UVSCOM_DTR);
-
- uvscom_set_line(sc, sc->sc_lcr);
-}
-
-static void
-uvscom_rts(struct uvscom_softc *sc, int onoff)
-{
- DPRINTF(("%s: uvscom_rts: onoff = %d\n",
- device_get_nameunit(sc->sc_ucom.sc_dev), onoff));
-
- if (sc->sc_rts == onoff)
- return; /* no change */
-
- sc->sc_rts = onoff;
-
- if (onoff)
- SET(sc->sc_lcr, UVSCOM_RTS);
- else
- CLR(sc->sc_lcr, UVSCOM_RTS);
-
- uvscom_set_line(sc, sc->sc_lcr);
-}
-
-static void
-uvscom_break(struct uvscom_softc *sc, int onoff)
-{
- DPRINTF(("%s: uvscom_break: onoff = %d\n",
- device_get_nameunit(sc->sc_ucom.sc_dev), onoff));
-
- if (onoff)
- uvscom_set_line(sc, SET(sc->sc_lcr, UVSCOM_BREAK));
-}
-
-static void
-uvscom_set(void *addr, int portno, int reg, int onoff)
-{
- struct uvscom_softc *sc = addr;
-
- switch (reg) {
- case UCOM_SET_DTR:
- uvscom_dtr(sc, onoff);
- break;
- case UCOM_SET_RTS:
- uvscom_rts(sc, onoff);
- break;
- case UCOM_SET_BREAK:
- uvscom_break(sc, onoff);
- break;
- default:
- break;
- }
-}
-
-static int
-uvscom_param(void *addr, int portno, struct termios *t)
-{
- struct uvscom_softc *sc = addr;
- usbd_status err;
- uint16_t lsp;
- uint16_t ls;
-
- DPRINTF(("%s: uvscom_param: sc = %p\n",
- device_get_nameunit(sc->sc_ucom.sc_dev), sc));
-
- ls = 0;
-
- switch (t->c_ospeed) {
- case B150:
- lsp = UVSCOM_SPEED_150BPS;
- break;
- case B300:
- lsp = UVSCOM_SPEED_300BPS;
- break;
- case B600:
- lsp = UVSCOM_SPEED_600BPS;
- break;
- case B1200:
- lsp = UVSCOM_SPEED_1200BPS;
- break;
- case B2400:
- lsp = UVSCOM_SPEED_2400BPS;
- break;
- case B4800:
- lsp = UVSCOM_SPEED_4800BPS;
- break;
- case B9600:
- lsp = UVSCOM_SPEED_9600BPS;
- break;
- case B19200:
- lsp = UVSCOM_SPEED_19200BPS;
- break;
- case B38400:
- lsp = UVSCOM_SPEED_38400BPS;
- break;
- case B57600:
- lsp = UVSCOM_SPEED_57600BPS;
- break;
- case B115200:
- lsp = UVSCOM_SPEED_115200BPS;
- break;
- default:
- return (EIO);
- }
-
- if (ISSET(t->c_cflag, CSTOPB))
- SET(ls, UVSCOM_STOP_BIT_2);
- else
- SET(ls, UVSCOM_STOP_BIT_1);
-
- if (ISSET(t->c_cflag, PARENB)) {
- if (ISSET(t->c_cflag, PARODD))
- SET(ls, UVSCOM_PARITY_ODD);
- else
- SET(ls, UVSCOM_PARITY_EVEN);
- } else
- SET(ls, UVSCOM_PARITY_NONE);
-
- switch (ISSET(t->c_cflag, CSIZE)) {
- case CS5:
- SET(ls, UVSCOM_DATA_BIT_5);
- break;
- case CS6:
- SET(ls, UVSCOM_DATA_BIT_6);
- break;
- case CS7:
- SET(ls, UVSCOM_DATA_BIT_7);
- break;
- case CS8:
- SET(ls, UVSCOM_DATA_BIT_8);
- break;
- default:
- return (EIO);
- }
-
- err = uvscom_set_line_coding(sc, lsp, ls);
- if (err)
- return (EIO);
-
- if (ISSET(t->c_cflag, CRTSCTS)) {
- err = uvscom_set_crtscts(sc);
- if (err)
- return (EIO);
- }
-
- return (0);
-}
-
-static int
-uvscom_open(void *addr, int portno)
-{
- struct uvscom_softc *sc = addr;
- int err;
- int i;
-
- if (sc->sc_ucom.sc_dying)
- return (ENXIO);
-
- DPRINTF(("uvscom_open: sc = %p\n", sc));
-
- /* change output packet size */
- sc->sc_ucom.sc_obufsize = uvscomobufsiz;
-
- if (sc->sc_intr_number != -1 && sc->sc_intr_pipe == NULL) {
- DPRINTF(("uvscom_open: open interrupt pipe.\n"));
-
- sc->sc_usr = 0; /* clear unit status */
-
- err = uvscom_readstat(sc);
- if (err) {
- DPRINTF(("%s: uvscom_open: readstat faild\n",
- device_get_nameunit(sc->sc_ucom.sc_dev)));
- return (ENXIO);
- }
-
- sc->sc_intr_buf = malloc(sc->sc_isize, M_USBDEV, M_WAITOK);
- err = usbd_open_pipe_intr(sc->sc_ucom.sc_iface,
- sc->sc_intr_number,
- USBD_SHORT_XFER_OK,
- &sc->sc_intr_pipe,
- sc,
- sc->sc_intr_buf,
- sc->sc_isize,
- uvscom_intr,
- uvscominterval);
- if (err) {
- device_printf(sc->sc_ucom.sc_dev,
- "cannot open interrupt pipe (addr %d)\n",
- sc->sc_intr_number);
- return (ENXIO);
- }
- } else {
- DPRINTF(("uvscom_open: did not open interrupt pipe.\n"));
- }
-
- if ((sc->sc_usr & UVSCOM_USTAT_MASK) == 0) {
- /* unit is not ready */
-
- for (i = UVSCOM_UNIT_WAIT; i > 0; --i) {
- pause("uvsop", hz); /* XXX */
- if (ISSET(sc->sc_usr, UVSCOM_USTAT_MASK))
- break;
- }
- if (i == 0) {
- DPRINTF(("%s: unit is not ready\n",
- device_get_nameunit(sc->sc_ucom.sc_dev)));
- return (ENXIO);
- }
-
- /* check PC Card was inserted */
- if (ISSET(sc->sc_usr, UVSCOM_NOCARD)) {
- DPRINTF(("%s: no card\n",
- device_get_nameunit(sc->sc_ucom.sc_dev)));
- return (ENXIO);
- }
- }
-
- return (0);
-}
-
-static void
-uvscom_close(void *addr, int portno)
-{
- struct uvscom_softc *sc = addr;
- int err;
-
- if (sc->sc_ucom.sc_dying)
- return;
-
- DPRINTF(("uvscom_close: close\n"));
-
- uvscom_shutdown(sc);
-
- if (sc->sc_intr_pipe != NULL) {
- err = usbd_abort_pipe(sc->sc_intr_pipe);
- if (err)
- device_printf(sc->sc_ucom.sc_dev,
- "abort interrupt pipe failed: %s\n",
- usbd_errstr(err));
- err = usbd_close_pipe(sc->sc_intr_pipe);
- if (err)
- device_printf(sc->sc_ucom.sc_dev,
- "close interrupt pipe failed: %s\n",
- usbd_errstr(err));
- free(sc->sc_intr_buf, M_USBDEV);
- sc->sc_intr_pipe = NULL;
- }
-}
-
-static void
-uvscom_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- struct uvscom_softc *sc = priv;
- u_char *buf = sc->sc_intr_buf;
- u_char pstatus;
-
- if (sc->sc_ucom.sc_dying)
- return;
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
- return;
-
- device_printf(sc->sc_ucom.sc_dev,
- "uvscom_intr: abnormal status: %s\n",
- usbd_errstr(status));
- usbd_clear_endpoint_stall_async(sc->sc_intr_pipe);
- return;
- }
-
- DPRINTFN(2, ("%s: uvscom status = %02x %02x\n",
- device_get_nameunit(sc->sc_ucom.sc_dev), buf[0], buf[1]));
-
- sc->sc_lsr = sc->sc_msr = 0;
- sc->sc_usr = buf[1];
-
- pstatus = buf[0];
- if (ISSET(pstatus, UVSCOM_TXRDY))
- SET(sc->sc_lsr, ULSR_TXRDY);
- if (ISSET(pstatus, UVSCOM_RXRDY))
- SET(sc->sc_lsr, ULSR_RXRDY);
-
- pstatus = buf[1];
- if (ISSET(pstatus, UVSCOM_CTS))
- SET(sc->sc_msr, SER_CTS);
- if (ISSET(pstatus, UVSCOM_DSR))
- SET(sc->sc_msr, SER_DSR);
- if (ISSET(pstatus, UVSCOM_DCD))
- SET(sc->sc_msr, SER_DCD);
-
- /* Deferred notifying to the ucom layer */
- taskqueue_enqueue(taskqueue_swi_giant, &sc->sc_task);
-}
-
-static void
-uvscom_notify(void *arg, int count)
-{
- struct uvscom_softc *sc;
-
- sc = (struct uvscom_softc *)arg;
- if (sc->sc_ucom.sc_dying)
- return;
- ucom_status_change(&sc->sc_ucom);
-}
-
-static void
-uvscom_get_status(void *addr, int portno, u_char *lsr, u_char *msr)
-{
- struct uvscom_softc *sc = addr;
-
- if (lsr != NULL)
- *lsr = sc->sc_lsr;
- if (msr != NULL)
- *msr = sc->sc_msr;
-}
diff --git a/sys/dev/usb/uxb360gp_rdesc.h b/sys/dev/usb/uxb360gp_rdesc.h
deleted file mode 100644
index b5a43f9..0000000
--- a/sys/dev/usb/uxb360gp_rdesc.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/*-
- * Copyright (c) 2005 Ed Schouten <ed@FreeBSD.org>
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- * $FreeBSD$
- */
-
-/*
- * The descriptor has no output report format, thus preventing you from
- * controlling the LEDs and the built-in rumblers.
- */
-static const uByte uhid_xb360gp_report_descr[] = {
- 0x05, 0x01, /* USAGE PAGE (Generic Desktop) */
- 0x09, 0x05, /* USAGE (Gamepad) */
- 0xa1, 0x01, /* COLLECTION (Application) */
- /* Unused */
- 0x75, 0x08, /* REPORT SIZE (8) */
- 0x95, 0x01, /* REPORT COUNT (1) */
- 0x81, 0x01, /* INPUT (Constant) */
- /* Byte count */
- 0x75, 0x08, /* REPORT SIZE (8) */
- 0x95, 0x01, /* REPORT COUNT (1) */
- 0x05, 0x01, /* USAGE PAGE (Generic Desktop) */
- 0x09, 0x3b, /* USAGE (Byte Count) */
- 0x81, 0x01, /* INPUT (Constant) */
- /* D-Pad */
- 0x05, 0x01, /* USAGE PAGE (Generic Desktop) */
- 0x09, 0x01, /* USAGE (Pointer) */
- 0xa1, 0x00, /* COLLECTION (Physical) */
- 0x75, 0x01, /* REPORT SIZE (1) */
- 0x15, 0x00, /* LOGICAL MINIMUM (0) */
- 0x25, 0x01, /* LOGICAL MAXIMUM (1) */
- 0x35, 0x00, /* PHYSICAL MINIMUM (0) */
- 0x45, 0x01, /* PHYSICAL MAXIMUM (1) */
- 0x95, 0x04, /* REPORT COUNT (4) */
- 0x05, 0x01, /* USAGE PAGE (Generic Desktop) */
- 0x09, 0x90, /* USAGE (D-Pad Up) */
- 0x09, 0x91, /* USAGE (D-Pad Down) */
- 0x09, 0x93, /* USAGE (D-Pad Left) */
- 0x09, 0x92, /* USAGE (D-Pad Right) */
- 0x81, 0x02, /* INPUT (Data, Variable, Absolute) */
- 0xc0, /* END COLLECTION */
- /* Buttons 5-11 */
- 0x75, 0x01, /* REPORT SIZE (1) */
- 0x15, 0x00, /* LOGICAL MINIMUM (0) */
- 0x25, 0x01, /* LOGICAL MAXIMUM (1) */
- 0x35, 0x00, /* PHYSICAL MINIMUM (0) */
- 0x45, 0x01, /* PHYSICAL MAXIMUM (1) */
- 0x95, 0x07, /* REPORT COUNT (7) */
- 0x05, 0x09, /* USAGE PAGE (Button) */
- 0x09, 0x08, /* USAGE (Button 8) */
- 0x09, 0x07, /* USAGE (Button 7) */
- 0x09, 0x09, /* USAGE (Button 9) */
- 0x09, 0x0a, /* USAGE (Button 10) */
- 0x09, 0x05, /* USAGE (Button 5) */
- 0x09, 0x06, /* USAGE (Button 6) */
- 0x09, 0x0b, /* USAGE (Button 11) */
- 0x81, 0x02, /* INPUT (Data, Variable, Absolute) */
- /* Unused */
- 0x75, 0x01, /* REPORT SIZE (1) */
- 0x95, 0x01, /* REPORT COUNT (1) */
- 0x81, 0x01, /* INPUT (Constant) */
- /* Buttons 1-4 */
- 0x75, 0x01, /* REPORT SIZE (1) */
- 0x15, 0x00, /* LOGICAL MINIMUM (0) */
- 0x25, 0x01, /* LOGICAL MAXIMUM (1) */
- 0x35, 0x00, /* PHYSICAL MINIMUM (0) */
- 0x45, 0x01, /* PHYSICAL MAXIMUM (1) */
- 0x95, 0x04, /* REPORT COUNT (4) */
- 0x05, 0x09, /* USAGE PAGE (Button) */
- 0x19, 0x01, /* USAGE MINIMUM (Button 1) */
- 0x29, 0x04, /* USAGE MAXIMUM (Button 4) */
- 0x81, 0x02, /* INPUT (Data, Variable, Absolute) */
- /* Triggers */
- 0x75, 0x08, /* REPORT SIZE (8) */
- 0x15, 0x00, /* LOGICAL MINIMUM (0) */
- 0x26, 0xff, 0x00, /* LOGICAL MAXIMUM (255) */
- 0x35, 0x00, /* PHYSICAL MINIMUM (0) */
- 0x46, 0xff, 0x00, /* PHYSICAL MAXIMUM (255) */
- 0x95, 0x02, /* REPORT SIZE (2) */
- 0x05, 0x01, /* USAGE PAGE (Generic Desktop) */
- 0x09, 0x32, /* USAGE (Z) */
- 0x09, 0x35, /* USAGE (Rz) */
- 0x81, 0x02, /* INPUT (Data, Variable, Absolute) */
- /* Sticks */
- 0x75, 0x10, /* REPORT SIZE (16) */
- 0x16, 0x00, 0x80, /* LOGICAL MINIMUM (-32768) */
- 0x26, 0xff, 0x7f, /* LOGICAL MAXIMUM (32767) */
- 0x36, 0x00, 0x80, /* PHYSICAL MINIMUM (-32768) */
- 0x46, 0xff, 0x7f, /* PHYSICAL MAXIMUM (32767) */
- 0x95, 0x04, /* REPORT COUNT (4) */
- 0x05, 0x01, /* USAGE PAGE (Generic Desktop) */
- 0x09, 0x30, /* USAGE (X) */
- 0x09, 0x31, /* USAGE (Y) */
- 0x09, 0x33, /* USAGE (Rx) */
- 0x09, 0x34, /* USAGE (Ry) */
- 0x81, 0x02, /* INPUT (Data, Variable, Absolute) */
- /* Unused */
- 0x75, 0x30, /* REPORT SIZE (48) */
- 0x95, 0x01, /* REPORT COUNT (1) */
- 0x81, 0x01, /* INPUT (Constant) */
- 0xc0, /* END COLLECTION */
-};
OpenPOWER on IntegriCloud