summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/usb/FILES21
-rw-r--r--sys/dev/usb/TODO2
-rw-r--r--sys/dev/usb/ehci.c2757
-rw-r--r--sys/dev/usb/ehcireg.h288
-rw-r--r--sys/dev/usb/ehcivar.h138
-rw-r--r--sys/dev/usb/files.usb113
-rw-r--r--sys/dev/usb/hid.c143
-rw-r--r--sys/dev/usb/hid.h21
-rw-r--r--sys/dev/usb/if_upl.c28
-rw-r--r--sys/dev/usb/if_url.c1609
-rw-r--r--sys/dev/usb/if_urlreg.h195
-rw-r--r--sys/dev/usb/ohci.c483
-rw-r--r--sys/dev/usb/ohcivar.h14
-rw-r--r--sys/dev/usb/ucom.c49
-rw-r--r--sys/dev/usb/ucomvar.h15
-rw-r--r--sys/dev/usb/udsbr.c279
-rw-r--r--sys/dev/usb/uftdi.c38
-rw-r--r--sys/dev/usb/uftdireg.h5
-rw-r--r--sys/dev/usb/ugen.c168
-rw-r--r--sys/dev/usb/uhci.c297
-rw-r--r--sys/dev/usb/uhcireg.h5
-rw-r--r--sys/dev/usb/uhcivar.h6
-rw-r--r--sys/dev/usb/uhid.c349
-rw-r--r--sys/dev/usb/uhidev.c513
-rw-r--r--sys/dev/usb/uhidev.h91
-rw-r--r--sys/dev/usb/uhub.c37
-rw-r--r--sys/dev/usb/ukbd.c492
-rw-r--r--sys/dev/usb/ukbdmap.c11
-rw-r--r--sys/dev/usb/umass.c2576
-rw-r--r--sys/dev/usb/umass_isdata.c589
-rw-r--r--sys/dev/usb/umass_isdata.h40
-rw-r--r--sys/dev/usb/umass_quirks.c333
-rw-r--r--sys/dev/usb/umass_quirks.h62
-rw-r--r--sys/dev/usb/umass_scsi.c488
-rw-r--r--sys/dev/usb/umass_scsi.h31
-rw-r--r--sys/dev/usb/umass_scsipi.c636
-rw-r--r--sys/dev/usb/umass_scsipi.h41
-rw-r--r--sys/dev/usb/umassvar.h271
-rw-r--r--sys/dev/usb/umct.c631
-rw-r--r--sys/dev/usb/umct.h109
-rw-r--r--sys/dev/usb/umidi.c1374
-rw-r--r--sys/dev/usb/umidi_quirks.c215
-rw-r--r--sys/dev/usb/umidi_quirks.h120
-rw-r--r--sys/dev/usb/umidireg.h80
-rw-r--r--sys/dev/usb/umidivar.h138
-rw-r--r--sys/dev/usb/umodem.c8
-rw-r--r--sys/dev/usb/ums.c197
-rw-r--r--sys/dev/usb/uplcom.c33
-rw-r--r--sys/dev/usb/urio.c36
-rw-r--r--sys/dev/usb/usb.c236
-rw-r--r--sys/dev/usb/usb.h117
-rw-r--r--sys/dev/usb/usb_port.h121
-rw-r--r--sys/dev/usb/usb_quirks.c6
-rw-r--r--sys/dev/usb/usb_subr.c80
-rw-r--r--sys/dev/usb/usbdevs.h2
-rw-r--r--sys/dev/usb/usbdevs_data.h2
-rw-r--r--sys/dev/usb/usbdi.c111
-rw-r--r--sys/dev/usb/usbdi.h73
-rw-r--r--sys/dev/usb/usbdi_util.c79
-rw-r--r--sys/dev/usb/usbdi_util.h8
-rw-r--r--sys/dev/usb/usbdivar.h27
-rw-r--r--sys/dev/usb/usbhid.h19
-rw-r--r--sys/dev/usb/uscanner.c334
-rw-r--r--sys/dev/usb/usscanner.c18
-rw-r--r--sys/dev/usb/uvisor.c62
65 files changed, 3902 insertions, 13568 deletions
diff --git a/sys/dev/usb/FILES b/sys/dev/usb/FILES
index 166fecb2dcd..ed7b4094b13 100644
--- a/sys/dev/usb/FILES
+++ b/sys/dev/usb/FILES
@@ -5,9 +5,6 @@ Makefile to install .h files
Makefile.usbdevs to run devlist2h.awk
TODO just a list of things to do
devlist2h.awk script to generate usbdevs*.h
-ehci.c Host controller driver for EHCI (just a stub now)
-ehcireg.h Hardware definitions for EHCI (just a stub now)
-ehcivar.h API for ehci.c
ezload.c EZ-USB firmware download subroutines
ezload.h API for ezload.c
files.usb config include file
@@ -34,27 +31,13 @@ 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 generic HID driver
-uhidev.c USB HID class driver
-uhidev.h and definitions for it
+uhid.c USB HID class driver
uhub.c USB hub driver
ukbd.c USB keyboard driver
ukbdmap.c wscons key mapping for ukbd
ukbdvar.h API for ukbd.c
ulpt.c USB printer class driver
-umass.c USB mass storage wire protocol driver
-umass_isdata.c In-System Design ATA over bulk-only driver
-umass_isdata.h and definitions for it
-umass_quirks.c Table of strange umass devices
-umass_quirks.h and definitions for it
-umass_scsipi.c umass command protocol driver
-umass_scsipi.h and definitions for it
-umassvar.h definitions for umass.c
-umidi.c USB MIDI driver
-umidi_quirks.c Strange MIDI devices
-umidi_quirks.h and definitions for it
-umidireg.h Protocol definitions for umidi.c
-umidivar.h definitions for umidi.c
+umass.c USB mass storage driver (bulk only for now)
umodem.c USB modem (CDC ACM) driver
ums.c USB mouse driver
urio.c USB Diamond Rio500 driver
diff --git a/sys/dev/usb/TODO b/sys/dev/usb/TODO
index 2bc3497628a..28088a69fb3 100644
--- a/sys/dev/usb/TODO
+++ b/sys/dev/usb/TODO
@@ -85,8 +85,6 @@ Get rid of hcpriv.
Keyspan serial driver
-Clean up umass driver
-
Documentation:
--------------
diff --git a/sys/dev/usb/ehci.c b/sys/dev/usb/ehci.c
deleted file mode 100644
index ea68e25be57..00000000000
--- a/sys/dev/usb/ehci.c
+++ /dev/null
@@ -1,2757 +0,0 @@
-/* $OpenBSD: ehci.c,v 1.1 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: ehci.c,v 1.29 2001/12/31 12:16:57 augustss Exp $ */
-
-/*
- * TODO
- * hold off explorations by companion controllers until ehci has started.
- */
-
-/*
- * 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.
- */
-
-/*
- * USB Enhanced Host Controller Driver, a.k.a. USB 2.0 controller.
- *
- * 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
- *
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/device.h>
-#include <sys/select.h>
-#include <sys/proc.h>
-#include <sys/queue.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>
-
-#if defined(__OpenBSD__)
-struct cfdriver ehci_cd = {
- NULL, "ehci", DV_DULL
-};
-#endif
-
-#ifdef EHCI_DEBUG
-#define DPRINTF(x) if (ehcidebug) printf x
-#define DPRINTFN(n,x) if (ehcidebug>(n)) printf x
-int ehcidebug = 0;
-#ifndef __NetBSD__
-#define bitmask_snprintf(q,f,b,l) snprintf((b), (l), "%b", (q), (f))
-#endif
-#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 */
- /* XXX */
- /* Bulk pipe */
- struct {
- u_int length;
- } bulk;
- /* Iso pipe */
- /* XXX */
- } u;
-};
-
-Static void ehci_shutdown(void *);
-Static void ehci_power(int, void *);
-
-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_idone(struct ehci_xfer *);
-Static void ehci_timeout(void *);
-Static void ehci_timeout_task(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_pcd_able(ehci_softc_t *, int);
-Static void ehci_pcd_enable(void *);
-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 **);
-Static void ehci_free_sqtd_chain(ehci_softc_t *, ehci_soft_qtd_t *,
- ehci_soft_qtd_t *);
-
-Static usbd_status ehci_device_request(usbd_xfer_handle xfer);
-
-Static void ehci_add_qh(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_set_qh_qtd(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);
-
-#ifdef EHCI_DEBUG
-Static void ehci_dump_regs(ehci_softc_t *);
-Static void ehci_dump(void);
-Static ehci_softc_t *theehci;
-Static void ehci_dump_link(ehci_link_t, int);
-Static void ehci_dump_sqtds(ehci_soft_qtd_t *);
-Static void ehci_dump_sqtd(ehci_soft_qtd_t *);
-Static void ehci_dump_qtd(ehci_qtd_t *);
-Static void ehci_dump_sqh(ehci_soft_qh_t *);
-Static void ehci_dump_exfer(struct ehci_xfer *);
-#endif
-
-#define MS_TO_TICKS(ms) ((ms) * hz / 1000)
-
-#define EHCI_NULL htole32(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) \
- LIST_REMOVE((ex), inext)
-
-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_init(ehci_softc_t *sc)
-{
- u_int32_t version, sparams, cparams, hcr;
- u_int i;
- usbd_status err;
- ehci_soft_qh_t *sqh;
-
- DPRINTF(("ehci_init: start\n"));
-#ifdef EHCI_DEBUG
- theehci = sc;
-#endif
-
- sc->sc_offs = EREAD1(sc, EHCI_CAPLENGTH);
-
- version = EREAD2(sc, EHCI_HCIVERSION);
- printf("%s: EHCI version %x.%x\n", USBDEVNAME(sc->sc_bus.bdev),
- 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);
- if (EHCI_HCS_N_CC(sparams) != sc->sc_ncomp) {
- printf("%s: wrong number of companions (%d != %d)\n",
- USBDEVNAME(sc->sc_bus.bdev),
- EHCI_HCS_N_CC(sparams), sc->sc_ncomp);
- return (USBD_IOERROR);
- }
- if (sc->sc_ncomp > 0) {
- printf("%s: companion controller%s, %d port%s each:",
- USBDEVNAME(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", USBDEVNAME(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));
-
- sc->sc_bus.usbrev = USBREV_2_0;
-
- /* Reset the controller */
- DPRINTF(("%s: resetting\n", USBDEVNAME(sc->sc_bus.bdev)));
- EOWRITE4(sc, EHCI_USBCMD, 0); /* Halt controller */
- usb_delay_ms(&sc->sc_bus, 1);
- EOWRITE4(sc, EHCI_USBCMD, EHCI_CMD_HCRESET);
- for (i = 0; i < 100; i++) {
- delay(10);
- hcr = EOREAD4(sc, EHCI_USBCMD) & EHCI_CMD_HCRESET;
- if (!hcr)
- break;
- }
- if (hcr) {
- printf("%s: reset timeout\n", USBDEVNAME(sc->sc_bus.bdev));
- return (USBD_IOERROR);
- }
-
- /* 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*4; break;
- case 1: sc->sc_flsize = 512*4; break;
- case 2: sc->sc_flsize = 256*4; break;
- case 3: return (USBD_IOERROR);
- }
- err = usb_allocmem(&sc->sc_bus, sc->sc_flsize,
- EHCI_FLALIGN_ALIGN, &sc->sc_fldma);
- if (err)
- return (err);
- DPRINTF(("%s: flsize=%d\n", USBDEVNAME(sc->sc_bus.bdev),sc->sc_flsize));
-
- /* Set up the bus struct. */
- sc->sc_bus.methods = &ehci_bus_methods;
- sc->sc_bus.pipe_size = sizeof(struct ehci_pipe);
-
- sc->sc_powerhook = powerhook_establish(ehci_power, sc);
- sc->sc_shutdownhook = shutdownhook_establish(ehci_shutdown, sc);
-
- sc->sc_eintrs = EHCI_NORMAL_INTRS;
-
- /* 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 =
- htole32(EHCI_QH_SET_EPS(EHCI_QH_SPEED_HIGH) | EHCI_QH_HRECL);
- sqh->qh.qh_link =
- htole32(sqh->physaddr | EHCI_LINK_QH);
- sqh->qh.qh_curqtd = EHCI_NULL;
- sqh->next = NULL;
- /* Fill the overlay qTD */
- sqh->qh.qh_qtd.qtd_next = EHCI_NULL;
- sqh->qh.qh_qtd.qtd_altnext = EHCI_NULL;
- sqh->qh.qh_qtd.qtd_status = htole32(EHCI_QTD_HALTED);
- sqh->sqtd = NULL;
-#ifdef EHCI_DEBUG
- if (ehcidebug) {
- ehci_dump_sqh(sqh);
- }
-#endif
-
- /* Point to async list */
- sc->sc_async_head = sqh;
- EOWRITE4(sc, EHCI_ASYNCLISTADDR, sqh->physaddr | EHCI_LINK_QH);
-
- usb_callout_init(sc->sc_tmo_pcd);
-
- 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_8 | /* 8 microframes */
- (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++) {
- delay(10);
- hcr = EOREAD4(sc, EHCI_USBSTS) & EHCI_STS_HCH;
- if (!hcr)
- break;
- }
- if (hcr) {
- printf("%s: run timeout\n", USBDEVNAME(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) {
-#ifdef DIAGNOSTIC
- printf("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_intr: sc == NULL\n");
-#endif
- return (0);
- }
-
- intrs = EHCI_STS_INTRS(EOREAD4(sc, EHCI_USBSTS));
-
- if (!intrs)
- return (0);
-
- EOWRITE4(sc, EHCI_USBSTS, intrs); /* Acknowledge */
- eintrs = intrs & sc->sc_eintrs;
- DPRINTFN(7, ("ehci_intr: 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);
-
- 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)) {
- DPRINTF(("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",
- USBDEVNAME(sc->sc_bus.bdev));
- /* XXX what else */
- }
- if (eintrs & EHCI_STS_PCD) {
- ehci_pcd(sc, sc->sc_intrxfer);
- /*
- * Disable PCD interrupt for now, because it will be
- * on until the port has been reset.
- */
- ehci_pcd_able(sc, 0);
- /* Do not allow RHSC interrupts > 1 per second */
- usb_callout(sc->sc_tmo_pcd, hz, ehci_pcd_enable, sc);
- 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",
- USBDEVNAME(sc->sc_bus.bdev), eintrs);
- }
-
- return (1);
-}
-
-void
-ehci_pcd_able(ehci_softc_t *sc, int on)
-{
- DPRINTFN(4, ("ehci_pcd_able: on=%d\n", on));
- if (on)
- sc->sc_eintrs |= EHCI_STS_PCD;
- else
- sc->sc_eintrs &= ~EHCI_STS_PCD;
- EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs);
-}
-
-void
-ehci_pcd_enable(void *v_sc)
-{
- ehci_softc_t *sc = v_sc;
-
- ehci_pcd_able(sc, 1);
-}
-
-void
-ehci_pcd(ehci_softc_t *sc, usbd_xfer_handle xfer)
-{
- usbd_pipe_handle pipe;
- struct ehci_pipe *epipe;
- u_char *p;
- int i, m;
-
- if (xfer == NULL) {
- /* Just ignore the change. */
- return;
- }
-
- pipe = xfer->pipe;
- epipe = (struct ehci_pipe *)pipe;
-
- p = KERNADDR(&xfer->dmabuf);
- 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;
-
- usb_transfer_complete(xfer);
-}
-
-void
-ehci_softintr(void *v)
-{
- ehci_softc_t *sc = v;
- struct ehci_xfer *ex;
-
- DPRINTFN(10,("%s: ehci_softintr (%d)\n", USBDEVNAME(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 = LIST_NEXT(ex, inext))
- ehci_check_intr(sc, ex);
-
- if (sc->sc_softwake) {
- sc->sc_softwake = 0;
- wakeup(&sc->sc_softwake);
- }
-
- sc->sc_bus.intr_context--;
-}
-
-/* Check for an interrupt. */
-void
-ehci_check_intr(ehci_softc_t *sc, struct ehci_xfer *ex)
-{
- ehci_soft_qtd_t *sqtd, *lsqtd;
- u_int32_t status;
-
- DPRINTFN(/*15*/2, ("ehci_check_intr: ex=%p\n", ex));
-
- if (ex->sqtdstart == NULL) {
- printf("ehci_check_intr: sqtdstart=NULL\n");
- return;
- }
- lsqtd = ex->sqtdend;
-#ifdef DIAGNOSTIC
- if (lsqtd == NULL) {
- printf("ehci_check_intr: sqtd==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 (le32toh(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 = le32toh(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_SET_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));
- usb_uncallout(ex->xfer.timeout_handle, ehci_timeout, ex);
- ehci_idone(ex);
-}
-
-void
-ehci_idone(struct ehci_xfer *ex)
-{
- usbd_xfer_handle xfer = &ex->xfer;
-#ifdef EHCI_DEBUG
- struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
-#endif
- ehci_soft_qtd_t *sqtd;
- u_int32_t status = 0, nstatus;
- int actlen;
-
- 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(ex->sqtdstart);
-#endif
-
- /* The transfer is done, compute actual length and status. */
- actlen = 0;
- for (sqtd = ex->sqtdstart; sqtd != NULL; sqtd = sqtd->nextqtd) {
- nstatus = le32toh(sqtd->qtd.qtd_status);
- if (nstatus & EHCI_QTD_ACTIVE)
- break;
-
- status = nstatus;
- if (EHCI_QTD_GET_PID(status) != EHCI_QTD_PID_SETUP)
- actlen += sqtd->len - EHCI_QTD_GET_BYTES(status);
- }
-
- /* If there are left over TDs we need to update the toggle. */
- if (sqtd != NULL) {
- if (!(xfer->rqflags & URQ_REQUEST))
- printf("ehci_idone: need toggle update\n");
-#if 0
- epipe->nexttoggle = EHCI_TD_GET_DT(le32toh(std->td.td_token));
-#endif
- }
-
- status &= EHCI_QTD_STATERRS;
- DPRINTFN(/*10*/2, ("ehci_idone: len=%d, actlen=%d, status=0x%x\n",
- xfer->length, actlen, status));
- xfer->actlen = actlen;
- if (status != 0) {
-#ifdef EHCI_DEBUG
- char sbuf[128];
-
- bitmask_snprintf((u_int32_t)status,
- "\20\3MISSEDMICRO\4XACT\5BABBLE\6BABBLE"
- "\7HALTED",
- sbuf, sizeof(sbuf));
-
- DPRINTFN((status == EHCI_QTD_HALTED)*/*10*/2,
- ("ehci_idone: error, addr=%d, endpt=0x%02x, "
- "status 0x%s\n",
- xfer->pipe->device->address,
- xfer->pipe->endpoint->edesc->bEndpointAddress,
- sbuf));
- if (ehcidebug > 2) {
- ehci_dump_sqh(epipe->sqh);
- ehci_dump_sqtds(ex->sqtdstart);
- }
-#endif
- if (status == EHCI_QTD_HALTED)
- xfer->status = USBD_STALLED;
- else
- xfer->status = USBD_IOERROR; /* more info XXX */
- } else {
- xfer->status = USBD_NORMAL_COMPLETION;
- }
-
- 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;
-
- if (sc->sc_child != NULL)
- rv = config_detach(sc->sc_child, flags);
-
- if (rv != 0)
- return (rv);
-
- usb_uncallout(sc->sc_tmo_pcd, ehci_pcd_enable, sc);
-
- if (sc->sc_powerhook != NULL)
- powerhook_disestablish(sc->sc_powerhook);
- if (sc->sc_shutdownhook != NULL)
- shutdownhook_disestablish(sc->sc_shutdownhook);
-
- usb_delay_ms(&sc->sc_bus, 300); /* XXX let stray task complete */
-
- /* XXX free other data structures XXX */
-
- return (rv);
-}
-
-
-int
-ehci_activate(device_ptr_t self, enum devact act)
-{
- struct ehci_softc *sc = (struct ehci_softc *)self;
- int rv = 0;
-
- switch (act) {
- case DVACT_ACTIVATE:
- return (EOPNOTSUPP);
- break;
-
- case DVACT_DEACTIVATE:
- if (sc->sc_child != NULL)
- rv = config_deactivate(sc->sc_child);
- sc->sc_dying = 1;
- break;
- }
- return (rv);
-}
-
-/*
- * 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
-ehci_power(int why, void *v)
-{
- ehci_softc_t *sc = v;
- //u_int32_t ctl;
- int s;
-
-#ifdef EHCI_DEBUG
- DPRINTF(("ehci_power: sc=%p, why=%d\n", sc, why));
- ehci_dump_regs(sc);
-#endif
-
- s = splhardusb();
- switch (why) {
- case PWR_SUSPEND:
- case PWR_STANDBY:
- sc->sc_bus.use_polling++;
-#if 0
-OOO
- ctl = OREAD4(sc, EHCI_CONTROL) & ~EHCI_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, EHCI_INTERRUPT_ENABLE);
- }
- ctl |= EHCI_HCFS_SUSPEND;
- OWRITE4(sc, EHCI_CONTROL, ctl);
-#endif
- usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT);
- sc->sc_bus.use_polling--;
- break;
- case PWR_RESUME:
- sc->sc_bus.use_polling++;
-#if 0
-OOO
- /* Some broken BIOSes do not recover these values */
- OWRITE4(sc, EHCI_HCCA, DMAADDR(&sc->sc_hccadma));
- OWRITE4(sc, EHCI_CONTROL_HEAD_ED, sc->sc_ctrl_head->physaddr);
- OWRITE4(sc, EHCI_BULK_HEAD_ED, sc->sc_bulk_head->physaddr);
- if (sc->sc_intre)
- OWRITE4(sc, EHCI_INTERRUPT_ENABLE,
- sc->sc_intre & (EHCI_ALL_INTRS | EHCI_MIE));
- if (sc->sc_control)
- ctl = sc->sc_control;
- else
- ctl = OREAD4(sc, EHCI_CONTROL);
- ctl |= EHCI_HCFS_RESUME;
- OWRITE4(sc, EHCI_CONTROL, ctl);
- usb_delay_ms(&sc->sc_bus, USB_RESUME_DELAY);
- ctl = (ctl & ~EHCI_HCFS_MASK) | EHCI_HCFS_OPERATIONAL;
- OWRITE4(sc, EHCI_CONTROL, ctl);
- usb_delay_ms(&sc->sc_bus, USB_RESUME_RECOVERY);
- sc->sc_control = sc->sc_intre = 0;
-#endif
- sc->sc_bus.use_polling--;
- break;
-#if defined(__NetBSD__)
- case PWR_SOFTSUSPEND:
- case PWR_SOFTSTANDBY:
- case PWR_SOFTRESUME:
- break;
-#endif
- }
- splx(s);
-}
-
-/*
- * 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"));
- EOWRITE4(sc, EHCI_USBCMD, 0); /* Halt controller */
- EOWRITE4(sc, EHCI_USBCMD, EHCI_CMD_HCRESET);
-}
-
-usbd_status
-ehci_allocm(struct usbd_bus *bus, usb_dma_t *dma, u_int32_t size)
-{
- struct ehci_softc *sc = (struct ehci_softc *)bus;
- usbd_status err;
-
- err = usb_allocmem(&sc->sc_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)
-{
- struct ehci_softc *sc = (struct ehci_softc *)bus;
-
- usb_freemem(&sc->sc_bus, dma);
-}
-
-usbd_xfer_handle
-ehci_allocx(struct usbd_bus *bus)
-{
- struct ehci_softc *sc = (struct ehci_softc *)bus;
- usbd_xfer_handle xfer;
-
- xfer = SIMPLEQ_FIRST(&sc->sc_free_xfers);
- if (xfer != NULL) {
- SIMPLEQ_REMOVE_HEAD(&sc->sc_free_xfers, xfer, 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 ehci_xfer), M_USB, M_NOWAIT);
- }
- if (xfer != NULL) {
- memset(xfer, 0, sizeof (struct ehci_xfer));
-#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
- SIMPLEQ_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;
-
- 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
- epipe->sqh->qh.qh_qtd.qtd_status &= htole32(~EHCI_QTD_TOGGLE);
-}
-
-Static void
-ehci_noop(usbd_pipe_handle pipe)
-{
-}
-
-#ifdef EHCI_DEBUG
-void
-ehci_dump_regs(ehci_softc_t *sc)
-{
- int i;
- printf("cmd=0x%08x, sts=0x%08x, ien=0x%08x\n",
- EOREAD4(sc, EHCI_USBCMD),
- EOREAD4(sc, EHCI_USBSTS),
- EOREAD4(sc, EHCI_USBINTR));
- 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++)
- printf("port %d status=0x%08x\n", i,
- EOREAD4(sc, EHCI_PORTSC(i)));
-}
-
-void
-ehci_dump()
-{
- ehci_dump_regs(theehci);
-}
-
-void
-ehci_dump_link(ehci_link_t link, int type)
-{
- link = le32toh(link);
- printf("0x%08x", link);
- if (link & EHCI_LINK_TERMINATE)
- printf("<T>");
- else {
- printf("<");
- if (type) {
- switch (EHCI_LINK_TYPE(link)) {
- case EHCI_LINK_ITD: printf("ITD"); break;
- case EHCI_LINK_QH: printf("QH"); break;
- case EHCI_LINK_SITD: printf("SITD"); break;
- case EHCI_LINK_FSTN: printf("FSTN"); break;
- }
- }
- printf(">");
- }
-}
-
-void
-ehci_dump_sqtds(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(sqtd);
- stop = sqtd->qtd.qtd_next & EHCI_LINK_TERMINATE;
- }
- if (sqtd)
- printf("dump aborted, too many TDs\n");
-}
-
-void
-ehci_dump_sqtd(ehci_soft_qtd_t *sqtd)
-{
- printf("QTD(%p) at 0x%08x:\n", sqtd, sqtd->physaddr);
- ehci_dump_qtd(&sqtd->qtd);
-}
-
-void
-ehci_dump_qtd(ehci_qtd_t *qtd)
-{
- u_int32_t s;
- char sbuf[128];
-
- printf(" next="); ehci_dump_link(qtd->qtd_next, 0);
- printf(" altnext="); ehci_dump_link(qtd->qtd_altnext, 0);
- printf("\n");
- s = le32toh(qtd->qtd_status);
- bitmask_snprintf(EHCI_QTD_GET_STATUS(s),
- "\20\10ACTIVE\7HALTED\6BUFERR\5BABBLE\4XACTERR"
- "\3MISSED\2SPLIT\1PING", sbuf, sizeof(sbuf));
- 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));
- printf(" cerr=%d pid=%d stat=0x%s\n", EHCI_QTD_GET_CERR(s),
- EHCI_QTD_GET_PID(s), sbuf);
- for (s = 0; s < 5; s++)
- printf(" buffer[%d]=0x%08x\n", s, le32toh(qtd->qtd_buffer[s]));
-}
-
-void
-ehci_dump_sqh(ehci_soft_qh_t *sqh)
-{
- ehci_qh_t *qh = &sqh->qh;
- u_int32_t endp, endphub;
-
- printf("QH(%p) at 0x%08x:\n", sqh, sqh->physaddr);
- printf(" link="); ehci_dump_link(qh->qh_link, 1); printf("\n");
- endp = le32toh(qh->qh_endp);
- printf(" endp=0x%08x\n", endp);
- 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));
- 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 = le32toh(qh->qh_endphub);
- printf(" endphub=0x%08x\n", endphub);
- 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));
- printf(" curqtd="); ehci_dump_link(qh->qh_curqtd, 0); printf("\n");
- printf("Overlay qTD:\n");
- ehci_dump_qtd(&qh->qh_qtd);
-}
-
-Static void
-ehci_dump_exfer(struct ehci_xfer *ex)
-{
- printf("ehci_dump_exfer: ex=%p\n", ex);
-}
-#endif
-
-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 speed, naks;
-
- DPRINTFN(1, ("ehci_open: pipe=%p, addr=%d, endpt=%d (%d)\n",
- pipe, addr, ed->bEndpointAddress, sc->sc_addr));
-
- 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:
- 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\n", dev->speed);
- }
- naks = 8; /* XXX */
- sqh = ehci_alloc_sqh(sc);
- if (sqh == NULL)
- goto bad0;
- /* qh_link filled when the QH is added */
- sqh->qh.qh_endp = htole32(
- EHCI_QH_SET_ADDR(addr) |
- EHCI_QH_SET_ENDPT(ed->bEndpointAddress) |
- EHCI_QH_SET_EPS(speed) | /* XXX */
- /* XXX EHCI_QH_DTC ? */
- 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 = htole32(
- EHCI_QH_SET_MULT(1)
- /* XXX TT stuff */
- /* XXX interrupt mask */
- );
- sqh->qh.qh_curqtd = EHCI_NULL;
- /* Fill the overlay qTD */
- sqh->qh.qh_qtd.qtd_next = EHCI_NULL;
- sqh->qh.qh_qtd.qtd_altnext = EHCI_NULL;
- sqh->qh.qh_qtd.qtd_status = htole32(0);
-
- epipe->sqh = sqh;
-
- 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(sqh, sc->sc_async_head);
- splx(s);
- break;
- case UE_BULK:
- pipe->methods = &ehci_device_bulk_methods;
- s = splusb();
- ehci_add_qh(sqh, sc->sc_async_head);
- splx(s);
- break;
- case UE_INTERRUPT:
- pipe->methods = &ehci_device_intr_methods;
- return (USBD_INVAL);
- case UE_ISOCHRONOUS:
- pipe->methods = &ehci_device_isoc_methods;
- return (USBD_INVAL);
- default:
- return (USBD_INVAL);
- }
- return (USBD_NORMAL_COMPLETION);
-
- bad1:
- ehci_free_sqh(sc, sqh);
- bad0:
- return (USBD_NOMEM);
-}
-
-/*
- * Add an ED to the schedule. Called at splusb().
- */
-void
-ehci_add_qh(ehci_soft_qh_t *sqh, ehci_soft_qh_t *head)
-{
- SPLUSBCHECK;
-
- sqh->next = head->next;
- sqh->qh.qh_link = head->qh.qh_link;
- head->next = sqh;
- head->qh.qh_link = htole32(sqh->physaddr | EHCI_LINK_QH);
-
-#ifdef EHCI_DEBUG
- if (ehcidebug > 5) {
- printf("ehci_add_qh:\n");
- ehci_dump_sqh(sqh);
- }
-#endif
-}
-
-/*
- * Remove an ED from the schedule. Called at splusb().
- */
-void
-ehci_rem_qh(ehci_softc_t *sc, ehci_soft_qh_t *sqh, ehci_soft_qh_t *head)
-{
- ehci_soft_qh_t *p;
-
- SPLUSBCHECK;
- /* XXX */
- for (p = head; p == NULL && p->next != sqh; p = p->next)
- ;
- if (p == NULL)
- panic("ehci_rem_qh: ED not found\n");
- p->next = sqh->next;
- p->qh.qh_link = sqh->qh.qh_link;
-
- ehci_sync_hc(sc);
-}
-
-void
-ehci_set_qh_qtd(ehci_soft_qh_t *sqh, ehci_soft_qtd_t *sqtd)
-{
- /* Halt while we are messing. */
- sqh->qh.qh_qtd.qtd_status |= htole32(EHCI_QTD_HALTED);
- sqh->qh.qh_curqtd = 0;
- sqh->qh.qh_qtd.qtd_next = htole32(sqtd->physaddr);
- sqh->sqtd = sqtd;
- /* Keep toggle, clear the rest, including length. */
- sqh->qh.qh_qtd.qtd_status &= htole32(EHCI_QTD_TOGGLE);
-}
-
-/*
- * 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 */
- usb_lockmgr(&sc->sc_doorbell_lock, LK_EXCLUSIVE, NULL, curproc);
-
- 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 */
- usb_lockmgr(&sc->sc_doorbell_lock, LK_RELEASE, NULL, curproc);
-
-#ifdef DIAGNOSTIC
- if (error)
- printf("ehci_sync_hc: tsleep() = %d\n", error);
-#endif
- DPRINTFN(2,("ehci_sync_hc: exit\n"));
-}
-
-/***********/
-
-/*
- * 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(p, l, s)
- 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(SIMPLEQ_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_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 = KERNADDR(&xfer->dmabuf);
-
-#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_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(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 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_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 = 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_transfer: clear port test "
- "%d\n", index));
- break;
- case UHF_PORT_INDICATOR:
- DPRINTFN(2,("ehci_root_ctrl_transfer: 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;
- }
-#if 0
- 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)
- ehci_pcd_able(sc, 1);
- break;
- default:
- break;
- }
-#endif
- break;
- case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE):
- if (value != 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_INCICATOR(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_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 = EOREAD4(sc, EHCI_PORTSC(index));
- DPRINTFN(8,("ehci_root_ctrl_transfer: port status=0x%04x\n",
- v));
- i = UPS_HIGH_SPEED;
- 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_transfer: reset port %d\n",
- index));
- if (EHCI_PS_IS_LOWSPEED(v)) {
- /* 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. */
- 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",
- USBDEVNAME(sc->sc_bus.bdev));
- return (USBD_TIMEOUT);
- }
- if (!(v & EHCI_PS_PE)) {
- /* 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_transfer: set port power "
- "%d\n", index));
- EOWRITE4(sc, port, v | EHCI_PS_PP);
- break;
- case UHF_PORT_TEST:
- DPRINTFN(2,("ehci_root_ctrl_transfer: set port test "
- "%d\n", index));
- break;
- case UHF_PORT_INDICATOR:
- DPRINTFN(2,("ehci_root_ctrl_transfer: 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();
- 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",
- USBDEVNAME(sc->sc_bus.bdev));
- else
- printf("%s: handing over %s speed device on "
- "port %d to %s\n",
- USBDEVNAME(sc->sc_bus.bdev),
- lowspeed ? "low" : "full",
- index, USBDEVNAME(sc->sc_comps[i]->bdev));
- } else {
- printf("%s: npcomp == 0\n", USBDEVNAME(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)
-{
- xfer->hcpriv = NULL;
-}
-
-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(SIMPLEQ_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)
-{
- xfer->hcpriv = NULL;
-}
-
-/************************/
-
-ehci_soft_qh_t *
-ehci_alloc_sqh(ehci_softc_t *sc)
-{
- ehci_soft_qh_t *sqh;
- 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 = (ehci_soft_qh_t *)((char *)KERNADDR(&dma) + offs);
- sqh->physaddr = DMAADDR(&dma) + offs;
- sqh->next = sc->sc_freeqhs;
- sc->sc_freeqhs = sqh;
- }
- }
- sqh = sc->sc_freeqhs;
- sc->sc_freeqhs = sqh->next;
- memset(&sqh->qh, 0, sizeof(ehci_qh_t));
- sqh->next = NULL;
- return (sqh);
-}
-
-void
-ehci_free_sqh(ehci_softc_t *sc, ehci_soft_qh_t *sqh)
-{
- 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 = (ehci_soft_qtd_t *)((char *)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;
- memset(&sqtd->qtd, 0, sizeof(ehci_qtd_t));
- 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 **sp, ehci_soft_qtd_t **ep)
-{
- ehci_soft_qtd_t *next, *cur;
- ehci_physaddr_t dataphys, dataphyspage, dataphyslastpage, nextphys;
- u_int32_t qtdstatus;
- int len, curlen;
- int i;
- usb_dma_t *dma = &xfer->dmabuf;
-
- DPRINTFN(alen<4*4096,("ehci_alloc_sqtd_chain: start len=%d\n", alen));
-
- len = alen;
- dataphys = DMAADDR(dma);
- dataphyslastpage = EHCI_PAGE(dataphys + len - 1);
- qtdstatus = htole32(
- 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 */
- /* XXX Data toggle */
- );
-
- cur = ehci_alloc_sqtd(sc);
- *sp = cur;
- if (cur == NULL)
- goto nomem;
- for (;;) {
- dataphyspage = EHCI_PAGE(dataphys);
- /* The EHCI hardware can handle at most 5 pages. */
- if (dataphyslastpage - dataphyspage <
- EHCI_QTD_NBUFFERS * EHCI_PAGE_SIZE) {
- /* we can handle it in this QTD */
- curlen = len;
- } else {
- /* must use multiple TDs, fill as much as possible. */
- curlen = EHCI_QTD_NBUFFERS * EHCI_PAGE_SIZE -
- EHCI_PAGE_OFFSET(dataphys);
-#ifdef DIAGNOSTIC
- if (curlen > len) {
- printf("ehci_alloc_sqtd_chain: curlen=0x%x "
- "len=0x%x offs=0x%x\n", curlen, len,
- EHCI_PAGE_OFFSET(dataphys));
- printf("lastpage=0x%x page=0x%x phys=0x%x\n",
- dataphyslastpage, dataphyspage,
- dataphys);
- curlen = len;
- }
-#endif
-
- /* XXX true for EHCI? */
- /* the length must be a multiple of the max size */
- curlen -= curlen % UGETW(epipe->pipe.endpoint->edesc->wMaxPacketSize);
- DPRINTFN(1,("ehci_alloc_sqtd_chain: multiple QTDs, "
- "curlen=%d\n", curlen));
-#ifdef DIAGNOSTIC
- if (curlen == 0)
- panic("ehci_alloc_std: curlen == 0\n");
-#endif
- }
- DPRINTFN(4,("ehci_alloc_sqtd_chain: dataphys=0x%08x "
- "dataphyslastpage=0x%08x len=%d curlen=%d\n",
- dataphys, dataphyslastpage,
- len, curlen));
- len -= curlen;
-
- if (len != 0) {
- next = ehci_alloc_sqtd(sc);
- if (next == NULL)
- goto nomem;
- nextphys = next->physaddr;
- } else {
- next = NULL;
- nextphys = EHCI_NULL;
- }
-
- for (i = 0; i * EHCI_PAGE_SIZE < curlen; i++) {
- ehci_physaddr_t a = dataphys + i * EHCI_PAGE_SIZE;
- if (i != 0) /* use offset only in first buffer */
- a = EHCI_PAGE(a);
- cur->qtd.qtd_buffer[i] = htole32(a);
-#ifdef DIAGNOSTIC
- if (i >= EHCI_QTD_NBUFFERS) {
- printf("ehci_alloc_sqtd_chain: i=%d\n", i);
- goto nomem;
- }
-#endif
- }
- cur->nextqtd = next;
- cur->qtd.qtd_next = cur->qtd.qtd_altnext = htole32(nextphys);
- cur->qtd.qtd_status =
- qtdstatus | htole32(EHCI_QTD_SET_BYTES(curlen));
- cur->xfer = xfer;
- cur->len = curlen;
- DPRINTFN(10,("ehci_alloc_sqtd_chain: cbp=0x%08x end=0x%08x\n",
- dataphys, dataphys + curlen));
- if (len == 0)
- break;
- DPRINTFN(10,("ehci_alloc_sqtd_chain: extend chain\n"));
- dataphys += curlen;
- cur = next;
- }
- cur->qtd.qtd_status |= htole32(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);
-}
-
-Static void
-ehci_free_sqtd_chain(ehci_softc_t *sc, ehci_soft_qtd_t *sqtd,
- ehci_soft_qtd_t *sqtdend)
-{
- ehci_soft_qtd_t *p;
- int i;
-
- DPRINTFN(10,("ehci_free_sqtd_chain: sqtd=%p sqtdend=%p\n",
- sqtd, sqtdend));
-
- for (i = 0; sqtd != sqtdend; sqtd = p, i++) {
- p = sqtd->nextqtd;
- ehci_free_sqtd(sc, sqtd);
- }
-}
-
-/****************/
-
-/*
- * 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);
- 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.
- * XXX This is most probably wrong.
- */
-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;
- ehci_physaddr_t cur;
- u_int32_t qhstatus;
- int s;
- int hit;
-
- 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 */
- usb_uncallout(xfer->timeout_handle, ehci_timeout, xfer);
- usb_transfer_complete(xfer);
- splx(s);
- return;
- }
-
- if (xfer->device->bus->intr_context || !curproc)
- panic("ehci_abort_xfer: not in process context\n");
-
- /*
- * Step 1: Make interrupt routine and hardware ignore xfer.
- */
- s = splusb();
- xfer->status = status; /* make software ignore it */
- usb_uncallout(xfer->timeout_handle, ehci_timeout, xfer);
- qhstatus = sqh->qh.qh_qtd.qtd_status;
- sqh->qh.qh_qtd.qtd_status = qhstatus | htole32(EHCI_QTD_HALTED);
- for (sqtd = exfer->sqtdstart; ; sqtd = sqtd->nextqtd) {
- sqtd->qtd.qtd_status |= htole32(EHCI_QTD_HALTED);
- if (sqtd == exfer->sqtdend)
- break;
- }
- 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.
- */
- ehci_sync_hc(sc);
- s = splusb();
- sc->sc_softwake = 1;
- usb_schedsoftintr(&sc->sc_bus);
- tsleep(&sc->sc_softwake, PZERO, "ehciab", 0);
- 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? */
- cur = EHCI_LINK_ADDR(le32toh(sqh->qh.qh_curqtd));
- hit = 0;
- for (sqtd = exfer->sqtdstart; ; sqtd = sqtd->nextqtd) {
- hit |= cur == sqtd->physaddr;
- if (sqtd == exfer->sqtdend)
- break;
- }
- sqtd = sqtd->nextqtd;
- /* Zap curqtd register if hardware pointed inside the xfer. */
- if (hit && sqtd != NULL) {
- DPRINTFN(1,("ehci_abort_xfer: cur=0x%08x\n", sqtd->physaddr));
- sqh->qh.qh_curqtd = htole32(sqtd->physaddr); /* unlink qTDs */
- sqh->qh.qh_qtd.qtd_status = qhstatus;
- } else {
- DPRINTFN(1,("ehci_abort_xfer: no hit\n"));
- }
-
- /*
- * Step 4: Execute callback.
- */
-#ifdef DIAGNOSTIC
- exfer->isdone = 1;
-#endif
- usb_transfer_complete(xfer);
-
- 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_init_task(&exfer->abort_task, ehci_timeout_task, addr);
- usb_add_task(exfer->xfer.pipe->device, &exfer->abort_task);
-}
-
-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);
-}
-
-/************************/
-
-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(SIMPLEQ_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\n");
- }
-#endif
-
- if (xfer->status != USBD_NOMEM) {
- ehci_del_intr_list(ex); /* remove from active list */
- ehci_free_sqtd_chain(sc, ex->sqtdstart, NULL);
- }
-
- 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;
- int addr = dev->address;
- ehci_soft_qtd_t *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_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, addr,
- epipe->pipe.endpoint->edesc->bEndpointAddress));
-
- setup = ehci_alloc_sqtd(sc);
- if (setup == NULL) {
- err = USBD_NOMEM;
- goto bad1;
- }
- stat = ehci_alloc_sqtd(sc);
- if (stat == NULL) {
- err = USBD_NOMEM;
- goto bad2;
- }
-
- sqh = epipe->sqh;
- epipe->u.ctl.length = len;
-
- /* XXX
- * Since we're messing with the QH we must know the HC is in sync.
- * This needs to go away since it slows down control transfers.
- * Removing it entails:
- * - fill the QH only once with addr & wMaxPacketSize
- * - put the correct data toggles in the qtds and set DTC
- */
- /* ehci_sync_hc(sc); */
- /* Update device address and length since they may have changed. */
- /* XXX This only needs to be done once, but it's too early in open. */
- /* XXXX Should not touch ED here! */
- sqh->qh.qh_endp =
- (sqh->qh.qh_endp & htole32(~(EHCI_QH_ADDRMASK | EHCI_QG_MPLMASK))) |
- htole32(
- EHCI_QH_SET_ADDR(addr) |
- /* EHCI_QH_DTC | */
- EHCI_QH_SET_MPL(UGETW(epipe->pipe.endpoint->edesc->wMaxPacketSize))
- );
- /* Clear toggle */
- sqh->qh.qh_qtd.qtd_status &= htole32(~EHCI_QTD_TOGGLE);
-
- /* Set up data transaction */
- if (len != 0) {
- ehci_soft_qtd_t *end;
-
- err = ehci_alloc_sqtd_chain(epipe, sc, len, isread, xfer,
- &next, &end);
- if (err)
- goto bad3;
- end->nextqtd = stat;
- end->qtd.qtd_next =
- end->qtd.qtd_altnext = htole32(stat->physaddr);
- /* Start toggle at 1. */
- /*next->qtd.td_flags |= htole32(EHCI_QTD_TOGGLE);*/
- } else {
- next = stat;
- }
-
- memcpy(KERNADDR(&epipe->u.ctl.reqdma), req, sizeof *req);
-
- setup->qtd.qtd_status = htole32(
- EHCI_QTD_ACTIVE |
- EHCI_QTD_SET_PID(EHCI_QTD_PID_SETUP) |
- EHCI_QTD_SET_CERR(3) |
- EHCI_QTD_SET_BYTES(sizeof *req)
- );
- setup->qtd.qtd_buffer[0] = htole32(DMAADDR(&epipe->u.ctl.reqdma));
- setup->nextqtd = next;
- setup->qtd.qtd_next = setup->qtd.qtd_altnext = htole32(next->physaddr);
- setup->xfer = xfer;
- setup->len = sizeof *req;
-
- stat->qtd.qtd_status = htole32(
- EHCI_QTD_ACTIVE |
- EHCI_QTD_SET_PID(isread ? EHCI_QTD_PID_OUT : EHCI_QTD_PID_IN) |
- EHCI_QTD_SET_CERR(3) |
- EHCI_QTD_IOC
- );
- stat->qtd.qtd_buffer[0] = 0; /* XXX not needed? */
- stat->nextqtd = NULL;
- stat->qtd.qtd_next = stat->qtd.qtd_altnext = EHCI_NULL;
- stat->xfer = xfer;
- stat->len = 0;
-
-#ifdef EHCI_DEBUG
- if (ehcidebug > 5) {
- DPRINTF(("ehci_device_request:\n"));
- ehci_dump_sqh(sqh);
- ehci_dump_sqtds(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
-
- /* Insert qTD in QH list. */
- s = splusb();
- ehci_set_qh_qtd(sqh, setup);
- if (xfer->timeout && !sc->sc_bus.use_polling) {
- usb_callout(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_async_head);
- ehci_dump_sqh(sqh);
- ehci_dump_sqtds(setup);
- }
-#endif
-
- return (USBD_NORMAL_COMPLETION);
-
- bad3:
- ehci_free_sqtd(sc, stat);
- bad2:
- ehci_free_sqtd(sc, setup);
- 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(SIMPLEQ_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;
- ehci_soft_qh_t *sqh;
- usbd_status err;
- int len, isread, endpt;
- int s;
-
- DPRINTFN(2, ("ehci_device_bulk_transfer: 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_transfer: a request\n");
-#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;
-
- err = ehci_alloc_sqtd_chain(epipe, sc, len, isread, xfer, &data,
- &dataend);
- if (err) {
- DPRINTFN(-1,("ehci_device_bulk_transfer: no memory\n"));
- xfer->status = err;
- usb_transfer_complete(xfer);
- return (err);
- }
-
-#ifdef EHCI_DEBUG
- if (ehcidebug > 5) {
- DPRINTF(("ehci_device_bulk_transfer: data(1)\n"));
- ehci_dump_sqh(sqh);
- ehci_dump_sqtds(data);
- }
-#endif
-
- /* Set up interrupt info. */
- exfer->sqtdstart = data;
- exfer->sqtdend = dataend;
-#ifdef DIAGNOSTIC
- if (!exfer->isdone) {
- printf("ehci_device_bulk_transfer: not done, ex=%p\n", exfer);
- }
- exfer->isdone = 0;
-#endif
-
- s = splusb();
- ehci_set_qh_qtd(sqh, data);
- if (xfer->timeout && !sc->sc_bus.use_polling) {
- usb_callout(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_transfer: data(2)\n"));
- delay(10000);
- DPRINTF(("ehci_device_bulk_transfer: 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(sqh);
- ehci_dump_sqtds(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_del_intr_list(ex); /* remove from active list */
- ehci_free_sqtd_chain(sc, ex->sqtdstart, 0);
- }
-
- DPRINTFN(5, ("ehci_bulk_done: length=%d\n", xfer->actlen));
-}
-
-/************************/
-
-Static usbd_status ehci_device_intr_transfer(usbd_xfer_handle xfer) { return USBD_IOERROR; }
-Static usbd_status ehci_device_intr_start(usbd_xfer_handle xfer) { return USBD_IOERROR; }
-Static void ehci_device_intr_abort(usbd_xfer_handle xfer) { }
-Static void ehci_device_intr_close(usbd_pipe_handle pipe) { }
-Static void ehci_device_intr_done(usbd_xfer_handle xfer) { }
-
-/************************/
-
-Static usbd_status ehci_device_isoc_transfer(usbd_xfer_handle xfer) { return USBD_IOERROR; }
-Static usbd_status ehci_device_isoc_start(usbd_xfer_handle xfer) { return USBD_IOERROR; }
-Static void ehci_device_isoc_abort(usbd_xfer_handle xfer) { }
-Static void ehci_device_isoc_close(usbd_pipe_handle pipe) { }
-Static void ehci_device_isoc_done(usbd_xfer_handle xfer) { }
diff --git a/sys/dev/usb/ehcireg.h b/sys/dev/usb/ehcireg.h
deleted file mode 100644
index 341644210b1..00000000000
--- a/sys/dev/usb/ehcireg.h
+++ /dev/null
@@ -1,288 +0,0 @@
-/* $OpenBSD: ehcireg.h,v 1.1 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: ehcireg.h,v 1.13 2001/11/23 01:16:27 augustss Exp $ */
-
-/*
- * 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) */
-
-/* Regs ar EECP + offset */
-#define PCI_EHCI_USBLEGSUP 0x00
-#define PCI_EHCI_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_INCICATOR(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_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)
-
-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;
-
-/* Isochronous Transfer Descriptor */
-typedef struct {
- ehci_link_t itd_next;
- /* XXX many more */
-} 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_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_TOGGLE 0x80000000
- ehci_physaddr_t qtd_buffer[EHCI_QTD_NBUFFERS];
-} ehci_qtd_t;
-#define EHCI_QTD_ALIGN 32
-
-/* 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_QG_MPLMASK 0x07ff0000
-#define EHCI_QH_GET_CTL(x) (((x) >> 26) & 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 1aa7c866580..00000000000
--- a/sys/dev/usb/ehcivar.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/* $OpenBSD: ehcivar.h,v 1.1 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: ehcivar.h,v 1.12 2001/12/31 12:16:57 augustss Exp $ */
-
-/*
- * 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_qtd *sqtd;
- ehci_physaddr_t physaddr;
-} 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)
-
-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;
-#ifdef DIAGNOSTIC
- int isdone;
-#endif
-};
-#define EXFER(xfer) ((struct ehci_xfer *)(xfer))
-
-
-#define EHCI_HASH_SIZE 128
-#define EHCI_COMPANION_MAX 8
-
-typedef struct ehci_softc {
- struct usbd_bus sc_bus; /* base device */
- bus_space_tag_t iot;
- bus_space_handle_t ioh;
- bus_size_t sc_size;
- u_int sc_offs; /* offset to operational regs */
-
- char sc_vendor[16]; /* vendor string for root hub */
- int sc_id_vendor; /* vendor ID for root hub */
-
- void *sc_powerhook; /* cookie from power hook */
- void *sc_shutdownhook; /* cookie from shutdown hook */
-
- u_int sc_ncomp;
- u_int sc_npcomp;
- struct usbd_bus *sc_comps[EHCI_COMPANION_MAX];
-
- usb_dma_t sc_fldma;
- u_int sc_flsize;
-
- LIST_HEAD(, ehci_xfer) sc_intrhead;
-
- ehci_soft_qh_t *sc_freeqhs;
- ehci_soft_qtd_t *sc_freeqtds;
-
- 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;
- char sc_softwake;
-
- u_int32_t sc_eintrs;
- ehci_soft_qh_t *sc_async_head;
-
- SIMPLEQ_HEAD(, usbd_xfer) sc_free_xfers; /* free xfers */
-
- struct lock sc_doorbell_lock;
-
- usb_callout_t sc_tmo_pcd;
-
- device_ptr_t sc_child; /* /dev/usb# device */
-
- 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))
-
-usbd_status ehci_init(ehci_softc_t *);
-int ehci_intr(void *);
-int ehci_detach(ehci_softc_t *, int);
-int ehci_activate(device_ptr_t, enum devact);
diff --git a/sys/dev/usb/files.usb b/sys/dev/usb/files.usb
index 77fa22bf4ab..2d6d6b5ce34 100644
--- a/sys/dev/usb/files.usb
+++ b/sys/dev/usb/files.usb
@@ -1,5 +1,5 @@
-# $OpenBSD: files.usb,v 1.22 2002/05/07 18:08:04 nate Exp $
-# $NetBSD: files.usb,v 1.38 2002/01/02 03:21:36 augustss Exp $
+# $OpenBSD: files.usb,v 1.23 2002/05/07 18:29:18 nate Exp $
+# $NetBSD: files.usb,v 1.16 2000/02/14 20:29:54 augustss Exp $
#
# Config file and device description for machine-independent USB code.
# Included by ports that need it. Ports that use it must provide
@@ -7,7 +7,8 @@
device usb { }
attach usb at usbus
-file dev/usb/usb.c usb needs-flag
+file dev/usb/hid.c usb
+file dev/usb/usb.c usb needs-flag
file dev/usb/usbdi.c usb
file dev/usb/usbdi_util.c usb
file dev/usb/usb_mem.c usb
@@ -34,91 +35,62 @@ device uaudio: audio, auconv, mulaw
attach uaudio at uhub
file dev/usb/uaudio.c uaudio
-# MIDI devices
-device umidi: midibus
-attach umidi at uhub
-file dev/usb/umidi.c umidi
-file dev/usb/umidi_quirks.c umidi
-
# Modem and com serial port
device ucom
attach ucom at ucombus
-file dev/usb/ucom.c ucom | ucombus needs-flag
-
+file dev/usb/ucom.c ucom | ucombus needs-flag
# Generic devices
device ugen
attach ugen at uhub
-file dev/usb/ugen.c ugen needs-flag
-
-
-# HID
-# HID "bus"
-define uhidbus {[ reportid = -1 ]}
-
-# HID processing
-define hid
-file dev/usb/hid.c hid
-
-# HID root device for multiple report IDs
-device uhidev: hid, uhidbus
-attach uhidev at uhub
-file dev/usb/uhidev.c uhidev
+file dev/usb/ugen.c ugen needs-flag
# Generic HID devices
-device uhid: hid
-attach uhid at uhidbus
-file dev/usb/uhid.c uhid needs-flag
+device uhid
+attach uhid at uhub
+file dev/usb/uhid.c uhid needs-flag
# Keyboards
-device ukbd: hid, wskbddev
-attach ukbd at uhidbus
-file dev/usb/ukbd.c ukbd needs-flag
-file dev/usb/ukbdmap.c ukbd
-
-# Mice
-device ums: hid, wsmousedev
-attach ums at uhidbus
-file dev/usb/ums.c ums
-
+device ukbd: wskbddev
+attach ukbd at uhub
+file dev/usb/ukbd.c ukbd needs-flag
+file dev/usb/ukbdmap.c ukbd
# Printers
device ulpt
attach ulpt at uhub
-file dev/usb/ulpt.c ulpt needs-flag
-
+file dev/usb/ulpt.c ulpt needs-flag
# Mass storage
-device umass: scsi, atapi, ata
+device umass: scsi, atapi
attach umass at uhub
file dev/usb/umass.c umass
-#file dev/usb/umass_isdata.c umass & wd
-file dev/usb/umass_quirks.c umass
-file dev/usb/umass_scsi.c umass & (scsibus | atapiscsi)
+# Modems
+device umodem: ucombus
+attach umodem at uhub
+file dev/usb/umodem.c umodem
+
+# Mice
+device ums: wsmousedev
+attach ums at uhub
+file dev/usb/ums.c ums
-# Misc
# Diamond Multimedia Rio 500
device urio
attach urio at uhub
-file dev/usb/urio.c urio needs-flag
+file dev/usb/urio.c urio needs-flag
# Handspring Visor
device uvisor: ucombus
attach uvisor at uhub
file dev/usb/uvisor.c uvisor
-# YAP phone firmware loader
+# YAP firmware loader
device uyap: ezload
attach uyap at uhub
file dev/usb/uyap.c uyap
-# D-Link DSB-R100 FM radio
-device udsbr: radio
-attach udsbr at uhub
-file dev/usb/udsbr.c udsbr
-
-
# Ethernet adapters
# ADMtek AN986 Pegasus
device aue: ether, ifnet, mii, ifmedia
@@ -136,48 +108,25 @@ attach kue at uhub
file dev/usb/if_kue.c kue
# Prolific PL2302 host-host
-device upl: ether, ifnet, ifmedia
+device upl: ifnet
attach upl at uhub
file dev/usb/if_upl.c upl
-# Realtek RTL8150L(M)
-device url: ether, ifnet, mii
-attach url at uhub
-file dev/usb/if_url.c url
-
-
# Serial drivers
-# Modems
-device umodem: ucombus
-attach umodem at uhub
-file dev/usb/umodem.c umodem
-
# FTDI serial driver
device uftdi: ucombus
attach uftdi at uhub
file dev/usb/uftdi.c uftdi
# Prolific PL2303 serial driver
-device uplcom: ucombus
-attach uplcom at uhub
-file dev/usb/uplcom.c uplcom
-
-# MCT USB-232 serial driver
-device umct: ucombus
-attach umct at uhub
-file dev/usb/umct.c umct
-
-# SUNTAC Slipper U VS-10U driver
-device uvscom: ucombus
-attach uvscom at uhub
-file dev/usb/uvscom.c uvscom
-
+device uplcom: ucombus
+attach uplcom at uhub
+file dev/usb/uplcom.c uplcom
# Scanners
-# Generic scanner support
device uscanner
attach uscanner at uhub
-file dev/usb/uscanner.c uscanner needs-flag
+file dev/usb/uscanner.c uscanner needs-flag
# Avision SCSI over USB, HP5300
device usscanner: scsi
diff --git a/sys/dev/usb/hid.c b/sys/dev/usb/hid.c
index 2a8a91a35cb..d14721fe107 100644
--- a/sys/dev/usb/hid.c
+++ b/sys/dev/usb/hid.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: hid.c,v 1.10 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: hid.c,v 1.22 2002/01/12 17:11:03 tsutsui Exp $ */
+/* $OpenBSD: hid.c,v 1.11 2002/05/07 18:29:18 nate Exp $ */
+/* $NetBSD: hid.c,v 1.16 2000/06/01 14:28:57 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/hid.c,v 1.11 1999/11/17 22:33:39 n_hibma Exp $ */
/*
@@ -51,10 +51,10 @@
#include <dev/usb/hid.h>
-#ifdef UHIDEV_DEBUG
-#define DPRINTF(x) if (uhidevdebug) logprintf x
-#define DPRINTFN(n,x) if (uhidevdebug>(n)) logprintf x
-extern int uhidevdebug;
+#ifdef UHID_DEBUG
+#define DPRINTF(x) if (usbdebug) logprintf x
+#define DPRINTFN(n,x) if (usbdebug>(n)) logprintf x
+extern int usbdebug;
#else
#define DPRINTF(x)
#define DPRINTFN(n,x)
@@ -62,7 +62,7 @@ extern int uhidevdebug;
Static void hid_clear_local(struct hid_item *);
-#define MAXUSAGE 256
+#define MAXUSAGE 100
struct hid_data {
u_char *start;
u_char *end;
@@ -73,14 +73,13 @@ struct hid_data {
int minset;
int multi;
int multimax;
- enum hid_kind kind;
+ int kindset;
};
Static void
hid_clear_local(struct hid_item *c)
{
- DPRINTFN(5,("hid_clear_local\n"));
c->usage = 0;
c->usage_minimum = 0;
c->usage_maximum = 0;
@@ -94,18 +93,15 @@ hid_clear_local(struct hid_item *c)
}
struct hid_data *
-hid_start_parse(void *d, int len, enum hid_kind kind)
+hid_start_parse(void *d, int len, int kindset)
{
struct hid_data *s;
s = malloc(sizeof *s, M_TEMP, M_WAITOK);
- if (s == NULL)
- panic("hid_start_parse");
memset(s, 0, sizeof *s);
-
s->start = s->p = d;
s->end = (char *)d + len;
- s->kind = kind;
+ s->kindset = kindset;
return (s);
}
@@ -132,19 +128,15 @@ hid_get_item(struct hid_data *s, struct hid_item *h)
u_char *p;
struct hid_item *hi;
int i;
- enum hid_kind retkind;
top:
- DPRINTFN(5,("hid_get_item: multi=%d multimax=%d\n",
- s->multi, s->multimax));
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 = NULL;
- DPRINTFN(5,("return multi\n"));
+ h->next = 0;
return (1);
} else {
c->loc.count = s->multimax;
@@ -182,12 +174,12 @@ hid_get_item(struct hid_data *s, struct hid_item *h)
dval = 0;
break;
case 1:
- dval = /*(int8_t)*/ *data++;
+ dval = (int8_t)*data++;
break;
case 2:
dval = *data++;
dval |= *data++ << 8;
- dval = /*(int16_t)*/ dval;
+ dval = (int16_t)dval;
break;
case 4:
dval = *data++;
@@ -200,22 +192,15 @@ hid_get_item(struct hid_data *s, struct hid_item *h)
continue;
}
- DPRINTFN(5,("hid_get_item: bType=%d bTag=%d dval=%d\n",
- bType, bTag, dval));
switch (bType) {
case 0: /* Main */
switch (bTag) {
case 8: /* Input */
- retkind = hid_input;
- ret:
- if (s->kind != retkind) {
- s->minset = 0;
- s->nu = 0;
- hid_clear_local(c);
+ if (!(s->kindset & (1 << hid_input)))
continue;
- }
- c->kind = retkind;
+ c->kind = hid_input;
c->flags = dval;
+ ret:
if (c->flags & HIO_VARIABLE) {
s->multimax = c->loc.count;
s->multi = 0;
@@ -232,18 +217,19 @@ hid_get_item(struct hid_data *s, struct hid_item *h)
}
goto top;
} else {
- c->usage = c->_usage_page; /* XXX */
*h = *c;
- h->next = NULL;
+ h->next = 0;
c->loc.pos +=
- c->loc.size * c->loc.count;
- s->minset = 0;
- s->nu = 0;
+ c->loc.size * c->loc.count;
hid_clear_local(c);
+ s->minset = 0;
return (1);
}
case 9: /* Output */
- retkind = hid_output;
+ if (!(s->kindset & (1 << hid_output)))
+ continue;
+ c->kind = hid_output;
+ c->flags = dval;
goto ret;
case 10: /* Collection */
c->kind = hid_collection;
@@ -254,12 +240,16 @@ hid_get_item(struct hid_data *s, struct hid_item *h)
s->nu = 0;
return (1);
case 11: /* Feature */
- retkind = hid_feature;
+ if (!(s->kindset & (1 << hid_feature)))
+ 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:
@@ -295,7 +285,6 @@ hid_get_item(struct hid_data *s, struct hid_item *h)
break;
case 8:
c->report_ID = dval;
- c->loc.pos = 0;
break;
case 9:
c->loc.count = dval;
@@ -378,51 +367,35 @@ 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)
+hid_report_size(void *buf, int len, enum hid_kind k, u_int8_t *idp)
{
struct hid_data *d;
struct hid_item h;
- int lo, hi;
+ int size, id;
- h.report_ID = 0;
- lo = hi = -1;
- DPRINTFN(2,("hid_report_size: kind=%d id=%d\n", k, id));
- for (d = hid_start_parse(buf, len, k); hid_get_item(d, &h); ) {
- DPRINTFN(2,("hid_report_size: item kind=%d id=%d pos=%d "
- "size=%d count=%d\n",
- h.kind, h.report_ID, h.loc.pos, h.loc.size,
- h.loc.count));
- if (h.report_ID == id && h.kind == k) {
- if (lo < 0) {
- lo = h.loc.pos;
-#ifdef DIAGNOSTIC
- if (lo != 0) {
- printf("hid_report_size: lo != 0\n");
- }
-#endif
- }
- hi = h.loc.pos + h.loc.size * h.loc.count;
- DPRINTFN(2,("hid_report_size: lo=%d hi=%d\n", lo, hi));
- }
- }
+ id = 0;
+ for (d = hid_start_parse(buf, len, 1<<k); hid_get_item(d, &h); )
+ if (h.report_ID != 0)
+ id = h.report_ID;
hid_end_parse(d);
- return ((hi - lo + 7) / 8);
+ size = h.loc.pos;
+ 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, u_int8_t id, enum hid_kind k,
+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;
- h.report_ID = 0;
- DPRINTFN(5,("hid_locate: enter usage=0x%x kind=%d id=%d\n", u, k, id));
- for (d = hid_start_parse(desc, size, k); hid_get_item(d, &h); ) {
- DPRINTFN(5,("hid_locate: usage=0x%x kind=%d id=%d flags=0x%x\n",
- h.usage, h.kind, h.report_ID, h.flags));
- if (h.kind == k && !(h.flags & HIO_CONST) &&
- h.usage == u && h.report_ID == id) {
+ 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)
@@ -464,33 +437,19 @@ hid_get_data(u_char *buf, struct hid_location *loc)
}
int
-hid_is_collection(void *desc, int size, u_int8_t id, u_int32_t usage)
+hid_is_collection(void *desc, int size, u_int32_t usage)
{
struct hid_data *hd;
struct hid_item hi;
- u_int32_t coll_usage = ~0;
+ int err;
- hd = hid_start_parse(desc, size, hid_none);
+ hd = hid_start_parse(desc, size, hid_input);
if (hd == NULL)
return (0);
- DPRINTFN(2,("hid_is_collection: id=%d usage=0x%x\n", id, usage));
- while (hid_get_item(hd, &hi)) {
- DPRINTFN(2,("hid_is_collection: kind=%d id=%d usage=0x%x"
- "(0x%x)\n",
- hi.kind, hi.report_ID, hi.usage, coll_usage));
- if (hi.kind == hid_collection &&
- hi.collection == HCOLL_APPLICATION)
- coll_usage = hi.usage;
- if (hi.kind == hid_endcollection &&
- coll_usage == usage &&
- hi.report_ID == id) {
- DPRINTFN(2,("hid_is_collection: found\n"));
- hid_end_parse(hd);
- return (1);
- }
- }
- DPRINTFN(2,("hid_is_collection: not found\n"));
+ err = hid_get_item(hd, &hi) &&
+ hi.kind == hid_collection &&
+ hi.usage == usage;
hid_end_parse(hd);
- return (0);
+ return (err);
}
diff --git a/sys/dev/usb/hid.h b/sys/dev/usb/hid.h
index 928a86ce337..096a34e270f 100644
--- a/sys/dev/usb/hid.h
+++ b/sys/dev/usb/hid.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: hid.h,v 1.5 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: hid.h,v 1.7 2001/12/28 17:32:36 augustss Exp $ */
+/* $OpenBSD: hid.h,v 1.6 2002/05/07 18:29:18 nate Exp $ */
+/* $NetBSD: hid.h,v 1.6 2000/06/01 14:28:57 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/hid.h,v 1.7 1999/11/17 22:33:40 n_hibma Exp $ */
/*
@@ -40,12 +40,7 @@
*/
enum hid_kind {
- hid_input,
- hid_output,
- hid_feature,
- hid_collection,
- hid_endcollection,
- hid_none
+ hid_input, hid_output, hid_feature, hid_collection, hid_endcollection
};
struct hid_location {
@@ -86,11 +81,11 @@ struct hid_item {
struct hid_item *next;
};
-struct hid_data *hid_start_parse(void *d, int len, enum hid_kind kind);
+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, u_int8_t id,
- enum hid_kind kind, struct hid_location *loc, u_int32_t *flags);
+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_int8_t id, u_int32_t usage);
+int hid_is_collection(void *desc, int size, u_int32_t usage);
diff --git a/sys/dev/usb/if_upl.c b/sys/dev/usb/if_upl.c
index 49e29bdce8b..d6b566156b3 100644
--- a/sys/dev/usb/if_upl.c
+++ b/sys/dev/usb/if_upl.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: if_upl.c,v 1.6 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: if_upl.c,v 1.17 2002/03/05 04:12:59 itojun Exp $ */
+/* $OpenBSD: if_upl.c,v 1.7 2002/05/07 18:29:18 nate Exp $ */
+/* $NetBSD: if_upl.c,v 1.15 2001/06/14 05:44:27 itojun Exp $ */
/*
* Copyright (c) 2000 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -78,19 +78,27 @@
#include <net/bpf.h>
#endif
+#if defined(__NetBSD__)
#ifdef INET
#include <netinet/in.h>
#include <netinet/in_var.h>
-#if defined(__NetBSD__)
#include <netinet/if_inarp.h>
-#elif defined(__OpenBSD__)
+#else
+#error upl without INET?
+#endif
+#endif
+
+#if defined(__OpenBSD__)
+#ifdef INET
+#include <netinet/in.h>
#include <netinet/in_systm.h>
+#include <netinet/in_var.h>
#include <netinet/ip.h>
#include <netinet/if_ether.h>
-#endif
#else
#error upl without INET?
#endif
+#endif
#ifdef NS
#include <netns/ns.h>
@@ -325,22 +333,20 @@ USB_ATTACH(upl)
ifp->if_addrlen = 0;
ifp->if_hdrlen = 0;
ifp->if_output = upl_output;
- ifp->if_baudrate = 12000000;
#if defined(__NetBSD__)
ifp->if_input = upl_input;
- ifp->if_dlt = DLT_RAW;
#endif
+ ifp->if_baudrate = 12000000;
IFQ_SET_READY(&ifp->if_snd);
/* Attach the interface. */
if_attach(ifp);
-#if defined(__NetBSD__)
- if_alloc_sadl(ifp);
-#endif
-#if defined(__NetBSD__) && NBPFILTER > 0
+#if NBPFILTER > 0
+#if defined(__NetBSD__) || defined(__FreeBSD__)
bpfattach(ifp, DLT_RAW, 0);
#endif
+#endif
#if NRND > 0
rnd_attach_source(&sc->sc_rnd_source, USBDEVNAME(sc->sc_dev),
RND_TYPE_NET, 0);
diff --git a/sys/dev/usb/if_url.c b/sys/dev/usb/if_url.c
deleted file mode 100644
index d0d542a4171..00000000000
--- a/sys/dev/usb/if_url.c
+++ /dev/null
@@ -1,1609 +0,0 @@
-/* $OpenBSD: if_url.c,v 1.1 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: if_url.c,v 1.2 2002/03/28 21:49:19 ichiro Exp $ */
-/*
- * Copyright (c) 2001, 2002
- * 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. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Shingo WATANABE.
- * 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 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.
- *
- */
-
-/*
- * The RTL8150L(Realtek USB to fast ethernet controller) spec can be found at
- * ftp://ftp.realtek.com.tw/lancard/data_sheet/8150/8150v14.pdf
- * ftp://152.104.125.40/lancard/data_sheet/8150/8150v14.pdf
- */
-
-/*
- * TODO:
- * Interrupt Endpoint support
- * External PHYs
- * powerhook() support?
- */
-
-#include "opt_inet.h"
-#include "opt_ns.h"
-#include "bpfilter.h"
-#include "rnd.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/lock.h>
-#include <sys/mbuf.h>
-#include <sys/kernel.h>
-#include <sys/socket.h>
-
-#include <sys/device.h>
-#if 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>
-
-#if NBPFILTER > 0
-#include <net/bpf.h>
-#endif
-#define BPF_MTAP(ifp, m) bpf_mtap((ifp)->if_bpf, (m))
-
-#include <net/if_ether.h>
-#ifdef INET
-#include <netinet/in.h>
-#include <netinet/if_inarp.h>
-#endif
-#ifdef NS
-#include <netns/ns.h>
-#include <netns/ns_if.h>
-#endif
-
-#include <dev/mii/mii.h>
-#include <dev/mii/miivar.h>
-#include <dev/mii/urlphyreg.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include <dev/usb/usbdevs.h>
-
-#include <dev/usb/if_urlreg.h>
-
-
-/* Function declarations */
-USB_DECLARE_DRIVER(url);
-
-Static int url_openpipes(struct url_softc *);
-Static int url_rx_list_init(struct url_softc *);
-Static int url_tx_list_init(struct url_softc *);
-Static int url_newbuf(struct url_softc *, struct url_chain *, struct mbuf *);
-Static void url_start(struct ifnet *);
-Static int url_send(struct url_softc *, struct mbuf *, int);
-Static void url_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
-Static void url_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
-Static void url_tick(void *);
-Static void url_tick_task(void *);
-Static int url_ioctl(struct ifnet *, u_long, caddr_t);
-Static void url_stop_task(struct url_softc *);
-Static void url_stop(struct ifnet *, int);
-Static void url_watchdog(struct ifnet *);
-Static int url_ifmedia_change(struct ifnet *);
-Static void url_ifmedia_status(struct ifnet *, struct ifmediareq *);
-Static void url_lock_mii(struct url_softc *);
-Static void url_unlock_mii(struct url_softc *);
-Static int url_int_miibus_readreg(device_ptr_t, int, int);
-Static void url_int_miibus_writereg(device_ptr_t, int, int, int);
-Static void url_miibus_statchg(device_ptr_t);
-Static int url_init(struct ifnet *);
-Static void url_setmulti(struct url_softc *);
-Static void url_reset(struct url_softc *);
-
-Static int url_csr_read_1(struct url_softc *, int);
-Static int url_csr_read_2(struct url_softc *, int);
-Static int url_csr_write_1(struct url_softc *, int, int);
-Static int url_csr_write_2(struct url_softc *, int, int);
-Static int url_csr_write_4(struct url_softc *, int, int);
-Static int url_mem(struct url_softc *, int, int, void *, int);
-
-/* Macros */
-#ifdef URL_DEBUG
-#define DPRINTF(x) if (urldebug) logprintf x
-#define DPRINTFN(n,x) if (urldebug >= (n)) logprintf x
-int urldebug = 0;
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-#define URL_SETBIT(sc, reg, x) \
- url_csr_write_1(sc, reg, url_csr_read_1(sc, reg) | (x))
-
-#define URL_SETBIT2(sc, reg, x) \
- url_csr_write_2(sc, reg, url_csr_read_2(sc, reg) | (x))
-
-#define URL_CLRBIT(sc, reg, x) \
- url_csr_write_1(sc, reg, url_csr_read_1(sc, reg) & ~(x))
-
-#define URL_CLRBIT2(sc, reg, x) \
- url_csr_write_2(sc, reg, url_csr_read_2(sc, reg) & ~(x))
-
-static const struct url_type {
- struct usb_devno url_dev;
- u_int16_t url_flags;
-#define URL_EXT_PHY 0x0001
-} url_devs [] = {
- /* MELCO LUA-KTX */
- {{ USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUAKTX }, 0},
- /* GREEN HOUSE USBKR100 */
- {{ USB_VENDOR_GREENHOUSE2, USB_PRODUCT_GREENHOUSE2_USBKR100}, 0}
-};
-#define url_lookup(v, p) ((struct url_type *)usb_lookup(url_devs, v, p))
-
-
-/* Probe */
-USB_MATCH(url)
-{
- USB_MATCH_START(url, uaa);
-
- if (uaa->iface != NULL)
- return (UMATCH_NONE);
-
- return (url_lookup(uaa->vendor, uaa->product) != NULL ?
- UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
-}
-/* Attach */
-USB_ATTACH(url)
-{
- USB_ATTACH_START(url, 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;
- char devinfo[1024];
- char *devname = USBDEVNAME(sc->sc_dev);
- struct ifnet *ifp;
- struct mii_data *mii;
- u_char eaddr[ETHER_ADDR_LEN];
- int i, s;
-
- usbd_devinfo(dev, 0, devinfo);
- USB_ATTACH_SETUP;
- printf("%s: %s\n", devname, devinfo);
-
- /* Move the device into the configured state. */
- err = usbd_set_config_no(dev, URL_CONFIG_NO, 1);
- if (err) {
- printf("%s: setting config no failed\n", devname);
- goto bad;
- }
-
- usb_init_task(&sc->sc_tick_task, url_tick_task, sc);
- lockinit(&sc->sc_mii_lock, PZERO, "urlmii", 0, 0);
- usb_init_task(&sc->sc_stop_task, (void (*)(void *)) url_stop_task, sc);
-
- /* get control interface */
- err = usbd_device2interface_handle(dev, URL_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 = url_lookup(uaa->vendor, uaa->product)->url_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;
- }
-
- s = splnet();
-
- /* reset the adapter */
- url_reset(sc);
-
- /* Get Ethernet Address */
- err = url_mem(sc, URL_CMD_READMEM, URL_IDR0, (void *)eaddr,
- ETHER_ADDR_LEN);
- if (err) {
- printf("%s: read MAC address faild\n", devname);
- splx(s);
- goto bad;
- }
-
- /* Print Ethernet Address */
- printf("%s: Ethernet address %s\n", devname, ether_sprintf(eaddr));
-
- /* initialize interface infomation */
- ifp = GET_IFP(sc);
- ifp->if_softc = sc;
- strncpy(ifp->if_xname, devname, IFNAMSIZ);
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_start = url_start;
- ifp->if_ioctl = url_ioctl;
- ifp->if_watchdog = url_watchdog;
- ifp->if_init = url_init;
- ifp->if_stop = url_stop;
-
- IFQ_SET_READY(&ifp->if_snd);
-
- /*
- * Do ifmedia setup.
- */
- mii = &sc->sc_mii;
- mii->mii_ifp = ifp;
- mii->mii_readreg = url_int_miibus_readreg;
- mii->mii_writereg = url_int_miibus_writereg;
-#if 0
- if (sc->sc_flags & URL_EXT_PHY) {
- mii->mii_readreg = url_ext_miibus_readreg;
- mii->mii_writereg = url_ext_miibus_writereg;
- }
-#endif
- mii->mii_statchg = url_miibus_statchg;
- mii->mii_flags = MIIF_AUTOTSLEEP;
- ifmedia_init(&mii->mii_media, 0,
- url_ifmedia_change, url_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);
-
-#if NRND > 0
- rnd_attach_source(&sc->rnd_source, devname, RND_TYPE_NET, 0);
-#endif
-
- usb_callout_init(sc->sc_stat_ch);
- sc->sc_attached = 1;
- splx(s);
-
- usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, dev, USBDEV(sc->sc_dev));
-
- USB_ATTACH_SUCCESS_RETURN;
-
- bad:
- sc->sc_dying = 1;
- USB_ATTACH_ERROR_RETURN;
-}
-
-/* detach */
-USB_DETACH(url)
-{
- USB_DETACH_START(url, sc);
- struct ifnet *ifp = GET_IFP(sc);
- int s;
-
- DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __FUNCTION__));
-
- /* Detached before attached finished */
- if (!sc->sc_attached)
- return (0);
-
- usb_uncallout(sc->sc_stat_ch, url_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);
-
- s = splusb();
-
- if (--sc->sc_refcnt >= 0) {
- /* Wait for processes to go away */
- usb_detach_wait(USBDEV(sc->sc_dev));
- }
-
- if (ifp->if_flags & IFF_RUNNING)
- url_stop(GET_IFP(sc), 1);
-
-#if NRND > 0
- rnd_detach_source(&sc->rnd_source);
-#endif
- mii_detach(&sc->sc_mii, MII_PHY_ANY, MII_OFFSET_ANY);
- ifmedia_delete_instance(&sc->sc_mii.mii_media, IFM_INST_ANY);
- ether_ifdetach(ifp);
- if_detach(ifp);
-
-#ifdef DIAGNOSTIC
- if (sc->sc_pipe_tx != NULL)
- printf("%s: detach has active tx endpoint.\n",
- USBDEVNAME(sc->sc_dev));
- if (sc->sc_pipe_rx != NULL)
- printf("%s: detach has active rx endpoint.\n",
- USBDEVNAME(sc->sc_dev));
- if (sc->sc_pipe_intr != NULL)
- printf("%s: detach has active intr endpoint.\n",
- USBDEVNAME(sc->sc_dev));
-#endif
-
- sc->sc_attached = 0;
-
- splx(s);
-
- usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
- USBDEV(sc->sc_dev));
-
- return (0);
-}
-
-/* read/write memory */
-Static int
-url_mem(struct url_softc *sc, int cmd, 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", USBDEVNAME(sc->sc_dev), __FUNCTION__));
-
- if (sc->sc_dying)
- return (0);
-
- if (cmd == URL_CMD_READMEM)
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- else
- req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
- req.bRequest = URL_REQ_MEM;
- USETW(req.wValue, offset);
- USETW(req.wIndex, 0x0000);
- USETW(req.wLength, len);
-
- sc->sc_refcnt++;
- err = usbd_do_request(sc->sc_udev, &req, buf);
- if (--sc->sc_refcnt < 0)
- usb_detach_wakeup(USBDEV(sc->sc_dev));
- if (err) {
- DPRINTF(("%s: url_mem(): %s failed. off=%04x, err=%d\n",
- USBDEVNAME(sc->sc_dev),
- cmd == URL_CMD_READMEM ? "read" : "write",
- offset, err));
- }
-
- return (err);
-}
-
-/* read 1byte from register */
-Static int
-url_csr_read_1(struct url_softc *sc, int reg)
-{
- u_int8_t val = 0;
-
- DPRINTFN(0x100,
- ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __FUNCTION__));
-
- if (sc->sc_dying)
- return (0);
-
- return (url_mem(sc, URL_CMD_READMEM, reg, &val, 1) ? 0 : val);
-}
-
-/* read 2bytes from register */
-Static int
-url_csr_read_2(struct url_softc *sc, int reg)
-{
- uWord val;
-
- DPRINTFN(0x100,
- ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __FUNCTION__));
-
- if (sc->sc_dying)
- return (0);
-
- USETW(val, 0);
- return (url_mem(sc, URL_CMD_READMEM, reg, &val, 2) ? 0 : UGETW(val));
-}
-
-/* write 1byte to register */
-Static int
-url_csr_write_1(struct url_softc *sc, int reg, int aval)
-{
- u_int8_t val = aval;
-
- DPRINTFN(0x100,
- ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __FUNCTION__));
-
- if (sc->sc_dying)
- return (0);
-
- return (url_mem(sc, URL_CMD_WRITEMEM, reg, &val, 1) ? -1 : 0);
-}
-
-/* write 2bytes to register */
-Static int
-url_csr_write_2(struct url_softc *sc, int reg, int aval)
-{
- uWord val;
-
- DPRINTFN(0x100,
- ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __FUNCTION__));
-
- USETW(val, aval);
-
- if (sc->sc_dying)
- return (0);
-
- return (url_mem(sc, URL_CMD_WRITEMEM, reg, &val, 2) ? -1 : 0);
-}
-
-/* write 4bytes to register */
-Static int
-url_csr_write_4(struct url_softc *sc, int reg, int aval)
-{
- uDWord val;
-
- DPRINTFN(0x100,
- ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __FUNCTION__));
-
- USETDW(val, aval);
-
- if (sc->sc_dying)
- return (0);
-
- return (url_mem(sc, URL_CMD_WRITEMEM, reg, &val, 4) ? -1 : 0);
-}
-
-Static int
-url_init(struct ifnet *ifp)
-{
- struct url_softc *sc = ifp->if_softc;
- struct mii_data *mii = GET_MII(sc);
- u_char *eaddr;
- int i, s;
-
- DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __FUNCTION__));
-
- if (sc->sc_dying)
- return (EIO);
-
- s = splnet();
-
- /* Cancel pending I/O and free all TX/RX buffers */
- url_stop(ifp, 1);
-
- eaddr = LLADDR(ifp->if_sadl);
- for (i = 0; i < ETHER_ADDR_LEN; i++)
- url_csr_write_1(sc, URL_IDR0 + i, eaddr[i]);
-
- /* Init transmission control register */
- URL_CLRBIT(sc, URL_TCR,
- URL_TCR_TXRR1 | URL_TCR_TXRR0 |
- URL_TCR_IFG1 | URL_TCR_IFG0 |
- URL_TCR_NOCRC);
-
- /* Init receive control register */
- URL_SETBIT2(sc, URL_RCR, URL_RCR_TAIL | URL_RCR_AD);
- if (ifp->if_flags & IFF_BROADCAST)
- URL_SETBIT2(sc, URL_RCR, URL_RCR_AB);
- else
- URL_CLRBIT2(sc, URL_RCR, URL_RCR_AB);
-
- /* If we want promiscuous mode, accept all physical frames. */
- if (ifp->if_flags & IFF_PROMISC)
- URL_SETBIT2(sc, URL_RCR, URL_RCR_AAM|URL_RCR_AAP);
- else
- URL_CLRBIT2(sc, URL_RCR, URL_RCR_AAM|URL_RCR_AAP);
-
-
- /* Initialize transmit ring */
- if (url_tx_list_init(sc) == ENOBUFS) {
- printf("%s: tx list init failed\n", USBDEVNAME(sc->sc_dev));
- splx(s);
- return (EIO);
- }
-
- /* Initialize receive ring */
- if (url_rx_list_init(sc) == ENOBUFS) {
- printf("%s: rx list init failed\n", USBDEVNAME(sc->sc_dev));
- splx(s);
- return (EIO);
- }
-
- /* Load the multicast filter */
- url_setmulti(sc);
-
- /* Enable RX and TX */
- URL_SETBIT(sc, URL_CR, URL_CR_TE | URL_CR_RE);
-
- mii_mediachg(mii);
-
- if (sc->sc_pipe_tx == NULL || sc->sc_pipe_rx == NULL) {
- if (url_openpipes(sc)) {
- splx(s);
- return (EIO);
- }
- }
-
- ifp->if_flags |= IFF_RUNNING;
- ifp->if_flags &= ~IFF_OACTIVE;
-
- splx(s);
-
- usb_callout(sc->sc_stat_ch, hz, url_tick, sc);
-
- return (0);
-}
-
-Static void
-url_reset(struct url_softc *sc)
-{
- int i;
-
- DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __FUNCTION__));
-
- if (sc->sc_dying)
- return;
-
- URL_SETBIT(sc, URL_CR, URL_CR_SOFT_RST);
-
- for (i = 0; i < URL_TX_TIMEOUT; i++) {
- if (!(url_csr_read_1(sc, URL_CR) & URL_CR_SOFT_RST))
- break;
- delay(10); /* XXX */
- }
-
- delay(10000); /* XXX */
-}
-
-int
-url_activate(device_ptr_t self, enum devact act)
-{
- struct url_softc *sc = (struct url_softc *)self;
-
- DPRINTF(("%s: %s: enter, act=%d\n", USBDEVNAME(sc->sc_dev),
- __FUNCTION__, 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);
-}
-
-#define url_calchash(addr) (ether_crc32_be((addr), ETHER_ADDR_LEN) >> 26)
-
-
-Static void
-url_setmulti(struct url_softc *sc)
-{
- struct ifnet *ifp;
- struct ether_multi *enm;
- struct ether_multistep step;
- u_int32_t hashes[2] = { 0, 0 };
- int h = 0;
- int mcnt = 0;
-
- DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __FUNCTION__));
-
- if (sc->sc_dying)
- return;
-
- ifp = GET_IFP(sc);
-
- if (ifp->if_flags & IFF_PROMISC) {
- URL_SETBIT2(sc, URL_RCR, URL_RCR_AAM|URL_RCR_AAP);
- return;
- } else if (ifp->if_flags & IFF_ALLMULTI) {
- allmulti:
- ifp->if_flags |= IFF_ALLMULTI;
- URL_SETBIT2(sc, URL_RCR, URL_RCR_AAM);
- URL_CLRBIT2(sc, URL_RCR, URL_RCR_AAP);
- return;
- }
-
- /* first, zot all the existing hash bits */
- url_csr_write_4(sc, URL_MAR0, 0);
- url_csr_write_4(sc, URL_MAR4, 0);
-
- /* now program new ones */
- 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 = url_calchash(enm->enm_addrlo);
- if (h < 32)
- hashes[0] |= (1 << h);
- else
- hashes[1] |= (1 << (h -32));
- mcnt++;
- ETHER_NEXT_MULTI(step, enm);
- }
-
- ifp->if_flags &= ~IFF_ALLMULTI;
-
- URL_CLRBIT2(sc, URL_RCR, URL_RCR_AAM|URL_RCR_AAP);
-
- if (mcnt){
- URL_SETBIT2(sc, URL_RCR, URL_RCR_AM);
- } else {
- URL_CLRBIT2(sc, URL_RCR, URL_RCR_AM);
- }
- url_csr_write_4(sc, URL_MAR0, hashes[0]);
- url_csr_write_4(sc, URL_MAR4, hashes[1]);
-}
-
-Static int
-url_openpipes(struct url_softc *sc)
-{
- struct url_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",
- USBDEVNAME(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",
- USBDEVNAME(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.url_ibuf, URL_INTR_PKGLEN,
- url_intr, URL_INTR_INTERVAL);
- if (err) {
- printf("%s: open intr pipe failed: %s\n",
- USBDEVNAME(sc->sc_dev), usbd_errstr(err));
- error = EIO;
- goto done;
- }
-#endif
-
-
- /* Start up the receive pipe. */
- for (i = 0; i < URL_RX_LIST_CNT; i++) {
- c = &sc->sc_cdata.url_rx_chain[i];
- usbd_setup_xfer(c->url_xfer, sc->sc_pipe_rx,
- c, c->url_buf, URL_BUFSZ,
- USBD_SHORT_XFER_OK | USBD_NO_COPY,
- USBD_NO_TIMEOUT, url_rxeof);
- (void)usbd_transfer(c->url_xfer);
- DPRINTF(("%s: %s: start read\n", USBDEVNAME(sc->sc_dev),
- __FUNCTION__));
- }
-
- done:
- if (--sc->sc_refcnt < 0)
- usb_detach_wakeup(USBDEV(sc->sc_dev));
-
- return (error);
-}
-
-Static int
-url_newbuf(struct url_softc *sc, struct url_chain *c, struct mbuf *m)
-{
- struct mbuf *m_new = NULL;
-
- DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __FUNCTION__));
-
- if (m == NULL) {
- MGETHDR(m_new, M_DONTWAIT, MT_DATA);
- if (m_new == NULL) {
- printf("%s: no memory for rx list "
- "-- packet dropped!\n", USBDEVNAME(sc->sc_dev));
- return (ENOBUFS);
- }
- MCLGET(m_new, M_DONTWAIT);
- if (!(m_new->m_flags & M_EXT)) {
- printf("%s: no memory for rx list "
- "-- packet dropped!\n", USBDEVNAME(sc->sc_dev));
- m_freem(m_new);
- return (ENOBUFS);
- }
- m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
- } else {
- m_new = m;
- m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
- m_new->m_data = m_new->m_ext.ext_buf;
- }
-
- m_adj(m_new, ETHER_ALIGN);
- c->url_mbuf = m_new;
-
- return (0);
-}
-
-
-Static int
-url_rx_list_init(struct url_softc *sc)
-{
- struct url_cdata *cd;
- struct url_chain *c;
- int i;
-
- DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __FUNCTION__));
-
- cd = &sc->sc_cdata;
- for (i = 0; i < URL_RX_LIST_CNT; i++) {
- c = &cd->url_rx_chain[i];
- c->url_sc = sc;
- c->url_idx = i;
- if (url_newbuf(sc, c, NULL) == ENOBUFS)
- return (ENOBUFS);
- if (c->url_xfer == NULL) {
- c->url_xfer = usbd_alloc_xfer(sc->sc_udev);
- if (c->url_xfer == NULL)
- return (ENOBUFS);
- c->url_buf = usbd_alloc_buffer(c->url_xfer, URL_BUFSZ);
- if (c->url_buf == NULL) {
- usbd_free_xfer(c->url_xfer);
- return (ENOBUFS);
- }
- }
- }
-
- return (0);
-}
-
-Static int
-url_tx_list_init(struct url_softc *sc)
-{
- struct url_cdata *cd;
- struct url_chain *c;
- int i;
-
- DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __FUNCTION__));
-
- cd = &sc->sc_cdata;
- for (i = 0; i < URL_TX_LIST_CNT; i++) {
- c = &cd->url_tx_chain[i];
- c->url_sc = sc;
- c->url_idx = i;
- c->url_mbuf = NULL;
- if (c->url_xfer == NULL) {
- c->url_xfer = usbd_alloc_xfer(sc->sc_udev);
- if (c->url_xfer == NULL)
- return (ENOBUFS);
- c->url_buf = usbd_alloc_buffer(c->url_xfer, URL_BUFSZ);
- if (c->url_buf == NULL) {
- usbd_free_xfer(c->url_xfer);
- return (ENOBUFS);
- }
- }
- }
-
- return (0);
-}
-
-Static void
-url_start(struct ifnet *ifp)
-{
- struct url_softc *sc = ifp->if_softc;
- struct mbuf *m_head = NULL;
-
- DPRINTF(("%s: %s: enter, link=%d\n", USBDEVNAME(sc->sc_dev),
- __FUNCTION__, sc->sc_link));
-
- if (sc->sc_dying)
- return;
-
- if (!sc->sc_link)
- return;
-
- if (ifp->if_flags & IFF_OACTIVE)
- return;
-
- IFQ_POLL(&ifp->if_snd, m_head);
- if (m_head == NULL)
- return;
-
- if (url_send(sc, m_head, 0)) {
- ifp->if_flags |= IFF_OACTIVE;
- return;
- }
-
- IFQ_DEQUEUE(&ifp->if_snd, m_head);
-
-#if NBPFILTER > 0
- if (ifp->if_bpf)
- bpf_mtap(ifp->if_bpf, m_head);
-#endif
-
- ifp->if_flags |= IFF_OACTIVE;
-
- /* Set a timeout in case the chip goes out to lunch. */
- ifp->if_timer = 5;
-}
-
-Static int
-url_send(struct url_softc *sc, struct mbuf *m, int idx)
-{
- int total_len;
- struct url_chain *c;
- usbd_status err;
-
- DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),__FUNCTION__));
-
- c = &sc->sc_cdata.url_tx_chain[idx];
-
- /* Copy the mbuf data into a contiguous buffer */
- m_copydata(m, 0, m->m_pkthdr.len, c->url_buf);
- c->url_mbuf = m;
- total_len = m->m_pkthdr.len;
-
- if (total_len < URL_MIN_FRAME_LEN)
- total_len = URL_MIN_FRAME_LEN;
- usbd_setup_xfer(c->url_xfer, sc->sc_pipe_tx, c, c->url_buf, total_len,
- USBD_FORCE_SHORT_XFER | USBD_NO_COPY,
- URL_TX_TIMEOUT, url_txeof);
-
- /* Transmit */
- sc->sc_refcnt++;
- err = usbd_transfer(c->url_xfer);
- if (--sc->sc_refcnt < 0)
- usb_detach_wakeup(USBDEV(sc->sc_dev));
- if (err != USBD_IN_PROGRESS) {
- printf("%s: url_send error=%s\n", USBDEVNAME(sc->sc_dev),
- usbd_errstr(err));
- /* Stop the interface */
- usb_add_task(sc->sc_udev, &sc->sc_stop_task);
- return (EIO);
- }
-
- DPRINTF(("%s: %s: send %d bytes\n", USBDEVNAME(sc->sc_dev),
- __FUNCTION__, total_len));
-
- sc->sc_cdata.url_tx_cnt++;
-
- return (0);
-}
-
-Static void
-url_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- struct url_chain *c = priv;
- struct url_softc *sc = c->url_sc;
- struct ifnet *ifp = GET_IFP(sc);
- int s;
-
- if (sc->sc_dying)
- return;
-
- s = splnet();
-
- DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __FUNCTION__));
-
- ifp->if_timer = 0;
- ifp->if_flags &= ~IFF_OACTIVE;
-
- if (status != USBD_NORMAL_COMPLETION) {
- if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
- splx(s);
- return;
- }
- ifp->if_oerrors++;
- printf("%s: usb error on tx: %s\n", USBDEVNAME(sc->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(USBDEV(sc->sc_dev));
- }
- splx(s);
- return;
- }
-
- ifp->if_opackets++;
-
- m_free(c->url_mbuf);
- c->url_mbuf = NULL;
-
- if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
- url_start(ifp);
-
- splx(s);
-}
-
-Static void
-url_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- struct url_chain *c = priv;
- struct url_softc *sc = c->url_sc;
- struct ifnet *ifp = GET_IFP(sc);
- struct mbuf *m;
- u_int32_t total_len;
- url_rxhdr_t rxhdr;
- int s;
-
- DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),__FUNCTION__));
-
- 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",
- USBDEVNAME(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(USBDEV(sc->sc_dev));
- }
- goto done;
- }
-
- usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
-
- memcpy(mtod(c->url_mbuf, char *), c->url_buf, total_len);
-
- if (total_len <= ETHER_CRC_LEN) {
- ifp->if_ierrors++;
- goto done;
- }
-
- memcpy(&rxhdr, c->url_buf + total_len - ETHER_CRC_LEN, sizeof(rxhdr));
-
- DPRINTF(("%s: RX Status: %dbytes%s%s%s%s packets\n",
- USBDEVNAME(sc->sc_dev),
- UGETW(rxhdr) & URL_RXHDR_BYTEC_MASK,
- UGETW(rxhdr) & URL_RXHDR_VALID_MASK ? ", Valid" : "",
- UGETW(rxhdr) & URL_RXHDR_RUNTPKT_MASK ? ", Runt" : "",
- UGETW(rxhdr) & URL_RXHDR_PHYPKT_MASK ? ", Physical match" : "",
- UGETW(rxhdr) & URL_RXHDR_MCASTPKT_MASK ? ", Multicast" : ""));
-
- if ((UGETW(rxhdr) & URL_RXHDR_VALID_MASK) == 0) {
- ifp->if_ierrors++;
- goto done;
- }
-
- ifp->if_ipackets++;
- total_len -= ETHER_CRC_LEN;
-
- m = c->url_mbuf;
- m->m_pkthdr.len = m->m_len = total_len;
- m->m_pkthdr.rcvif = ifp;
-
- s = splnet();
-
- if (url_newbuf(sc, c, NULL) == ENOBUFS) {
- ifp->if_ierrors++;
- goto done1;
- }
-
-#if NBPFILTER > 0
- if (ifp->if_bpf)
- BPF_MTAP(ifp, m);
-#endif
-
- DPRINTF(("%s: %s: deliver %d\n", USBDEVNAME(sc->sc_dev),
- __FUNCTION__, m->m_len));
- IF_INPUT(ifp, m);
-
- done1:
- splx(s);
-
- done:
- /* Setup new transfer */
- usbd_setup_xfer(xfer, sc->sc_pipe_rx, c, c->url_buf, URL_BUFSZ,
- USBD_SHORT_XFER_OK | USBD_NO_COPY,
- USBD_NO_TIMEOUT, url_rxeof);
- sc->sc_refcnt++;
- usbd_transfer(xfer);
- if (--sc->sc_refcnt < 0)
- usb_detach_wakeup(USBDEV(sc->sc_dev));
-
- DPRINTF(("%s: %s: start rx\n", USBDEVNAME(sc->sc_dev), __FUNCTION__));
-}
-
-#if 0
-Static void url_intr()
-{
-}
-#endif
-
-Static int
-url_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
-{
- struct url_softc *sc = ifp->if_softc;
- struct ifreq *ifr = (struct ifreq *)data;
- struct mii_data *mii;
- int s, error = 0;
-
- DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __FUNCTION__));
-
- if (sc->sc_dying)
- return (EIO);
-
- s = splnet();
-
- switch (cmd) {
- 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 (error == ENETRESET) {
- url_setmulti(sc);
- error = 0;
- }
- break;
- }
-
- splx(s);
-
- return (error);
-}
-
-Static void
-url_watchdog(struct ifnet *ifp)
-{
- struct url_softc *sc = ifp->if_softc;
- struct url_chain *c;
- usbd_status stat;
- int s;
-
- DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __FUNCTION__));
-
- ifp->if_oerrors++;
- printf("%s: watchdog timeout\n", USBDEVNAME(sc->sc_dev));
-
- s = splusb();
- c = &sc->sc_cdata.url_tx_chain[0];
- usbd_get_xfer_status(c->url_xfer, NULL, NULL, NULL, &stat);
- url_txeof(c->url_xfer, c, stat);
-
- if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
- url_start(ifp);
- splx(s);
-}
-
-Static void
-url_stop_task(struct url_softc *sc)
-{
- url_stop(GET_IFP(sc), 1);
-}
-
-/* Stop the adapter and free any mbufs allocated to the RX and TX lists. */
-Static void
-url_stop(struct ifnet *ifp, int disable)
-{
- struct url_softc *sc = ifp->if_softc;
- usbd_status err;
- int i;
-
- DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __FUNCTION__));
-
- ifp->if_timer = 0;
-
- url_reset(sc);
-
- usb_uncallout(sc->sc_stat_ch, url_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",
- USBDEVNAME(sc->sc_dev), usbd_errstr(err));
- err = usbd_close_pipe(sc->sc_pipe_rx);
- if (err)
- printf("%s: close rx pipe failed: %s\n",
- USBDEVNAME(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",
- USBDEVNAME(sc->sc_dev), usbd_errstr(err));
- err = usbd_close_pipe(sc->sc_pipe_tx);
- if (err)
- printf("%s: close tx pipe failed: %s\n",
- USBDEVNAME(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",
- USBDEVNAME(sc->sc_dev), usbd_errstr(err));
- err = usbd_close_pipe(sc->sc_pipe_intr);
- if (err)
- printf("%s: close intr pipe failed: %s\n",
- USBDEVNAME(sc->sc_dev), usbd_errstr(err));
- sc->sc_pipe_intr = NULL;
- }
-#endif
-
- /* Free RX resources. */
- for (i = 0; i < URL_RX_LIST_CNT; i++) {
- if (sc->sc_cdata.url_rx_chain[i].url_mbuf != NULL) {
- m_freem(sc->sc_cdata.url_rx_chain[i].url_mbuf);
- sc->sc_cdata.url_rx_chain[i].url_mbuf = NULL;
- }
- if (sc->sc_cdata.url_rx_chain[i].url_xfer != NULL) {
- usbd_free_xfer(sc->sc_cdata.url_rx_chain[i].url_xfer);
- sc->sc_cdata.url_rx_chain[i].url_xfer = NULL;
- }
- }
-
- /* Free TX resources. */
- for (i = 0; i < URL_TX_LIST_CNT; i++) {
- if (sc->sc_cdata.url_tx_chain[i].url_mbuf != NULL) {
- m_freem(sc->sc_cdata.url_tx_chain[i].url_mbuf);
- sc->sc_cdata.url_tx_chain[i].url_mbuf = NULL;
- }
- if (sc->sc_cdata.url_tx_chain[i].url_xfer != NULL) {
- usbd_free_xfer(sc->sc_cdata.url_tx_chain[i].url_xfer);
- sc->sc_cdata.url_tx_chain[i].url_xfer = NULL;
- }
- }
-
- sc->sc_link = 0;
- ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
-}
-
-/* Set media options */
-Static int
-url_ifmedia_change(struct ifnet *ifp)
-{
- struct url_softc *sc = ifp->if_softc;
- struct mii_data *mii = GET_MII(sc);
-
- DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __FUNCTION__));
-
- 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
-url_ifmedia_status(struct ifnet *ifp, struct ifmediareq *ifmr)
-{
- struct url_softc *sc = ifp->if_softc;
- struct mii_data *mii = GET_MII(sc);
-
- DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __FUNCTION__));
-
- if (sc->sc_dying)
- return;
-
- if ((ifp->if_flags & IFF_RUNNING) == 0) {
- 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
-url_tick(void *xsc)
-{
- struct url_softc *sc = xsc;
-
- if (sc == NULL)
- return;
-
- DPRINTFN(0xff, ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),
- __FUNCTION__));
-
- if (sc->sc_dying)
- return;
-
- /* Perform periodic stuff in process context */
- usb_add_task(sc->sc_udev, &sc->sc_tick_task);
-}
-
-Static void
-url_tick_task(void *xsc)
-{
- struct url_softc *sc = xsc;
- struct ifnet *ifp;
- struct mii_data *mii;
- int s;
-
- if (sc == NULL)
- return;
-
- DPRINTFN(0xff, ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),
- __FUNCTION__));
-
- if (sc->sc_dying)
- return;
-
- ifp = GET_IFP(sc);
- mii = GET_MII(sc);
-
- if (mii == NULL)
- return;
-
- s = splnet();
-
- 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",
- USBDEVNAME(sc->sc_dev), __FUNCTION__));
- sc->sc_link++;
- if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
- url_start(ifp);
- }
- }
-
- usb_callout(sc->sc_stat_ch, hz, url_tick, sc);
-
- splx(s);
-}
-
-/* Get exclusive access to the MII registers */
-Static void
-url_lock_mii(struct url_softc *sc)
-{
- DPRINTFN(0xff, ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),
- __FUNCTION__));
-
- sc->sc_refcnt++;
- lockmgr(&sc->sc_mii_lock, LK_EXCLUSIVE, NULL);
-}
-
-Static void
-url_unlock_mii(struct url_softc *sc)
-{
- DPRINTFN(0xff, ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),
- __FUNCTION__));
-
- lockmgr(&sc->sc_mii_lock, LK_RELEASE, NULL);
- if (--sc->sc_refcnt < 0)
- usb_detach_wakeup(USBDEV(sc->sc_dev));
-}
-
-Static int
-url_int_miibus_readreg(device_ptr_t dev, int phy, int reg)
-{
- struct url_softc *sc;
- u_int16_t val;
-
- if (dev == NULL)
- return (0);
-
- sc = USBGETSOFTC(dev);
-
- DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x\n",
- USBDEVNAME(sc->sc_dev), __FUNCTION__, phy, reg));
-
- if (sc->sc_dying) {
-#ifdef DIAGNOSTIC
- printf("%s: %s: dying\n", USBDEVNAME(sc->sc_dev),
- __FUNCTION__);
-#endif
- return (0);
- }
-
- /* XXX: one PHY only for the RTL8150 internal PHY */
- if (phy != 0) {
- DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n",
- USBDEVNAME(sc->sc_dev), __FUNCTION__, phy));
- return (0);
- }
-
- url_lock_mii(sc);
-
- switch (reg) {
- case MII_BMCR: /* Control Register */
- reg = URL_BMCR;
- break;
- case MII_BMSR: /* Status Register */
- reg = URL_BMSR;
- break;
- case MII_PHYIDR1:
- case MII_PHYIDR2:
- val = 0;
- goto R_DONE;
- break;
- case MII_ANAR: /* Autonegotiation advertisement */
- reg = URL_ANAR;
- break;
- case MII_ANLPAR: /* Autonegotiation link partner abilities */
- reg = URL_ANLP;
- break;
- case URLPHY_MSR: /* Media Status Register */
- reg = URL_MSR;
- break;
- default:
- printf("%s: %s: bad register %04x\n",
- USBDEVNAME(sc->sc_dev), __FUNCTION__, reg);
- val = 0;
- goto R_DONE;
- break;
- }
-
- if (reg == URL_MSR)
- val = url_csr_read_1(sc, reg);
- else
- val = url_csr_read_2(sc, reg);
-
- R_DONE:
- DPRINTFN(0xff, ("%s: %s: phy=%d reg=0x%04x => 0x%04x\n",
- USBDEVNAME(sc->sc_dev), __FUNCTION__, phy, reg, val));
-
- url_unlock_mii(sc);
- return (val);
-}
-
-Static void
-url_int_miibus_writereg(device_ptr_t dev, int phy, int reg, int data)
-{
- struct url_softc *sc;
-
- if (dev == NULL)
- return;
-
- sc = USBGETSOFTC(dev);
-
- DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x data=0x%04x\n",
- USBDEVNAME(sc->sc_dev), __FUNCTION__, phy, reg, data));
-
- if (sc->sc_dying) {
-#ifdef DIAGNOSTIC
- printf("%s: %s: dying\n", USBDEVNAME(sc->sc_dev),
- __FUNCTION__);
-#endif
- return;
- }
-
- /* XXX: one PHY only for the RTL8150 internal PHY */
- if (phy != 0) {
- DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n",
- USBDEVNAME(sc->sc_dev), __FUNCTION__, phy));
- return;
- }
-
- url_lock_mii(sc);
-
- switch (reg) {
- case MII_BMCR: /* Control Register */
- reg = URL_BMCR;
- break;
- case MII_BMSR: /* Status Register */
- reg = URL_BMSR;
- break;
- case MII_PHYIDR1:
- case MII_PHYIDR2:
- goto W_DONE;
- break;
- case MII_ANAR: /* Autonegotiation advertisement */
- reg = URL_ANAR;
- break;
- case MII_ANLPAR: /* Autonegotiation link partner abilities */
- reg = URL_ANLP;
- break;
- case URLPHY_MSR: /* Media Status Register */
- reg = URL_MSR;
- break;
- default:
- printf("%s: %s: bad register %04x\n",
- USBDEVNAME(sc->sc_dev), __FUNCTION__, reg);
- goto W_DONE;
- break;
- }
-
- if (reg == URL_MSR)
- url_csr_write_1(sc, reg, data);
- else
- url_csr_write_2(sc, reg, data);
- W_DONE:
-
- url_unlock_mii(sc);
- return;
-}
-
-Static void
-url_miibus_statchg(device_ptr_t dev)
-{
-#ifdef URL_DEBUG
- struct url_softc *sc;
-
- if (dev == NULL)
- return;
-
- sc = USBGETSOFTC(dev);
- DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __FUNCTION__));
-#endif
- /* Nothing to do */
-}
-
-#if 0
-/*
- * external PHYs support, but not test.
- */
-Static int
-url_ext_miibus_redreg(device_ptr_t dev, int phy, int reg)
-{
- struct url_softc *sc = USBGETSOFTC(dev);
- u_int16_t val;
-
- DPRINTF(("%s: %s: enter, phy=%d reg=0x%04x\n",
- USBDEVNAME(sc->sc_dev), __FUNCTION__, phy, reg));
-
- if (sc->sc_dying) {
-#ifdef DIAGNOSTIC
- printf("%s: %s: dying\n", USBDEVNAME(sc->sc_dev),
- __FUNCTION__);
-#endif
- return (0);
- }
-
- url_lock_mii(sc);
-
- url_csr_write_1(sc, URL_PHYADD, phy & URL_PHYADD_MASK);
- /*
- * RTL8150L will initiate a MII management data transaction
- * if PHYCNT_OWN bit is set 1 by software. After transaction,
- * this bit is auto cleared by TRL8150L.
- */
- url_csr_write_1(sc, URL_PHYCNT,
- (reg | URL_PHYCNT_PHYOWN) & ~URL_PHYCNT_RWCR);
- for (i = 0; i < URL_TIMEOUT; i++) {
- if ((url_csr_read_1(sc, URL_PHYCNT) & URL_PHYCNT_PHYOWN) == 0)
- break;
- }
- if (i == URL_TIMEOUT) {
- printf("%s: MII read timed out\n", USBDEVNAME(sc->sc_dev));
- }
-
- val = url_csr_read_2(sc, URL_PHYDAT);
-
- DPRINTF(("%s: %s: phy=%d reg=0x%04x => 0x%04x\n",
- USBDEVNAME(sc->sc_dev), __FUNCTION__, phy, reg, val));
-
- url_unlock_mii(sc);
- return (val);
-}
-
-Static void
-url_ext_miibus_writereg(device_ptr_t dev, int phy, int reg, int data)
-{
- struct url_softc *sc = USBGETSOFTC(dev);
-
- DPRINTF(("%s: %s: enter, phy=%d reg=0x%04x data=0x%04x\n",
- USBDEVNAME(sc->sc_dev), __FUNCTION__, phy, reg, data));
-
- if (sc->sc_dying) {
-#ifdef DIAGNOSTIC
- printf("%s: %s: dying\n", USBDEVNAME(sc->sc_dev),
- __FUNCTION__);
-#endif
- return;
- }
-
- url_lock_mii(sc);
-
- url_csr_write_2(sc, URL_PHYDAT, data);
- url_csr_write_1(sc, URL_PHYADD, phy);
- url_csr_write_1(sc, URL_PHYCNT, reg | URL_PHYCNT_RWCR); /* Write */
-
- for (i=0; i < URL_TIMEOUT; i++) {
- if (url_csr_read_1(sc, URL_PHYCNT) & URL_PHYCNT_PHYOWN)
- break;
- }
-
- if (i == URL_TIMEOUT) {
- printf("%s: MII write timed out\n",
- USBDEVNAME(sc->sc_dev));
- }
-
- url_unlock_mii(sc);
- return;
-}
-#endif
-
diff --git a/sys/dev/usb/if_urlreg.h b/sys/dev/usb/if_urlreg.h
deleted file mode 100644
index f76bb380f00..00000000000
--- a/sys/dev/usb/if_urlreg.h
+++ /dev/null
@@ -1,195 +0,0 @@
-/* $OpenBSD: if_urlreg.h,v 1.1 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: if_urlreg.h,v 1.1 2002/03/28 21:09:11 ichiro Exp $ */
-/*
- * Copyright (c) 2001, 2002
- * 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. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Shingo WATANABE.
- * 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 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 URL_IFACE_INDEX 0
-#define URL_CONFIG_NO 1
-
-#define URL_TX_LIST_CNT 1
-#define URL_RX_LIST_CNT 1
-
-#define URL_TX_TIMEOUT 1000
-#define URL_TIMEOUT 10000
-
-#define ETHER_ALIGN 2
-
-
-/* Packet length */
-#define URL_MAX_MTU 1536
-#define URL_MIN_FRAME_LEN 60
-#define URL_BUFSZ URL_MAX_MTU
-
-/* Request */
-#define URL_REQ_MEM 0x05
-
-#define URL_CMD_READMEM 1
-#define URL_CMD_WRITEMEM 2
-
-/* Registers */
-#define URL_IDR0 0x0120 /* Ethernet Address, load from 93C46 */
-#define URL_IDR1 0x0121 /* Ethernet Address, load from 93C46 */
-#define URL_IDR2 0x0122 /* Ethernet Address, load from 93C46 */
-#define URL_IDR3 0x0123 /* Ethernet Address, load from 93C46 */
-#define URL_IDR4 0x0124 /* Ethernet Address, load from 93C46 */
-#define URL_IDR5 0x0125 /* Ethernet Address, load from 93C46 */
-
-#define URL_MAR0 0x0126 /* Multicast register */
-#define URL_MAR1 0x0127 /* Multicast register */
-#define URL_MAR2 0x0128 /* Multicast register */
-#define URL_MAR3 0x0129 /* Multicast register */
-#define URL_MAR4 0x012a /* Multicast register */
-#define URL_MAR5 0x012b /* Multicast register */
-#define URL_MAR6 0x012c /* Multicast register */
-#define URL_MAR7 0x012d /* Multicast register */
-#define URL_MAR URL_MAR0
-
-#define URL_CR 0x012e /* Command Register */
-#define URL_CR_WEPROM (1<<5) /* EEPROM Write Enable */
-#define URL_CR_SOFT_RST (1<<4) /* Software Reset */
-#define URL_CR_RE (1<<3) /* Ethernet Receive Enable */
-#define URL_CR_TE (1<<2) /* Ethernet Transmit Enable */
-#define URL_CR_EP3CLREN (1<<1) /* Enable clearing the performance counter */
-#define URL_CR_AUTOLOAD (1<<0) /* Auto-load the contents of 93C46 */
-
-#define URL_TCR 0x012f /* Transmit Control Register */
-#define URL_TCR_TXRR1 (1<<7) /* TX Retry Count */
-#define URL_TCR_TXRR0 (1<<6) /* TX Retry Count */
-#define URL_TCR_IFG1 (1<<4) /* Interframe Gap Time */
-#define URL_TCR_IFG0 (1<<4) /* Interframe Gap Time */
-#define URL_TCR_NOCRC (1<<0) /* no CRC Append */
-
-#define URL_RCR 0x0130 /* Receive Configuration Register */
-#define URL_RCR_TAIL (1<<7)
-#define URL_RCR_AER (1<<6)
-#define URL_RCR_AR (1<<5)
-#define URL_RCR_AM (1<<4)
-#define URL_RCR_AB (1<<3)
-#define URL_RCR_AD (1<<2)
-#define URL_RCR_AAM (1<<1)
-#define URL_RCR_AAP (1<<0)
-
-#define URL_MSR 0x137 /* Media Status Register */
-#define URL_MSR_TXFCE (1<<7)
-#define URL_MSR_RXFCE (1<<6)
-#define URL_MSR_DUPLEX (1<<4)
-#define URL_MSR_SPEED_100 (1<<3)
-#define URL_MSR_LINK (1<<2)
-#define URL_MSR_TXPF (1<<1)
-#define URL_MSR_RXPF (1<<0)
-
-#define URL_PHYADD 0x138 /* MII PHY Address select */
-#define URL_PHYADD_MASK 0x1f /* MII PHY Address select */
-
-#define URL_PHYDAT 0x139 /* MII PHY data */
-
-#define URL_PHYCNT 0x13b /* MII PHY control */
-#define URL_PHYCNT_PHYOWN (1<<6) /* Own bit */
-#define URL_PHYCNT_RWCR (1<<5) /* MII management data R/W control */
-#define URL_PHY_PHYOFF_MASK 0x1f /* PHY register offset */
-
-#define URL_BMCR 0x140 /* Basic mode control register */
-#define URL_BMSR 0x142 /* Basic mode status register */
-#define URL_ANAR 0x144 /* Auto-negotiation advertisement register */
-#define URL_ANLP 0x146 /* Auto-negotiation link partner ability register */
-
-
-typedef uWord url_rxhdr_t; /* Recive Header */
-#define URL_RXHDR_BYTEC_MASK (0x0fff) /* RX bytes count */
-#define URL_RXHDR_VALID_MASK (0x1000) /* Valid packet */
-#define URL_RXHDR_RUNTPKT_MASK (0x2000) /* Runt packet */
-#define URL_RXHDR_PHYPKT_MASK (0x4000) /* Physical match packet */
-#define URL_RXHDR_MCASTPKT_MASK (0x8000) /* Multicast packet */
-
-#define GET_IFP(sc) (&(sc)->sc_ec.ec_if)
-#define GET_MII(sc) (&(sc)->sc_mii)
-
-struct url_chain {
- struct url_softc *url_sc;
- usbd_xfer_handle url_xfer;
- char *url_buf;
- struct mbuf *url_mbuf;
- int url_idx;
-};
-
-struct url_cdata {
- struct url_chain url_tx_chain[URL_TX_LIST_CNT];
- struct url_chain url_rx_chain[URL_TX_LIST_CNT];
-#if 0
- /* XXX: Intrrupt Endpoint is not yet supported! */
- struct url_intrpkg url_ibuf;
-#endif
- int url_tx_prod;
- int url_tx_cons;
- int url_tx_cnt;
- int url_rx_prod;
-};
-
-struct url_softc {
- USBBASEDEVICE 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 */
- struct ethercom sc_ec; /* ethernet common */
- struct mii_data sc_mii;
- struct lock sc_mii_lock;
- int sc_link;
-#define sc_media url_mii.mii_media
-#if NRND > 0
- rndsource_element_t rnd_source;
-#endif
- struct url_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/ohci.c b/sys/dev/usb/ohci.c
index 4e1107f020f..008038435de 100644
--- a/sys/dev/usb/ohci.c
+++ b/sys/dev/usb/ohci.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: ohci.c,v 1.27 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: ohci.c,v 1.122 2002/03/17 18:02:52 augustss Exp $ */
+/* $OpenBSD: ohci.c,v 1.28 2002/05/07 18:29:18 nate Exp $ */
+/* $NetBSD: ohci.c,v 1.104 2001/09/28 23:57:21 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/ohci.c,v 1.22 1999/11/17 22:33:40 n_hibma Exp $ */
/*
@@ -198,18 +198,18 @@ 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,
+Static usbd_status ohci_device_setintr(ohci_softc_t *sc,
struct ohci_pipe *pipe, int ival);
-Static int ohci_str(usb_string_descriptor_t *, int, const char *);
+Static int ohci_str(usb_string_descriptor_t *, int, 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_rhsc_enable(void *sc);
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_abort_xfer_end(void *);
Static void ohci_device_clear_toggle(usbd_pipe_handle pipe);
Static void ohci_noop(usbd_pipe_handle pipe);
@@ -236,7 +236,7 @@ Static void ohci_dump_itds(ohci_soft_itd_t *);
#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] =
+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,
@@ -286,7 +286,7 @@ Static struct usbd_bus_methods ohci_bus_methods = {
ohci_freex,
};
-Static struct usbd_pipe_methods ohci_root_ctrl_methods = {
+Static struct usbd_pipe_methods ohci_root_ctrl_methods = {
ohci_root_ctrl_transfer,
ohci_root_ctrl_start,
ohci_root_ctrl_abort,
@@ -295,7 +295,7 @@ Static struct usbd_pipe_methods ohci_root_ctrl_methods = {
ohci_root_ctrl_done,
};
-Static struct usbd_pipe_methods ohci_root_intr_methods = {
+Static struct usbd_pipe_methods ohci_root_intr_methods = {
ohci_root_intr_transfer,
ohci_root_intr_start,
ohci_root_intr_abort,
@@ -304,7 +304,7 @@ Static struct usbd_pipe_methods ohci_root_intr_methods = {
ohci_root_intr_done,
};
-Static struct usbd_pipe_methods ohci_device_ctrl_methods = {
+Static struct usbd_pipe_methods ohci_device_ctrl_methods = {
ohci_device_ctrl_transfer,
ohci_device_ctrl_start,
ohci_device_ctrl_abort,
@@ -313,7 +313,7 @@ Static struct usbd_pipe_methods ohci_device_ctrl_methods = {
ohci_device_ctrl_done,
};
-Static struct usbd_pipe_methods ohci_device_intr_methods = {
+Static struct usbd_pipe_methods ohci_device_intr_methods = {
ohci_device_intr_transfer,
ohci_device_intr_start,
ohci_device_intr_abort,
@@ -322,7 +322,7 @@ Static struct usbd_pipe_methods ohci_device_intr_methods = {
ohci_device_intr_done,
};
-Static struct usbd_pipe_methods ohci_device_bulk_methods = {
+Static struct usbd_pipe_methods ohci_device_bulk_methods = {
ohci_device_bulk_transfer,
ohci_device_bulk_start,
ohci_device_bulk_abort,
@@ -368,19 +368,15 @@ ohci_detach(struct ohci_softc *sc, int flags)
if (sc->sc_child != NULL)
rv = config_detach(sc->sc_child, flags);
-
+
if (rv != 0)
return (rv);
- usb_uncallout(sc->sc_tmo_rhsc, ohci_rhsc_enable, sc);
-
#if defined(__NetBSD__) || defined(__OpenBSD__)
powerhook_disestablish(sc->sc_powerhook);
shutdownhook_disestablish(sc->sc_shutdownhook);
#endif
- usb_delay_ms(&sc->sc_bus, 300); /* XXX let stray task complete */
-
/* free data structures XXX */
return (rv);
@@ -492,7 +488,7 @@ ohci_alloc_std_chain(struct ohci_pipe *opipe, ohci_softc_t *sc,
dataphys = DMAADDR(dma);
dataphysend = OHCI_PAGE(dataphys + len - 1);
tdflags = htole32(
- (rd ? OHCI_TD_IN : OHCI_TD_OUT) |
+ (rd ? OHCI_TD_IN : OHCI_TD_OUT) |
(flags & USBD_SHORT_XFER_OK ? OHCI_TD_R : 0) |
OHCI_TD_NOCC | OHCI_TD_TOGGLE_CARRY | OHCI_TD_NOINTR);
@@ -508,7 +504,7 @@ ohci_alloc_std_chain(struct ohci_pipe *opipe, ohci_softc_t *sc,
curlen = len;
} else {
/* must use multiple TDs, fill as much as possible. */
- curlen = 2 * OHCI_PAGE_SIZE -
+ curlen = 2 * OHCI_PAGE_SIZE -
(dataphys & (OHCI_PAGE_SIZE-1));
/* the length must be a multiple of the max size */
curlen -= curlen % UGETW(opipe->pipe.endpoint->edesc->wMaxPacketSize);
@@ -569,7 +565,7 @@ ohci_alloc_std_chain(struct ohci_pipe *opipe, ohci_softc_t *sc,
#if 0
Static void
-ohci_free_std_chain(ohci_softc_t *sc, ohci_soft_td_t *std,
+ohci_free_std_chain(ohci_softc_t *sc, ohci_soft_td_t *std,
ohci_soft_td_t *stdend)
{
ohci_soft_td_t *p;
@@ -641,6 +637,15 @@ ohci_free_sitd(ohci_softc_t *sc, ohci_soft_itd_t *sitd)
splx(s);
}
+void
+ohci_reset(ohci_softc_t *sc)
+{
+ ohci_shutdown(sc);
+ /* disable all interrupts and then switch on all desired
+ interrupts */
+ OWRITE4(sc, OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTRS);
+}
+
usbd_status
ohci_init(ohci_softc_t *sc)
{
@@ -660,7 +665,7 @@ ohci_init(ohci_softc_t *sc)
OHCI_REV_LEGACY(rev) ? ", legacy support" : "");
if (OHCI_REV_HI(rev) != 1 || OHCI_REV_LO(rev) != 0) {
- printf("%s: unsupported OHCI revision\n",
+ printf("%s: unsupported OHCI revision\n",
USBDEVNAME(sc->sc_bus.bdev));
sc->sc_bus.usbrev = USBREV_UNKNOWN;
return (USBD_INVAL);
@@ -676,7 +681,7 @@ ohci_init(ohci_softc_t *sc)
/* XXX determine alignment by R/W */
/* Allocate the HCCA area. */
- err = usb_allocmem(&sc->sc_bus, OHCI_HCCA_SIZE,
+ err = usb_allocmem(&sc->sc_bus, OHCI_HCCA_SIZE,
OHCI_HCCA_ALIGN, &sc->sc_hccadma);
if (err)
return (err);
@@ -728,12 +733,12 @@ ohci_init(ohci_softc_t *sc)
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]] =
+ sc->sc_hcca->hcca_interrupt_table[revbits[i]] =
htole32(sc->sc_eds[OHCI_NO_EDS-OHCI_NO_INTRS+i]->physaddr);
#ifdef OHCI_DEBUG
@@ -856,7 +861,7 @@ ohci_init(ohci_softc_t *sc)
if (ohcidebug > 5)
ohci_dumpregs(sc);
#endif
-
+
/* Set up the bus struct. */
sc->sc_bus.methods = &ohci_bus_methods;
sc->sc_bus.pipe_size = sizeof(struct ohci_pipe);
@@ -870,8 +875,6 @@ ohci_init(ohci_softc_t *sc)
timeout_set(&sc->sc_tmo_rhsc, ohci_rhsc_enable, sc);
#endif
- usb_callout_init(sc->sc_tmo_rhsc);
-
return (USBD_NORMAL_COMPLETION);
bad5:
@@ -915,23 +918,12 @@ ohci_allocx(struct usbd_bus *bus)
usbd_xfer_handle xfer;
xfer = SIMPLEQ_FIRST(&sc->sc_free_xfers);
- if (xfer != NULL) {
+ if (xfer != NULL)
SIMPLEQ_REMOVE_HEAD(&sc->sc_free_xfers, xfer, next);
-#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));
-#ifdef DIAGNOSTIC
- xfer->busy_free = XFER_BUSY;
-#endif
- }
+ else
+ xfer = malloc(sizeof(*xfer), M_USB, M_NOWAIT);
+ if (xfer != NULL)
+ memset(xfer, 0, sizeof *xfer);
return (xfer);
}
@@ -940,14 +932,6 @@ 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
SIMPLEQ_INSERT_HEAD(&sc->sc_free_xfers, xfer, next);
}
@@ -1081,22 +1065,15 @@ ohci_intr(void *p)
{
ohci_softc_t *sc = p;
- 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) {
#ifdef DIAGNOSTIC
- static int repeat = 0;
- if (repeat < 10) {
- printf("ohci_intr: ignored interrupt while polling\n");
- ++repeat;
- }
+ printf("ohci_intr: ignored interrupt while polling\n");
#endif
return (0);
}
- return (ohci_intr1(sc));
+ return (ohci_intr1(sc));
}
Static int
@@ -1105,8 +1082,6 @@ 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
@@ -1136,7 +1111,7 @@ ohci_intr1(ohci_softc_t *sc)
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",
+ 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));
@@ -1148,13 +1123,13 @@ ohci_intr1(ohci_softc_t *sc)
sc->sc_overrun_cnt = 0;
}
/* XXX do what */
- eintrs &= ~OHCI_SO;
+ intrs &= ~OHCI_SO;
}
if (eintrs & OHCI_WDH) {
ohci_add_done(sc, done &~ OHCI_DONE_INTRS);
sc->sc_hcca->hcca_done_head = 0;
usb_schedsoftintr(&sc->sc_bus);
- eintrs &= ~OHCI_WDH;
+ intrs &= ~OHCI_WDH;
}
if (eintrs & OHCI_RD) {
printf("%s: resume detect\n", USBDEVNAME(sc->sc_bus.bdev));
@@ -1168,28 +1143,24 @@ ohci_intr1(ohci_softc_t *sc)
}
if (eintrs & OHCI_RHSC) {
ohci_rhsc(sc, sc->sc_intrxfer);
- /*
+ intrs &= ~OHCI_RHSC;
+
+ /*
* Disable RHSC interrupt for now, because it will be
* on until the port has been reset.
*/
ohci_rhsc_able(sc, 0);
- DPRINTFN(2, ("%s: rhsc interrupt disabled\n",
- USBDEVNAME(sc->sc_bus.bdev)));
-
+#if defined (__OpenBSD__)
/* Do not allow RHSC interrupts > 1 per second */
- usb_callout(sc->sc_tmo_rhsc, hz, ohci_rhsc_enable, sc);
- eintrs &= ~OHCI_RHSC;
+ timeout_add(&sc->sc_tmo_rhsc, hz);
+#endif
}
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",
- USBDEVNAME(sc->sc_bus.bdev), eintrs);
- }
+ /* Block unprocessed interrupts. XXX */
+ OWRITE4(sc, OHCI_INTERRUPT_DISABLE, intrs);
+ sc->sc_eintrs &= ~intrs;
return (1);
}
@@ -1212,10 +1183,6 @@ ohci_rhsc_enable(void *v_sc)
{
ohci_softc_t *sc = v_sc;
- ohci_rhsc(sc, sc->sc_intrxfer);
- DPRINTFN(2, ("%s: rhsc interrupt enabled\n",
- USBDEVNAME(sc->sc_bus.bdev)));
-
ohci_rhsc_able(sc, 1);
}
@@ -1286,8 +1253,6 @@ ohci_softintr(void *v)
usbd_xfer_handle xfer;
int len, cc, s;
- DPRINTFN(10,("ohci_softintr: enter\n:"));
-
sc->sc_bus.intr_context++;
s = splhardusb();
@@ -1297,7 +1262,7 @@ ohci_softintr(void *v)
sc->sc_sidone = NULL;
splx(s);
- DPRINTFN(10,("ohci_softintr: sdone=%p sidone=%p\n", sdone, sidone));
+ DPRINTFN(10,("ohci_process_done: sdone=%p sidone=%p\n", sdone, sidone));
#ifdef OHCI_DEBUG
if (ohcidebug > 10) {
@@ -1312,11 +1277,9 @@ ohci_softintr(void *v)
DPRINTFN(10, ("ohci_process_done: std=%p xfer=%p hcpriv=%p\n",
std, xfer, xfer ? xfer->hcpriv : 0));
if (xfer == NULL) {
- /*
- * xfer == NULL: There seems to be no xfer associated
+ /* xfer == NULL: There seems to be no xfer associated
* with this TD. It is tailp that happened to end up on
* the done queue.
- * Shouldn't happen, but some chips are broken(?).
*/
continue;
}
@@ -1350,7 +1313,7 @@ ohci_softintr(void *v)
* the endpoint.
*/
ohci_soft_td_t *p, *n;
- struct ohci_pipe *opipe =
+ struct ohci_pipe *opipe =
(struct ohci_pipe *)xfer->pipe;
DPRINTFN(15,("ohci_process_done: error cc=%d (%s)\n",
@@ -1377,7 +1340,7 @@ ohci_softintr(void *v)
#ifdef OHCI_DEBUG
if (ohcidebug > 10) {
- DPRINTF(("ohci_softintr: ITD done:\n"));
+ DPRINTF(("ohci_process_done: ITD done:\n"));
ohci_dump_itds(sidone);
}
#endif
@@ -1404,7 +1367,7 @@ ohci_softintr(void *v)
cc = OHCI_ITD_GET_CC(le32toh(sitd->itd.itd_flags));
if (cc == OHCI_CC_NO_ERROR) {
/* XXX compute length for input */
- struct ohci_pipe *opipe =
+ struct ohci_pipe *opipe =
(struct ohci_pipe *)xfer->pipe;
if (sitd->flags & OHCI_CALL_DONE) {
opipe->u.iso.inuse -= xfer->nframes;
@@ -1420,13 +1383,7 @@ ohci_softintr(void *v)
}
}
- if (sc->sc_softwake) {
- sc->sc_softwake = 0;
- wakeup(&sc->sc_softwake);
- }
-
sc->sc_bus.intr_context--;
- DPRINTFN(10,("ohci_softintr: done:\n"));
}
void
@@ -1451,7 +1408,7 @@ ohci_device_intr_done(usbd_xfer_handle xfer)
ohci_soft_td_t *data, *tail;
- DPRINTFN(10,("ohci_intr_done: xfer=%p, actlen=%d\n",
+ DPRINTFN(10,("ohci_intr_done: xfer=%p, actlen=%d\n",
xfer, xfer->actlen));
xfer->hcpriv = NULL;
@@ -1464,9 +1421,9 @@ ohci_device_intr_done(usbd_xfer_handle xfer)
return;
}
tail->xfer = NULL;
-
+
data->td.td_flags = htole32(
- OHCI_TD_IN | OHCI_TD_NOCC |
+ 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);
@@ -1489,7 +1446,7 @@ ohci_device_intr_done(usbd_xfer_handle xfer)
void
ohci_device_bulk_done(usbd_xfer_handle xfer)
{
- DPRINTFN(10,("ohci_bulk_done: xfer=%p, actlen=%d\n",
+ DPRINTFN(10,("ohci_bulk_done: xfer=%p, actlen=%d\n",
xfer, xfer->actlen));
xfer->hcpriv = NULL;
@@ -1505,7 +1462,7 @@ ohci_rhsc(ohci_softc_t *sc, usbd_xfer_handle xfer)
int hstatus;
hstatus = OREAD4(sc, OHCI_RH_STATUS);
- DPRINTF(("ohci_rhsc: sc=%p xfer=%p hstatus=0x%08x\n",
+ DPRINTF(("ohci_rhsc: sc=%p xfer=%p hstatus=0x%08x\n",
sc, xfer, hstatus));
if (xfer == NULL) {
@@ -1558,8 +1515,6 @@ ohci_waitintr(ohci_softc_t *sc, usbd_xfer_handle xfer)
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 OHCI_DEBUG
@@ -1584,15 +1539,6 @@ void
ohci_poll(struct usbd_bus *bus)
{
ohci_softc_t *sc = (ohci_softc_t *)bus;
-#ifdef OHCI_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);
@@ -1619,7 +1565,7 @@ ohci_device_request(usbd_xfer_handle xfer)
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, addr,
+ UGETW(req->wIndex), len, addr,
opipe->pipe.endpoint->edesc->bEndpointAddress));
setup = opipe->tail.td;
@@ -1705,15 +1651,11 @@ ohci_device_request(usbd_xfer_handle xfer)
}
splx(s);
-#ifdef OHCI_DEBUG
- if (ohcidebug > 20) {
+#if 0
+ if (ohcidebug > 10) {
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);
}
@@ -1735,8 +1677,6 @@ ohci_device_request(usbd_xfer_handle xfer)
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;
@@ -1750,7 +1690,7 @@ ohci_add_ed(ohci_soft_ed_t *sed, ohci_soft_ed_t *head)
void
ohci_rem_ed(ohci_soft_ed_t *sed, ohci_soft_ed_t *head)
{
- ohci_soft_ed_t *p;
+ ohci_soft_ed_t *p;
SPLUSBCHECK;
@@ -1800,7 +1740,7 @@ ohci_hash_find_td(ohci_softc_t *sc, ohci_physaddr_t a)
int h = HASH(a);
ohci_soft_td_t *std;
- for (std = LIST_FIRST(&sc->sc_hash_tds[h]);
+ for (std = LIST_FIRST(&sc->sc_hash_tds[h]);
std != NULL;
std = LIST_NEXT(std, hnext))
if (std->physaddr == a)
@@ -1816,7 +1756,7 @@ ohci_hash_add_itd(ohci_softc_t *sc, ohci_soft_itd_t *sitd)
SPLUSBCHECK;
- DPRINTFN(10,("ohci_hash_add_itd: sitd=%p physaddr=0x%08lx\n",
+ 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);
@@ -1828,7 +1768,7 @@ 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",
+ DPRINTFN(10,("ohci_hash_rem_itd: sitd=%p physaddr=0x%08lx\n",
sitd, (u_long)sitd->physaddr));
LIST_REMOVE(sitd, hnext);
@@ -1840,7 +1780,7 @@ 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]);
+ for (sitd = LIST_FIRST(&sc->sc_hash_itds[h]);
sitd != NULL;
sitd = LIST_NEXT(sitd, hnext))
if (sitd->physaddr == a)
@@ -1851,32 +1791,15 @@ ohci_hash_find_itd(ohci_softc_t *sc, ohci_physaddr_t a)
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_init_task(&oxfer->abort_task, ohci_timeout_task, addr);
- usb_add_task(oxfer->xfer.pipe->device, &oxfer->abort_task);
-}
-
-void
-ohci_timeout_task(void *addr)
-{
usbd_xfer_handle xfer = addr;
int s;
- DPRINTF(("ohci_timeout_task: xfer=%p\n", xfer));
+ DPRINTF(("ohci_timeout: xfer=%p\n", xfer));
s = splusb();
+ xfer->device->bus->intr_context++;
ohci_abort_xfer(xfer, USBD_TIMEOUT);
+ xfer->device->bus->intr_context--;
splx(s);
}
@@ -1893,19 +1816,19 @@ ohci_dump_td(ohci_soft_td_t *std)
{
char sbuf[128];
- bitmask_snprintf((u_int32_t)le32toh(std->td.td_flags),
+ bitmask_snprintf((int)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));
+ DPRINTF(("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
@@ -1913,20 +1836,20 @@ 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));
+ DPRINTF(("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");
+ DPRINTF(("offs[%d]=0x%04x ", i,
+ (u_int)le16toh(sitd->itd.itd_offset[i])));
+ DPRINTF(("\n"));
}
void
@@ -1941,21 +1864,21 @@ ohci_dump_ed(ohci_soft_ed_t *sed)
{
char sbuf[128], sbuf2[128];
- bitmask_snprintf((u_int32_t)le32toh(sed->ed.ed_flags),
+ bitmask_snprintf((int)le32toh(sed->ed.ed_flags),
"\20\14OUT\15IN\16LOWSPEED\17SKIP\20ISO",
sbuf, sizeof(sbuf));
- bitmask_snprintf((u_int32_t)le32toh(sed->ed.ed_headp),
+ bitmask_snprintf((u_long)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\n"
- "tailp=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));
+ DPRINTF(("ED(%p) at 0x%08lx: addr=%d endpt=%d maxp=%d %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
@@ -1980,9 +1903,6 @@ ohci_open(usbd_pipe_handle pipe)
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;
@@ -2026,17 +1946,17 @@ ohci_open(usbd_pipe_handle pipe)
fmt = OHCI_ED_FORMAT_GEN | OHCI_ED_DIR_TD;
}
sed->ed.ed_flags = htole32(
- OHCI_ED_SET_FA(addr) |
+ OHCI_ED_SET_FA(addr) |
OHCI_ED_SET_EN(ed->bEndpointAddress) |
- (dev->speed == USB_SPEED_LOW ? OHCI_ED_SPEED : 0) |
- fmt | OHCI_ED_SET_MAXP(UGETW(ed->wMaxPacketSize)));
+ (dev->lowspeed ? OHCI_ED_SPEED : 0) | fmt |
+ OHCI_ED_SET_MAXP(UGETW(ed->wMaxPacketSize)));
sed->ed.ed_headp = sed->ed.ed_tailp = htole32(tdphys);
switch (xfertype) {
case UE_CONTROL:
pipe->methods = &ohci_device_ctrl_methods;
- err = usb_allocmem(&sc->sc_bus,
- sizeof(usb_device_request_t),
+ err = usb_allocmem(&sc->sc_bus,
+ sizeof(usb_device_request_t),
0, &opipe->u.ctl.reqdma);
if (err)
goto bad;
@@ -2071,7 +1991,7 @@ ohci_open(usbd_pipe_handle pipe)
ohci_free_sed(sc, sed);
bad0:
return (USBD_NOMEM);
-
+
}
/*
@@ -2089,25 +2009,22 @@ ohci_close_pipe(usbd_pipe_handle pipe, ohci_soft_ed_t *head)
s = splusb();
#ifdef DIAGNOSTIC
sed->ed.ed_flags |= htole32(OHCI_ED_SKIP);
- if ((le32toh(sed->ed.ed_tailp) & OHCI_HEADMASK) !=
+ if ((le32toh(sed->ed.ed_tailp) & OHCI_HEADMASK) !=
(le32toh(sed->ed.ed_headp) & OHCI_HEADMASK)) {
+ ohci_physaddr_t td = le32toh(sed->ed.ed_headp);
ohci_soft_td_t *std;
- std = ohci_hash_find_td(sc, le32toh(sed->ed.ed_headp));
+ for (std = LIST_FIRST(&sc->sc_hash_tds[HASH(td)]);
+ std != NULL;
+ std = LIST_NEXT(std, hnext))
+ if (std->physaddr == td)
+ break;
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 OHCI_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) !=
+ if ((le32toh(sed->ed.ed_tailp) & OHCI_HEADMASK) !=
(le32toh(sed->ed.ed_headp) & OHCI_HEADMASK))
printf("ohci_close_pipe: pipe still not empty\n");
}
@@ -2117,7 +2034,7 @@ ohci_close_pipe(usbd_pipe_handle pipe, ohci_soft_ed_t *head)
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
@@ -2131,96 +2048,68 @@ void
ohci_abort_xfer(usbd_xfer_handle xfer, usbd_status status)
{
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;
+ ohci_soft_ed_t *sed;
- DPRINTF(("ohci_abort_xfer: xfer=%p pipe=%p sed=%p\n", xfer, opipe,
- sed));
+ DPRINTF(("ohci_abort_xfer: xfer=%p pipe=%p\n", xfer, opipe));
- if (sc->sc_dying) {
- /* If we're dying, just do the software part. */
- s = splusb();
- xfer->status = status; /* make software ignore it */
- usb_uncallout(xfer->timeout_handle, ohci_timeout, xfer);
- usb_transfer_complete(xfer);
- splx(s);
- }
+ xfer->status = status;
- if (xfer->device->bus->intr_context || !curproc)
- panic("ohci_abort_xfer: not in process context\n");
-
- /*
- * Step 1: Make interrupt routine and hardware ignore xfer.
- */
- s = splusb();
- xfer->status = status; /* make software ignore it */
usb_uncallout(xfer->timeout_handle, ohci_timeout, xfer);
- splx(s);
+
+ sed = opipe->sed;
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 */
+#if 1
+ if (xfer->device->bus->intr_context) {
+ /* We have no process context, so we can't use tsleep(). */
+ usb_callout(xfer->pipe->abort_handle,
+ hz / USB_FRAMES_PER_SECOND, ohci_abort_xfer_end, xfer);
+ } else {
+#if defined(DIAGNOSTIC) && defined(__i386__) && defined(__FreeBSD__)
+ KASSERT(intr_nesting_level == 0,
+ ("ohci_abort_req in interrupt context"));
+#endif
+ usb_delay_ms(opipe->pipe.device->bus, 1);
+ ohci_abort_xfer_end(xfer);
+ }
+#else
+ delay(1000);
+ ohci_abort_xfer_end(xfer);
+#endif
+}
+
+void
+ohci_abort_xfer_end(void *v)
+{
+ usbd_xfer_handle xfer = v;
+ 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_td_t *p, *n;
+ int s;
+
s = splusb();
- sc->sc_softwake = 1;
- usb_schedsoftintr(&sc->sc_bus);
- tsleep(&sc->sc_softwake, PZERO, "ohciab", 0);
- 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) {
splx(s);
- printf("ohci_abort_xfer: hcpriv is NULL\n");
+ printf("ohci_abort_xfer: hcpriv==0\n");
return;
}
#endif
-#ifdef OHCI_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 = opipe->sed;
+ DPRINTFN(2,("ohci_abort_xfer: set hd=%x, tl=%x\n",
+ (int)p->physaddr, (int)le32toh(sed->ed.ed_tailp)));
+ sed->ed.ed_headp = htole32(p->physaddr); /* unlink TDs */
sed->ed.ed_flags &= htole32(~OHCI_ED_SKIP); /* remove hardware skip */
- /*
- * Step 5: Execute callback.
- */
usb_transfer_complete(xfer);
splx(s);
@@ -2235,7 +2124,7 @@ Static usb_device_descriptor_t ohci_devd = {
{0x00, 0x01}, /* USB version */
UDCLASS_HUB, /* class */
UDSUBCLASS_HUB, /* subclass */
- UDPROTO_FSHUB,
+ 0, /* protocol */
64, /* max packet */
{0},{0},{0x00,0x01}, /* device id */
1,2,0, /* string indicies */
@@ -2263,7 +2152,7 @@ Static usb_interface_descriptor_t ohci_ifcd = {
1,
UICLASS_HUB,
UISUBCLASS_HUB,
- UIPROTO_FSHUB,
+ 0,
0
};
@@ -2287,7 +2176,10 @@ Static usb_hub_descriptor_t ohci_hubd = {
};
Static int
-ohci_str(usb_string_descriptor_t *p, int l, const char *s)
+ohci_str(p, l, s)
+ usb_string_descriptor_t *p;
+ int l;
+ char *s;
{
int i;
@@ -2343,7 +2235,7 @@ ohci_root_ctrl_start(usbd_xfer_handle xfer)
#endif
req = &xfer->request;
- DPRINTFN(4,("ohci_root_ctrl_control type=0x%02x request=%02x\n",
+ DPRINTFN(4,("ohci_root_ctrl_control type=0x%02x request=%02x\n",
req->bmRequestType, req->bRequest));
len = UGETW(req->wLength);
@@ -2358,7 +2250,7 @@ ohci_root_ctrl_start(usbd_xfer_handle xfer)
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.
*/
@@ -2527,13 +2419,13 @@ ohci_root_ctrl_start(usbd_xfer_handle xfer)
hubd = ohci_hubd;
hubd.bNbrPorts = sc->sc_noport;
USETW(hubd.wHubCharacteristics,
- (v & OHCI_NPS ? UHD_PWR_NO_SWITCH :
+ (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)
+ 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);
@@ -2590,13 +2482,8 @@ ohci_root_ctrl_start(usbd_xfer_handle xfer)
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;
- }
+ for (i = 0; i < 10; i++) {
+ usb_delay_ms(&sc->sc_bus, 10); /* XXX */
if ((OREAD4(sc, port) & UPS_RESET) == 0)
break;
}
@@ -2691,7 +2578,7 @@ 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;
@@ -2894,7 +2781,7 @@ ohci_device_bulk_abort(usbd_xfer_handle xfer)
ohci_abort_xfer(xfer, USBD_CANCELLED);
}
-/*
+/*
* Close a device bulk pipe.
*/
Static void
@@ -2956,7 +2843,7 @@ ohci_device_intr_start(usbd_xfer_handle xfer)
tail->xfer = NULL;
data->td.td_flags = htole32(
- OHCI_TD_IN | OHCI_TD_NOCC |
+ 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);
@@ -3029,7 +2916,7 @@ ohci_device_intr_close(usbd_pipe_handle pipe)
pipe, nslots, pos));
s = splusb();
sed->ed.ed_flags |= htole32(OHCI_ED_SKIP);
- if ((le32toh(sed->ed.ed_tailp) & OHCI_HEADMASK) !=
+ if ((le32toh(sed->ed.ed_tailp) & OHCI_HEADMASK) !=
(le32toh(sed->ed.ed_headp) & OHCI_HEADMASK))
usb_delay_ms(&sc->sc_bus, 2);
@@ -3092,7 +2979,7 @@ ohci_device_setintr(ohci_softc_t *sc, struct ohci_pipe *opipe, int ival)
bestbw = bw;
}
}
- DPRINTFN(2, ("ohci_setintr: best=%d(%d..%d) bestbw=%d\n",
+ DPRINTFN(2, ("ohci_setintr: best=%d(%d..%d) bestbw=%d\n",
best, slow, shigh, bestbw));
s = splusb();
@@ -3148,7 +3035,7 @@ ohci_device_isoc_enter(usbd_xfer_handle xfer)
ohci_softc_t *sc = (ohci_softc_t *)dev->bus;
ohci_soft_ed_t *sed = opipe->sed;
struct iso *iso = &opipe->u.iso;
- ohci_soft_itd_t *sitd, *nsitd;
+ ohci_soft_itd_t *sitd, *nsitd;
ohci_physaddr_t buf, offs, noffs, bp0;
int i, ncur, nframes;
int s;
@@ -3163,7 +3050,7 @@ ohci_device_isoc_enter(usbd_xfer_handle xfer)
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",
+ DPRINTFN(2,("ohci_device_isoc_enter: start next=%d\n",
iso->next));
}
@@ -3177,7 +3064,7 @@ ohci_device_isoc_enter(usbd_xfer_handle xfer)
noffs = offs + xfer->frlengths[i];
if (ncur == OHCI_ITD_NOFFSET || /* all offsets used */
OHCI_PAGE(buf + noffs) > bp0 + OHCI_PAGE_SIZE) { /* too many page crossings */
-
+
/* Allocate next ITD */
nsitd = ohci_alloc_sitd(sc);
if (nsitd == NULL) {
@@ -3189,7 +3076,7 @@ ohci_device_isoc_enter(usbd_xfer_handle xfer)
/* Fill current ITD */
sitd->itd.itd_flags = htole32(
- OHCI_ITD_NOCC |
+ OHCI_ITD_NOCC |
OHCI_ITD_SET_SF(iso->next) |
OHCI_ITD_SET_DI(6) | /* delay intr a little */
OHCI_ITD_SET_FC(ncur));
@@ -3201,7 +3088,7 @@ ohci_device_isoc_enter(usbd_xfer_handle xfer)
sitd->flags = 0;
sitd = nsitd;
- iso->next = iso->next + ncur;
+ iso->next = iso->next + ncur;
bp0 = OHCI_PAGE(buf + offs);
ncur = 0;
}
@@ -3211,13 +3098,13 @@ ohci_device_isoc_enter(usbd_xfer_handle xfer)
nsitd = ohci_alloc_sitd(sc);
if (nsitd == NULL) {
/* XXX what now? */
- printf("%s: isoc TD alloc failed\n",
+ printf("%s: isoc TD alloc failed\n",
USBDEVNAME(sc->sc_bus.bdev));
return;
}
/* Fixup last used ITD */
sitd->itd.itd_flags = htole32(
- OHCI_ITD_NOCC |
+ OHCI_ITD_NOCC |
OHCI_ITD_SET_SF(iso->next) |
OHCI_ITD_SET_DI(0) |
OHCI_ITD_SET_FC(ncur));
@@ -3273,7 +3160,7 @@ ohci_device_isoc_start(usbd_xfer_handle xfer)
#ifdef DIAGNOSTIC
if (xfer->status != USBD_IN_PROGRESS)
- printf("ohci_device_isoc_start: not in progress %p\n", xfer);
+ printf("uhci_device_isoc_start: not in progress %p\n", xfer);
#endif
/* XXX anything to do? */
@@ -3295,7 +3182,7 @@ ohci_device_isoc_abort(usbd_xfer_handle xfer)
DPRINTFN(1,("ohci_device_isoc_abort: xfer=%p\n", xfer));
/* Transfer is already done. */
- if (xfer->status != USBD_NOT_STARTED &&
+ if (xfer->status != USBD_NOT_STARTED &&
xfer->status != USBD_IN_PROGRESS) {
splx(s);
printf("ohci_device_isoc_abort: early return\n");
@@ -3343,7 +3230,7 @@ ohci_device_isoc_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;
- ohci_soft_itd_t *sitd, *nsitd;
+ ohci_soft_itd_t *sitd, *nsitd;
DPRINTFN(1,("ohci_device_isoc_done: xfer=%p\n", xfer));
diff --git a/sys/dev/usb/ohcivar.h b/sys/dev/usb/ohcivar.h
index 19f4d228691..396f9dacf65 100644
--- a/sys/dev/usb/ohcivar.h
+++ b/sys/dev/usb/ohcivar.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: ohcivar.h,v 1.16 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: ohcivar.h,v 1.30 2001/12/31 12:20:35 augustss Exp $ */
+/* $OpenBSD: ohcivar.h,v 1.17 2002/05/07 18:29:18 nate Exp $ */
+/* $NetBSD: ohcivar.h,v 1.28 2001/09/28 23:57:21 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/ohcivar.h,v 1.13 1999/11/17 22:33:41 n_hibma Exp $ */
/*
@@ -106,7 +106,6 @@ typedef struct ohci_softc {
int sc_noport;
u_int8_t sc_addr; /* device address */
u_int8_t sc_conf; /* device configuration */
- char sc_softwake;
ohci_soft_ed_t *sc_freeeds;
ohci_soft_td_t *sc_freetds;
@@ -139,18 +138,13 @@ typedef struct ohci_softc {
char sc_dying;
} ohci_softc_t;
-struct ohci_xfer {
- struct usbd_xfer xfer;
- struct usb_task abort_task;
-};
-
-#define OXFER(xfer) ((struct ehci_xfer *)(xfer))
-
+void ohci_reset(ohci_softc_t *);
usbd_status ohci_init(ohci_softc_t *);
int ohci_intr(void *);
#if defined(__NetBSD__) || defined(__OpenBSD__)
int ohci_detach(ohci_softc_t *, int);
int ohci_activate(device_ptr_t, enum devact);
#endif
+Static void ohci_rhsc_enable(void *sc);
#define MS_TO_TICKS(ms) ((ms) * hz / 1000)
diff --git a/sys/dev/usb/ucom.c b/sys/dev/usb/ucom.c
index eb32bd3ad49..0c2a8d88ff6 100644
--- a/sys/dev/usb/ucom.c
+++ b/sys/dev/usb/ucom.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: ucom.c,v 1.10 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: ucom.c,v 1.40 2001/11/13 06:24:54 lukem Exp $ */
+/* $OpenBSD: ucom.c,v 1.11 2002/05/07 18:29:18 nate Exp $ */
+/* $NetBSD: ucom.c,v 1.39 2001/08/16 22:31:24 augustss Exp $ */
/*
* Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
@@ -85,16 +85,12 @@ int ucomdebug = 0;
#define UCOMUNIT_MASK 0x3ffff
#define UCOMDIALOUT_MASK 0x80000
#define UCOMCALLUNIT_MASK 0x40000
-
-#define LINESW(tp, func) ((tp)->t_linesw->func)
#endif
#if defined(__OpenBSD__)
#define UCOMUNIT_MASK 0x3f
#define UCOMDIALOUT_MASK 0x80
#define UCOMCALLUNIT_MASK 0x40
-
-#define LINESW(tp, func) (linesw[(tp)->t_line].func)
#endif
#define UCOMUNIT(x) (minor(x) & UCOMUNIT_MASK)
@@ -151,7 +147,7 @@ Static int ucomparam(struct tty *, struct termios *);
Static void ucomstart(struct tty *);
Static void ucom_shutdown(struct ucom_softc *);
Static int ucom_do_ioctl(struct ucom_softc *, u_long, caddr_t,
- int, usb_proc_ptr);
+ int, struct proc *);
Static void ucom_dtr(struct ucom_softc *, int);
Static void ucom_rts(struct ucom_softc *, int);
Static void ucom_break(struct ucom_softc *, int);
@@ -301,7 +297,7 @@ ucom_shutdown(struct ucom_softc *sc)
}
int
-ucomopen(dev_t dev, int flag, int mode, usb_proc_ptr p)
+ucomopen(dev_t dev, int flag, int mode, struct proc *p)
{
int unit = UCOMUNIT(dev);
usbd_status err;
@@ -467,7 +463,7 @@ ucomopen(dev_t dev, int flag, int mode, usb_proc_ptr p)
if (error)
goto bad;
- error = (*LINESW(tp, l_open))(dev, tp);
+ error = (*linesw[tp->t_line].l_open)(dev, tp);
if (error)
goto bad;
@@ -508,7 +504,7 @@ bad:
}
int
-ucomclose(dev_t dev, int flag, int mode, usb_proc_ptr p)
+ucomclose(dev_t dev, int flag, int mode, struct proc *p)
{
struct ucom_softc *sc = ucom_cd.cd_devs[UCOMUNIT(dev)];
struct tty *tp = sc->sc_tty;
@@ -519,7 +515,7 @@ ucomclose(dev_t dev, int flag, int mode, usb_proc_ptr p)
sc->sc_refcnt++;
- (*LINESW(tp, l_close))(tp, flag);
+ (*linesw[tp->t_line].l_close)(tp, flag);
ttyclose(tp);
#if defined(__NetBSD__)
@@ -555,7 +551,7 @@ ucomread(dev_t dev, struct uio *uio, int flag)
return (EIO);
sc->sc_refcnt++;
- error = (*LINESW(tp, l_read))(tp, uio, flag);
+ error = ((*linesw[tp->t_line].l_read)(tp, uio, flag));
if (--sc->sc_refcnt < 0)
usb_detach_wakeup(USBDEV(sc->sc_dev));
return (error);
@@ -572,15 +568,18 @@ ucomwrite(dev_t dev, struct uio *uio, int flag)
return (EIO);
sc->sc_refcnt++;
- error = (*LINESW(tp, l_write))(tp, uio, flag);
+ error = ((*linesw[tp->t_line].l_write)(tp, uio, flag));
if (--sc->sc_refcnt < 0)
usb_detach_wakeup(USBDEV(sc->sc_dev));
return (error);
}
-#if defined(__NetBSD__)
+#if 0
int
-ucompoll(dev_t dev, int events, usb_proc_ptr p)
+ucompoll(dev, events, p)
+ dev_t dev;
+ int events;
+ struct proc *p;
{
struct ucom_softc *sc = ucom_cd.cd_devs[UCOMUNIT(dev)];
struct tty *tp = sc->sc_tty;
@@ -590,7 +589,7 @@ ucompoll(dev_t dev, int events, usb_proc_ptr p)
return (EIO);
sc->sc_refcnt++;
- error = (*LINESW(tp, l_poll))(tp, events, p);
+ error = ((*linesw[tp->t_line].l_poll)(tp, events, p));
if (--sc->sc_refcnt < 0)
usb_detach_wakeup(USBDEV(sc->sc_dev));
return (error);
@@ -607,7 +606,7 @@ ucomtty(dev_t dev)
}
int
-ucomioctl(dev_t dev, u_long cmd, caddr_t data, int flag, usb_proc_ptr p)
+ucomioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
{
struct ucom_softc *sc = ucom_cd.cd_devs[UCOMUNIT(dev)];
int error;
@@ -621,7 +620,7 @@ ucomioctl(dev_t dev, u_long cmd, caddr_t data, int flag, usb_proc_ptr p)
Static int
ucom_do_ioctl(struct ucom_softc *sc, u_long cmd, caddr_t data,
- int flag, usb_proc_ptr p)
+ int flag, struct proc *p)
{
struct tty *tp = sc->sc_tty;
int error;
@@ -632,7 +631,7 @@ ucom_do_ioctl(struct ucom_softc *sc, u_long cmd, caddr_t data,
DPRINTF(("ucomioctl: cmd=0x%08lx\n", cmd));
- error = (*LINESW(tp, l_ioctl))(tp, cmd, data, flag, p);
+ error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
if (error >= 0)
return (error);
@@ -806,7 +805,7 @@ ucom_status_change(struct ucom_softc *sc)
sc->sc_methods->ucom_get_status(sc->sc_parent, sc->sc_portno,
&sc->sc_lsr, &sc->sc_msr);
if (ISSET((sc->sc_msr ^ old_msr), UMSR_DCD))
- (*LINESW(tp, l_modem))(tp,
+ (*linesw[tp->t_line].l_modem)(tp,
ISSET(sc->sc_msr, UMSR_DCD));
} else {
sc->sc_lsr = 0;
@@ -867,7 +866,7 @@ ucomparam(struct tty *tp, struct termios *t)
* explicit request.
*/
DPRINTF(("ucomparam: l_modem\n"));
- (void) (*LINESW(tp, l_modem))(tp, 1 /* XXX carrier */ );
+ (void) (*linesw[tp->t_line].l_modem)(tp, 1 /* XXX carrier */ );
#if 0
XXX what if the hardware is not open
@@ -1034,7 +1033,7 @@ ucomwritecb(usbd_xfer_handle xfer, usbd_private_handle p, usbd_status status)
CLR(tp->t_state, TS_FLUSH);
else
ndflush(&tp->t_outq, cc);
- (*LINESW(tp, l_start))(tp);
+ (*linesw[tp->t_line].l_start)(tp);
splx(s);
return;
@@ -1068,7 +1067,7 @@ 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;
- int (*rint)(int c, struct tty *tp) = LINESW(tp, l_rint);
+ int (*rint)(int c, struct tty *tp) = linesw[tp->t_line].l_rint;
usbd_status err;
u_int32_t cc;
u_char *cp;
@@ -1169,9 +1168,9 @@ ucomsubmatch(struct device *parent, void *match, void *aux)
ucomsubmatch(struct device *parent, struct cfdata *cf, void *aux)
#endif
{
- struct ucom_attach_args *uca = aux;
+ struct ucom_attach_args *uca = aux;
#if defined(__OpenBSD__)
- struct cfdata *cf = match;
+ struct cfdata *cf = match;
#endif
if (uca->portno != UCOM_UNK_PORTNO &&
diff --git a/sys/dev/usb/ucomvar.h b/sys/dev/usb/ucomvar.h
index 0e4e9b40a7a..3899af5c7bd 100644
--- a/sys/dev/usb/ucomvar.h
+++ b/sys/dev/usb/ucomvar.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: ucomvar.h,v 1.9 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: ucomvar.h,v 1.10 2001/12/31 12:15:21 augustss Exp $ */
+/* $OpenBSD: ucomvar.h,v 1.10 2002/05/07 18:29:18 nate Exp $ */
+/* $NetBSD: ucomvar.h,v 1.9 2001/01/23 21:56:17 augustss Exp $ */
/*
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -56,7 +56,7 @@ struct ucom_methods {
#define UCOM_SET_BREAK 3
int (*ucom_param)(void *sc, int portno, struct termios *);
int (*ucom_ioctl)(void *sc, int portno, u_long cmd,
- caddr_t data, int flag, usb_proc_ptr p);
+ caddr_t data, int flag, struct proc *p);
int (*ucom_open)(void *sc, int portno);
void (*ucom_close)(void *sc, int portno);
void (*ucom_read)(void *sc, int portno, u_char **ptr, u_int32_t *count);
@@ -105,11 +105,10 @@ struct ucom_attach_args {
void *arg;
};
-#if defined(__NetBSD__)
-int ucomsubmatch(struct device *, struct cfdata *, void *);
+int ucomprint(void *aux, const char *pnp);
+#if defined(__OpenBSD__)
+int ucomsubmatch(struct device *parent, void *cf, void *aux);
#else
-int ucomsubmatch(struct device *, void *, void *);
+int ucomsubmatch(struct device *parent, struct cfdata *cf, void *aux);
#endif
-
-int ucomprint(void *aux, const char *pnp);
void ucom_status_change(struct ucom_softc *);
diff --git a/sys/dev/usb/udsbr.c b/sys/dev/usb/udsbr.c
deleted file mode 100644
index dc7a35abb09..00000000000
--- a/sys/dev/usb/udsbr.c
+++ /dev/null
@@ -1,279 +0,0 @@
-/* $OpenBSD: udsbr.c,v 1.1 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: udsbr.c,v 1.6 2002/02/12 10:51:49 tron Exp $ */
-
-/*
- * Copyright (c) 2002 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.
- */
-
-/*
- * Driver for the D-Link DSB-R100 FM radio.
- * I apologize for the magic hex constants, but this is what happens
- * when you have to reverse engineer the driver.
- * Parts of the code borrowed from Linux and parts from Warner Losh's
- * FreeBSD driver.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/device.h>
-
-#include <sys/radioio.h>
-#include <dev/radio_if.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-
-#include <dev/usb/usbdevs.h>
-
-#ifdef UDSBR_DEBUG
-#define DPRINTF(x) if (udsbrdebug) logprintf x
-#define DPRINTFN(n,x) if (udsbrdebug>(n)) logprintf x
-int udsbrdebug = 0;
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-#define UDSBR_CONFIG_NO 1
-
-Static int udsbr_get_info(void *, struct radio_info *);
-Static int udsbr_set_info(void *, struct radio_info *);
-
-struct radio_hw_if udsbr_hw_if = {
- NULL, /* open */
- NULL, /* close */
- udsbr_get_info,
- udsbr_set_info,
- NULL
-};
-
-struct udsbr_softc {
- USBBASEDEVICE sc_dev;
- usbd_device_handle sc_udev;
-
- char sc_mute;
- char sc_vol;
- u_int32_t sc_freq;
-
- struct device *sc_child;
-
- char sc_dying;
-};
-
-Static int udsbr_req(struct udsbr_softc *sc, int ureq, int value,
- int index);
-Static void udsbr_start(struct udsbr_softc *sc);
-Static void udsbr_stop(struct udsbr_softc *sc);
-Static void udsbr_setfreq(struct udsbr_softc *sc, int freq);
-Static int udsbr_status(struct udsbr_softc *sc);
-
-USB_DECLARE_DRIVER(udsbr);
-
-USB_MATCH(udsbr)
-{
- USB_MATCH_START(udsbr, uaa);
-
- DPRINTFN(50,("udsbr_match\n"));
-
- if (uaa->iface != NULL)
- return (UMATCH_NONE);
-
- if (uaa->vendor != USB_VENDOR_CYPRESS ||
- uaa->product != USB_PRODUCT_CYPRESS_FMRADIO)
- return (UMATCH_NONE);
- return (UMATCH_VENDOR_PRODUCT);
-}
-
-USB_ATTACH(udsbr)
-{
- USB_ATTACH_START(udsbr, sc, uaa);
- usbd_device_handle dev = uaa->device;
- char devinfo[1024];
- usbd_status err;
-
- DPRINTFN(10,("udsbr_attach: sc=%p\n", sc));
-
- usbd_devinfo(dev, 0, devinfo);
- USB_ATTACH_SETUP;
- printf("%s: %s\n", USBDEVNAME(sc->sc_dev), devinfo);
-
- err = usbd_set_config_no(dev, UDSBR_CONFIG_NO, 1);
- if (err) {
- printf("%s: setting config no failed\n",
- USBDEVNAME(sc->sc_dev));
- USB_ATTACH_ERROR_RETURN;
- }
-
- sc->sc_udev = dev;
-
- DPRINTFN(10, ("udsbr_attach: %p\n", sc->sc_udev));
-
- usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
- USBDEV(sc->sc_dev));
-
- sc->sc_child = radio_attach_mi(&udsbr_hw_if, sc, USBDEV(sc->sc_dev));
-
- USB_ATTACH_SUCCESS_RETURN;
-}
-
-USB_DETACH(udsbr)
-{
- USB_DETACH_START(udsbr, sc);
- int rv = 0;
-
- if (sc->sc_child != NULL)
- rv = config_detach(sc->sc_child, flags);
-
- usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
- USBDEV(sc->sc_dev));
-
- return (rv);
-}
-
-int
-udsbr_activate(device_ptr_t self, enum devact act)
-{
- struct udsbr_softc *sc = (struct udsbr_softc *)self;
- int rv = 0;
-
- switch (act) {
- case DVACT_ACTIVATE:
- return (EOPNOTSUPP);
- break;
-
- case DVACT_DEACTIVATE:
- sc->sc_dying = 1;
- if (sc->sc_child != NULL)
- rv = config_deactivate(sc->sc_child);
- break;
- }
- return (rv);
-}
-
-int
-udsbr_req(struct udsbr_softc *sc, int ureq, int value, int index)
-{
- usb_device_request_t req;
- usbd_status err;
- u_char data;
-
- DPRINTFN(1,("udsbr_req: ureq=0x%02x value=0x%04x index=0x%04x\n",
- ureq, value, index));
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = ureq;
- USETW(req.wValue, value);
- USETW(req.wIndex, index);
- USETW(req.wLength, 1);
- err = usbd_do_request(sc->sc_udev, &req, &data);
- if (err) {
- printf("%s: request failed err=%d\n", USBDEVNAME(sc->sc_dev),
- err);
- }
- return !(data & 1);
-}
-
-void
-udsbr_start(struct udsbr_softc *sc)
-{
- (void)udsbr_req(sc, 0x00, 0x0000, 0x00c7);
- (void)udsbr_req(sc, 0x02, 0x0001, 0x0000);
-}
-
-void
-udsbr_stop(struct udsbr_softc *sc)
-{
- (void)udsbr_req(sc, 0x00, 0x0016, 0x001c);
- (void)udsbr_req(sc, 0x02, 0x0000, 0x0000);
-}
-
-void
-udsbr_setfreq(struct udsbr_softc *sc, int freq)
-{
- DPRINTF(("udsbr_setfreq: setfreq=%d\n", freq));
- /*
- * 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.
- */
- freq = (freq * 1000 + 10700001) / 12500;
- (void)udsbr_req(sc, 0x01, (freq >> 8) & 0xff, freq & 0xff);
- (void)udsbr_req(sc, 0x00, 0x0096, 0x00b7);
- usbd_delay_ms(sc->sc_udev, 240); /* wait for signal to settle */
-}
-
-int
-udsbr_status(struct udsbr_softc *sc)
-{
- return (udsbr_req(sc, 0x00, 0x0000, 0x0024));
-}
-
-
-int
-udsbr_get_info(void *v, struct radio_info *ri)
-{
- struct udsbr_softc *sc = v;
-
- ri->mute = sc->sc_mute;
- ri->volume = sc->sc_vol ? 255 : 0;
- ri->caps = RADIO_CAPS_DETECT_STEREO;
- ri->rfreq = 0;
- ri->lock = 0;
- ri->freq = sc->sc_freq;
- ri->info = udsbr_status(sc) ? RADIO_INFO_STEREO : 0;
-
- return (0);
-}
-
-int
-udsbr_set_info(void *v, struct radio_info *ri)
-{
- struct udsbr_softc *sc = v;
-
- sc->sc_mute = ri->mute != 0;
- sc->sc_vol = ri->volume != 0;
- sc->sc_freq = ri->freq;
- udsbr_setfreq(sc, sc->sc_freq);
-
- if (sc->sc_mute || sc->sc_vol == 0)
- udsbr_stop(sc);
- else
- udsbr_start(sc);
-
- return (0);
-}
diff --git a/sys/dev/usb/uftdi.c b/sys/dev/usb/uftdi.c
index a86b3785fc4..f24ac10e7ea 100644
--- a/sys/dev/usb/uftdi.c
+++ b/sys/dev/usb/uftdi.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: uftdi.c,v 1.4 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: uftdi.c,v 1.9 2001/12/17 14:34:37 ichiro Exp $ */
+/* $OpenBSD: uftdi.c,v 1.5 2002/05/07 18:29:18 nate Exp $ */
+/* $NetBSD: uftdi.c,v 1.6 2001/01/23 21:56:17 augustss Exp $ */
/*
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -95,19 +95,15 @@ struct uftdi_softc {
device_ptr_t sc_subdev;
u_char sc_dying;
-
- 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 void uftdi_read(void *sc, int portno, u_char **ptr,u_int32_t *count);
Static void uftdi_write(void *sc, int portno, u_char *to, u_char *from,
u_int32_t *count);
-Static void uftdi_break(void *sc, int portno, int onoff);
struct ucom_methods uftdi_methods = {
uftdi_get_status,
@@ -380,7 +376,7 @@ uftdi_set(void *vsc, int portno, int reg, int onoff)
ctl = onoff ? FTDI_SIO_SET_RTS_HIGH : FTDI_SIO_SET_RTS_LOW;
break;
case UCOM_SET_BREAK:
- uftdi_break(sc, portno, onoff);
+ /* XXX how do we set break? */
return;
default:
return;
@@ -460,8 +456,6 @@ uftdi_param(void *vsc, int portno, struct termios *t)
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);
@@ -490,27 +484,3 @@ uftdi_get_status(void *vsc, int portno, u_char *lsr, u_char *msr)
if (lsr != NULL)
*lsr = sc->sc_lsr;
}
-
-void
-uftdi_break(void *vsc, int portno, int onoff)
-{
- struct uftdi_softc *sc = 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(sc->sc_udev, &req, NULL);
-}
diff --git a/sys/dev/usb/uftdireg.h b/sys/dev/usb/uftdireg.h
index ce2dfb2ea78..03a953ce474 100644
--- a/sys/dev/usb/uftdireg.h
+++ b/sys/dev/usb/uftdireg.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: uftdireg.h,v 1.4 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: uftdireg.h,v 1.4 2001/12/17 14:31:02 ichiro Exp $ */
+/* $OpenBSD: uftdireg.h,v 1.5 2002/05/07 18:29:18 nate Exp $ */
+/* $NetBSD: uftdireg.h,v 1.3 2001/06/12 14:59:28 wiz Exp $ */
/*
* Definitions for the FTDI USB Single Port Serial Converter -
@@ -121,7 +121,6 @@ enum {
#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)
/*
diff --git a/sys/dev/usb/ugen.c b/sys/dev/usb/ugen.c
index 6ba08f1ab6e..ab1996330d9 100644
--- a/sys/dev/usb/ugen.c
+++ b/sys/dev/usb/ugen.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: ugen.c,v 1.19 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: ugen.c,v 1.58 2002/02/20 20:30:12 christos Exp $ */
+/* $OpenBSD: ugen.c,v 1.20 2002/05/07 18:29:18 nate Exp $ */
+/* $NetBSD: ugen.c,v 1.49 2001/10/24 22:31:04 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/ugen.c,v 1.26 1999/11/17 22:33:41 n_hibma Exp $ */
/*
@@ -20,8 +20,8 @@
* 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.
+ * 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.
@@ -150,16 +150,16 @@ Static struct cdevsw ugen_cdevsw = {
};
#endif
-Static void ugenintr(usbd_xfer_handle xfer, usbd_private_handle addr,
+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, usb_proc_ptr);
+Static int ugen_do_ioctl(struct ugen_softc *, int, u_long,
+ caddr_t, int, struct proc *);
Static int ugen_set_config(struct ugen_softc *sc, int configno);
-Static usb_config_descriptor_t *ugen_get_cdesc(struct ugen_softc *sc,
+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);
@@ -201,7 +201,7 @@ USB_ATTACH(ugen)
/* First set configuration index 0, the default one for ugen. */
err = usbd_set_config_index(udev, 0, 0);
if (err) {
- printf("%s: setting configuration index 0 failed\n",
+ printf("%s: setting configuration index 0 failed\n",
USBDEVNAME(sc->sc_dev));
sc->sc_dying = 1;
USB_ATTACH_ERROR_RETURN;
@@ -211,7 +211,7 @@ USB_ATTACH(ugen)
/* Set up all the local state for this configuration. */
err = ugen_set_config(sc, conf);
if (err) {
- printf("%s: setting configuration %d failed\n",
+ printf("%s: setting configuration %d failed\n",
USBDEVNAME(sc->sc_dev), conf);
sc->sc_dying = 1;
USB_ATTACH_ERROR_RETURN;
@@ -247,19 +247,6 @@ ugen_set_config(struct ugen_softc *sc, int configno)
DPRINTFN(1,("ugen_set_config: %s to configno %d, sc=%p\n",
USBDEVNAME(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",
- USBDEVNAME(sc->sc_dev), endptno));
- return (USBD_IN_USE);
- }
-
/* Avoid setting the current value. */
if (usbd_get_config_descriptor(dev)->bConfigurationValue != configno) {
err = usbd_set_config_no(dev, configno, 1);
@@ -285,7 +272,7 @@ ugen_set_config(struct ugen_softc *sc, int configno)
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",
+ "(%d,%d), sce=%p\n",
endptno, endpt, UE_GET_ADDR(endpt),
UE_GET_DIR(endpt), sce));
sce->sc = sc;
@@ -297,7 +284,7 @@ ugen_set_config(struct ugen_softc *sc, int configno)
}
int
-ugenopen(dev_t dev, int flag, int mode, usb_proc_ptr p)
+ugenopen(dev_t dev, int flag, int mode, struct proc *p)
{
struct ugen_softc *sc;
int unit = UGENUNIT(dev);
@@ -312,7 +299,7 @@ ugenopen(dev_t dev, int flag, int mode, usb_proc_ptr p)
USB_GET_SC_OPEN(ugen, unit, sc);
- DPRINTFN(5, ("ugenopen: flag=%d, mode=%d, unit=%d endpt=%d\n",
+ DPRINTFN(5, ("ugenopen: flag=%d, mode=%d, unit=%d endpt=%d\n",
flag, mode, unit, endpt));
if (sc == NULL || sc->sc_dying)
@@ -343,7 +330,7 @@ ugenopen(dev_t dev, int flag, int mode, usb_proc_ptr p)
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",
+ DPRINTFN(5, ("ugenopen: sc=%p, endpt=%d, dir=%d, sce=%p\n",
sc, endpt, dir, sce));
edesc = sce->edesc;
switch (edesc->bmAttributes & UE_XFERTYPE) {
@@ -352,14 +339,14 @@ ugenopen(dev_t dev, int flag, int mode, usb_proc_ptr p)
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",
+ DPRINTFN(5, ("ugenopen: intr endpt=%d,isize=%d\n",
endpt, isize));
- if (clalloc(&sce->q, UGEN_IBSIZE, 0) == -1)
- return (ENOMEM);
- err = usbd_open_pipe_intr(sce->iface,
- edesc->bEndpointAddress,
- USBD_SHORT_XFER_OK, &sce->pipeh, sce,
- sce->ibuf, isize, ugenintr,
+ if (clalloc(&sce->q, UGEN_IBSIZE, 0) == -1)
+ return (ENOMEM);
+ err = usbd_open_pipe_intr(sce->iface,
+ edesc->bEndpointAddress,
+ USBD_SHORT_XFER_OK, &sce->pipeh, sce,
+ sce->ibuf, isize, ugenintr,
USBD_DEFAULT_INTERVAL);
if (err) {
free(sce->ibuf, M_USBDEV);
@@ -369,7 +356,7 @@ ugenopen(dev_t dev, int flag, int mode, usb_proc_ptr p)
DPRINTFN(5, ("ugenopen: interrupt open done\n"));
break;
case UE_BULK:
- err = usbd_open_pipe(sce->iface,
+ err = usbd_open_pipe(sce->iface,
edesc->bEndpointAddress, 0, &sce->pipeh);
if (err)
return (EIO);
@@ -384,7 +371,7 @@ ugenopen(dev_t dev, int flag, int mode, usb_proc_ptr p)
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",
+ DPRINTFN(5, ("ugenopen: isoc endpt=%d, isize=%d\n",
endpt, isize));
err = usbd_open_pipe(sce->iface,
edesc->bEndpointAddress, 0, &sce->pipeh);
@@ -421,7 +408,6 @@ ugenopen(dev_t dev, int flag, int mode, usb_proc_ptr p)
usbd_free_xfer(sce->isoreqs[i].xfer);
return (ENOMEM);
case UE_CONTROL:
- sce->timeout = USBD_DEFAULT_TIMEOUT;
return (EINVAL);
}
}
@@ -430,7 +416,7 @@ ugenopen(dev_t dev, int flag, int mode, usb_proc_ptr p)
}
int
-ugenclose(dev_t dev, int flag, int mode, usb_proc_ptr p)
+ugenclose(dev_t dev, int flag, int mode, struct proc *p)
{
int endpt = UGENENDPOINT(dev);
struct ugen_softc *sc;
@@ -462,30 +448,31 @@ ugenclose(dev_t dev, int flag, int mode, usb_proc_ptr p)
sce = &sc->sc_endpoints[endpt][dir];
if (sce == NULL || sce->pipeh == NULL)
continue;
- DPRINTFN(5, ("ugenclose: endpt=%d dir=%d sce=%p\n",
+ 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);
- clfree(&sce->q);
- break;
- case UE_ISOCHRONOUS:
- for (i = 0; i < UGEN_NISOREQS; ++i)
- usbd_free_xfer(sce->isoreqs[i].xfer);
-
- default:
- break;
+ switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
+ case UE_INTERRUPT:
+ ndflush(&sce->q, sce->q.c_cc);
+ clfree(&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;
clfree(&sce->q);
+
}
}
sc->sc_is_open[endpt] = 0;
@@ -571,8 +558,8 @@ ugen_do_read(struct ugen_softc *sc, int endpt, struct uio *uio, int flag)
tn = n;
err = usbd_bulk_transfer(
xfer, sce->pipeh,
- sce->state & UGEN_SHORT_OK ?
- USBD_SHORT_XFER_OK : 0,
+ sce->state & UGEN_SHORT_OK ?
+ USBD_SHORT_XFER_OK : 0,
sce->timeout, buf, &tn, "ugenrb");
if (err) {
if (err == USBD_INTERRUPTED)
@@ -690,7 +677,7 @@ ugen_do_write(struct ugen_softc *sc, int endpt, struct uio *uio, int flag)
if (error)
break;
DPRINTFN(1, ("ugenwrite: transfer %d bytes\n", n));
- err = usbd_bulk_transfer(xfer, sce->pipeh, 0,
+ err = usbd_bulk_transfer(xfer, sce->pipeh, 0,
sce->timeout, buf, &n,"ugenwb");
if (err) {
if (err == USBD_INTERRUPTED)
@@ -811,15 +798,14 @@ ugenintr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status)
if (status != USBD_NORMAL_COMPLETION) {
DPRINTF(("ugenintr: status=%d\n", status));
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall_async(sce->pipeh);
+ 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",
+ 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]));
@@ -835,7 +821,7 @@ 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,
+ugen_isoc_rintr(usbd_xfer_handle xfer, usbd_private_handle addr,
usbd_status status)
{
struct isoreq *req = addr;
@@ -973,8 +959,7 @@ ugen_get_cdesc(struct ugen_softc *sc, int index, int *lenp)
if (lenp)
*lenp = len;
cdesc = malloc(len, M_TEMP, M_WAITOK);
- err = usbd_get_config_desc_full(sc->sc_udev, index, cdesc,
- len);
+ err = usbd_get_config_desc_full(sc->sc_udev, index, cdesc,len);
if (err) {
free(cdesc, M_TEMP);
return (0);
@@ -997,7 +982,7 @@ ugen_get_alt_index(struct ugen_softc *sc, int ifaceidx)
Static int
ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd,
- caddr_t addr, int flag, usb_proc_ptr p)
+ caddr_t addr, int flag, struct proc *p)
{
struct ugen_endpoint *sce;
usbd_status err;
@@ -1021,12 +1006,18 @@ ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd,
/* All handled in the upper FS layer. */
return (0);
case USB_SET_SHORT_XFER:
+ /* This flag only affects read */
if (endpt == USB_CONTROL_ENDPOINT)
return (EINVAL);
- /* This flag only affects read */
sce = &sc->sc_endpoints[endpt][IN];
- if (sce == NULL || sce->pipeh == NULL)
+ if (sce == NULL)
return (EINVAL);
+#ifdef DIAGNOSTIC
+ if (sce->pipeh == NULL) {
+ printf("ugenioctl: USB_SET_SHORT_XFER, no pipe\n");
+ return (EIO);
+ }
+#endif
if (*(int *)addr)
sce->state |= UGEN_SHORT_OK;
else
@@ -1034,12 +1025,14 @@ ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd,
return (0);
case USB_SET_TIMEOUT:
sce = &sc->sc_endpoints[endpt][IN];
- if (sce == NULL
- /* XXX this shouldn't happen, but the distinction between
- input and output pipes isn't clear enough.
- || sce->pipeh == NULL */
- )
+ if (sce == NULL)
return (EINVAL);
+#ifdef DIAGNOSTIC
+ if (sce->pipeh == NULL) {
+ printf("ugenioctl: USB_SET_TIMEOUT, no pipe\n");
+ return (EIO);
+ }
+#endif
sce->timeout = *(int *)addr;
return (0);
default:
@@ -1065,19 +1058,13 @@ ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd,
if (!(flag & FWRITE))
return (EPERM);
err = ugen_set_config(sc, *(int *)addr);
- switch (err) {
- case USBD_NORMAL_COMPLETION:
- break;
- case USBD_IN_USE:
- return (EBUSY);
- default:
+ if (err)
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);
+ err = usbd_device2interface_handle(sc->sc_udev,
+ ai->uai_interface_index, &iface);
if (err)
return (EINVAL);
idesc = usbd_get_interface_descriptor(iface);
@@ -1089,12 +1076,11 @@ ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd,
if (!(flag & FWRITE))
return (EPERM);
ai = (struct usb_alt_interface *)addr;
- err = usbd_device2interface_handle(sc->sc_udev,
- ai->uai_interface_index, &iface);
+ 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);
+ err = ugen_set_interface(sc, ai->uai_interface_index, ai->uai_alt_no);
if (err)
return (EINVAL);
break;
@@ -1108,8 +1094,7 @@ ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd,
free(cdesc, M_TEMP);
return (EINVAL);
}
- ai->uai_alt_no = usbd_get_no_alts(cdesc,
- idesc->bInterfaceNumber);
+ ai->uai_alt_no = usbd_get_no_alts(cdesc, idesc->bInterfaceNumber);
free(cdesc, M_TEMP);
break;
case USB_GET_DEVICE_DESC:
@@ -1152,7 +1137,7 @@ ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd,
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,
+ edesc = usbd_find_edesc(cdesc, ed->ued_interface_index,
alt, ed->ued_endpoint_index);
if (edesc == NULL) {
free(cdesc, M_TEMP);
@@ -1187,7 +1172,7 @@ ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd,
}
case USB_GET_STRING_DESC:
si = (struct usb_string_desc *)addr;
- err = usbd_get_string_desc(sc->sc_udev, si->usd_string_index,
+ err = usbd_get_string_desc(sc->sc_udev, si->usd_string_index,
si->usd_language_id, &si->usd_desc);
if (err)
return (EINVAL);
@@ -1224,7 +1209,7 @@ ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd,
uio.uio_offset = 0;
uio.uio_segflg = UIO_USERSPACE;
uio.uio_rw =
- ur->ucr_request.bmRequestType & UT_READ ?
+ ur->ucr_request.bmRequestType & UT_READ ?
UIO_READ : UIO_WRITE;
uio.uio_procp = p;
ptr = malloc(len, M_TEMP, M_WAITOK);
@@ -1234,9 +1219,8 @@ ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd,
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);
+ err = usbd_do_request_flags(sc->sc_udev, &ur->ucr_request,
+ ptr, ur->ucr_flags, &ur->ucr_actlen);
if (err) {
error = EIO;
goto ret;
@@ -1264,7 +1248,7 @@ ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd,
}
int
-ugenioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, usb_proc_ptr p)
+ugenioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
{
int endpt = UGENENDPOINT(dev);
struct ugen_softc *sc;
@@ -1280,7 +1264,7 @@ ugenioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, usb_proc_ptr p)
}
int
-ugenpoll(dev_t dev, int events, usb_proc_ptr p)
+ugenpoll(dev_t dev, int events, struct proc *p)
{
struct ugen_softc *sc;
struct ugen_endpoint *sce;
@@ -1325,12 +1309,12 @@ ugenpoll(dev_t dev, int events, usb_proc_ptr p)
}
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 &
+ revents |= events &
(POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM);
break;
default:
diff --git a/sys/dev/usb/uhci.c b/sys/dev/usb/uhci.c
index 090f26f99f8..a233ff1b502 100644
--- a/sys/dev/usb/uhci.c
+++ b/sys/dev/usb/uhci.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: uhci.c,v 1.24 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: uhci.c,v 1.158 2002/03/17 18:02:53 augustss Exp $ */
+/* $OpenBSD: uhci.c,v 1.25 2002/05/07 18:29:18 nate Exp $ */
+/* $NetBSD: uhci.c,v 1.142 2001/10/25 02:08:13 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/uhci.c,v 1.33 1999/11/17 22:33:41 n_hibma Exp $ */
/*
@@ -174,10 +174,10 @@ Static void uhci_enter_ctl_q(uhci_softc_t *, uhci_soft_qh_t *,
Static void uhci_exit_ctl_q(uhci_softc_t *, uhci_soft_qh_t *);
#endif
-Static void uhci_free_std_chain(uhci_softc_t *,
+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, usb_dma_t *,
+ uhci_softc_t *, int, int, u_int16_t, usb_dma_t *,
uhci_soft_td_t **, uhci_soft_td_t **);
Static void uhci_poll_hub(void *);
Static void uhci_waitintr(uhci_softc_t *, usbd_xfer_handle);
@@ -187,7 +187,6 @@ Static void uhci_idone(uhci_intr_info_t *);
Static void uhci_abort_xfer(usbd_xfer_handle, usbd_status status);
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 *);
@@ -250,8 +249,8 @@ 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,
+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);
@@ -302,7 +301,7 @@ struct usbd_bus_methods uhci_bus_methods = {
uhci_freex,
};
-struct usbd_pipe_methods uhci_root_ctrl_methods = {
+struct usbd_pipe_methods uhci_root_ctrl_methods = {
uhci_root_ctrl_transfer,
uhci_root_ctrl_start,
uhci_root_ctrl_abort,
@@ -311,7 +310,7 @@ struct usbd_pipe_methods uhci_root_ctrl_methods = {
uhci_root_ctrl_done,
};
-struct usbd_pipe_methods uhci_root_intr_methods = {
+struct usbd_pipe_methods uhci_root_intr_methods = {
uhci_root_intr_transfer,
uhci_root_intr_start,
uhci_root_intr_abort,
@@ -367,7 +366,7 @@ 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(UHCI_DEBUG)
+#if defined(DIAGNOSTIC) || defined(UHCI_DEBUG)
if (le32toh(pqh->qh.qh_hlink) & UHCI_PTR_T) {
printf("uhci_find_prev_qh: QH not found\n");
return (NULL);
@@ -402,12 +401,13 @@ uhci_init(uhci_softc_t *sc)
uhci_dumpregs(sc);
#endif
+ uhci_run(sc, 0); /* stop the controller */
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,
+ err = usb_allocmem(&sc->sc_bus,
UHCI_FRAMELIST_COUNT * sizeof(uhci_physaddr_t),
UHCI_FRAMELIST_ALIGN, &sc->sc_dma);
if (err)
@@ -416,7 +416,7 @@ uhci_init(uhci_softc_t *sc)
UWRITE2(sc, UHCI_FRNUM, 0); /* set frame number to 0 */
UWRITE4(sc, UHCI_FLBASEADDR, DMAADDR(&sc->sc_dma)); /* 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.
@@ -470,7 +470,7 @@ uhci_init(uhci_softc_t *sc)
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.
@@ -493,8 +493,8 @@ uhci_init(uhci_softc_t *sc)
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;
+ for (j = i;
+ j < UHCI_FRAMELIST_COUNT;
j += UHCI_VFRAMELIST_COUNT)
sc->sc_pframes[j] = htole32(std->physaddr);
}
@@ -516,7 +516,7 @@ uhci_init(uhci_softc_t *sc)
#endif
DPRINTFN(1,("uhci_init: enabling\n"));
- UWRITE2(sc, UHCI_INTR, UHCI_INTR_TOCRCIE | UHCI_INTR_RIE |
+ 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 */
@@ -552,7 +552,7 @@ uhci_detach(struct uhci_softc *sc, int flags)
if (sc->sc_child != NULL)
rv = config_detach(sc->sc_child, flags);
-
+
if (rv != 0)
return (rv);
@@ -568,7 +568,7 @@ uhci_detach(struct uhci_softc *sc, int flags)
break;
SIMPLEQ_REMOVE_HEAD(&sc->sc_free_xfers, xfer, next);
free(xfer, M_USB);
- }
+ }
/* XXX free other data structures XXX */
@@ -582,10 +582,10 @@ uhci_allocm(struct usbd_bus *bus, usb_dma_t *dma, u_int32_t size)
struct uhci_softc *sc = (struct uhci_softc *)bus;
u_int32_t n;
- /*
+ /*
* XXX
* Since we are allocating a buffer we can assume that we will
- * need TDs for it. Since we don't want to allocate those from
+ * need TDs for it. Since we don't want to alolocate those from
* an interrupt context, we allocate them here and free them again.
* This is no guarantee that we'll get the TDs next time...
*/
@@ -594,8 +594,7 @@ uhci_allocm(struct usbd_bus *bus, usb_dma_t *dma, u_int32_t size)
u_int32_t i;
uhci_soft_td_t **stds;
DPRINTF(("uhci_allocm: get %d TDs\n", n));
- stds = malloc(sizeof(uhci_soft_td_t *) * n, M_TEMP,
- M_NOWAIT);
+ stds = malloc(sizeof(uhci_soft_td_t *) * n, M_TEMP, M_NOWAIT);
if (stds == NULL)
panic("uhci_allocm");
memset(stds, 0, sizeof(uhci_soft_td_t *) * n);
@@ -694,7 +693,7 @@ uhci_power(int why, void *v)
s = splhardusb();
cmd = UREAD2(sc, UHCI_CMD);
- DPRINTF(("uhci_power: sc=%p, why=%d (was %d), cmd=0x%x\n",
+ DPRINTF(("uhci_power: sc=%p, why=%d (was %d), cmd=0x%x\n",
sc, why, sc->sc_suspend, cmd));
switch (why) {
@@ -740,7 +739,7 @@ uhci_power(int why, void *v)
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 |
+ UWRITE2(sc, UHCI_INTR, UHCI_INTR_TOCRCIE | UHCI_INTR_RIE |
UHCI_INTR_IOCE | UHCI_INTR_SPIE); /* re-enable intrs */
uhci_run(sc, 1); /* and start traffic again */
usb_delay_ms(&sc->sc_bus, USB_RESUME_RECOVERY);
@@ -793,9 +792,9 @@ uhci_dump_td(uhci_soft_td_t *p)
(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",
+ bitmask_snprintf((int)le32toh(p->td.td_link), "\20\1T\2Q\3VF",
sbuf, sizeof(sbuf));
- bitmask_snprintf((u_int32_t)le32toh(p->td.td_status),
+ bitmask_snprintf((int)le32toh(p->td.td_status),
"\20\22BITSTUFF\23CRCTO\24NAK\25BABBLE\26DBUFFER\27"
"STALLED\30ACTIVE\31IOC\32ISO\33LS\36SPD",
sbuf2, sizeof(sbuf2));
@@ -892,7 +891,7 @@ 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
@@ -925,8 +924,8 @@ uhci_dump_ii(uhci_intr_info_t *ii)
}
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,
+ 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,
@@ -1011,7 +1010,7 @@ uhci_add_loop(uhci_softc_t *sc) {
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 =
+ sc->sc_last_qh->qh.qh_hlink =
htole32(sc->sc_hctl_start->physaddr | UHCI_PTR_QH);
}
}
@@ -1074,7 +1073,7 @@ uhci_remove_hs_ctrl(uhci_softc_t *sc, uhci_soft_qh_t *sqh)
}
pqh = uhci_find_prev_qh(sc->sc_hctl_start, sqh);
- pqh->hlink = sqh->hlink;
+ pqh->hlink = sqh->hlink;
pqh->qh.qh_hlink = sqh->qh.qh_hlink;
delay(UHCI_QH_REMOVE_DELAY);
if (sc->sc_hctl_end == sqh)
@@ -1091,9 +1090,9 @@ uhci_add_ls_ctrl(uhci_softc_t *sc, uhci_soft_qh_t *sqh)
DPRINTFN(10, ("uhci_add_ls_ctrl: sqh=%p\n", sqh));
eqh = sc->sc_lctl_end;
- sqh->hlink = eqh->hlink;
+ sqh->hlink = eqh->hlink;
sqh->qh.qh_hlink = eqh->qh.qh_hlink;
- eqh->hlink = sqh;
+ eqh->hlink = sqh;
eqh->qh.qh_hlink = htole32(sqh->physaddr | UHCI_PTR_QH);
sc->sc_lctl_end = sqh;
}
@@ -1113,7 +1112,7 @@ uhci_remove_ls_ctrl(uhci_softc_t *sc, uhci_soft_qh_t *sqh)
delay(UHCI_QH_REMOVE_DELAY);
}
pqh = uhci_find_prev_qh(sc->sc_lctl_start, sqh);
- pqh->hlink = sqh->hlink;
+ pqh->hlink = sqh->hlink;
pqh->qh.qh_hlink = sqh->qh.qh_hlink;
delay(UHCI_QH_REMOVE_DELAY);
if (sc->sc_lctl_end == sqh)
@@ -1130,9 +1129,9 @@ uhci_add_bulk(uhci_softc_t *sc, uhci_soft_qh_t *sqh)
DPRINTFN(10, ("uhci_add_bulk: sqh=%p\n", sqh));
eqh = sc->sc_bulk_end;
- sqh->hlink = eqh->hlink;
+ sqh->hlink = eqh->hlink;
sqh->qh.qh_hlink = eqh->qh.qh_hlink;
- eqh->hlink = sqh;
+ eqh->hlink = sqh;
eqh->qh.qh_hlink = htole32(sqh->physaddr | UHCI_PTR_QH);
sc->sc_bulk_end = sqh;
uhci_add_loop(sc);
@@ -1168,9 +1167,6 @@ 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
@@ -1194,10 +1190,15 @@ uhci_intr1(uhci_softc_t *sc)
}
#endif
- status = UREAD2(sc, UHCI_STS) & UHCI_STS_ALLINTRS;
+ status = UREAD2(sc, UHCI_STS);
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",
USBDEVNAME(sc->sc_bus.bdev));
@@ -1222,13 +1223,13 @@ uhci_intr1(uhci_softc_t *sc)
}
if (status & UHCI_STS_HCPE) {
ack |= UHCI_STS_HCPE;
- printf("%s: host controller process error\n",
+ printf("%s: host controller process error\n",
USBDEVNAME(sc->sc_bus.bdev));
}
if (status & UHCI_STS_HCH) {
/* no acknowledge needed */
if (!sc->sc_dying) {
- printf("%s: host controller halted\n",
+ printf("%s: host controller halted\n",
USBDEVNAME(sc->sc_bus.bdev));
#ifdef UHCI_DEBUG
uhci_dump_all(sc);
@@ -1274,11 +1275,6 @@ uhci_softintr(void *v)
for (ii = LIST_FIRST(&sc->sc_intrhead); ii; ii = LIST_NEXT(ii, list))
uhci_check_intr(sc, ii);
- if (sc->sc_softwake) {
- sc->sc_softwake = 0;
- wakeup(&sc->sc_softwake);
- }
-
sc->sc_bus.intr_context--;
}
@@ -1296,12 +1292,6 @@ uhci_check_intr(uhci_softc_t *sc, uhci_intr_info_t *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;
@@ -1311,7 +1301,7 @@ uhci_check_intr(uhci_softc_t *sc, uhci_intr_info_t *ii)
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).
@@ -1328,7 +1318,7 @@ uhci_check_intr(uhci_softc_t *sc, uhci_intr_info_t *ii)
goto done;
/* We want short packets, and it is short: it's done */
if ((status & UHCI_TD_SPD) &&
- UHCI_TD_GET_ACTLEN(status) <
+ UHCI_TD_GET_ACTLEN(status) <
UHCI_TD_GET_MAXLEN(le32toh(std->td.td_token)))
goto done;
}
@@ -1371,6 +1361,12 @@ uhci_idone(uhci_intr_info_t *ii)
}
#endif
+ if (xfer->status == USBD_CANCELLED ||
+ xfer->status == USBD_TIMEOUT) {
+ DPRINTF(("uhci_idone: aborted xfer=%p\n", xfer));
+ return;
+ }
+
if (xfer->nframes != 0) {
/* Isoc transfer, do things differently. */
uhci_soft_td_t **stds = upipe->u.iso.stds;
@@ -1426,15 +1422,14 @@ uhci_idone(uhci_intr_info_t *ii)
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",
+ DPRINTFN(10, ("uhci_idone: actlen=%d, status=0x%x\n",
actlen, status));
xfer->actlen = actlen;
if (status != 0) {
#ifdef UHCI_DEBUG
char sbuf[128];
- bitmask_snprintf((u_int32_t)status,
- "\20\22BITSTUFF\23CRCTO\24NAK\25"
+ bitmask_snprintf((int)status, "\20\22BITSTUFF\23CRCTO\24NAK\25"
"BABBLE\26DBUFFER\27STALLED\30ACTIVE",
sbuf, sizeof(sbuf));
@@ -1466,33 +1461,17 @@ 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_init_task(&uxfer->abort_task, uhci_timeout_task, ii->xfer);
- usb_add_task(uxfer->xfer.pipe->device, &uxfer->abort_task);
-}
+ DPRINTF(("uhci_timeout: ii=%p\n", ii));
-void
-uhci_timeout_task(void *addr)
-{
- usbd_xfer_handle xfer = addr;
- int s;
-
- DPRINTF(("uhci_timeout_task: xfer=%p\n", xfer));
+#ifdef UHCI_DEBUG
+ if (uhcidebug > 10)
+ uhci_dump_tds(ii->stdstart);
+#endif
- s = splusb();
- uhci_abort_xfer(xfer, USBD_TIMEOUT);
- splx(s);
+ ii->xfer->device->bus->intr_context++;
+ uhci_abort_xfer(ii->xfer, USBD_TIMEOUT);
+ ii->xfer->device->bus->intr_context--;
}
/*
@@ -1523,7 +1502,7 @@ uhci_waitintr(uhci_softc_t *sc, usbd_xfer_handle xfer)
/* Timeout */
DPRINTF(("uhci_waitintr: timeout\n"));
for (ii = LIST_FIRST(&sc->sc_intrhead);
- ii != NULL && ii->xfer != xfer;
+ ii != NULL && ii->xfer != xfer;
ii = LIST_NEXT(ii, list))
;
#ifdef DIAGNOSTIC
@@ -1549,11 +1528,11 @@ uhci_reset(uhci_softc_t *sc)
UHCICMD(sc, UHCI_CMD_HCRESET);
/* The reset bit goes low when the controller is done. */
- for (n = 0; n < UHCI_RESET_TIMEOUT &&
+ 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",
+ printf("%s: controller did not reset\n",
USBDEVNAME(sc->sc_bus.bdev));
}
@@ -1701,9 +1680,9 @@ uhci_alloc_std_chain(struct uhci_pipe *upipe, uhci_softc_t *sc, int len,
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));
+ DPRINTFN(8, ("uhci_alloc_std_chain: addr=%d endpt=%d len=%d ls=%d "
+ "flags=0x%x\n", addr, UE_GET_ADDR(endpt), len,
+ upipe->pipe.device->lowspeed, flags));
maxp = UGETW(upipe->pipe.endpoint->edesc->wMaxPacketSize);
if (maxp == 0) {
printf("uhci_alloc_std_chain: maxp=0\n");
@@ -1726,14 +1705,14 @@ uhci_alloc_std_chain(struct uhci_pipe *upipe, uhci_softc_t *sc, int len,
lastlink = UHCI_PTR_T;
ntd--;
status = UHCI_TD_ZERO_ACTLEN(UHCI_TD_SET_ERRCNT(3) | UHCI_TD_ACTIVE);
- if (upipe->pipe.device->speed == USB_SPEED_LOW)
+ if (upipe->pipe.device->lowspeed)
status |= UHCI_TD_LS;
if (flags & USBD_SHORT_XFER_OK)
status |= UHCI_TD_SPD;
for (i = ntd; i >= 0; i--) {
p = uhci_alloc_std(sc);
if (p == NULL) {
- uhci_free_std_chain(sc, lastp, NULL);
+ uhci_free_std_chain(sc, lastp, 0);
return (USBD_NOMEM);
}
p->link.std = lastp;
@@ -1749,14 +1728,14 @@ uhci_alloc_std_chain(struct uhci_pipe *upipe, uhci_softc_t *sc, int len,
*ep = p;
} else
l = maxp;
- p->td.td_token =
+ p->td.td_token =
htole32(rd ? UHCI_TD_IN (l, endpt, addr, tog) :
UHCI_TD_OUT(l, endpt, addr, tog));
p->td.td_buffer = htole32(DMAADDR(dma) + i * maxp);
tog ^= 1;
}
*sp = lastp;
- DPRINTFN(10, ("uhci_alloc_std_chain: nexttog=%d\n",
+ DPRINTFN(10, ("uhci_alloc_std_chain: nexttog=%d\n",
upipe->nexttoggle));
return (USBD_NORMAL_COMPLETION);
}
@@ -1783,7 +1762,7 @@ uhci_device_bulk_transfer(usbd_xfer_handle xfer)
if (err)
return (err);
- /*
+ /*
* Pipe isn't running (otherwise err would be USBD_INPROG),
* so start it first.
*/
@@ -1882,68 +1861,44 @@ uhci_device_bulk_abort(usbd_xfer_handle xfer)
}
/*
- * 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.
+ * XXX This way of aborting is neither safe, nor good.
+ * But it will have to do until I figure out what to do.
+ * I apologize for the delay().
*/
void
uhci_abort_xfer(usbd_xfer_handle xfer, usbd_status status)
{
uhci_intr_info_t *ii = &UXFER(xfer)->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 */
- usb_uncallout(xfer->timeout_handle, uhci_timeout, xfer);
- usb_transfer_complete(xfer);
+ s = splusb();
+
+ /* Transfer is already done. */
+ if (xfer->status != USBD_NOT_STARTED &&
+ xfer->status != USBD_IN_PROGRESS) {
splx(s);
+ return;
}
- if (xfer->device->bus->intr_context || !curproc)
- panic("uhci_abort_xfer: not in process context\n");
+ /* Make interrupt routine ignore it, */
+ xfer->status = status;
- /*
- * Step 1: Make interrupt routine and hardware ignore xfer.
- */
- s = splusb();
- xfer->status = status; /* make software ignore it */
+ /* don't timeout, */
usb_uncallout(xfer->timeout_handle, uhci_timeout, ii);
- DPRINTFN(1,("uhci_abort_xfer: stop ii=%p\n", ii));
+
+ /* make hardware ignore it, */
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();
- sc->sc_softwake = 1;
- usb_schedsoftintr(&sc->sc_bus);
- DPRINTFN(1,("uhci_abort_xfer: tsleep\n"));
- tsleep(&sc->sc_softwake, PZERO, "uhciab", 0);
- splx(s);
-
- /*
- * Step 3: Execute callback.
- */
xfer->hcpriv = ii;
- DPRINTFN(1,("uhci_abort_xfer: callback\n"));
+ splx(s);
+
+ delay(1000);
+
s = splusb();
#ifdef DIAGNOSTIC
ii->isdone = 1;
@@ -1973,7 +1928,7 @@ uhci_device_ctrl_transfer(usbd_xfer_handle xfer)
if (err)
return (err);
- /*
+ /*
* Pipe isn't running (otherwise err would be USBD_INPROG),
* so start it first.
*/
@@ -2013,7 +1968,7 @@ uhci_device_intr_transfer(usbd_xfer_handle xfer)
if (err)
return (err);
- /*
+ /*
* Pipe isn't running (otherwise err would be USBD_INPROG),
* so start it first.
*/
@@ -2069,7 +2024,7 @@ uhci_device_intr_start(usbd_xfer_handle xfer)
ii->isdone = 0;
#endif
- DPRINTFN(10,("uhci_device_intr_transfer: qhs[0]=%p\n",
+ 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];
@@ -2112,7 +2067,7 @@ 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;
+ xfer->pipe->intrxfer = 0;
}
uhci_abort_xfer(xfer, USBD_CANCELLED);
}
@@ -2133,7 +2088,7 @@ uhci_device_intr_close(usbd_pipe_handle pipe)
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.
*/
@@ -2170,7 +2125,7 @@ uhci_device_request(usbd_xfer_handle xfer)
UGETW(req->wIndex), UGETW(req->wLength),
addr, endpt));
- ls = dev->speed == USB_SPEED_LOW ? UHCI_TD_LS : 0;
+ ls = dev->lowspeed ? UHCI_TD_LS : 0;
isread = req->bmRequestType & UT_READ;
len = UGETW(req->wLength);
@@ -2204,9 +2159,9 @@ uhci_device_request(usbd_xfer_handle xfer)
stat->link.std = NULL;
stat->td.td_link = htole32(UHCI_PTR_T);
- stat->td.td_status = htole32(UHCI_TD_SET_ERRCNT(3) | ls |
+ stat->td.td_status = htole32(UHCI_TD_SET_ERRCNT(3) | ls |
UHCI_TD_ACTIVE | UHCI_TD_IOC);
- stat->td.td_token =
+ 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);
@@ -2233,7 +2188,7 @@ uhci_device_request(usbd_xfer_handle xfer)
sqh->qh.qh_elink = htole32(setup->physaddr | UHCI_PTR_TD);
s = splusb();
- if (dev->speed == USB_SPEED_LOW)
+ if (dev->lowspeed)
uhci_add_ls_ctrl(sc, sqh);
else
uhci_add_hs_ctrl(sc, sqh);
@@ -2256,7 +2211,7 @@ uhci_device_request(usbd_xfer_handle xfer)
uhci_dump_qh(sxqh);
for (xqh = sxqh;
xqh != NULL;
- xqh = (maxqh++ == 5 || xqh->hlink == sxqh ||
+ xqh = (maxqh++ == 5 || xqh->hlink == sxqh ||
xqh->hlink == xqh ? NULL : xqh->hlink)) {
uhci_dump_qh(xqh);
}
@@ -2308,7 +2263,7 @@ uhci_device_isoc_enter(usbd_xfer_handle xfer)
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;
+ uhci_soft_td_t *std;
u_int32_t buf, len, status;
int s, i, next, nframes;
@@ -2404,7 +2359,7 @@ uhci_device_isoc_start(usbd_xfer_handle xfer)
#endif
s = splusb();
-
+
/* Set up interrupt info. */
ii->xfer = xfer;
ii->stdstart = end;
@@ -2415,7 +2370,7 @@ uhci_device_isoc_start(usbd_xfer_handle xfer)
ii->isdone = 0;
#endif
uhci_add_intr_info(sc, ii);
-
+
splx(s);
return (USBD_IN_PROGRESS);
@@ -2432,7 +2387,7 @@ uhci_device_isoc_abort(usbd_xfer_handle xfer)
s = splusb();
/* Transfer is already done. */
- if (xfer->status != USBD_NOT_STARTED &&
+ if (xfer->status != USBD_NOT_STARTED &&
xfer->status != USBD_IN_PROGRESS) {
splx(s);
return;
@@ -2616,7 +2571,7 @@ uhci_device_intr_done(usbd_xfer_handle xfer)
sqh->elink = NULL;
sqh->qh.qh_elink = htole32(UHCI_PTR_T);
}
- uhci_free_std_chain(sc, ii->stdstart, NULL);
+ uhci_free_std_chain(sc, ii->stdstart, 0);
/* XXX Wasteful. */
if (xfer->pipe->repeat) {
@@ -2673,7 +2628,7 @@ uhci_device_ctrl_done(usbd_xfer_handle xfer)
uhci_del_intr_info(ii); /* remove from active list */
- if (upipe->pipe.device->speed == USB_SPEED_LOW)
+ if (upipe->pipe.device->lowspeed)
uhci_remove_ls_ctrl(sc, upipe->u.ctl.sqh);
else
uhci_remove_hs_ctrl(sc, upipe->u.ctl.sqh);
@@ -2696,7 +2651,7 @@ uhci_device_bulk_done(usbd_xfer_handle xfer)
uhci_remove_bulk(sc, upipe->u.bulk.sqh);
- uhci_free_std_chain(sc, ii->stdstart, NULL);
+ uhci_free_std_chain(sc, ii->stdstart, 0);
DPRINTFN(5, ("uhci_bulk_done: length=%d\n", xfer->actlen));
}
@@ -2762,10 +2717,10 @@ uhci_device_setintr(uhci_softc_t *sc, struct uhci_pipe *upipe, int ival)
DPRINTFN(2, ("uhci_setintr: ival=%d npoll=%d\n", ival, npoll));
upipe->u.intr.npoll = npoll;
- upipe->u.intr.qhs =
+ 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.
*/
@@ -2809,7 +2764,7 @@ uhci_open(usbd_pipe_handle pipe)
int ival;
DPRINTFN(1, ("uhci_open: pipe=%p, addr=%d, endpt=%d (%d)\n",
- pipe, pipe->device->address,
+ pipe, pipe->device->address,
ed->bEndpointAddress, sc->sc_addr));
upipe->aborting = 0;
@@ -2844,8 +2799,8 @@ uhci_open(usbd_pipe_handle pipe)
uhci_free_std(sc, upipe->u.ctl.setup);
goto bad;
}
- err = usb_allocmem(&sc->sc_bus,
- sizeof(usb_device_request_t),
+ 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);
@@ -2886,7 +2841,7 @@ usb_device_descriptor_t uhci_devd = {
{0x00, 0x01}, /* USB version */
UDCLASS_HUB, /* class */
UDSUBCLASS_HUB, /* subclass */
- UDPROTO_FSHUB, /* protocol */
+ 0, /* protocol */
64, /* max packet */
{0},{0},{0x00,0x01}, /* device id */
1,2,0, /* string indicies */
@@ -2914,7 +2869,7 @@ usb_interface_descriptor_t uhci_ifcd = {
1,
UICLASS_HUB,
UISUBCLASS_HUB,
- UIPROTO_FSHUB,
+ 0,
0
};
@@ -2967,7 +2922,7 @@ uhci_root_ctrl_transfer(usbd_xfer_handle xfer)
if (err)
return (err);
- /*
+ /*
* Pipe isn't running (otherwise err would be USBD_INPROG),
* so start it first.
*/
@@ -2994,7 +2949,7 @@ uhci_root_ctrl_start(usbd_xfer_handle xfer)
#endif
req = &xfer->request;
- DPRINTFN(2,("uhci_root_ctrl_control type=0x%02x request=%02x\n",
+ DPRINTFN(2,("uhci_root_ctrl_control type=0x%02x request=%02x\n",
req->bmRequestType, req->bRequest));
len = UGETW(req->wLength);
@@ -3009,7 +2964,7 @@ uhci_root_ctrl_start(usbd_xfer_handle xfer)
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.
*/
@@ -3177,7 +3132,7 @@ uhci_root_ctrl_start(usbd_xfer_handle xfer)
goto ret;
}
if (len > 0) {
- *(u_int8_t *)buf =
+ *(u_int8_t *)buf =
(UREAD2(sc, port) & UHCI_PORTSC_LS) >>
UHCI_PORTSC_LS_SHIFT;
totlen = 1;
@@ -3217,19 +3172,19 @@ uhci_root_ctrl_start(usbd_xfer_handle xfer)
status = change = 0;
if (x & UHCI_PORTSC_CCS)
status |= UPS_CURRENT_CONNECT_STATUS;
- if (x & UHCI_PORTSC_CSC)
+ if (x & UHCI_PORTSC_CSC)
change |= UPS_C_CONNECT_STATUS;
- if (x & UHCI_PORTSC_PE)
+ if (x & UHCI_PORTSC_PE)
status |= UPS_PORT_ENABLED;
- if (x & UHCI_PORTSC_POEDC)
+ if (x & UHCI_PORTSC_POEDC)
change |= UPS_C_PORT_ENABLED;
- if (x & UHCI_PORTSC_OCI)
+ if (x & UHCI_PORTSC_OCI)
status |= UPS_OVERCURRENT_INDICATOR;
- if (x & UHCI_PORTSC_OCIC)
+ if (x & UHCI_PORTSC_OCIC)
change |= UPS_C_OVERCURRENT_INDICATOR;
- if (x & UHCI_PORTSC_SUSP)
+ if (x & UHCI_PORTSC_SUSP)
status |= UPS_SUSPEND;
- if (x & UHCI_PORTSC_LSDA)
+ if (x & UHCI_PORTSC_LSDA)
status |= UPS_LOW_SPEED;
status |= UPS_PORT_POWER;
if (sc->sc_isreset)
@@ -3266,7 +3221,7 @@ uhci_root_ctrl_start(usbd_xfer_handle xfer)
case UHF_PORT_RESET:
x = URWMASK(UREAD2(sc, port));
UWRITE2(sc, port, x | UHCI_PORTSC_PR);
- usb_delay_ms(&sc->sc_bus, USB_PORT_ROOT_RESET_DELAY);
+ usb_delay_ms(&sc->sc_bus, 50); /*XXX USB v1.1 7.1.7.3 */
UWRITE2(sc, port, x & ~UHCI_PORTSC_PR);
delay(100);
x = UREAD2(sc, port);
diff --git a/sys/dev/usb/uhcireg.h b/sys/dev/usb/uhcireg.h
index c0d73cedc4c..d51b7492396 100644
--- a/sys/dev/usb/uhcireg.h
+++ b/sys/dev/usb/uhcireg.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: uhcireg.h,v 1.10 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: uhcireg.h,v 1.15 2002/02/11 11:41:30 augustss Exp $ */
+/* $OpenBSD: uhcireg.h,v 1.11 2002/05/07 18:29:18 nate Exp $ */
+/* $NetBSD: uhcireg.h,v 1.14 2001/08/06 15:15:08 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/uhcireg.h,v 1.12 1999/11/17 22:33:42 n_hibma Exp $ */
/*
@@ -76,7 +76,6 @@
#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
diff --git a/sys/dev/usb/uhcivar.h b/sys/dev/usb/uhcivar.h
index b8fdfeea482..acf3d7cd860 100644
--- a/sys/dev/usb/uhcivar.h
+++ b/sys/dev/usb/uhcivar.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: uhcivar.h,v 1.12 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: uhcivar.h,v 1.33 2002/02/11 11:41:30 augustss Exp $ */
+/* $OpenBSD: uhcivar.h,v 1.13 2002/05/07 18:29:18 nate Exp $ */
+/* $NetBSD: uhcivar.h,v 1.32 2000/08/13 16:18:09 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/uhcivar.h,v 1.14 1999/11/17 22:33:42 n_hibma Exp $ */
/*
@@ -84,7 +84,6 @@ typedef struct uhci_intr_info {
struct uhci_xfer {
struct usbd_xfer xfer;
uhci_intr_info_t iinfo;
- struct usb_task abort_task;
int curframe;
};
@@ -162,7 +161,6 @@ typedef struct uhci_softc {
u_int8_t sc_saved_sof;
u_int16_t sc_saved_frnum;
- char sc_softwake;
char sc_isreset;
char sc_suspend;
char sc_dying;
diff --git a/sys/dev/usb/uhid.c b/sys/dev/usb/uhid.c
index 48fb9f7d21d..968af28c593 100644
--- a/sys/dev/usb/uhid.c
+++ b/sys/dev/usb/uhid.c
@@ -1,5 +1,6 @@
-/* $OpenBSD: uhid.c,v 1.17 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: uhid.c,v 1.51 2002/03/17 18:02:53 augustss Exp $ */
+/* $OpenBSD: uhid.c,v 1.18 2002/05/07 18:29:18 nate Exp $ */
+/* $NetBSD: uhid.c,v 1.45 2001/10/26 17:58:21 augustss Exp $ */
+/* $FreeBSD: src/sys/dev/usb/uhid.c,v 1.22 1999/11/17 22:33:43 n_hibma Exp $ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -47,8 +48,16 @@
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/signalvar.h>
+#if defined(__NetBSD__) || defined(__OpenBSD__)
#include <sys/device.h>
#include <sys/ioctl.h>
+#elif defined(__FreeBSD__)
+#include <sys/ioccom.h>
+#include <sys/filio.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/ioccom.h>
+#endif
#include <sys/conf.h>
#include <sys/tty.h>
#include <sys/file.h>
@@ -66,7 +75,8 @@
#include <dev/usb/hid.h>
#include <dev/usb/usb_quirks.h>
-#include <dev/usb/uhidev.h>
+/* Report descriptor for broken Wacom Graphire */
+#include <dev/usb/ugraphire_rdesc.h>
#ifdef UHID_DEBUG
#define DPRINTF(x) if (uhiddebug) logprintf x
@@ -78,20 +88,33 @@ int uhiddebug = 0;
#endif
struct uhid_softc {
- struct uhidev sc_hdev;
+ USBBASEDEVICE 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;
- usb_proc_ptr sc_async; /* process that wants SIGIO */
+ struct proc *sc_async; /* process that wants SIGIO */
u_char sc_state; /* driver state */
-#define UHID_ASLP 0x01 /* waiting for device data */
-#define UHID_IMMED 0x02 /* return read data immediately */
+#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;
@@ -101,52 +124,153 @@ struct uhid_softc {
#define UHID_CHUNK 128 /* chunk size for read */
#define UHID_BSIZE 1020 /* buffer size */
+#if defined(__NetBSD__) || defined(__OpenBSD__)
cdev_decl(uhid);
+#elif defined(__FreeBSD__)
+d_open_t uhidopen;
+d_close_t uhidclose;
+d_read_t uhidread;
+d_write_t uhidwrite;
+d_ioctl_t uhidioctl;
+d_poll_t uhidpoll;
+
+#define UHID_CDEV_MAJOR 122
+
+Static struct cdevsw uhid_cdevsw = {
+ /* open */ uhidopen,
+ /* close */ uhidclose,
+ /* read */ uhidread,
+ /* write */ uhidwrite,
+ /* ioctl */ uhidioctl,
+ /* poll */ uhidpoll,
+ /* mmap */ nommap,
+ /* strategy */ nostrategy,
+ /* name */ "uhid",
+ /* maj */ UHID_CDEV_MAJOR,
+ /* dump */ nodump,
+ /* psize */ nopsize,
+ /* flags */ 0,
+ /* bmaj */ -1
+};
+#endif
-Static void uhid_intr(struct uhidev *, void *, u_int len);
+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,
- usb_proc_ptr);
+Static int uhid_do_ioctl(struct uhid_softc*, u_long, caddr_t, int,struct proc*);
USB_DECLARE_DRIVER(uhid);
USB_MATCH(uhid)
{
USB_MATCH_START(uhid, uaa);
- struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)uaa;
-
- DPRINTF(("uhid_match: report=%d\n", uha->reportid));
-
- if (uha->matchlvl)
- return (uha->matchlvl);
+ usb_interface_descriptor_t *id;
+
+ if (uaa->iface == NULL)
+ return (UMATCH_NONE);
+ id = usbd_get_interface_descriptor(uaa->iface);
+ if (id == NULL || id->bInterfaceClass != UICLASS_HID)
+ return (UMATCH_NONE);
+ if (uaa->matchlvl)
+ return (uaa->matchlvl);
return (UMATCH_IFACECLASS_GENERIC);
}
USB_ATTACH(uhid)
{
USB_ATTACH_START(uhid, sc, uaa);
- struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)uaa;
- int size, repid;
+ usbd_interface_handle iface = uaa->iface;
+ usb_interface_descriptor_t *id;
+ usb_endpoint_descriptor_t *ed;
+ int size;
void *desc;
+ usbd_status err;
+ char devinfo[1024];
+
+ sc->sc_udev = uaa->device;
+ sc->sc_iface = iface;
+ id = usbd_get_interface_descriptor(iface);
+ usbd_devinfo(uaa->device, 0, devinfo);
+ USB_ATTACH_SETUP;
+ printf("%s: %s, iclass %d/%d\n", USBDEVNAME(sc->sc_dev),
+ devinfo, id->bInterfaceClass, id->bInterfaceSubClass);
+
+ ed = usbd_interface2endpoint_descriptor(iface, 0);
+ if (ed == NULL) {
+ printf("%s: could not read endpoint descriptor\n",
+ USBDEVNAME(sc->sc_dev));
+ sc->sc_dying = 1;
+ USB_ATTACH_ERROR_RETURN;
+ }
+
+ 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", USBDEVNAME(sc->sc_dev));
+ sc->sc_dying = 1;
+ USB_ATTACH_ERROR_RETURN;
+ }
+
+ sc->sc_ep_addr = ed->bEndpointAddress;
+
+ if (uaa->vendor == USB_VENDOR_WACOM &&
+ uaa->product == USB_PRODUCT_WACOM_GRAPHIRE /* &&
+ uaa->revision == 0x???? */) { /* XXX should use revision */
+ /* The report descriptor for the Wacom Graphire is broken. */
+ size = sizeof uhid_graphire_report_descr;
+ desc = malloc(size, M_USBDEV, M_NOWAIT);
+ if (desc == NULL)
+ err = USBD_NOMEM;
+ else {
+ err = USBD_NORMAL_COMPLETION;
+ memcpy(desc, uhid_graphire_report_descr, size);
+ }
+ } else {
+ desc = NULL;
+ err = usbd_read_report_desc(uaa->iface, &desc, &size,M_USBDEV);
+ }
+ if (err) {
+ printf("%s: no report descriptor\n", USBDEVNAME(sc->sc_dev));
+ sc->sc_dying = 1;
+ USB_ATTACH_ERROR_RETURN;
+ }
- sc->sc_hdev.sc_intr = uhid_intr;
- sc->sc_hdev.sc_parent = uha->parent;
- sc->sc_hdev.sc_report_id = uha->reportid;
+ (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);
- uhidev_get_report_desc(uha->parent, &desc, &size);
- repid = uha->reportid;
- sc->sc_isize = hid_report_size(desc, size, hid_input, repid);
- sc->sc_osize = hid_report_size(desc, size, hid_output, repid);
- sc->sc_fsize = hid_report_size(desc, size, hid_feature, repid);
+ sc->sc_repdesc = desc;
+ sc->sc_repdesc_size = size;
- printf(": input=%d, output=%d, feature=%d\n",
- sc->sc_isize, sc->sc_osize, sc->sc_fsize);
+#ifdef __FreeBSD__
+ {
+ static int global_init_done = 0;
+
+ if (!global_init_done) {
+ cdevsw_add(&uhid_cdevsw);
+ global_init_done = 1;
+ }
+ }
+#endif
+
+ usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
+ USBDEV(sc->sc_dev));
USB_ATTACH_SUCCESS_RETURN;
}
+#if defined(__NetBSD__) || defined(__OpenBSD__)
int
uhid_activate(device_ptr_t self, enum devact act)
{
@@ -163,28 +287,36 @@ uhid_activate(device_ptr_t self, enum devact act)
}
return (0);
}
+#endif
USB_DETACH(uhid)
{
USB_DETACH_START(uhid, sc);
int s;
+#if defined(__NetBSD__) || defined(__OpenBSD__)
int maj, mn;
DPRINTF(("uhid_detach: sc=%p flags=%d\n", sc, flags));
+#else
+ DPRINTF(("uhid_detach: sc=%p\n", sc));
+#endif
sc->sc_dying = 1;
+ if (sc->sc_intrpipe != NULL)
+ usbd_abort_pipe(sc->sc_intrpipe);
- if (sc->sc_hdev.sc_state & UHIDEV_OPEN) {
+ 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(USBDEV(sc->sc_hdev.sc_dev));
+ usb_detach_wait(USBDEV(sc->sc_dev));
}
splx(s);
}
+#if defined(__NetBSD__) || defined(__OpenBSD__)
/* locate the major number */
for (maj = 0; maj < nchrdev; maj++)
if (cdevsw[maj].d_open == uhidopen)
@@ -193,33 +325,47 @@ USB_DETACH(uhid)
/* Nuke the vnodes for any open instances (calls close). */
mn = self->dv_unit;
vdevgone(maj, mn, mn, VCHR);
-
-#if 0
- usbd_add_drv_event(USB_EVENT_DRIVER_DETACH,
- sc->sc_hdev.sc_parent->sc_udev,
- USBDEV(sc->sc_hdev.sc_dev));
+#elif defined(__FreeBSD__)
+ /* XXX not implemented yet */
#endif
+ if (sc->sc_repdesc)
+ free(sc->sc_repdesc, M_USBDEV);
+
+ usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
+ USBDEV(sc->sc_dev));
+
return (0);
}
void
-uhid_intr(struct uhidev *addr, void *data, u_int len)
+uhid_intr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status)
{
- struct uhid_softc *sc = (struct uhid_softc *)addr;
+ struct uhid_softc *sc = addr;
#ifdef UHID_DEBUG
if (uhiddebug > 5) {
- u_int32_t i;
+ 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 < len; i++)
- DPRINTF((" %02x", ((u_char *)data)[i]));
+ for (i = 0; i < cc; i++)
+ DPRINTF((" %02x", sc->sc_ibuf[i]));
DPRINTF(("\n"));
}
#endif
- (void)b_to_q(data, len, &sc->sc_q);
+ if (status == USBD_CANCELLED)
+ return;
+
+ if (status != USBD_NORMAL_COMPLETION) {
+ DPRINTF(("uhid_intr: status=%d\n", status));
+ 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;
@@ -234,10 +380,10 @@ uhid_intr(struct uhidev *addr, void *data, u_int len)
}
int
-uhidopen(dev_t dev, int flag, int mode, usb_proc_ptr p)
+uhidopen(dev_t dev, int flag, int mode, struct proc *p)
{
struct uhid_softc *sc;
- int error;
+ usbd_status err;
USB_GET_SC_OPEN(uhid, UHIDUNIT(dev), sc);
@@ -246,23 +392,40 @@ uhidopen(dev_t dev, int flag, int mode, usb_proc_ptr p)
if (sc->sc_dying)
return (ENXIO);
- error = uhidev_open(&sc->sc_hdev);
- if (error)
- return (error);
+ if (sc->sc_state & UHID_OPEN)
+ return (EBUSY);
+ sc->sc_state |= UHID_OPEN;
if (clalloc(&sc->sc_q, UHID_BSIZE, 0) == -1) {
- uhidev_close(&sc->sc_hdev);
+ sc->sc_state &= ~UHID_OPEN;
return (ENOMEM);
}
+
+ 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_state &= ~UHID_OPEN;
+ return (EIO);
+ }
+
sc->sc_state &= ~UHID_IMMED;
- sc->sc_async = NULL;
+
+ sc->sc_async = 0;
return (0);
}
int
-uhidclose(dev_t dev, int flag, int mode, usb_proc_ptr p)
+uhidclose(dev_t dev, int flag, int mode, struct proc *p)
{
struct uhid_softc *sc;
@@ -270,10 +433,19 @@ uhidclose(dev_t dev, int flag, int mode, usb_proc_ptr p)
DPRINTF(("uhidclose: sc=%p\n", sc));
+ /* Disable interrupts. */
+ usbd_abort_pipe(sc->sc_intrpipe);
+ usbd_close_pipe(sc->sc_intrpipe);
+ sc->sc_intrpipe = 0;
+
clfree(&sc->sc_q);
+
+ free(sc->sc_ibuf, M_USBDEV);
free(sc->sc_obuf, M_USBDEV);
- sc->sc_async = NULL;
- uhidev_close(&sc->sc_hdev);
+
+ sc->sc_state &= ~UHID_OPEN;
+
+ sc->sc_async = 0;
return (0);
}
@@ -283,7 +455,6 @@ uhid_do_read(struct uhid_softc *sc, struct uio *uio, int flag)
{
int s;
int error = 0;
- int extra;
size_t length;
u_char buffer[UHID_CHUNK];
usbd_status err;
@@ -291,12 +462,12 @@ uhid_do_read(struct uhid_softc *sc, struct uio *uio, int flag)
DPRINTFN(1, ("uhidread\n"));
if (sc->sc_state & UHID_IMMED) {
DPRINTFN(1, ("uhidread immed\n"));
- extra = sc->sc_hdev.sc_report_id != 0;
- err = uhidev_get_report(&sc->sc_hdev, UHID_INPUT_REPORT,
- buffer, sc->sc_isize + extra);
+
+ err = usbd_get_report(sc->sc_iface, UHID_INPUT_REPORT,
+ sc->sc_iid, buffer, sc->sc_isize);
if (err)
return (EIO);
- return (uiomove(buffer+extra, sc->sc_isize, uio));
+ return (uiomove(buffer, sc->sc_isize, uio));
}
s = splusb();
@@ -315,6 +486,11 @@ uhid_do_read(struct uhid_softc *sc, struct uio *uio, int flag)
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);
@@ -347,7 +523,7 @@ uhidread(dev_t dev, struct uio *uio, int flag)
sc->sc_refcnt++;
error = uhid_do_read(sc, uio, flag);
if (--sc->sc_refcnt < 0)
- usb_detach_wakeup(USBDEV(sc->sc_hdev.sc_dev));
+ usb_detach_wakeup(USBDEV(sc->sc_dev));
return (error);
}
@@ -369,8 +545,12 @@ uhid_do_write(struct uhid_softc *sc, struct uio *uio, int flag)
return (EINVAL);
error = uiomove(sc->sc_obuf, size, uio);
if (!error) {
- err = uhidev_set_report(&sc->sc_hdev, UHID_OUTPUT_REPORT,
- sc->sc_obuf, size);
+ 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;
}
@@ -389,20 +569,18 @@ uhidwrite(dev_t dev, struct uio *uio, int flag)
sc->sc_refcnt++;
error = uhid_do_write(sc, uio, flag);
if (--sc->sc_refcnt < 0)
- usb_detach_wakeup(USBDEV(sc->sc_hdev.sc_dev));
+ usb_detach_wakeup(USBDEV(sc->sc_dev));
return (error);
}
int
uhid_do_ioctl(struct uhid_softc *sc, u_long cmd, caddr_t addr,
- int flag, usb_proc_ptr p)
+ int flag, struct proc *p)
{
struct usb_ctl_report_desc *rd;
struct usb_ctl_report *re;
- u_char buffer[UHID_CHUNK];
- int size, extra;
+ int size, id;
usbd_status err;
- void *desc;
DPRINTFN(2, ("uhidioctl: cmd=%lx\n", cmd));
@@ -433,18 +611,17 @@ uhid_do_ioctl(struct uhid_softc *sc, u_long cmd, caddr_t addr,
break;
case USB_GET_REPORT_DESC:
- uhidev_get_report_desc(sc->sc_hdev.sc_parent, &desc, &size);
rd = (struct usb_ctl_report_desc *)addr;
- size = min(size, sizeof rd->ucrd_data);
+ size = min(sc->sc_repdesc_size, sizeof rd->ucrd_data);
rd->ucrd_size = size;
- memcpy(rd->ucrd_data, desc, size);
+ memcpy(rd->ucrd_data, sc->sc_repdesc, size);
break;
case USB_SET_IMMED:
if (*(int *)addr) {
- extra = sc->sc_hdev.sc_report_id != 0;
- err = uhidev_get_report(&sc->sc_hdev, UHID_INPUT_REPORT,
- buffer, sc->sc_isize + extra);
+ /* 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);
@@ -458,21 +635,21 @@ uhid_do_ioctl(struct uhid_softc *sc, u_long cmd, caddr_t 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);
}
- extra = sc->sc_hdev.sc_report_id != 0;
- err = uhidev_get_report(&sc->sc_hdev, re->ucr_report,
- re->ucr_data, size + extra);
- if (extra)
- memcpy(re->ucr_data, re->ucr_data+1, size);
+ err = usbd_get_report(sc->sc_iface, re->ucr_report, id,
+ re->ucr_data, size);
if (err)
return (EIO);
break;
@@ -482,26 +659,26 @@ uhid_do_ioctl(struct uhid_softc *sc, u_long cmd, caddr_t 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 = uhidev_set_report(&sc->sc_hdev, re->ucr_report,
- re->ucr_data, size);
+ 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 = sc->sc_hdev.sc_report_id;
- break;
-
default:
return (EINVAL);
}
@@ -509,7 +686,7 @@ uhid_do_ioctl(struct uhid_softc *sc, u_long cmd, caddr_t addr,
}
int
-uhidioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, usb_proc_ptr p)
+uhidioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
{
struct uhid_softc *sc;
int error;
@@ -519,12 +696,12 @@ uhidioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, usb_proc_ptr p)
sc->sc_refcnt++;
error = uhid_do_ioctl(sc, cmd, addr, flag, p);
if (--sc->sc_refcnt < 0)
- usb_detach_wakeup(USBDEV(sc->sc_hdev.sc_dev));
+ usb_detach_wakeup(USBDEV(sc->sc_dev));
return (error);
}
int
-uhidpoll(dev_t dev, int events, usb_proc_ptr p)
+uhidpoll(dev_t dev, int events, struct proc *p)
{
struct uhid_softc *sc;
int revents = 0;
@@ -548,3 +725,7 @@ uhidpoll(dev_t dev, int events, usb_proc_ptr p)
splx(s);
return (revents);
}
+
+#if defined(__FreeBSD__)
+DRIVER_MODULE(uhid, uhub, uhid_driver, uhid_devclass, usbd_driver_load, 0);
+#endif
diff --git a/sys/dev/usb/uhidev.c b/sys/dev/usb/uhidev.c
deleted file mode 100644
index 263ab111bf1..00000000000
--- a/sys/dev/usb/uhidev.c
+++ /dev/null
@@ -1,513 +0,0 @@
-/* $OpenBSD: uhidev.c,v 1.1 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: uhidev.c,v 1.5 2002/02/27 01:30:50 augustss Exp $ */
-
-/*
- * 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) 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/data/devclass/hid1_1.pdf
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/signalvar.h>
-#include <sys/device.h>
-#include <sys/ioctl.h>
-#include <sys/conf.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbhid.h>
-
-#include <dev/usb/usbdevs.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include <dev/usb/hid.h>
-#include <dev/usb/usb_quirks.h>
-
-#include <dev/usb/uhidev.h>
-
-/* Report descriptor for broken Wacom Graphire */
-#include <dev/usb/ugraphire_rdesc.h>
-
-#ifdef UHIDEV_DEBUG
-#define DPRINTF(x) if (uhidevdebug) logprintf x
-#define DPRINTFN(n,x) if (uhidevdebug>(n)) logprintf x
-int uhidevdebug = 0;
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-Static void uhidev_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
-
-Static int uhidev_maxrepid(void *buf, int len);
-Static int uhidevprint(void *aux, const char *pnp);
-#if defined(__NetBSD__)
-Static int uhidevsubmatch(struct device *parent, struct cfdata *cf, void *aux);
-#else
-Static int uhidevsubmatch(struct device *parent, void *cf, void *aux);
-#endif
-
-USB_DECLARE_DRIVER(uhidev);
-
-USB_MATCH(uhidev)
-{
- USB_MATCH_START(uhidev, uaa);
- usb_interface_descriptor_t *id;
-
- if (uaa->iface == NULL)
- return (UMATCH_NONE);
- id = usbd_get_interface_descriptor(uaa->iface);
- if (id == NULL || id->bInterfaceClass != UICLASS_HID)
- return (UMATCH_NONE);
- if (uaa->matchlvl)
- return (uaa->matchlvl);
- return (UMATCH_IFACECLASS_GENERIC);
-}
-
-int repproto = 1;
-
-USB_ATTACH(uhidev)
-{
- USB_ATTACH_START(uhidev, sc, uaa);
- usbd_interface_handle iface = uaa->iface;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
- struct uhidev_attach_arg uha;
- struct uhidev *dev;
- int size, nrepid, repid, repsz;
- int repsizes[256];
- void *desc;
- usbd_status err;
- char devinfo[1024];
-
- sc->sc_udev = uaa->device;
- sc->sc_iface = iface;
- id = usbd_get_interface_descriptor(iface);
- usbd_devinfo(uaa->device, 0, devinfo);
- USB_ATTACH_SETUP;
- printf("%s: %s, iclass %d/%d\n", USBDEVNAME(sc->sc_dev),
- devinfo, id->bInterfaceClass, id->bInterfaceSubClass);
-
- (void)usbd_set_idle(iface, 0, 0);
-#if 0
-
- qflags = usbd_get_quirks(sc->sc_udev)->uq_flags;
- if ((qflags & UQ_NO_SET_PROTO) == 0 &&
- id->bInterfaceSubClass != UISUBCLASS_BOOT)
- (void)usbd_set_protocol(iface, 1);
-#endif
-
- ed = usbd_interface2endpoint_descriptor(iface, 0);
- if (ed == NULL) {
- printf("%s: could not read endpoint descriptor\n",
- USBDEVNAME(sc->sc_dev));
- sc->sc_dying = 1;
- USB_ATTACH_ERROR_RETURN;
- }
-
- DPRINTFN(10,("uhidev_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", USBDEVNAME(sc->sc_dev));
- sc->sc_dying = 1;
- USB_ATTACH_ERROR_RETURN;
- }
-
- sc->sc_ep_addr = ed->bEndpointAddress;
-
- /* XXX need to extend this */
- if (uaa->vendor == USB_VENDOR_WACOM &&
- uaa->product == USB_PRODUCT_WACOM_GRAPHIRE /* &&
- uaa->revision == 0x???? */) { /* XXX should use revision */
- /* The report descriptor for the Wacom Graphire is broken. */
- size = sizeof uhid_graphire_report_descr;
- desc = malloc(size, M_USBDEV, M_NOWAIT);
- if (desc == NULL)
- err = USBD_NOMEM;
- else {
- err = USBD_NORMAL_COMPLETION;
- memcpy(desc, uhid_graphire_report_descr, size);
- }
- } else {
- desc = NULL;
- err = usbd_read_report_desc(uaa->iface, &desc, &size, M_USBDEV);
- }
- if (err) {
- printf("%s: no report descriptor\n", USBDEVNAME(sc->sc_dev));
- sc->sc_dying = 1;
- USB_ATTACH_ERROR_RETURN;
- }
-
- sc->sc_repdesc = desc;
- sc->sc_repdesc_size = size;
-
- uha.uaa = uaa;
- nrepid = uhidev_maxrepid(desc, size);
- if (nrepid < 0)
- USB_ATTACH_SUCCESS_RETURN;
- if (nrepid > 0)
- printf("%s: %d report ids\n", USBDEVNAME(sc->sc_dev), nrepid);
- nrepid++;
- sc->sc_subdevs = malloc(nrepid * sizeof(device_ptr_t),
- M_USBDEV, M_NOWAIT);
- bzero(sc->sc_subdevs, nrepid * sizeof(device_ptr_t));
- if (sc->sc_subdevs == NULL) {
- printf("%s: no memory\n", USBDEVNAME(sc->sc_dev));
- USB_ATTACH_ERROR_RETURN;
- }
- sc->sc_nrepid = nrepid;
- sc->sc_isize = 0;
-
- usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
- USBDEV(sc->sc_dev));
-
- for (repid = 0; repid < nrepid; repid++) {
- repsz = hid_report_size(desc, size, hid_input, repid);
- DPRINTF(("uhidev_match: repid=%d, repsz=%d\n", repid, repsz));
- repsizes[repid] = repsz;
- if (repsz > 0) {
- if (repsz > sc->sc_isize)
- sc->sc_isize = repsz;
- }
- }
- sc->sc_isize += nrepid != 1; /* space for report ID */
- DPRINTF(("uhidev_attach: isize=%d\n", sc->sc_isize));
-
- uha.parent = sc;
- for (repid = 0; repid < nrepid; repid++) {
- DPRINTF(("uhidev_match: try repid=%d\n", repid));
- if (hid_report_size(desc, size, hid_input, repid) == 0 &&
- hid_report_size(desc, size, hid_output, repid) == 0 &&
- hid_report_size(desc, size, hid_feature, repid) == 0) {
- ; /* already NULL in sc->sc_subdevs[repid] */
- } else {
- uha.reportid = repid;
- dev = (struct uhidev *)config_found_sm(self, &uha,
- uhidevprint, uhidevsubmatch);
- sc->sc_subdevs[repid] = dev;
- if (dev != NULL) {
- dev->sc_in_rep_size = repsizes[repid];
-#ifdef DIAGNOSTIC
- DPRINTF(("uhidev_match: repid=%d dev=%p\n",
- repid, dev));
- if (dev->sc_intr == NULL) {
- printf("%s: sc_intr == NULL\n",
- USBDEVNAME(sc->sc_dev));
- USB_ATTACH_ERROR_RETURN;
- }
-#endif
- }
- }
- }
-
- USB_ATTACH_SUCCESS_RETURN;
-}
-
-int
-uhidev_maxrepid(void *buf, int len)
-{
- struct hid_data *d;
- struct hid_item h;
- int maxid;
-
- maxid = -1;
- h.report_ID = 0;
- for (d = hid_start_parse(buf, len, hid_none); hid_get_item(d, &h); )
- if (h.report_ID > maxid)
- maxid = h.report_ID;
- hid_end_parse(d);
- return (maxid);
-}
-
-int
-uhidevprint(void *aux, const char *pnp)
-{
- struct uhidev_attach_arg *uha = aux;
-
- if (pnp)
- printf("uhid at %s", pnp);
- if (uha->reportid != 0)
- printf(" reportid %d", uha->reportid);
- return (UNCONF);
-}
-
-#if defined(__NetBSD__)
-Static int uhidevsubmatch(struct device *parent, struct cfdata *cf, void *aux)
-#else
-Static int uhidevsubmatch(struct device *parent, void *match, void *aux)
-#endif
-{
- struct uhidev_attach_arg *uha = aux;
-#if defined(__OpenBSD__)
- struct cfdata *cf = match;
-#endif
-
- if (cf->uhidevcf_reportid != UHIDEV_UNK_REPORTID &&
- cf->uhidevcf_reportid != uha->reportid)
- return (0);
- if (cf->uhidevcf_reportid == uha->reportid)
- uha->matchlvl = UMATCH_VENDOR_PRODUCT;
- else
- uha->matchlvl = 0;
- return ((*cf->cf_attach->ca_match)(parent, cf, aux));
-}
-
-int
-uhidev_activate(device_ptr_t self, enum devact act)
-{
- struct uhidev_softc *sc = (struct uhidev_softc *)self;
- int i, rv;
-
- switch (act) {
- case DVACT_ACTIVATE:
- return (EOPNOTSUPP);
- break;
-
- case DVACT_DEACTIVATE:
- rv = 0;
- for (i = 0; i < sc->sc_nrepid; i++)
- if (sc->sc_subdevs[i] != NULL)
- rv |= config_deactivate(
- &sc->sc_subdevs[i]->sc_dev);
- sc->sc_dying = 1;
- break;
- }
- return (rv);
-}
-
-USB_DETACH(uhidev)
-{
- USB_DETACH_START(uhidev, sc);
- int i, rv;
-
- DPRINTF(("uhidev_detach: sc=%p flags=%d\n", sc, flags));
-
- sc->sc_dying = 1;
- if (sc->sc_intrpipe != NULL)
- usbd_abort_pipe(sc->sc_intrpipe);
-
- if (sc->sc_repdesc != NULL)
- free(sc->sc_repdesc, M_USBDEV);
-
- rv = 0;
- for (i = 0; i < sc->sc_nrepid; i++) {
- if (sc->sc_subdevs[i] != NULL) {
- rv |= config_detach(&sc->sc_subdevs[i]->sc_dev, flags);
- sc->sc_subdevs[i] = NULL;
- }
- }
-
- usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
- USBDEV(sc->sc_dev));
-
- return (rv);
-}
-
-void
-uhidev_intr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status)
-{
- struct uhidev_softc *sc = addr;
- struct uhidev *scd;
- u_char *p;
- u_int rep;
- u_int32_t cc;
-
- usbd_get_xfer_status(xfer, NULL, NULL, &cc, NULL);
-
-#ifdef UHIDEV_DEBUG
- if (uhidevdebug > 5) {
- u_int32_t i;
-
- DPRINTF(("uhidev_intr: status=%d cc=%d\n", status, cc));
- DPRINTF(("uhidev_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(("%s: interrupt status=%d\n", USBDEVNAME(sc->sc_dev),
- status));
- usbd_clear_endpoint_stall_async(sc->sc_intrpipe);
- return;
- }
-
- p = sc->sc_ibuf;
- if (sc->sc_nrepid != 1)
- rep = *p++, cc--;
- else
- rep = 0;
- if (rep >= sc->sc_nrepid) {
- printf("uhidev_intr: bad repid %d\n", rep);
- return;
- }
- scd = sc->sc_subdevs[rep];
- DPRINTFN(5,("uhidev_intr: rep=%d, scd=%p state=0x%x\n",
- rep, scd, scd ? scd->sc_state : 0));
- if (scd == NULL || !(scd->sc_state & UHIDEV_OPEN))
- return;
-#ifdef DIAGNOSTIC
- if (scd->sc_in_rep_size != cc)
- printf("%s: bad input length %d != %d\n",USBDEVNAME(sc->sc_dev),
- scd->sc_in_rep_size, cc);
-#endif
- scd->sc_intr(scd, p, cc);
-}
-
-void
-uhidev_get_report_desc(struct uhidev_softc *sc, void **desc, int *size)
-{
- *desc = sc->sc_repdesc;
- *size = sc->sc_repdesc_size;
-}
-
-int
-uhidev_open(struct uhidev *scd)
-{
- struct uhidev_softc *sc = scd->sc_parent;
- usbd_status err;
-
- DPRINTF(("uhidev_open: open pipe, state=%d refcnt=%d\n",
- scd->sc_state, sc->sc_refcnt));
-
- if (scd->sc_state & UHIDEV_OPEN)
- return (EBUSY);
- scd->sc_state |= UHIDEV_OPEN;
- if (sc->sc_refcnt++)
- return (0);
-
- if (sc->sc_isize == 0)
- return (0);
-
- sc->sc_ibuf = malloc(sc->sc_isize, M_USBDEV, M_WAITOK);
-
- /* Set up interrupt pipe. */
- DPRINTF(("uhidev_open: isize=%d, ep=0x%02x\n", sc->sc_isize,
- sc->sc_ep_addr));
- 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, uhidev_intr, USBD_DEFAULT_INTERVAL);
- if (err) {
- DPRINTF(("uhidopen: usbd_open_pipe_intr failed, "
- "error=%d\n",err));
- free(sc->sc_ibuf, M_USBDEV);
- scd->sc_state &= ~UHIDEV_OPEN;
- sc->sc_refcnt = 0;
- sc->sc_intrpipe = NULL;
- return (EIO);
- }
- return (0);
-}
-
-void
-uhidev_close(struct uhidev *scd)
-{
- struct uhidev_softc *sc = scd->sc_parent;
-
- if (!(scd->sc_state & UHIDEV_OPEN))
- return;
- scd->sc_state &= ~UHIDEV_OPEN;
- if (--sc->sc_refcnt)
- return;
- DPRINTF(("uhidev_close: close pipe\n"));
-
- /* Disable interrupts. */
- if (sc->sc_intrpipe != NULL) {
- usbd_abort_pipe(sc->sc_intrpipe);
- usbd_close_pipe(sc->sc_intrpipe);
- sc->sc_intrpipe = NULL;
- }
-
- if (sc->sc_ibuf != NULL) {
- free(sc->sc_ibuf, M_USBDEV);
- sc->sc_ibuf = NULL;
- }
-}
-
-usbd_status
-uhidev_set_report(struct uhidev *scd, int type, void *data, int len)
-{
- /* XXX */
- char buf[100];
- if (scd->sc_report_id) {
- buf[0] = scd->sc_report_id;
- memcpy(buf+1, data, len);
- len++;
- data = buf;
- }
-
- return usbd_set_report(scd->sc_parent->sc_iface, type,
- scd->sc_report_id, data, len);
-}
-
-void
-uhidev_set_report_async(struct uhidev *scd, int type, void *data, int len)
-{
- /* XXX */
- char buf[100];
- if (scd->sc_report_id) {
- buf[0] = scd->sc_report_id;
- memcpy(buf+1, data, len);
- len++;
- data = buf;
- }
-
- usbd_set_report_async(scd->sc_parent->sc_iface, type,
- scd->sc_report_id, data, len);
-}
-
-usbd_status
-uhidev_get_report(struct uhidev *scd, int type, void *data, int len)
-{
- return usbd_get_report(scd->sc_parent->sc_iface, type,
- scd->sc_report_id, data, len);
-}
diff --git a/sys/dev/usb/uhidev.h b/sys/dev/usb/uhidev.h
deleted file mode 100644
index 8d2700132cb..00000000000
--- a/sys/dev/usb/uhidev.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/* $OpenBSD: uhidev.h,v 1.1 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: uhidev.h,v 1.2 2001/12/29 18:56:52 augustss Exp $ */
-
-/*
- * 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) 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.
- */
-
-#if defined(__NetBSD__)
-#include "locators.h"
-#endif
-
-#define uhidevcf_reportid cf_loc[UHIDBUSCF_REPORTID]
-#define UHIDEV_UNK_REPORTID UHIDBUSCF_REPORTID_DEFAULT
-
-struct uhidev_softc {
- USBBASEDEVICE 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;
-
- u_char *sc_ibuf;
- u_int sc_isize;
-
- void *sc_repdesc;
- int sc_repdesc_size;
-
- u_int sc_nrepid;
- struct uhidev **sc_subdevs;
-
- int sc_refcnt;
- u_char sc_dying;
-};
-
-struct uhidev {
- USBBASEDEVICE sc_dev; /* base device */
- struct uhidev_softc *sc_parent;
- uByte sc_report_id;
- u_int8_t sc_state;
- int sc_in_rep_size;
-#define UHIDEV_OPEN 0x01 /* device is open */
- void (*sc_intr)(struct uhidev *, void *, u_int);
-};
-
-struct uhidev_attach_arg {
- struct usb_attach_arg *uaa;
- struct uhidev_softc *parent;
- int reportid;
- int reportsize;
- int matchlvl;
-};
-
-void uhidev_get_report_desc(struct uhidev_softc *, void **, int *);
-int uhidev_open(struct uhidev *);
-void uhidev_close(struct uhidev *);
-usbd_status uhidev_set_report(struct uhidev *scd, int type, void *data,int len);
-void uhidev_set_report_async(struct uhidev *scd, int type, void *data, int len);
-usbd_status uhidev_get_report(struct uhidev *scd, int type, void *data,int len);
diff --git a/sys/dev/usb/uhub.c b/sys/dev/usb/uhub.c
index 364de76d3f4..19c6acc0b10 100644
--- a/sys/dev/usb/uhub.c
+++ b/sys/dev/usb/uhub.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: uhub.c,v 1.15 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: uhub.c,v 1.57 2001/11/20 16:08:37 augustss Exp $ */
+/* $OpenBSD: uhub.c,v 1.16 2002/05/07 18:29:18 nate Exp $ */
+/* $NetBSD: uhub.c,v 1.52 2001/10/26 17:53:59 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/uhub.c,v 1.18 1999/11/17 22:33:43 n_hibma Exp $ */
/*
@@ -268,7 +268,6 @@ USB_ATTACH(uhub)
* For all ports
* get port status
* if device connected
- * wait 100 ms
* turn on reset
* wait
* clear C_PORT_RESET
@@ -324,7 +323,6 @@ uhub_explore(usbd_device_handle dev)
struct uhub_softc *sc = dev->hub->hubsoftc;
struct usbd_port *up;
usbd_status err;
- int speed;
int port;
int change, status;
@@ -425,38 +423,15 @@ uhub_explore(usbd_device_handle dev)
/* Reset port, which implies enabling it. */
if (usbd_reset_port(dev, port, &up->status)) {
- printf("%s: port %d reset failed\n",
- USBDEVNAME(sc->sc_dev), 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
- printf("%s: port %d, device disappeared after reset\n",
- USBDEVNAME(sc->sc_dev), port);
-#endif
+ printf("uhub_explore: port=%d reset failed\n",
+ port);
continue;
}
- /* 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(USBDEV(sc->sc_dev), dev->bus,
- dev->depth + 1, speed, port, up);
+ dev->depth + 1, status & UPS_LOW_SPEED,
+ port, up);
/* XXX retry a few times? */
if (err) {
DPRINTFN(-1,("uhub_explore: usb_new_device failed, "
diff --git a/sys/dev/usb/ukbd.c b/sys/dev/usb/ukbd.c
index b57d0f4e37b..0843bd9392d 100644
--- a/sys/dev/usb/ukbd.c
+++ b/sys/dev/usb/ukbd.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: ukbd.c,v 1.12 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: ukbd.c,v 1.79 2001/12/30 19:37:43 augustss Exp $ */
+/* $OpenBSD: ukbd.c,v 1.13 2002/05/07 18:29:18 nate Exp $ */
+/* $NetBSD: ukbd.c,v 1.69 2001/10/24 21:02:18 augustss Exp $ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -66,7 +66,6 @@
#include <dev/usb/usbdi_util.h>
#include <dev/usb/usbdevs.h>
#include <dev/usb/usb_quirks.h>
-#include <dev/usb/uhidev.h>
#include <dev/usb/hid.h>
#include <dev/usb/ukbdvar.h>
@@ -89,96 +88,119 @@ int ukbddebug = 0;
#define DPRINTFN(n,x)
#endif
-#define MAXKEYCODE 6
-#define MAXMOD 8 /* max 32 */
+#define NKEYCODE 6
+
+#define NUM_LOCK 0x01
+#define CAPS_LOCK 0x02
+#define SCROLL_LOCK 0x04
struct ukbd_data {
- u_int32_t modifiers;
- u_int8_t keycode[MAXKEYCODE];
+ 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 PRESS 0x000
#define RELEASE 0x100
#define CODEMASK 0x0ff
+/* Translate USB bitmap to USB keycode. */
+#define NMOD 8
+Static const struct {
+ int mask, key;
+} ukbd_mods[NMOD] = {
+ { MOD_CONTROL_L, 224 },
+ { MOD_CONTROL_R, 228 },
+ { MOD_SHIFT_L, 225 },
+ { MOD_SHIFT_R, 229 },
+ { MOD_ALT_L, 226 },
+ { MOD_ALT_R, 230 },
+ { MOD_WIN_L, 227 },
+ { MOD_WIN_R, 231 },
+};
+
#if defined(WSDISPLAY_COMPAT_RAWKBD)
#define NN 0 /* no translation */
/*
* Translate USB keycodes to US keyboard XT scancodes.
- * Scancodes >= 0x80 represent EXTENDED keycodes.
- *
- * See http://www.microsoft.com/HWDEV/TECH/input/Scancode.asp
+ * Scancodes >= 128 represent EXTENDED keycodes.
*/
Static const u_int8_t ukbd_trtab[256] = {
- NN, NN, NN, NN, 0x1e, 0x30, 0x2e, 0x20, /* 00 - 07 */
- 0x12, 0x21, 0x22, 0x23, 0x17, 0x24, 0x25, 0x26, /* 08 - 0f */
- 0x32, 0x31, 0x18, 0x19, 0x10, 0x13, 0x1f, 0x14, /* 10 - 17 */
- 0x16, 0x2f, 0x11, 0x2d, 0x15, 0x2c, 0x02, 0x03, /* 18 - 1f */
- 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, /* 20 - 27 */
- 0x1c, 0x01, 0x0e, 0x0f, 0x39, 0x0c, 0x0d, 0x1a, /* 28 - 2f */
- 0x1b, 0x2b, 0x2b, 0x27, 0x28, 0x29, 0x33, 0x34, /* 30 - 37 */
- 0x35, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, /* 38 - 3f */
- 0x41, 0x42, 0x43, 0x44, 0x57, 0x58, 0xaa, 0x46, /* 40 - 47 */
- 0x7f, 0xd2, 0xc7, 0xc9, 0xd3, 0xcf, 0xd1, 0xcd, /* 48 - 4f */
- 0xcb, 0xd0, 0xc8, 0x45, 0xb5, 0x37, 0x4a, 0x4e, /* 50 - 57 */
- 0x9c, 0x4f, 0x50, 0x51, 0x4b, 0x4c, 0x4d, 0x47, /* 58 - 5f */
- 0x48, 0x49, 0x52, 0x53, 0x56, 0xdd, NN, 0x59, /* 60 - 67 */
- 0x5d, 0x5e, 0x5f, NN, NN, NN, NN, NN, /* 68 - 6f */
- NN, NN, NN, NN, NN, NN, NN, NN, /* 70 - 77 */
- NN, NN, NN, NN, NN, NN, NN, NN, /* 78 - 7f */
- NN, NN, NN, NN, NN, 0x7e, NN, 0x73, /* 80 - 87 */
- 0x70, 0x7d, 0x79, 0x7b, 0x5c, NN, NN, NN, /* 88 - 8f */
- NN, NN, 0x78, 0x77, 0x76, 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 */
- 0x1d, 0x2a, 0x38, 0xdb, 0x9d, 0x36, 0xb8, 0xdc, /* 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 */
+ NN, NN, NN, NN, 30, 48, 46, 32, /* 00 - 07 */
+ 18, 33, 34, 35, 23, 36, 37, 38, /* 08 - 0F */
+ 50, 49, 24, 25, 16, 19, 31, 20, /* 10 - 17 */
+ 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, 170, 70, /* 40 - 47 */
+ 127, 210, 199, 201, 211, 207, 209, 205, /* 48 - 4F */
+ 203, 208, 200, 69, 181, 55, 74, 78, /* 50 - 57 */
+ 156, 79, 80, 81, 75, 76, 77, 71, /* 58 - 5F */
+ 72, 73, 82, 83, 86, 221, NN, NN, /* 60 - 67 */
+ NN, NN, NN, NN, NN, NN, NN, NN, /* 68 - 6F */
+ NN, NN, NN, NN, NN, NN, NN, NN, /* 70 - 77 */
+ NN, NN, NN, NN, NN, NN, NN, NN, /* 78 - 7F */
+ NN, NN, NN, NN, NN, NN, NN, NN, /* 80 - 87 */
+ NN, NN, NN, NN, 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, 219, 157, 54, 184,220, /* 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 */
};
#endif /* defined(WSDISPLAY_COMPAT_RAWKBD) */
#define KEY_ERROR 0x01
-#define MAXKEYS (MAXMOD+2*MAXKEYCODE)
+#define MAXKEYS (NMOD+2*NKEYCODE)
struct ukbd_softc {
- struct uhidev sc_hdev;
+ USBBASEDEVICE 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;
struct ukbd_data sc_ndata;
struct ukbd_data sc_odata;
- struct hid_location sc_modloc[MAXMOD];
- u_int sc_nmod;
- struct {
- u_int32_t mask;
- u_int8_t key;
- } sc_mods[MAXMOD];
-
- struct hid_location sc_keycodeloc;
- u_int sc_nkeycode;
char sc_enabled;
int sc_console_keyboard; /* we are the console keyboard */
char sc_debounce; /* for quirk handling */
- usb_callout_t sc_delay; /* for quirk handling */
struct ukbd_data sc_data; /* for quirk handling */
- struct hid_location sc_numloc;
- struct hid_location sc_capsloc;
- struct hid_location sc_scroloc;
int sc_leds;
- usb_callout_t sc_rawrepeat_ch;
+#if defined(__OpenBSD__)
+ struct timeout sc_delay; /* for quirk handling */
+ struct timeout sc_rawrepeat_ch;
+#else
+ struct callout sc_delay; /* for quirk handling */
+ struct callout sc_rawrepeat_ch;
+#endif
+#if defined(__NetBSD__) || defined(__OpenBSD__)
struct device *sc_wskbddev;
#if defined(WSDISPLAY_COMPAT_RAWKBD)
#define REP_DELAY1 400
@@ -191,6 +213,7 @@ struct ukbd_softc {
int sc_polling;
int sc_npollchar;
u_int16_t sc_pollchars[MAXKEYS];
+#endif
u_char sc_dying;
};
@@ -231,21 +254,22 @@ Static int ukbd_is_console;
Static void ukbd_cngetc(void *, u_int *, int *);
Static void ukbd_cnpollc(void *, int);
+#if defined(__NetBSD__) || defined(__OpenBSD__)
const struct wskbd_consops ukbd_consops = {
ukbd_cngetc,
ukbd_cnpollc,
};
+#endif
-Static const char *ukbd_parse_desc(struct ukbd_softc *sc);
-
-Static void ukbd_intr(struct uhidev *addr, void *ibuf, u_int len);
+Static void ukbd_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
Static void ukbd_decode(struct ukbd_softc *sc, struct ukbd_data *ud);
Static void ukbd_delayed_decode(void *addr);
Static int ukbd_enable(void *, int);
Static void ukbd_set_leds(void *, int);
-Static int ukbd_ioctl(void *, u_long, caddr_t, int, usb_proc_ptr );
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+Static int ukbd_ioctl(void *, u_long, caddr_t, int, struct proc *);
#ifdef WSDISPLAY_COMPAT_RAWKBD
Static void ukbd_rawrepeat(void *v);
#endif
@@ -266,53 +290,90 @@ const struct wskbd_mapdata ukbd_keymapdata = {
KB_US,
#endif
};
+#endif
USB_DECLARE_DRIVER(ukbd);
USB_MATCH(ukbd)
{
USB_MATCH_START(ukbd, uaa);
- struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)uaa;
- int size;
- void *desc;
+ usb_interface_descriptor_t *id;
- uhidev_get_report_desc(uha->parent, &desc, &size);
- if (!hid_is_collection(desc, size, uha->reportid,
- HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_KEYBOARD)))
+ /* Check that this is a keyboard that speaks the boot protocol. */
+ if (uaa->iface == NULL)
return (UMATCH_NONE);
-
- return (UMATCH_IFACECLASS);
+ id = usbd_get_interface_descriptor(uaa->iface);
+ if (id == NULL ||
+ id->bInterfaceClass != UICLASS_HID ||
+ id->bInterfaceSubClass != UISUBCLASS_BOOT ||
+ id->bInterfaceProtocol != UIPROTO_BOOT_KEYBOARD)
+ return (UMATCH_NONE);
+ return (UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO);
}
USB_ATTACH(ukbd)
{
USB_ATTACH_START(ukbd, sc, uaa);
- struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)uaa;
+ usbd_interface_handle iface = uaa->iface;
+ usb_interface_descriptor_t *id;
+ usb_endpoint_descriptor_t *ed;
+ usbd_status err;
u_int32_t qflags;
- const char *parseerr;
+ char devinfo[1024];
+#if defined(__NetBSD__) || defined(__OpenBSD__)
struct wskbddev_attach_args a;
+#else
+ int i;
+#endif
- sc->sc_hdev.sc_intr = ukbd_intr;
- sc->sc_hdev.sc_parent = uha->parent;
- sc->sc_hdev.sc_report_id = uha->reportid;
-
- parseerr = ukbd_parse_desc(sc);
- if (parseerr != NULL) {
- printf("\n%s: attach failed, %s\n",
- sc->sc_hdev.sc_dev.dv_xname, parseerr);
+ sc->sc_udev = uaa->device;
+ sc->sc_iface = iface;
+ id = usbd_get_interface_descriptor(iface);
+ usbd_devinfo(uaa->device, 0, devinfo);
+ USB_ATTACH_SETUP;
+ printf("%s: %s, iclass %d/%d\n", USBDEVNAME(sc->sc_dev),
+ devinfo, id->bInterfaceClass, id->bInterfaceSubClass);
+
+ ed = usbd_interface2endpoint_descriptor(iface, 0);
+ if (ed == NULL) {
+ printf("%s: could not read endpoint descriptor\n",
+ USBDEVNAME(sc->sc_dev));
USB_ATTACH_ERROR_RETURN;
}
-
-#ifdef DIAGNOSTIC
- printf(": %d modifier keys, %d key codes", sc->sc_nmod,
- sc->sc_nkeycode);
-#endif
- printf("\n");
+ DPRINTFN(10,("ukbd_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",
+ USBDEVNAME(sc->sc_dev));
+ USB_ATTACH_ERROR_RETURN;
+ }
- qflags = usbd_get_quirks(uha->parent->sc_udev)->uq_flags;
+ qflags = usbd_get_quirks(uaa->device)->uq_flags;
+ if ((qflags & UQ_NO_SET_PROTO) == 0) {
+ err = usbd_set_protocol(iface, 0);
+ DPRINTFN(5, ("ukbd_attach: protocol set\n"));
+ if (err) {
+ printf("%s: set protocol failed\n",
+ USBDEVNAME(sc->sc_dev));
+ USB_ATTACH_ERROR_RETURN;
+ }
+ }
sc->sc_debounce = (qflags & UQ_SPUR_BUT_UP) != 0;
+ /* Ignore if SETIDLE fails since it is not crucial. */
+ (void)usbd_set_idle(iface, 0, 0);
+
+ sc->sc_ep_addr = ed->bEndpointAddress;
+
/*
* Remember if we're the console keyboard.
*
@@ -337,14 +398,26 @@ USB_ATTACH(ukbd)
a.accessops = &ukbd_accessops;
a.accesscookie = sc;
- usb_callout_init(sc->sc_rawrepeat_ch);
- usb_callout_init(sc->sc_delay);
+#if defined(__OpenBSD__)
+#ifdef WSDISPLAY_COMPAT_RAWKBD
+ timeout_set(&sc->sc_rawrepeat_ch, ukbd_rawrepeat, sc);
+#endif
+ timeout_set(&sc->sc_delay, ukbd_delayed_decode, sc);
+#endif
+
+#if defined(__NetBSD__)
+ callout_init(&sc->sc_rawrepeat_ch);
+ callout_init(&sc->sc_delay);
+#endif
/* Flash the leds; no real purpose, just shows we're alive. */
ukbd_set_leds(sc, WSKBD_LED_SCROLL | WSKBD_LED_NUM | WSKBD_LED_CAPS);
- usbd_delay_ms(uha->parent->sc_udev, 400);
+ usbd_delay_ms(uaa->device, 400);
ukbd_set_leds(sc, 0);
+ usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
+ USBDEV(sc->sc_dev));
+
sc->sc_wskbddev = config_found(self, &a, wskbddevprint);
USB_ATTACH_SUCCESS_RETURN;
@@ -354,27 +427,38 @@ int
ukbd_enable(void *v, int on)
{
struct ukbd_softc *sc = v;
+ usbd_status err;
if (on && sc->sc_dying)
return (EIO);
/* Should only be called to change state */
if (sc->sc_enabled == on) {
-#ifdef DIAGNOSTIC
+#ifdef UKBD_DEBUG
printf("ukbd_enable: %s: bad call on=%d\n",
- USBDEVNAME(sc->sc_hdev.sc_dev), on);
+ USBDEVNAME(sc->sc_dev), on);
#endif
return (EBUSY);
}
DPRINTF(("ukbd_enable: sc=%p on=%d\n", sc, on));
- sc->sc_enabled = on;
if (on) {
- return (uhidev_open(&sc->sc_hdev));
+ /* 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_ndata, sizeof(sc->sc_ndata), ukbd_intr,
+ USBD_DEFAULT_INTERVAL);
+ if (err)
+ return (EIO);
} else {
- uhidev_close(&sc->sc_hdev);
- return (0);
+ /* Disable interrupts. */
+ usbd_abort_pipe(sc->sc_intrpipe);
+ usbd_close_pipe(sc->sc_intrpipe);
+ sc->sc_intrpipe = NULL;
}
+ sc->sc_enabled = on;
+
+ return (0);
}
int
@@ -423,8 +507,7 @@ USB_DETACH(ukbd)
* XXX Should notify some other keyboard that it can be
* XXX console, if there are any other keyboards.
*/
- printf("%s: was console keyboard\n",
- USBDEVNAME(sc->sc_hdev.sc_dev));
+ printf("%s: was console keyboard\n", USBDEVNAME(sc->sc_dev));
wskbd_cndetach();
ukbd_is_console = 1;
#endif
@@ -434,34 +517,37 @@ USB_DETACH(ukbd)
rv = config_detach(sc->sc_wskbddev, flags);
/* The console keyboard does not get a disable call, so check pipe. */
- if (sc->sc_hdev.sc_state & UHIDEV_OPEN)
- uhidev_close(&sc->sc_hdev);
+ if (sc->sc_intrpipe != NULL) {
+ usbd_abort_pipe(sc->sc_intrpipe);
+ usbd_close_pipe(sc->sc_intrpipe);
+ sc->sc_intrpipe = NULL;
+ }
+
+ usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
+ USBDEV(sc->sc_dev));
return (rv);
}
void
-ukbd_intr(struct uhidev *addr, void *ibuf, u_int len)
+ukbd_intr(xfer, addr, status)
+ usbd_xfer_handle xfer;
+ usbd_private_handle addr;
+ usbd_status status;
{
- struct ukbd_softc *sc = (struct ukbd_softc *)addr;
+ struct ukbd_softc *sc = addr;
struct ukbd_data *ud = &sc->sc_ndata;
- int i;
-#ifdef UKBD_DEBUG
- if (ukbddebug > 5) {
- printf("ukbd_intr: data");
- for (i = 0; i < len; i++)
- printf(" 0x%02x", ((u_char *)ibuf)[i]);
- printf("\n");
- }
-#endif
+ DPRINTFN(5, ("ukbd_intr: status=%d\n", status));
+ if (status == USBD_CANCELLED)
+ return;
- ud->modifiers = 0;
- for (i = 0; i < sc->sc_nmod; i++)
- if (hid_get_data(ibuf, &sc->sc_modloc[i]))
- ud->modifiers |= sc->sc_mods[i].mask;
- memcpy(ud->keycode, (char *)ibuf + sc->sc_keycodeloc.pos / 8,
- sc->sc_nkeycode);
+ if (status) {
+ DPRINTF(("ukbd_intr: status=%d\n", status));
+ if (status == USBD_STALLED)
+ usbd_clear_endpoint_stall_async(sc->sc_intrpipe);
+ return;
+ }
if (sc->sc_debounce && !sc->sc_polling) {
/*
@@ -471,8 +557,12 @@ ukbd_intr(struct uhidev *addr, void *ibuf, u_int len)
* We avoid this bug by holding off decoding for 20 ms.
*/
sc->sc_data = *ud;
- usb_callout(sc->sc_delay, hz / 50, ukbd_delayed_decode, sc);
-#ifdef DDB
+#if defined(__OpenBSD__)
+ timeout_add(&sc->sc_delay, hz / 50);
+#else
+ callout_reset(&sc->sc_delay, hz / 50, ukbd_delayed_decode, sc);
+#endif
+#if DDB
} else if (sc->sc_console_keyboard && !sc->sc_polling) {
/*
* For the console keyboard we can't deliver CTL-ALT-ESC
@@ -481,7 +571,11 @@ ukbd_intr(struct uhidev *addr, void *ibuf, u_int len)
* loses bigtime.
*/
sc->sc_data = *ud;
- usb_callout(sc->sc_delay, 1, ukbd_delayed_decode, sc);
+#if defined(__OpenBSD__)
+ timeout_add(&sc->sc_delay, 1); /* NOT an immediate timeout */
+#else
+ callout_reset(&sc->sc_delay, 0, ukbd_delayed_decode, sc);
+#endif
#endif
} else {
ukbd_decode(sc, ud);
@@ -513,7 +607,7 @@ ukbd_decode(struct ukbd_softc *sc, struct ukbd_data *ud)
*/
if (ukbdtrace) {
struct ukbdtraceinfo *p = &ukbdtracedata[ukbdtraceindex];
- p->unit = sc->sc_hdev.sc_dev.dv_unit;
+ p->unit = sc->sc_dev.dv_unit;
microtime(&p->tv);
p->ud = *ud;
if (++ukbdtraceindex >= UKBDTRACESIZE)
@@ -538,19 +632,19 @@ ukbd_decode(struct ukbd_softc *sc, struct ukbd_data *ud)
mod = ud->modifiers;
omod = sc->sc_odata.modifiers;
if (mod != omod)
- for (i = 0; i < sc->sc_nmod; i++)
- if (( mod & sc->sc_mods[i].mask) !=
- (omod & sc->sc_mods[i].mask))
- ADDKEY(sc->sc_mods[i].key |
- (mod & sc->sc_mods[i].mask
+ for (i = 0; i < NMOD; i++)
+ if (( mod & ukbd_mods[i].mask) !=
+ (omod & ukbd_mods[i].mask))
+ ADDKEY(ukbd_mods[i].key |
+ (mod & ukbd_mods[i].mask
? PRESS : RELEASE));
- if (memcmp(ud->keycode, sc->sc_odata.keycode, sc->sc_nkeycode) != 0) {
+ if (memcmp(ud->keycode, sc->sc_odata.keycode, NKEYCODE) != 0) {
/* Check for released keys. */
- for (i = 0; i < sc->sc_nkeycode; i++) {
+ for (i = 0; i < NKEYCODE; i++) {
key = sc->sc_odata.keycode[i];
if (key == 0)
continue;
- for (j = 0; j < sc->sc_nkeycode; j++)
+ for (j = 0; j < NKEYCODE; j++)
if (key == ud->keycode[j])
goto rfound;
DPRINTFN(3,("ukbd_intr: relse key=0x%02x\n", key));
@@ -560,11 +654,11 @@ ukbd_decode(struct ukbd_softc *sc, struct ukbd_data *ud)
}
/* Check for pressed keys. */
- for (i = 0; i < sc->sc_nkeycode; i++) {
+ for (i = 0; i < NKEYCODE; i++) {
key = ud->keycode[i];
if (key == 0)
continue;
- for (j = 0; j < sc->sc_nkeycode; j++)
+ for (j = 0; j < NKEYCODE; j++)
if (key == sc->sc_odata.keycode[j])
goto pfound;
DPRINTFN(2,("ukbd_intr: press key=0x%02x\n", key));
@@ -586,7 +680,7 @@ ukbd_decode(struct ukbd_softc *sc, struct ukbd_data *ud)
}
#ifdef WSDISPLAY_COMPAT_RAWKBD
if (sc->sc_rawkbd) {
- u_char cbuf[MAXKEYS * 2];
+ char cbuf[MAXKEYS * 2];
int c;
int npress;
@@ -614,11 +708,19 @@ ukbd_decode(struct ukbd_softc *sc, struct ukbd_data *ud)
s = spltty();
wskbd_rawinput(sc->sc_wskbddev, cbuf, j);
splx(s);
- usb_uncallout(sc->sc_rawrepeat_ch, ukbd_rawrepeat, sc);
+#if defined(__OpenBSD__)
+ timeout_del(&sc->sc_rawrepeat_ch);
+#else
+ callout_stop(&sc->sc_rawrepeat_ch);
+#endif
if (npress != 0) {
sc->sc_nrep = npress;
- usb_callout(sc->sc_rawrepeat_ch,
+#if defined(__OpenBSD__)
+ timeout_add(&sc->sc_rawrepeat_ch, hz * REP_DELAY1/1000);
+#else
+ callout_reset(&sc->sc_rawrepeat_ch,
hz * REP_DELAY1 / 1000, ukbd_rawrepeat, sc);
+#endif
}
return;
}
@@ -640,24 +742,21 @@ ukbd_set_leds(void *v, int leds)
struct ukbd_softc *sc = v;
u_int8_t res;
- DPRINTF(("ukbd_set_leds: sc=%p leds=%d, sc_leds=%d\n",
- sc, leds, sc->sc_leds));
+ DPRINTF(("ukbd_set_leds: sc=%p leds=%d\n", sc, leds));
if (sc->sc_dying)
return;
- if (sc->sc_leds == leds)
- return;
sc->sc_leds = leds;
res = 0;
- /* XXX not really right */
- if ((leds & WSKBD_LED_SCROLL) && sc->sc_scroloc.size == 1)
- res |= 1 << sc->sc_scroloc.pos;
- if ((leds & WSKBD_LED_NUM) && sc->sc_numloc.size == 1)
- res |= 1 << sc->sc_numloc.pos;
- if ((leds & WSKBD_LED_CAPS) && sc->sc_capsloc.size == 1)
- res |= 1 << sc->sc_capsloc.pos;
- uhidev_set_report_async(&sc->sc_hdev, UHID_OUTPUT_REPORT, &res, 1);
+ if (leds & WSKBD_LED_SCROLL)
+ res |= SCROLL_LOCK;
+ if (leds & WSKBD_LED_NUM)
+ res |= NUM_LOCK;
+ if (leds & WSKBD_LED_CAPS)
+ res |= CAPS_LOCK;
+ res |= leds & 0xf8;
+ usbd_set_report_async(sc->sc_iface, UHID_OUTPUT_REPORT, 0, &res, 1);
}
#ifdef WSDISPLAY_COMPAT_RAWKBD
@@ -670,13 +769,17 @@ ukbd_rawrepeat(void *v)
s = spltty();
wskbd_rawinput(sc->sc_wskbddev, sc->sc_rep, sc->sc_nrep);
splx(s);
- usb_callout(sc->sc_rawrepeat_ch, hz * REP_DELAYN / 1000,
+#if defined(__OpenBSD__)
+ timeout_add(&sc->sc_rawrepeat_ch, hz * REP_DELAYN / 1000);
+#else
+ callout_reset(&sc->sc_rawrepeat_ch, hz * REP_DELAYN / 1000,
ukbd_rawrepeat, sc);
+#endif
}
#endif
int
-ukbd_ioctl(void *v, u_long cmd, caddr_t data, int flag, usb_proc_ptr p)
+ukbd_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
{
struct ukbd_softc *sc = v;
@@ -694,19 +797,17 @@ ukbd_ioctl(void *v, u_long cmd, caddr_t data, int flag, usb_proc_ptr p)
case WSKBDIO_SETMODE:
DPRINTF(("ukbd_ioctl: set raw = %d\n", *(int *)data));
sc->sc_rawkbd = *(int *)data == WSKBD_RAW;
- usb_uncallout(sc->sc_rawrepeat_ch, ukbd_rawrepeat, sc);
+#if defined(__OpenBSD__)
+ timeout_del(&sc->sc_rawrepeat_ch);
+#else
+ callout_stop(&sc->sc_rawrepeat_ch);
+#endif
return (0);
#endif
}
return (-1);
}
-/*
- * This is a hack to work around some broken ports that don't call
- * cnpollc() before cngetc().
- */
-static int pollenter, warned;
-
/* Console interface. */
void
ukbd_cngetc(void *v, u_int *type, int *data)
@@ -714,25 +815,12 @@ ukbd_cngetc(void *v, u_int *type, int *data)
struct ukbd_softc *sc = v;
int s;
int c;
- int broken;
-
- if (pollenter == 0) {
- if (!warned) {
- printf("\n"
-"This port is broken, it does not call cnpollc() before calling cngetc().\n"
-"This should be fixed, but it will work anyway (for now).\n");
- warned = 1;
- }
- broken = 1;
- ukbd_cnpollc(v, 1);
- } else
- broken = 0;
DPRINTFN(0,("ukbd_cngetc: enter\n"));
s = splusb();
sc->sc_polling = 1;
while(sc->sc_npollchar <= 0)
- usbd_dopoll(sc->sc_hdev.sc_parent->sc_iface);
+ usbd_dopoll(sc->sc_iface);
sc->sc_polling = 0;
c = sc->sc_pollchars[0];
sc->sc_npollchar--;
@@ -742,8 +830,6 @@ ukbd_cngetc(void *v, u_int *type, int *data)
*data = c & CODEMASK;
splx(s);
DPRINTFN(0,("ukbd_cngetc: return 0x%02x\n", c));
- if (broken)
- ukbd_cnpollc(v, 0);
}
void
@@ -754,8 +840,7 @@ ukbd_cnpollc(void *v, int on)
DPRINTFN(2,("ukbd_cnpollc: sc=%p on=%d\n", v, on));
- usbd_interface2device_handle(sc->sc_hdev.sc_parent->sc_iface, &dev);
- if (on) pollenter++; else pollenter--;
+ (void)usbd_interface2device_handle(sc->sc_iface,&dev);
usbd_set_polling(dev, on);
}
@@ -771,64 +856,3 @@ ukbd_cnattach(void)
ukbd_is_console = 1;
return (0);
}
-
-const char *
-ukbd_parse_desc(struct ukbd_softc *sc)
-{
- struct hid_data *d;
- struct hid_item h;
- int size;
- void *desc;
- int imod;
-
- uhidev_get_report_desc(sc->sc_hdev.sc_parent, &desc, &size);
- imod = 0;
- sc->sc_nkeycode = 0;
- d = hid_start_parse(desc, size, hid_input);
- while (hid_get_item(d, &h)) {
- /*printf("ukbd: id=%d kind=%d usage=0x%x flags=0x%x pos=%d size=%d cnt=%d\n",
- h.report_ID, h.kind, h.usage, h.flags, h.loc.pos, h.loc.size, h.loc.count);*/
- if (h.kind != hid_input || (h.flags & HIO_CONST) ||
- HID_GET_USAGE_PAGE(h.usage) != HUP_KEYBOARD ||
- h.report_ID != sc->sc_hdev.sc_report_id)
- continue;
- DPRINTF(("ukbd: imod=%d usage=0x%x flags=0x%x pos=%d size=%d "
- "cnt=%d\n", imod,
- h.usage, h.flags, h.loc.pos, h.loc.size, h.loc.count));
- if (h.flags & HIO_VARIABLE) {
- if (h.loc.size != 1)
- return ("bad modifier size");
- /* Single item */
- if (imod < MAXMOD) {
- sc->sc_modloc[imod] = h.loc;
- sc->sc_mods[imod].mask = 1 << imod;
- sc->sc_mods[imod].key = HID_GET_USAGE(h.usage);
- imod++;
- } else
- return ("too many modifier keys");
- } else {
- /* Array */
- if (h.loc.size != 8)
- return ("key code size != 8");
- if (h.loc.count > MAXKEYCODE)
- return ("too many key codes");
- if (h.loc.pos % 8 != 0)
- return ("key codes not on byte boundary");
- if (sc->sc_nkeycode != 0)
- return ("multiple key code arrays\n");
- sc->sc_keycodeloc = h.loc;
- sc->sc_nkeycode = h.loc.count;
- }
- }
- sc->sc_nmod = imod;
- hid_end_parse(d);
-
- hid_locate(desc, size, HID_USAGE2(HUP_LEDS, HUD_LED_NUM_LOCK),
- sc->sc_hdev.sc_report_id, hid_output, &sc->sc_numloc, NULL);
- hid_locate(desc, size, HID_USAGE2(HUP_LEDS, HUD_LED_CAPS_LOCK),
- sc->sc_hdev.sc_report_id, hid_output, &sc->sc_capsloc, NULL);
- hid_locate(desc, size, HID_USAGE2(HUP_LEDS, HUD_LED_SCROLL_LOCK),
- sc->sc_hdev.sc_report_id, hid_output, &sc->sc_scroloc, NULL);
-
- return (NULL);
-}
diff --git a/sys/dev/usb/ukbdmap.c b/sys/dev/usb/ukbdmap.c
index 9d0ad9f25d8..b5f4bb01d69 100644
--- a/sys/dev/usb/ukbdmap.c
+++ b/sys/dev/usb/ukbdmap.c
@@ -1,8 +1,8 @@
-/* $OpenBSD: ukbdmap.c,v 1.10 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: ukbdmap.c,v 1.10 2002/03/17 18:01:07 augustss Exp $ */
+/* $OpenBSD: ukbdmap.c,v 1.11 2002/05/07 18:29:18 nate Exp $ */
+/* $NetBSD: ukbdmap.c,v 1.6 2001/04/04 05:31:57 toshii Exp $ */
/*
- * Copyright (c) 1999,2001 The NetBSD Foundation, Inc.
+ * Copyright (c) 1999 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@@ -94,7 +94,7 @@ Static const keysym_t ukbd_keydesc_us[] = {
KC(47), KS_bracketleft, KS_braceleft,
KC(48), KS_bracketright,KS_braceright,
KC(49), KS_backslash, KS_bar,
- KC(50), KS_backslash, KS_bar,
+ KC(50), KS_numbersign, KS_asciitilde,
KC(51), KS_semicolon, KS_colon,
KC(52), KS_apostrophe, KS_quotedbl,
KC(53), KS_grave, KS_asciitilde,
@@ -256,7 +256,6 @@ Static const keysym_t ukbd_keydesc_sv[] = {
/* pos normal shifted altgr shift-altgr */
KC(45), KS_plus, KS_question, KS_backslash,
KC(48), KS_dead_diaeresis, KS_dead_circumflex, KS_dead_tilde,
- KC(50), KS_comma, KS_asterisk,
KC(51), KS_odiaeresis,
KC(52), KS_adiaeresis,
KC(53), KS_paragraph, KS_onehalf,
@@ -274,7 +273,6 @@ Static const keysym_t ukbd_keydesc_no[] = {
/* pos normal shifted altgr shift-altgr */
KC(46), KS_backslash, KS_dead_grave, KS_dead_acute,
KC(48), KS_dead_diaeresis, KS_dead_circumflex, KS_dead_tilde,
- KC(50), KS_comma, KS_asterisk,
KC(51), KS_oslash,
KC(52), KS_ae,
KC(53), KS_bar, KS_paragraph,
@@ -360,7 +358,6 @@ Static const keysym_t ukbd_keydesc_uk[] = {
KC(45), KS_minus, KS_underscore, KS_hyphen, KS_ssharp,
KC(46), KS_equal, KS_plus, KS_onehalf, KS_guillemotleft,
KC(49), KS_numbersign, KS_asciitilde, KS_sterling, KS_thorn,
- KC(50), KS_numbersign, KS_asciitilde,
KC(52), KS_apostrophe, KS_at, KS_section, KS_Agrave,
KC(53), KS_grave, KS_grave, KS_agrave, KS_agrave,
KC(100), KS_backslash, KS_bar, KS_Udiaeresis,
diff --git a/sys/dev/usb/umass.c b/sys/dev/usb/umass.c
index a47e31a0d27..b1a38c934f8 100644
--- a/sys/dev/usb/umass.c
+++ b/sys/dev/usb/umass.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: umass.c,v 1.15 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: umass.c,v 1.87 2002/03/17 18:02:53 augustss Exp $ */
+/* $OpenBSD: umass.c,v 1.16 2002/05/07 18:29:18 nate Exp $ */
+/* $NetBSD: umass.c,v 1.49 2001/01/21 18:56:38 augustss Exp $ */
/*-
* Copyright (c) 1999 MAEKAWA Masahide <bishop@rr.iij4u.or.jp>,
* Nick Hibma <n_hibma@freebsd.org>
@@ -30,7 +30,7 @@
*/
/*
- * Universal Serial Bus Mass Storage Class specs:
+ * Universal Serial Bus Mass Storage Class Bulk-Only Transport
* http://www.usb.org/developers/data/devclass/usbmassover_11.pdf
* http://www.usb.org/developers/data/devclass/usbmassbulk_10.pdf
* http://www.usb.org/developers/data/devclass/usbmass-cbi10.pdf
@@ -51,14 +51,13 @@
*
* Over these wire protocols it handles the following command protocols
* - SCSI
- * - 8070 (ATA/ATAPI for rewritable removable media)
- * - UFI (USB Floppy Interface)
+ * - UFI (floppy command set)
+ * - 8070 (ATA/ATAPI)
*
- * 8070i is a transformed version of the SCSI command set. UFI is a transformed
- * version of the 8070i command set. The sc->transform method is used to
- * convert the commands into the appropriate format (if at all necessary).
- * For example, ATAPI requires all commands to be 12 bytes in length amongst
- * other things.
+ * UFI and 8070i 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):
@@ -94,15 +93,15 @@
* umass_cam_cb again to complete the CAM command.
*/
-#if defined(__NetBSD__)
+/* XXX Should we split the driver into a number of files? umass.c,
+ * umass_scsi.c, umass_8070.c, umass_ufi.c, umass_bbb.c, umass_cbi.c or
+ * something similar?
+ */
+
+#if !defined(__OpenBSD__)
#include "atapibus.h"
-#include "scsibus.h"
-#elif defined(__OpenBSD__)
-#include "atapiscsi.h"
#endif
-#include "wd.h"
-
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
@@ -125,15 +124,396 @@
#include <dev/usb/usbdi_util.h>
#include <dev/usb/usbdevs.h>
-#include <dev/usb/umassvar.h>
-#include <dev/usb/umass_quirks.h>
-#include <dev/usb/umass_scsipi.h>
-#include <dev/usb/umass_isdata.h>
+#if defined(__FreeBSD__)
+#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>
+
+#ifdef UMASS_DO_CAM_RESCAN
+#include <sys/devicestat.h>
+#include <cam/cam_periph.h>
+#endif
+#elif defined(__NetBSD__)
+#include <sys/scsiio.h>
+#include <dev/scsipi/scsi_all.h>
+#include <dev/scsipi/scsipi_all.h>
+#include <dev/scsipi/scsiconf.h>
+
+#include <dev/scsipi/atapiconf.h>
+
+#include <dev/scsipi/scsipi_disk.h>
+#include <dev/scsipi/scsi_disk.h>
+#include <dev/scsipi/scsi_changer.h>
+
+#include <dev/ata/atavar.h> /* XXX */
+
+#define SCSI_LINK_TARGET(sc) ((sc)->scsipi_scsi.target)
+#define SCSI_LINK_LUN(sc) ((sc)->scsipi_scsi.lun)
+#elif defined(__OpenBSD__)
+#include <scsi/scsi_all.h>
+#include <scsi/scsiconf.h>
+#include <scsi/scsi_disk.h>
+#include <machine/bus.h>
+
+#define SCSI_LINK_TARGET(sc) ((sc)->target)
+#define SCSI_LINK_LUN(sc) ((sc)->lun)
+#define scsipi_generic scsi_generic
+
+#endif
+
+#define SHORT_INQUIRY_LENGTH 36 /* XXX */
#ifdef UMASS_DEBUG
+#define DIF(m, x) if (umassdebug & (m)) do { x ; } while (0)
+#define DPRINTF(m, x) if (umassdebug & (m)) logprintf x
+#define UDMASS_UPPER 0x00008000 /* upper layer */
+#define UDMASS_GEN 0x00010000 /* general */
+#define UDMASS_SCSI 0x00020000 /* scsi */
+#define UDMASS_UFI 0x00040000 /* ufi command set */
+#define UDMASS_8070 0x00080000 /* 8070i command set */
+#define UDMASS_USB 0x00100000 /* USB general */
+#define UDMASS_BBB 0x00200000 /* Bulk-Only transfers */
+#define UDMASS_CBI 0x00400000 /* CBI transfers */
+#define UDMASS_ALL 0xffff0000 /* all of the above */
+
+#define UDMASS_XFER 0x40000000 /* all transfers */
+#define UDMASS_CMD 0x80000000
+
int umassdebug = 0;
+#else
+#define DIF(m, x) /* nop */
+#define DPRINTF(m, x) /* nop */
+#endif
+
+
+/* Generic definitions */
+
+#define UFI_COMMAND_LENGTH 12
+#define ATAPI_COMMAND_LENGTH 12
+/* Direction for umass_*_transfer */
+#define DIR_NONE 0
+#define DIR_IN 1
+#define DIR_OUT 2
+
+/* The transfer speed determines the timeout value */
+#define UMASS_DEFAULT_TRANSFER_SPEED 150 /* in kb/s, conservative est. */
+#define UMASS_FLOPPY_TRANSFER_SPEED 20
+#define UMASS_ZIP100_TRANSFER_SPEED 650
+
+#define UMASS_SPINUP_TIME 10000 /* ms */
+
+#ifdef __FreeBSD__
+/* device name */
+#define DEVNAME "umass"
+#define DEVNAME_SIM "umass-"
+
+#define UMASS_MAX_TRANSFER_SIZE 65536
+
+/* CAM specific definitions */
+
+/* The bus id, whatever that is */
+#define UMASS_SCSI_BUS 0
+
+/* All USB drives are 'connected' to one SIM (SCSI controller). umass3
+ * ends up being target 3 on that SIM. When a request for target 3
+ * comes in we fetch the softc with devclass_get_softc(target_id).
+ *
+ * The SIM is the highest target number. This makes sure that umass0 corresponds
+ * to target 0 on the USB SCSI bus.
+ */
+#ifndef UMASS_DEBUG
+#define UMASS_SCSIID_MAX 32 /* maximum number of drives expected */
+#else
+/* while debugging avoid unnecessary clutter in the output at umass_cam_rescan
+ * (XPT_PATH_INQ)
+ */
+#define UMASS_SCSIID_MAX 3 /* maximum number of drives expected */
+#endif
+#define UMASS_SCSIID_HOST UMASS_SCSIID_MAX
+#endif
+
+#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
+
+/* 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];
+} umass_bbb_cbw_t;
+#define UMASS_BBB_CBW_SIZE 31
+
+/* Command Status Wrapper */
+typedef struct {
+ uDWord dCSWSignature;
+# define CSWSIGNATURE 0x53425355
+ uDWord dCSWTag;
+ uDWord dCSWDataResidue;
+ uByte bCSWStatus;
+# define CSWSTATUS_GOOD 0x0
+# define CSWSTATUS_FAILED 0x1
+# define CSWSTATUS_PHASE 0x2
+} 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, transfer_cb_f cb, void *priv);
+typedef void (*wire_state_f)(usbd_xfer_handle xfer,
+ usbd_private_handle priv, usbd_status err);
+
+#if defined(__FreeBSD__)
+typedef int (*command_transform_f)(struct umass_softc *sc,
+ unsigned char *cmd, int cmdlen,
+ unsigned char **rcmd, int *rcmdlen);
+#endif
+
+
+/* the per device structure */
+struct umass_softc {
+ USBBASEDEVICE sc_dev; /* base device */
+ usbd_device_handle sc_udev; /* device */
+
+ unsigned char drive;
+# define DRIVE_GENERIC 0 /* use defaults for this one */
+# define ZIP_100 1 /* to be used for quirks */
+# define ZIP_250 2
+# define SHUTTLE_EUSB 3
+# define INSYSTEM_USBCABLE 4
+ unsigned char quirks;
+ /* The drive does not support Test Unit Ready. Convert to
+ * Start Unit.
+ * Y-E Data
+ * ZIP 100
+ */
+# define NO_TEST_UNIT_READY 0x01
+ /* 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.
+ * Y-E Data
+ */
+# define RS_NO_CLEAR_UA 0x02 /* no REQUEST SENSE on INQUIRY*/
+ /* The drive does not support START_STOP.
+ * Shuttle E-USB
+ */
+# define NO_START_STOP 0x04
+ /* Don't ask for full inquiry data (255 bytes).
+ * Yano ATAPI-USB
+ */
+# define FORCE_SHORT_INQUIRY 0x08
+
+ unsigned int proto;
+# define PROTO_UNKNOWN 0x0000 /* unknown protocol */
+# define PROTO_BBB 0x0001 /* USB wire protocol */
+# define PROTO_CBI 0x0002
+# define PROTO_CBI_I 0x0004
+# define PROTO_WIRE 0x00ff /* USB wire protocol mask */
+# define PROTO_SCSI 0x0100 /* command protocol */
+# define PROTO_ATAPI 0x0200
+# define PROTO_UFI 0x0400
+# define PROTO_RBC 0x0800
+# define PROTO_COMMAND 0xff00 /* command protocol mask */
+
+ u_char subclass; /* interface subclass */
+ u_char protocol; /* interface protocol */
+
+ 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;
+
+#if defined(__FreeBSD__)
+ /* 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 */
+#endif
+
+ /* 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 */
+
+ void *data_buffer;
+
+ 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_IDLE 0
+# define TSTATE_BBB_COMMAND 1 /* CBW transfer */
+# define TSTATE_BBB_DATA 2 /* Data transfer */
+# define TSTATE_BBB_DCLEAR 3 /* clear endpt stall */
+# define TSTATE_BBB_STATUS1 4 /* clear endpt stall */
+# define TSTATE_BBB_SCLEAR 5 /* clear endpt stall */
+# define TSTATE_BBB_STATUS2 6 /* CSW transfer */
+# define TSTATE_BBB_RESET1 7 /* reset command */
+# define TSTATE_BBB_RESET2 8 /* in clear stall */
+# define TSTATE_BBB_RESET3 9 /* out clear stall */
+# define TSTATE_CBI_COMMAND 10 /* command transfer */
+# define TSTATE_CBI_DATA 11 /* data transfer */
+# define TSTATE_CBI_STATUS 12 /* status transfer */
+# define TSTATE_CBI_DCLEAR 13 /* clear ep stall */
+# define TSTATE_CBI_SCLEAR 14 /* clear ep stall */
+# define TSTATE_CBI_RESET1 15 /* reset command */
+# define TSTATE_CBI_RESET2 16 /* in clear stall */
+# define TSTATE_CBI_RESET3 17 /* out clear stall */
+# define TSTATE_STATES 18 /* # of states above */
+
+
+ int transfer_speed; /* in kb/s */
+ int timeout; /* in msecs */
+
+ u_int8_t maxlun; /* max lun supported */
+
+#ifdef UMASS_DEBUG
+ struct timeval tv;
+#endif
+
+#if defined(__FreeBSD__)
+ /* SCSI/CAM specific variables */
+ struct scsi_sense cam_scsi_sense;
+
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
+ union {
+ struct scsipi_link sc_link;
+#if defined(__NetBSD__)
+ struct {
+ struct ata_atapi_attach sc_aa;
+ struct ata_drive_datas sc_aa_drive;
+ } aa;
+#endif
+ } u;
+#if defined(__NetBSD__)
+ struct atapi_adapter sc_atapi_adapter;
+#define sc_adapter sc_atapi_adapter._generic
+#else
+ struct scsi_adapter sc_atapi_adapter;
+#define sc_adapter sc_atapi_adapter
+#endif
+ int sc_xfer_flags;
+ usbd_status sc_sync_status;
+ struct scsipi_sense sc_sense_cmd;
+
+ device_ptr_t sc_child; /* child device, for detach */
+ char sc_dying;
+
+#endif
+};
+
+#ifdef UMASS_DEBUG
char *states[TSTATE_STATES+1] = {
/* should be kept in sync with the list at transfer_state */
"Idle",
@@ -158,9 +538,17 @@ char *states[TSTATE_STATES+1] = {
};
#endif
+struct cam_sim *umass_sim; /* SCSI Interface Module */
+struct cam_path *umass_path; /* and its path */
+
+
/* USB device probe/attach/detach functions */
USB_DECLARE_DRIVER(umass);
Static void umass_disco(struct umass_softc *sc);
+Static int umass_match_proto(struct umass_softc *sc,
+ usbd_interface_handle iface,
+ usbd_device_handle dev);
+Static void umass_init_shuttle(struct umass_softc *sc);
/* generic transfer functions */
Static usbd_status umass_setup_transfer(struct umass_softc *sc,
@@ -168,43 +556,114 @@ Static usbd_status umass_setup_transfer(struct umass_softc *sc,
void *buffer, int buflen, int flags,
usbd_xfer_handle xfer);
Static usbd_status umass_setup_ctrl_transfer(struct umass_softc *sc,
+ usbd_device_handle dev,
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, int endpt,
- 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);
#if 0
-Static void umass_reset(struct umass_softc *sc, transfer_cb_f cb, void *priv);
+Static void umass_reset(struct umass_softc *sc,
+ transfer_cb_f cb, void *priv);
#endif
/* Bulk-Only related functions */
-Static void umass_bbb_transfer(struct umass_softc *, int, void *, int, void *,
- int, int, u_int, umass_callback, void *);
-Static void umass_bbb_reset(struct umass_softc *, int);
-Static void umass_bbb_state(usbd_xfer_handle, usbd_private_handle, usbd_status);
+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,
+ transfer_cb_f cb, void *priv);
+Static void umass_bbb_state(usbd_xfer_handle xfer,
+ usbd_private_handle priv,
+ usbd_status err);
+usbd_status umass_bbb_get_max_lun(struct umass_softc *sc,
+ u_int8_t *maxlun);
-usbd_status umass_bbb_get_max_lun(struct umass_softc *, u_int8_t *);
/* CBI related functions */
-Static void umass_cbi_transfer(struct umass_softc *, int, void *, int, void *,
- int, int, u_int, umass_callback, void *);
-Static void umass_cbi_reset(struct umass_softc *, int);
-Static void umass_cbi_state(usbd_xfer_handle, usbd_private_handle, usbd_status);
+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,
+ transfer_cb_f cb, void *priv);
+Static void umass_cbi_state(usbd_xfer_handle xfer,
+ usbd_private_handle priv, usbd_status err);
+
+#if defined(__FreeBSD__)
+/* 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);
+
+#ifdef UMASS_DO_CAM_RESCAN
+Static void umass_cam_rescan(struct umass_softc *sc);
+#endif
-Static int umass_cbi_adsc(struct umass_softc *, char *, int, usbd_xfer_handle);
+Static int umass_cam_attach_sim(void);
+Static int umass_cam_attach(struct umass_softc *sc);
+Static int umass_cam_detach_sim(void);
+Static int umass_cam_detach(struct umass_softc *sc);
-const struct umass_wire_methods umass_bbb_methods = {
- umass_bbb_transfer,
- umass_bbb_reset,
- umass_bbb_state
-};
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
+
+#define UMASS_SCSIID_HOST 0x00
+#define UMASS_SCSIID_DEVICE 0x01
-const struct umass_wire_methods umass_cbi_methods = {
- umass_cbi_transfer,
- umass_cbi_reset,
- umass_cbi_state
+#define UMASS_ATAPI_DRIVE 0
+
+#define UMASS_MAX_TRANSFER_SIZE MAXBSIZE
+
+struct scsipi_device umass_dev =
+{
+ NULL, /* Use default error handler */
+ NULL, /* have a queue, served by this */
+ NULL, /* have no async handler */
+ NULL, /* Use default 'done' routine */
};
+Static int umass_scsipi_cmd(struct scsipi_xfer *xs);
+Static void umass_scsipi_minphys(struct buf *bp);
+Static int umass_scsipi_ioctl(struct scsipi_link *, u_long,
+ caddr_t, int, struct proc *);
+Static void umass_scsipi_cb(struct umass_softc *sc, void *priv,
+ int residue, int status);
+Static void umass_scsipi_sense_cb(struct umass_softc *sc, void *priv,
+ int residue, int status);
+
+Static int scsipiprint(void *aux, const char *pnp);
+Static int umass_ufi_transform(struct umass_softc *sc,
+ struct scsipi_generic *cmd, int cmdlen,
+ struct scsipi_generic *rcmd, int *rcmdlen);
+
+#if NATAPIBUS > 0
+Static void umass_atapi_probedev(struct atapibus_softc *, int);
+#endif
+#endif
+
+#if defined(__FreeBSD__)
+/* 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 */
+Static int umass_ufi_transform(struct umass_softc *sc,
+ unsigned char *cmd, int cmdlen,
+ unsigned char **rcmd, int *rcmdlen);
+
+/* 8070 specific functions */
+Static int umass_8070_transform(struct umass_softc *sc,
+ unsigned char *cmd, int cmdlen,
+ unsigned char **rcmd, int *rcmdlen);
+#endif
+
#ifdef UMASS_DEBUG
/* General debugging functions */
Static void umass_bbb_dump_cbw(struct umass_softc *sc,
@@ -216,180 +675,292 @@ Static void umass_dump_buffer(struct umass_softc *sc, u_int8_t *buffer,
#endif
+void usbd_clear_endpoint_toggle(usbd_pipe_handle pipe); /* XXXXX */
+
/*
* USB device probe/attach/detach
*/
-USB_MATCH(umass)
+/*
+ * Match the device we are seeing with the devices supported. Fill in the
+ * proto and drive fields in the softc accordingly.
+ * This function is called from both probe and attach.
+ */
+
+Static int
+umass_match_proto(sc, iface, dev)
+ struct umass_softc *sc;
+ usbd_interface_handle iface;
+ usbd_device_handle dev;
{
- USB_MATCH_START(umass, uaa);
- const struct umass_quirk *quirk;
+ usb_device_descriptor_t *dd;
usb_interface_descriptor_t *id;
+ u_int vendor, product;
- if (uaa->iface == NULL)
- return (UMATCH_NONE);
+ /*
+ * Fill in sc->drive and sc->proto and return a match
+ * value if both are determined and 0 otherwise.
+ */
- quirk = umass_lookup(uaa->vendor, uaa->product);
- if (quirk != NULL)
- return (quirk->uq_match);
+ sc->drive = DRIVE_GENERIC;
+ sc->proto = PROTO_UNKNOWN;
+ sc->transfer_speed = UMASS_DEFAULT_TRANSFER_SPEED;
- id = usbd_get_interface_descriptor(uaa->iface);
+ sc->sc_udev = dev;
+ dd = usbd_get_device_descriptor(dev);
+ vendor = UGETW(dd->idVendor);
+ product = UGETW(dd->idProduct);
+
+ if (vendor == USB_VENDOR_SHUTTLE &&
+ product == USB_PRODUCT_SHUTTLE_EUSB) {
+ sc->drive = SHUTTLE_EUSB;
+#if CBI_I
+ sc->proto = PROTO_ATAPI | PROTO_CBI_I;
+#else
+ sc->proto = PROTO_ATAPI | PROTO_CBI;
+#endif
+ sc->subclass = UISUBCLASS_SFF8020I;
+ sc->protocol = UIPROTO_MASS_CBI;
+ sc->quirks |= NO_TEST_UNIT_READY | NO_START_STOP;
+ return (UMATCH_VENDOR_PRODUCT);
+ }
+
+ if (vendor == USB_VENDOR_YANO &&
+ product == USB_PRODUCT_YANO_U640MO) {
+ sc->proto = PROTO_ATAPI | PROTO_CBI_I;
+ sc->quirks |= FORCE_SHORT_INQUIRY;
+ return (UMATCH_VENDOR_PRODUCT);
+ }
+
+ if (vendor == USB_VENDOR_SONY &&
+ product == USB_PRODUCT_SONY_MSC) {
+ printf ("XXX Sony MSC\n");
+ sc->quirks |= FORCE_SHORT_INQUIRY;
+ }
+
+ if (vendor == USB_VENDOR_YEDATA &&
+ product == USB_PRODUCT_YEDATA_FLASHBUSTERU) {
+
+ /* Revisions < 1.28 do not handle the interrupt endpoint
+ * very well.
+ */
+ if (UGETW(dd->bcdDevice) < 0x128)
+ sc->proto = PROTO_UFI | PROTO_CBI;
+ else
+#if CBI_I
+ sc->proto = PROTO_UFI | PROTO_CBI_I;
+#else
+ sc->proto = PROTO_UFI | PROTO_CBI;
+#endif
+ /*
+ * 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->subclass = UISUBCLASS_UFI;
+ sc->protocol = UIPROTO_MASS_CBI;
+
+ sc->quirks |= RS_NO_CLEAR_UA;
+ sc->transfer_speed = UMASS_FLOPPY_TRANSFER_SPEED;
+ return (UMATCH_VENDOR_PRODUCT_REV);
+ }
+
+ if (vendor == USB_VENDOR_INSYSTEM &&
+ product == USB_PRODUCT_INSYSTEM_USBCABLE) {
+ sc->drive = INSYSTEM_USBCABLE;
+ sc->proto = PROTO_ATAPI | PROTO_CBI;
+ sc->quirks |= NO_TEST_UNIT_READY | NO_START_STOP;
+ return (UMATCH_VENDOR_PRODUCT);
+ }
+
+ id = usbd_get_interface_descriptor(iface);
if (id == NULL || id->bInterfaceClass != UICLASS_MASS)
return (UMATCH_NONE);
- switch (id->bInterfaceSubClass) {
- case UISUBCLASS_RBC:
- case UISUBCLASS_SFF8020I:
- case UISUBCLASS_QIC157:
+ if (vendor == USB_VENDOR_SONY && id->bInterfaceSubClass == 0xff) {
+ /*
+ * Sony DSC devices set the sub class to 0xff
+ * instead of 1 (RBC). Fix that here.
+ */
+ id->bInterfaceSubClass = UISUBCLASS_RBC;
+ /* They also should be able to do higher speed. */
+ sc->transfer_speed = 500;
+ }
+
+ if (vendor == USB_VENDOR_FUJIPHOTO &&
+ product == USB_PRODUCT_FUJIPHOTO_MASS0100)
+ sc->quirks |= NO_TEST_UNIT_READY | NO_START_STOP;
+
+ sc->subclass = id->bInterfaceSubClass;
+ sc->protocol = id->bInterfaceProtocol;
+
+ switch (sc->subclass) {
+ case UISUBCLASS_SCSI:
+ sc->proto |= PROTO_SCSI;
+ break;
case UISUBCLASS_UFI:
+ sc->transfer_speed = UMASS_FLOPPY_TRANSFER_SPEED;
+ sc->proto |= PROTO_UFI;
+ break;
+ case UISUBCLASS_SFF8020I:
case UISUBCLASS_SFF8070I:
- case UISUBCLASS_SCSI:
+ case UISUBCLASS_QIC157:
+ sc->proto |= PROTO_ATAPI;
+ break;
+ case UISUBCLASS_RBC:
+ sc->proto |= PROTO_RBC;
break;
default:
- return (UMATCH_IFACECLASS);
+ /* Assume that unsupported devices are ATAPI */
+ DPRINTF(UDMASS_GEN, ("%s: Unsupported command protocol %d\n",
+ USBDEVNAME(sc->sc_dev), id->bInterfaceSubClass));
+
+ sc->proto |= PROTO_ATAPI;
+ break;
}
- switch (id->bInterfaceProtocol) {
- case UIPROTO_MASS_CBI_I:
+ switch (sc->protocol) {
case UIPROTO_MASS_CBI:
- case UIPROTO_MASS_BBB_OLD:
+ sc->proto |= PROTO_CBI;
+ break;
+ case UIPROTO_MASS_CBI_I:
+#if CBI_I
+ sc->proto |= PROTO_CBI_I;
+#else
+ sc->proto |= PROTO_CBI;
+#endif
+ break;
case UIPROTO_MASS_BBB:
+ sc->proto |= PROTO_BBB;
+ break;
+ case UIPROTO_MASS_BBB_P:
+ sc->drive = ZIP_100;
+ sc->proto |= PROTO_BBB;
+ sc->transfer_speed = UMASS_ZIP100_TRANSFER_SPEED;
+ sc->quirks |= NO_TEST_UNIT_READY;
break;
default:
- return (UMATCH_IFACECLASS_IFACESUBCLASS);
+ DPRINTF(UDMASS_GEN, ("%s: Unsupported wire protocol %d\n",
+ USBDEVNAME(sc->sc_dev), id->bInterfaceProtocol));
+ return (UMATCH_NONE);
}
- return (UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO);
+ return (UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO);
}
+USB_MATCH(umass)
+{
+ USB_MATCH_START(umass, uaa);
+#if defined(__FreeBSD__)
+ struct umass_softc *sc = device_get_softc(self);
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
+ struct umass_softc scs, *sc = &scs;
+ memset(sc, 0, sizeof *sc);
+ strcpy(sc->sc_dev.dv_xname, "umass");
+#endif
+
+ if (uaa->iface == NULL)
+ return(UMATCH_NONE);
+
+ return (umass_match_proto(sc, uaa->iface, uaa->device));
+}
+
+void umass_delayed_attach(struct umass_softc *sc);
+
USB_ATTACH(umass)
{
USB_ATTACH_START(umass, sc, uaa);
- const struct umass_quirk *quirk;
usb_interface_descriptor_t *id;
usb_endpoint_descriptor_t *ed;
- const char *sWire, *sCommand;
+ const char *sSubclass, *sProto;
char devinfo[1024];
- usbd_status err;
- int i, bno, error;
+ int i, bno;
+ int err;
+
+ /*
+ * the softc struct is bzero-ed in device_set_driver. We can safely
+ * call umass_detach without specifically initialising the struct.
+ */
usbd_devinfo(uaa->device, 0, devinfo);
USB_ATTACH_SETUP;
- sc->sc_udev = uaa->device;
- sc->sc_iface = uaa->iface;
- sc->sc_ifaceno = uaa->ifaceno;
-
- quirk = umass_lookup(uaa->vendor, uaa->product);
- if (quirk != NULL) {
- sc->sc_wire = quirk->uq_wire;
- sc->sc_cmd = quirk->uq_cmd;
- sc->sc_quirks = quirk->uq_flags;
- sc->sc_busquirks = quirk->uq_busquirks;
-
- if (quirk->uq_fixup != NULL)
- (*quirk->uq_fixup)(sc);
- } else {
- sc->sc_wire = UMASS_WPROTO_UNSPEC;
- sc->sc_cmd = UMASS_CPROTO_UNSPEC;
- sc->sc_quirks = 0;
- sc->sc_busquirks = 0;
- }
+ sc->iface = uaa->iface;
+ sc->ifaceno = uaa->ifaceno;
- id = usbd_get_interface_descriptor(sc->sc_iface);
- if (id == NULL)
+ /* initialise the proto and drive values in the umass_softc (again) */
+ if (umass_match_proto(sc, sc->iface, uaa->device) == 0) {
+ printf("%s: match failed\n", USBDEVNAME(sc->sc_dev));
USB_ATTACH_ERROR_RETURN;
-
- if (sc->sc_wire == UMASS_WPROTO_UNSPEC) {
- switch (id->bInterfaceProtocol) {
- case UIPROTO_MASS_CBI:
- sc->sc_wire = UMASS_WPROTO_CBI;
- break;
- case UIPROTO_MASS_CBI_I:
- sc->sc_wire = UMASS_WPROTO_CBI_I;
- break;
- case UIPROTO_MASS_BBB:
- case UIPROTO_MASS_BBB_OLD:
- sc->sc_wire = UMASS_WPROTO_BBB;
- break;
- default:
- DPRINTF(UDMASS_GEN,
- ("%s: Unsupported wire protocol %u\n",
- USBDEVNAME(sc->sc_dev),
- id->bInterfaceProtocol));
- USB_ATTACH_ERROR_RETURN;
- }
}
- /* XXX - Now unsupported CBI with CCI */
- if (sc->sc_wire == UMASS_WPROTO_CBI_I)
- sc->sc_wire = UMASS_WPROTO_CBI;
-
- if (sc->sc_cmd == UMASS_CPROTO_UNSPEC) {
- switch (id->bInterfaceSubClass) {
- case UISUBCLASS_SCSI:
- sc->sc_cmd = UMASS_CPROTO_SCSI;
- break;
- case UISUBCLASS_UFI:
- sc->sc_cmd = UMASS_CPROTO_UFI;
- break;
- case UISUBCLASS_SFF8020I:
- case UISUBCLASS_SFF8070I:
- case UISUBCLASS_QIC157:
- sc->sc_cmd = UMASS_CPROTO_ATAPI;
- break;
- case UISUBCLASS_RBC:
- sc->sc_cmd = UMASS_CPROTO_RBC;
- break;
- default:
- DPRINTF(UDMASS_GEN,
- ("%s: Unsupported command protocol %u\n",
- USBDEVNAME(sc->sc_dev),
- id->bInterfaceSubClass));
- USB_ATTACH_ERROR_RETURN;
- }
- }
+ /*
+ * The timeout is based on the maximum expected transfer size
+ * divided by the expected transfer speed.
+ * We multiply by 4 to make sure a busy system doesn't make things
+ * fail.
+ */
+ sc->timeout = 4 * UMASS_MAX_TRANSFER_SIZE / sc->transfer_speed;
+ sc->timeout += UMASS_SPINUP_TIME; /* allow for spinning up */
+ id = usbd_get_interface_descriptor(sc->iface);
printf("%s: %s\n", USBDEVNAME(sc->sc_dev), devinfo);
- switch (sc->sc_wire) {
- case UMASS_WPROTO_CBI:
- sWire = "CBI";
+ switch (sc->subclass) {
+ case UISUBCLASS_RBC:
+ sSubclass = "RBC";
+ break;
+ case UISUBCLASS_SCSI:
+ sSubclass = "SCSI";
+ break;
+ case UISUBCLASS_UFI:
+ sSubclass = "UFI";
break;
- case UMASS_WPROTO_CBI_I:
- sWire = "CBI with CCI";
+ case UISUBCLASS_SFF8020I:
+ sSubclass = "SFF8020i";
break;
- case UMASS_WPROTO_BBB:
- sWire = "Bulk-Only";
+ case UISUBCLASS_SFF8070I:
+ sSubclass = "SFF8070i";
+ break;
+ case UISUBCLASS_QIC157:
+ sSubclass = "QIC157";
break;
default:
- sWire = "unknown";
+ sSubclass = "unknown";
break;
}
-
- switch (sc->sc_cmd) {
- case UMASS_CPROTO_RBC:
- sCommand = "RBC";
- break;
- case UMASS_CPROTO_SCSI:
- sCommand = "SCSI";
+ switch (sc->protocol) {
+ case UIPROTO_MASS_CBI:
+ sProto = "CBI";
break;
- case UMASS_CPROTO_UFI:
- sCommand = "UFI";
+ case UIPROTO_MASS_CBI_I:
+ sProto = "CBI-I";
break;
- case UMASS_CPROTO_ATAPI:
- sCommand = "ATAPI";
+ case UIPROTO_MASS_BBB:
+ sProto = "BBB";
break;
- case UMASS_CPROTO_ISD_ATA:
- sCommand = "ISD-ATA";
+ case UIPROTO_MASS_BBB_P:
+ sProto = "BBB-P";
break;
default:
- sCommand = "unknown";
+ sProto = "unknown";
break;
}
+ printf("%s: using %s over %s\n", USBDEVNAME(sc->sc_dev), sSubclass,
+ sProto);
- printf("%s: using %s over %s\n", USBDEVNAME(sc->sc_dev), sCommand,
- sWire);
+ if (sc->drive == INSYSTEM_USBCABLE) {
+ err = usbd_set_interface(0, 1);
+ if (err) {
+ DPRINTF(UDMASS_USB, ("%s: could not switch to "
+ "Alt Interface %d\n",
+ USBDEVNAME(sc->sc_dev), 1));
+ umass_disco(sc);
+ USB_ATTACH_ERROR_RETURN;
+ }
+ }
/*
* In addition to the Control endpoint the following endpoints
@@ -403,22 +974,22 @@ USB_ATTACH(umass)
* from the device descriptors of the current interface.
*/
for (i = 0 ; i < id->bNumEndpoints ; i++) {
- ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
- if (ed == NULL) {
+ ed = usbd_interface2endpoint_descriptor(sc->iface, i);
+ if (!ed) {
printf("%s: could not read endpoint descriptor\n",
USBDEVNAME(sc->sc_dev));
USB_ATTACH_ERROR_RETURN;
}
if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN
&& (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
- sc->sc_epaddr[UMASS_BULKIN] = ed->bEndpointAddress;
+ sc->bulkin = ed->bEndpointAddress;
} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT
&& (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
- sc->sc_epaddr[UMASS_BULKOUT] = ed->bEndpointAddress;
- } else if (sc->sc_wire == UMASS_WPROTO_CBI_I
+ sc->bulkout = ed->bEndpointAddress;
+ } else if (sc->proto & PROTO_CBI_I
&& UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN
&& (ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT) {
- sc->sc_epaddr[UMASS_INTRIN] = ed->bEndpointAddress;
+ sc->intrin = ed->bEndpointAddress;
#ifdef UMASS_DEBUG
if (UGETW(ed->wMaxPacketSize) > 2) {
DPRINTF(UDMASS_CBI, ("%s: intr size is %d\n",
@@ -430,21 +1001,19 @@ USB_ATTACH(umass)
}
/* check whether we found all the endpoints we need */
- if (!sc->sc_epaddr[UMASS_BULKIN] || !sc->sc_epaddr[UMASS_BULKOUT] ||
- (sc->sc_wire == UMASS_WPROTO_CBI_I &&
- !sc->sc_epaddr[UMASS_INTRIN])) {
- DPRINTF(UDMASS_USB, ("%s: endpoint not found %u/%u/%u\n",
- USBDEVNAME(sc->sc_dev), sc->sc_epaddr[UMASS_BULKIN],
- sc->sc_epaddr[UMASS_BULKOUT],
- sc->sc_epaddr[UMASS_INTRIN]));
+ if (!sc->bulkin || !sc->bulkout
+ || (sc->proto & PROTO_CBI_I && !sc->intrin) ) {
+ DPRINTF(UDMASS_USB, ("%s: endpoint not found %d/%d/%d\n",
+ USBDEVNAME(sc->sc_dev),
+ sc->bulkin, sc->bulkout, sc->intrin));
+ umass_disco(sc);
USB_ATTACH_ERROR_RETURN;
}
/*
* Get the maximum LUN supported by the device.
*/
- if (sc->sc_wire == UMASS_WPROTO_BBB &&
- !(sc->sc_quirks & UMASS_QUIRK_NO_MAX_LUN)) {
+ if ((sc->proto & PROTO_WIRE) == PROTO_BBB) {
err = umass_bbb_get_max_lun(sc, &sc->maxlun);
if (err) {
printf("%s: unable to get Max Lun: %s\n",
@@ -456,20 +1025,19 @@ USB_ATTACH(umass)
}
/* Open the bulk-in and -out pipe */
- err = usbd_open_pipe(sc->sc_iface, sc->sc_epaddr[UMASS_BULKOUT],
- USBD_EXCLUSIVE_USE,
- &sc->sc_pipe[UMASS_BULKOUT]);
+ err = usbd_open_pipe(sc->iface, sc->bulkout,
+ USBD_EXCLUSIVE_USE, &sc->bulkout_pipe);
if (err) {
- DPRINTF(UDMASS_USB, ("%s: cannot open %u-out pipe (bulk)\n",
- USBDEVNAME(sc->sc_dev), sc->sc_epaddr[UMASS_BULKOUT]));
+ DPRINTF(UDMASS_USB, ("%s: cannot open %d-out pipe (bulk)\n",
+ USBDEVNAME(sc->sc_dev), sc->bulkout));
umass_disco(sc);
USB_ATTACH_ERROR_RETURN;
}
- err = usbd_open_pipe(sc->sc_iface, sc->sc_epaddr[UMASS_BULKIN],
- USBD_EXCLUSIVE_USE, &sc->sc_pipe[UMASS_BULKIN]);
+ err = usbd_open_pipe(sc->iface, sc->bulkin,
+ USBD_EXCLUSIVE_USE, &sc->bulkin_pipe);
if (err) {
- DPRINTF(UDMASS_USB, ("%s: could not open %u-in pipe (bulk)\n",
- USBDEVNAME(sc->sc_dev), sc->sc_epaddr[UMASS_BULKIN]));
+ DPRINTF(UDMASS_USB, ("%s: could not open %d-in pipe (bulk)\n",
+ USBDEVNAME(sc->sc_dev), sc->bulkin));
umass_disco(sc);
USB_ATTACH_ERROR_RETURN;
}
@@ -485,13 +1053,12 @@ USB_ATTACH(umass)
* code for handling the data on that endpoint simpler. No data
* arriving concurrently.
*/
- if (sc->sc_wire == UMASS_WPROTO_CBI_I) {
- err = usbd_open_pipe(sc->sc_iface, sc->sc_epaddr[UMASS_INTRIN],
- USBD_EXCLUSIVE_USE, &sc->sc_pipe[UMASS_INTRIN]);
+ if (sc->proto & 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 %u-in (intr)\n",
- USBDEVNAME(sc->sc_dev),
- sc->sc_epaddr[UMASS_INTRIN]));
+ DPRINTF(UDMASS_USB, ("%s: couldn't open %d-in (intr)\n",
+ USBDEVNAME(sc->sc_dev), sc->intrin));
umass_disco(sc);
USB_ATTACH_ERROR_RETURN;
}
@@ -511,14 +1078,14 @@ USB_ATTACH(umass)
}
}
/* Allocate buffer for data transfer (it's huge). */
- switch (sc->sc_wire) {
- case UMASS_WPROTO_BBB:
+ switch (sc->proto & PROTO_WIRE) {
+ case PROTO_BBB:
bno = XFER_BBB_DATA;
goto dalloc;
- case UMASS_WPROTO_CBI:
+ case PROTO_CBI:
bno = XFER_CBI_DATA;
goto dalloc;
- case UMASS_WPROTO_CBI_I:
+ case PROTO_CBI_I:
bno = XFER_CBI_DATA;
dalloc:
sc->data_buffer = usbd_alloc_buffer(sc->transfer_xfer[bno],
@@ -533,89 +1100,123 @@ USB_ATTACH(umass)
}
/* Initialise the wire protocol specific methods */
- switch (sc->sc_wire) {
- case UMASS_WPROTO_BBB:
- sc->sc_methods = &umass_bbb_methods;
- break;
- case UMASS_WPROTO_CBI:
- case UMASS_WPROTO_CBI_I:
- sc->sc_methods = &umass_cbi_methods;
- break;
- default:
- umass_disco(sc);
- USB_ATTACH_ERROR_RETURN;
- }
-
- if (quirk != NULL && quirk->uq_init != NULL) {
- err = (*quirk->uq_init)(sc);
- if (err) {
- umass_disco(sc);
- USB_ATTACH_ERROR_RETURN;
- }
+ if (sc->proto & PROTO_BBB) {
+ sc->reset = umass_bbb_reset;
+ sc->transfer = umass_bbb_transfer;
+ sc->state = umass_bbb_state;
+ } else if ((sc->proto & PROTO_CBI) || (sc->proto & PROTO_CBI_I)) {
+ sc->reset = umass_cbi_reset;
+ sc->transfer = umass_cbi_transfer;
+ sc->state = umass_cbi_state;
+#ifdef UMASS_DEBUG
+ } else {
+ panic("%s:%d: Unknown proto 0x%02x\n",
+ __FILE__, __LINE__, sc->proto);
+#endif
}
- error = 0;
- switch (sc->sc_cmd) {
- case UMASS_CPROTO_RBC:
- case UMASS_CPROTO_SCSI:
-#if defined(__OpenBSD__) || NSCSIBUS > 0
- error = umass_scsi_attach(sc);
-#else
- printf("%s: scsibus not configured\n", USBDEVNAME(sc->sc_dev));
-#endif
- break;
+ if (sc->drive == SHUTTLE_EUSB)
+ umass_init_shuttle(sc);
- case UMASS_CPROTO_UFI:
- case UMASS_CPROTO_ATAPI:
-#if (NATAPIBUS > 0) || (NATAPISCSI > 0)
- error = umass_atapi_attach(sc);
-#else
- printf("%s: "UMASS_ATAPISTR" not configured\n",
- USBDEVNAME(sc->sc_dev));
-#endif
+ /*
+ * Fill in the adapter.
+ */
+ sc->sc_adapter.scsipi_cmd = umass_scsipi_cmd;
+ sc->sc_adapter.scsipi_minphys = umass_scsipi_minphys;
+
+ /*
+ * fill in the prototype scsipi_link.
+ */
+ switch (sc->proto & PROTO_COMMAND) {
+ case PROTO_SCSI:
+ case PROTO_UFI:
+ case PROTO_ATAPI:
+ case PROTO_RBC:
+ if ((sc->proto & PROTO_COMMAND) != PROTO_SCSI)
+ sc->u.sc_link.flags |= SDEV_ATAPI;
+ else
+ sc->u.sc_link.flags &= ~SDEV_ATAPI;
+
+ sc->u.sc_link.adapter_buswidth = 2;
+ sc->u.sc_link.adapter_target = UMASS_SCSIID_HOST;
+ sc->u.sc_link.luns = sc->maxlun + 1;
+
+ sc->u.sc_link.adapter_softc = sc;
+ sc->u.sc_link.adapter = &sc->sc_adapter;
+ sc->u.sc_link.device = &umass_dev;
+ sc->u.sc_link.openings = 1;
+
+ if(sc->quirks & NO_TEST_UNIT_READY)
+ sc->u.sc_link.quirks |= ADEV_NOTUR;
break;
- case UMASS_CPROTO_ISD_ATA:
-#if defined (__NetBSD__) && NWD > 0
- error = umass_isdata_attach(sc);
-#else
- printf("%s: isdata not configured\n", USBDEVNAME(sc->sc_dev));
-#endif
- break;
default:
- printf("%s: command protocol=0x%x not supported\n",
- USBDEVNAME(sc->sc_dev), sc->sc_cmd);
+ printf("%s: proto=0x%x not supported yet\n",
+ USBDEVNAME(sc->sc_dev), sc->proto);
umass_disco(sc);
USB_ATTACH_ERROR_RETURN;
}
- if (error) {
- printf("%s: bus attach failed\n", USBDEVNAME(sc->sc_dev));
+
+ if (cold) {
+ startuphook_establish((void (*)(void *))umass_delayed_attach,
+ sc);
+ } else {
+ /* hot plug, do it now */
+ umass_delayed_attach(sc);
+ }
+
+ DPRINTF(UDMASS_GEN, ("%s: Attach finished\n", USBDEVNAME(sc->sc_dev)));
+
+ USB_ATTACH_SUCCESS_RETURN;
+}
+
+void
+umass_delayed_attach(struct umass_softc *sc)
+{
+ sc->sc_child = config_found(&sc->sc_dev, &sc->u, scsipiprint);
+ if (sc->sc_child == NULL) {
umass_disco(sc);
- USB_ATTACH_ERROR_RETURN;
+ /* Not an error, just not a complete success. */
+ USB_ATTACH_SUCCESS_RETURN;
}
usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
USBDEV(sc->sc_dev));
+}
- DPRINTF(UDMASS_GEN, ("%s: Attach finished\n", USBDEVNAME(sc->sc_dev)));
-
- USB_ATTACH_SUCCESS_RETURN;
+Static int
+scsipiprint(aux, pnp)
+ void *aux;
+ const char *pnp;
+{
+#if !defined(__OpenBSD__)
+ extern int atapi_print(void *aux, const char *pnp);
+ struct scsipi_link *l = aux;
+
+ if (l->type == BUS_SCSI)
+ return (scsiprint(aux, pnp));
+ else
+ return (atapi_print(aux, pnp));
+#else
+ return (scsiprint(aux, pnp));
+#endif
}
USB_DETACH(umass)
{
USB_DETACH_START(umass, sc);
- struct umassbus_softc *scbus = sc->bus;
- int rv = 0, i;
+ int rv = 0;
DPRINTF(UDMASS_USB, ("%s: detached\n", USBDEVNAME(sc->sc_dev)));
/* Abort the pipes to wake up any waiting processes. */
- for (i = 0 ; i < UMASS_NEP ; i++) {
- if (sc->sc_pipe[i] != NULL)
- usbd_abort_pipe(sc->sc_pipe[i]);
- }
+ if (sc->bulkout_pipe != NULL)
+ usbd_abort_pipe(sc->bulkout_pipe);
+ if (sc->bulkin_pipe != NULL)
+ usbd_abort_pipe(sc->bulkin_pipe);
+ if (sc->intrin_pipe != NULL)
+ usbd_abort_pipe(sc->intrin_pipe);
#if 0
/* Do we really need reference counting? Perhaps in ioctl() */
@@ -627,13 +1228,16 @@ USB_DETACH(umass)
splx(s);
#endif
- if (scbus != NULL) {
- if (scbus->sc_child != NULL)
- rv = config_detach(scbus->sc_child, flags);
- free(scbus, M_DEVBUF);
- sc->bus = NULL;
- }
-
+#if defined(__FreeBSD__)
+ if ((sc->proto & PROTO_SCSI) ||
+ (sc->proto & PROTO_ATAPI) ||
+ (sc->proto & PROTO_UFI))
+ /* detach the device from the SCSI host controller (SIM) */
+ rv = umass_cam_detach(sc);
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
+ if (sc->sc_child != NULL)
+ rv = config_detach(sc->sc_child, flags);
+#endif
if (rv != 0)
return (rv);
@@ -642,14 +1246,16 @@ USB_DETACH(umass)
usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
USBDEV(sc->sc_dev));
- return (rv);
+ return (0);
}
+#if defined(__NetBSD__) || defined(__OpenBSD__)
int
-umass_activate(struct device *dev, enum devact act)
+umass_activate(self, act)
+ struct device *self;
+ enum devact act;
{
- struct umass_softc *sc = (struct umass_softc *)dev;
- struct umassbus_softc *scbus = sc->bus;
+ struct umass_softc *sc = (struct umass_softc *) self;
int rv = 0;
DPRINTF(UDMASS_USB, ("%s: umass_activate: %d\n",
@@ -661,19 +1267,22 @@ umass_activate(struct device *dev, enum devact act)
break;
case DVACT_DEACTIVATE:
- sc->sc_dying = 1;
- if (scbus == NULL || scbus->sc_child == NULL)
+ if (sc->sc_child == NULL)
break;
- rv = config_deactivate(scbus->sc_child);
+ rv = config_deactivate(sc->sc_child);
DPRINTF(UDMASS_USB, ("%s: umass_activate: child "
"returned %d\n", USBDEVNAME(sc->sc_dev), rv));
+ if (rv == 0)
+ sc->sc_dying = 1;
break;
}
return (rv);
}
+#endif
Static void
-umass_disco(struct umass_softc *sc)
+umass_disco(sc)
+ struct umass_softc *sc;
{
int i;
@@ -687,10 +1296,27 @@ umass_disco(struct umass_softc *sc)
}
/* Remove all the pipes. */
- for (i = 0 ; i < UMASS_NEP ; i++) {
- if (sc->sc_pipe[i] != NULL)
- usbd_close_pipe(sc->sc_pipe[i]);
- }
+ if (sc->bulkout_pipe != NULL)
+ usbd_close_pipe(sc->bulkout_pipe);
+ if (sc->bulkin_pipe != NULL)
+ usbd_close_pipe(sc->bulkin_pipe);
+ if (sc->intrin_pipe != NULL)
+ usbd_close_pipe(sc->intrin_pipe);
+}
+
+Static void
+umass_init_shuttle(struct umass_softc *sc)
+{
+ usb_device_request_t req;
+ u_char status[2];
+
+ /* The Linux driver does this */
+ req.bmRequestType = UT_READ_VENDOR_DEVICE;
+ req.bRequest = 1;
+ USETW(req.wValue, 0);
+ USETW(req.wIndex, sc->ifaceno);
+ USETW(req.wLength, sizeof status);
+ (void)usbd_do_request(sc->sc_udev, &req, &status);
}
/*
@@ -710,7 +1336,7 @@ umass_setup_transfer(struct umass_softc *sc, usbd_pipe_handle pipe,
/* Initialiase a USB transfer and then schedule it */
usbd_setup_xfer(xfer, pipe, (void *)sc, buffer, buflen,
- flags | sc->sc_xfer_flags, sc->timeout, sc->sc_methods->wire_state);
+ flags | sc->sc_xfer_flags, sc->timeout, sc->state);
err = usbd_transfer(xfer);
DPRINTF(UDMASS_XFER,("%s: start xfer buffer=%p buflen=%d flags=0x%x "
@@ -727,8 +1353,10 @@ umass_setup_transfer(struct umass_softc *sc, usbd_pipe_handle pipe,
Static usbd_status
-umass_setup_ctrl_transfer(struct umass_softc *sc, usb_device_request_t *req,
- void *buffer, int buflen, int flags, usbd_xfer_handle xfer)
+umass_setup_ctrl_transfer(struct umass_softc *sc, usbd_device_handle dev,
+ usb_device_request_t *req,
+ void *buffer, int buflen, int flags,
+ usbd_xfer_handle xfer)
{
usbd_status err;
@@ -737,8 +1365,8 @@ umass_setup_ctrl_transfer(struct umass_softc *sc, usb_device_request_t *req,
/* Initialiase a USB control transfer and then schedule it */
- usbd_setup_default_xfer(xfer, sc->sc_udev, (void *) sc, sc->timeout,
- req, buffer, buflen, flags, sc->sc_methods->wire_state);
+ usbd_setup_default_xfer(xfer, dev, (void *) sc,
+ sc->timeout, req, buffer, buflen, flags, sc->state);
err = usbd_transfer(xfer);
if (err && err != USBD_IN_PROGRESS) {
@@ -753,23 +1381,30 @@ umass_setup_ctrl_transfer(struct umass_softc *sc, usb_device_request_t *req,
}
Static void
-umass_clear_endpoint_stall(struct umass_softc *sc, int endpt,
- usbd_xfer_handle xfer)
+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 dev;
+
if (sc->sc_dying)
return;
DPRINTF(UDMASS_BBB, ("%s: Clear endpoint 0x%02x stall\n",
- USBDEVNAME(sc->sc_dev), sc->sc_epaddr[endpt]));
+ USBDEVNAME(sc->sc_dev), endpt));
+
+ usbd_interface2device_handle(sc->iface, &dev);
- usbd_clear_endpoint_toggle(sc->sc_pipe[endpt]);
+ sc->transfer_state = state;
- sc->sc_req.bmRequestType = UT_WRITE_ENDPOINT;
- sc->sc_req.bRequest = UR_CLEAR_FEATURE;
- USETW(sc->sc_req.wValue, UF_ENDPOINT_HALT);
- USETW(sc->sc_req.wIndex, sc->sc_epaddr[endpt]);
- USETW(sc->sc_req.wLength, 0);
- umass_setup_ctrl_transfer(sc, &sc->sc_req, NULL, 0, 0, xfer);
+ 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, dev, &sc->request, NULL, 0, 0, xfer);
}
#if 0
@@ -791,9 +1426,10 @@ umass_reset(struct umass_softc *sc, transfer_cb_f cb, void *priv)
Static void
umass_bbb_reset(struct umass_softc *sc, int status)
{
- KASSERT(sc->sc_wire & UMASS_WPROTO_BBB,
- ("sc->sc_wire == 0x%02x wrong for umass_bbb_reset\n",
- sc->sc_wire));
+ usbd_device_handle dev;
+
+ KASSERT(sc->proto & PROTO_BBB,
+ ("sc->proto == 0x%02x wrong for umass_bbb_reset\n", sc->proto));
if (sc->sc_dying)
return;
@@ -820,32 +1456,31 @@ umass_bbb_reset(struct umass_softc *sc, int status)
sc->transfer_state = TSTATE_BBB_RESET1;
sc->transfer_status = status;
+ usbd_interface2device_handle(sc->iface, &dev);
+
/* reset is a class specific interface write */
- sc->sc_req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- sc->sc_req.bRequest = UR_BBB_RESET;
- USETW(sc->sc_req.wValue, 0);
- USETW(sc->sc_req.wIndex, sc->sc_ifaceno);
- USETW(sc->sc_req.wLength, 0);
- umass_setup_ctrl_transfer(sc, &sc->sc_req, NULL, 0, 0,
+ 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, dev, &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,
- umass_callback cb, void *priv)
+ void *data, int datalen, int dir,
+ transfer_cb_f cb, void *priv)
{
static int dCBWtag = 42; /* unique for CBW of transfer */
DPRINTF(UDMASS_BBB,("%s: umass_bbb_transfer cmd=0x%02x\n",
USBDEVNAME(sc->sc_dev), *(u_char *)cmd));
- KASSERT(sc->sc_wire & UMASS_WPROTO_BBB,
- ("sc->sc_wire == 0x%02x wrong for umass_bbb_transfer\n",
- sc->sc_wire));
-
- /* Be a little generous. */
- sc->timeout = timeout + USBD_DEFAULT_TIMEOUT;
+ KASSERT(sc->proto & PROTO_BBB,
+ ("sc->proto == 0x%02x wrong for umass_bbb_transfer\n",
+ sc->proto));
/*
* Do a Bulk-Only transfer with cmdlen bytes from cmd, possibly
@@ -917,7 +1552,7 @@ umass_bbb_transfer(struct umass_softc *sc, int lun, void *cmd, int cmdlen,
sc->cbw.bCBWFlags = (dir == DIR_IN? CBWFLAGS_IN:CBWFLAGS_OUT);
sc->cbw.bCBWLUN = lun;
sc->cbw.bCDBLength = cmdlen;
- memcpy(sc->cbw.CBWCDB, cmd, cmdlen);
+ bcopy(cmd, sc->cbw.CBWCDB, cmdlen);
DIF(UDMASS_BBB, umass_bbb_dump_cbw(sc, &sc->cbw));
@@ -934,7 +1569,7 @@ umass_bbb_transfer(struct umass_softc *sc, int lun, void *cmd, int cmdlen,
sc->transfer_state = TSTATE_BBB_COMMAND;
/* Send the CBW from host to device via bulk-out endpoint. */
- if (umass_setup_transfer(sc, sc->sc_pipe[UMASS_BULKOUT],
+ 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);
@@ -949,9 +1584,8 @@ umass_bbb_state(usbd_xfer_handle xfer, usbd_private_handle priv,
struct umass_softc *sc = (struct umass_softc *) priv;
usbd_xfer_handle next_xfer;
- KASSERT(sc->sc_wire & UMASS_WPROTO_BBB,
- ("sc->sc_wire == 0x%02x wrong for umass_bbb_state\n",
- sc->sc_wire));
+ KASSERT(sc->proto & PROTO_BBB,
+ ("sc->proto == 0x%02x wrong for umass_bbb_state\n",sc->proto));
if (sc->sc_dying)
return;
@@ -990,7 +1624,7 @@ umass_bbb_state(usbd_xfer_handle xfer, usbd_private_handle priv,
/* Data transport phase, setup transfer */
sc->transfer_state = TSTATE_BBB_DATA;
if (sc->transfer_dir == DIR_IN) {
- if (umass_setup_transfer(sc, sc->sc_pipe[UMASS_BULKIN],
+ if (umass_setup_transfer(sc, sc->bulkin_pipe,
sc->data_buffer, sc->transfer_datalen,
USBD_SHORT_XFER_OK | USBD_NO_COPY,
sc->transfer_xfer[XFER_BBB_DATA]))
@@ -1000,7 +1634,7 @@ umass_bbb_state(usbd_xfer_handle xfer, usbd_private_handle priv,
} else if (sc->transfer_dir == DIR_OUT) {
memcpy(sc->data_buffer, sc->transfer_data,
sc->transfer_datalen);
- if (umass_setup_transfer(sc, sc->sc_pipe[UMASS_BULKOUT],
+ if (umass_setup_transfer(sc, sc->bulkout_pipe,
sc->data_buffer, sc->transfer_datalen,
USBD_NO_COPY,/* fixed length transfer */
sc->transfer_xfer[XFER_BBB_DATA]))
@@ -1022,16 +1656,18 @@ umass_bbb_state(usbd_xfer_handle xfer, usbd_private_handle priv,
&sc->transfer_actlen, NULL);
if (err) {
- DPRINTF(UDMASS_BBB, ("%s: Data-%s %d failed, "
+ DPRINTF(UDMASS_BBB, ("%s: Data-%s %db failed, "
"%s\n", USBDEVNAME(sc->sc_dev),
(sc->transfer_dir == DIR_IN?"in":"out"),
sc->transfer_datalen,usbd_errstr(err)));
if (err == USBD_STALLED) {
- sc->transfer_state = TSTATE_BBB_DCLEAR;
umass_clear_endpoint_stall(sc,
(sc->transfer_dir == DIR_IN?
- UMASS_BULKIN:UMASS_BULKOUT),
+ 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 {
@@ -1087,8 +1723,9 @@ umass_bbb_state(usbd_xfer_handle xfer, usbd_private_handle priv,
}
/* Read the Command Status Wrapper via bulk-in endpoint. */
- if (umass_setup_transfer(sc, sc->sc_pipe[UMASS_BULKIN],
- &sc->csw, UMASS_BBB_CSW_SIZE, 0, next_xfer)) {
+ 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;
}
@@ -1107,9 +1744,10 @@ umass_bbb_state(usbd_xfer_handle xfer, usbd_private_handle priv,
* retry it, otherwise fail.
*/
if (sc->transfer_state == TSTATE_BBB_STATUS1) {
- sc->transfer_state = TSTATE_BBB_SCLEAR;
- umass_clear_endpoint_stall(sc, UMASS_BULKIN,
- sc->transfer_xfer[XFER_BBB_SCLEAR]);
+ 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);
@@ -1119,11 +1757,6 @@ umass_bbb_state(usbd_xfer_handle xfer, usbd_private_handle priv,
DIF(UDMASS_BBB, umass_bbb_dump_csw(sc, &sc->csw));
- /* Translate weird command-status signatures. */
- if ((sc->sc_quirks & UMASS_QUIRK_WRONG_CSWSIG) &&
- UGETDW(sc->csw.dCSWSignature) == CSWSIGNATURE_OLYMPUS_C1)
- USETDW(sc->csw.dCSWSignature, CSWSIGNATURE);
-
/* Check CSW and handle any error */
if (UGETDW(sc->csw.dCSWSignature) != CSWSIGNATURE) {
/* Invalid CSW: Wrong signature or wrong tag might
@@ -1168,8 +1801,9 @@ umass_bbb_state(usbd_xfer_handle xfer, usbd_private_handle priv,
panic("%s: transferred %d bytes instead of %d bytes\n",
USBDEVNAME(sc->sc_dev),
sc->transfer_actlen, sc->transfer_datalen);
+ }
#if 0
- } else if (sc->transfer_datalen - sc->transfer_actlen
+ else if (sc->transfer_datalen - sc->transfer_actlen
!= UGETDW(sc->csw.dCSWDataResidue)) {
DPRINTF(UDMASS_BBB, ("%s: actlen=%d != residue=%d\n",
USBDEVNAME(sc->sc_dev),
@@ -1178,8 +1812,10 @@ umass_bbb_state(usbd_xfer_handle xfer, usbd_private_handle priv,
umass_bbb_reset(sc, STATUS_WIRE_FAILED);
return;
+
+ }
#endif
- } else if (sc->csw.bCSWStatus == CSWSTATUS_FAILED) {
+ else if (sc->csw.bCSWStatus == CSWSTATUS_FAILED) {
DPRINTF(UDMASS_BBB, ("%s: Command Failed, res = %d\n",
USBDEVNAME(sc->sc_dev),
UGETDW(sc->csw.dCSWDataResidue)));
@@ -1207,8 +1843,8 @@ umass_bbb_state(usbd_xfer_handle xfer, usbd_private_handle priv,
printf("%s: BBB reset failed, %s\n",
USBDEVNAME(sc->sc_dev), usbd_errstr(err));
- sc->transfer_state = TSTATE_BBB_RESET2;
- umass_clear_endpoint_stall(sc, UMASS_BULKIN,
+ umass_clear_endpoint_stall(sc,
+ sc->bulkin, sc->bulkin_pipe, TSTATE_BBB_RESET2,
sc->transfer_xfer[XFER_BBB_RESET2]);
return;
@@ -1218,8 +1854,8 @@ umass_bbb_state(usbd_xfer_handle xfer, usbd_private_handle priv,
USBDEVNAME(sc->sc_dev), usbd_errstr(err));
/* no error recovery, otherwise we end up in a loop */
- sc->transfer_state = TSTATE_BBB_RESET3;
- umass_clear_endpoint_stall(sc, UMASS_BULKOUT,
+ umass_clear_endpoint_stall(sc,
+ sc->bulkout, sc->bulkout_pipe, TSTATE_BBB_RESET3,
sc->transfer_xfer[XFER_BBB_RESET3]);
return;
@@ -1253,16 +1889,19 @@ Static int
umass_cbi_adsc(struct umass_softc *sc, char *buffer, int buflen,
usbd_xfer_handle xfer)
{
- KASSERT(sc->sc_wire & (UMASS_WPROTO_CBI|UMASS_WPROTO_CBI_I),
- ("sc->sc_wire == 0x%02x wrong for umass_cbi_adsc\n",
- sc->sc_wire));
-
- sc->sc_req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
- sc->sc_req.bRequest = UR_CBI_ADSC;
- USETW(sc->sc_req.wValue, 0);
- USETW(sc->sc_req.wIndex, sc->sc_ifaceno);
- USETW(sc->sc_req.wLength, buflen);
- return umass_setup_ctrl_transfer(sc, &sc->sc_req, buffer,
+ usbd_device_handle dev;
+
+ KASSERT(sc->proto & (PROTO_CBI|PROTO_CBI_I),
+ ("sc->proto == 0x%02x wrong for umass_cbi_adsc\n",sc->proto));
+
+ usbd_interface2device_handle(sc->iface, &dev);
+
+ 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, dev, &sc->request, buffer,
buflen, 0, xfer);
}
@@ -1273,9 +1912,8 @@ umass_cbi_reset(struct umass_softc *sc, int status)
int i;
# define SEND_DIAGNOSTIC_CMDLEN 12
- KASSERT(sc->sc_wire & (UMASS_WPROTO_CBI|UMASS_WPROTO_CBI_I),
- ("sc->sc_wire == 0x%02x wrong for umass_cbi_reset\n",
- sc->sc_wire));
+ KASSERT(sc->proto & (PROTO_CBI|PROTO_CBI_I),
+ ("sc->proto == 0x%02x wrong for umass_cbi_reset\n",sc->proto));
if (sc->sc_dying)
return;
@@ -1321,22 +1959,19 @@ 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, umass_callback cb, void *priv)
+ void *cmd, int cmdlen, void *data, int datalen, int dir,
+ transfer_cb_f cb, void *priv)
{
DPRINTF(UDMASS_CBI,("%s: umass_cbi_transfer cmd=0x%02x, len=%d\n",
USBDEVNAME(sc->sc_dev), *(u_char *)cmd, datalen));
- KASSERT(sc->sc_wire & (UMASS_WPROTO_CBI|UMASS_WPROTO_CBI_I),
- ("sc->sc_wire == 0x%02x wrong for umass_cbi_transfer\n",
- sc->sc_wire));
+ KASSERT(sc->proto & (PROTO_CBI|PROTO_CBI_I),
+ ("sc->proto == 0x%02x wrong for umass_cbi_transfer\n",
+ sc->proto));
if (sc->sc_dying)
return;
- /* Be a little generous. */
- sc->timeout = timeout + USBD_DEFAULT_TIMEOUT;
-
/*
* Do a CBI transfer with cmdlen bytes from cmd, possibly
* a data phase of datalen bytes from/to the device and finally a
@@ -1384,9 +2019,8 @@ umass_cbi_state(usbd_xfer_handle xfer, usbd_private_handle priv,
{
struct umass_softc *sc = (struct umass_softc *) priv;
- KASSERT(sc->sc_wire & (UMASS_WPROTO_CBI|UMASS_WPROTO_CBI_I),
- ("sc->sc_wire == 0x%02x wrong for umass_cbi_state\n",
- sc->sc_wire));
+ KASSERT(sc->proto & (PROTO_CBI|PROTO_CBI_I),
+ ("sc->proto == 0x%02x wrong for umass_cbi_state\n", sc->proto));
if (sc->sc_dying)
return;
@@ -1409,10 +2043,10 @@ umass_cbi_state(usbd_xfer_handle xfer, usbd_private_handle priv,
/* 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 stalled at this point.
+ * 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 stalled at this point.
*/
sc->transfer_state = TSTATE_IDLE;
@@ -1431,7 +2065,7 @@ umass_cbi_state(usbd_xfer_handle xfer, usbd_private_handle priv,
sc->transfer_state = TSTATE_CBI_DATA;
if (sc->transfer_dir == DIR_IN) {
- if (umass_setup_transfer(sc, sc->sc_pipe[UMASS_BULKIN],
+ if (umass_setup_transfer(sc, sc->bulkin_pipe,
sc->transfer_data, sc->transfer_datalen,
USBD_SHORT_XFER_OK | USBD_NO_COPY,
sc->transfer_xfer[XFER_CBI_DATA]))
@@ -1440,17 +2074,17 @@ umass_cbi_state(usbd_xfer_handle xfer, usbd_private_handle priv,
} else if (sc->transfer_dir == DIR_OUT) {
memcpy(sc->data_buffer, sc->transfer_data,
sc->transfer_datalen);
- if (umass_setup_transfer(sc, sc->sc_pipe[UMASS_BULKOUT],
+ if (umass_setup_transfer(sc, sc->bulkout_pipe,
sc->transfer_data, sc->transfer_datalen,
USBD_NO_COPY,/* fixed length transfer */
sc->transfer_xfer[XFER_CBI_DATA]))
umass_cbi_reset(sc, STATUS_WIRE_FAILED);
- } else if (sc->sc_wire == UMASS_WPROTO_CBI_I) {
+ } else if (sc->proto & PROTO_CBI_I) {
DPRINTF(UDMASS_CBI, ("%s: no data phase\n",
USBDEVNAME(sc->sc_dev)));
sc->transfer_state = TSTATE_CBI_STATUS;
- if (umass_setup_transfer(sc, sc->sc_pipe[UMASS_INTRIN],
+ if (umass_setup_transfer(sc, sc->intrin_pipe,
&sc->sbl, sizeof(sc->sbl),
0, /* fixed length transfer */
sc->transfer_xfer[XFER_CBI_STATUS])){
@@ -1476,14 +2110,15 @@ umass_cbi_state(usbd_xfer_handle xfer, usbd_private_handle priv,
USBDEVNAME(sc->sc_dev), sc->transfer_actlen));
if (err) {
- DPRINTF(UDMASS_CBI, ("%s: Data-%s %d failed, "
+ DPRINTF(UDMASS_CBI, ("%s: Data-%s %db failed, "
"%s\n", USBDEVNAME(sc->sc_dev),
(sc->transfer_dir == DIR_IN?"in":"out"),
sc->transfer_datalen,usbd_errstr(err)));
if (err == USBD_STALLED) {
- sc->transfer_state = TSTATE_CBI_DCLEAR;
- umass_clear_endpoint_stall(sc, UMASS_BULKIN,
+ 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);
@@ -1499,10 +2134,10 @@ umass_cbi_state(usbd_xfer_handle xfer, usbd_private_handle priv,
umass_dump_buffer(sc, sc->transfer_data,
sc->transfer_actlen, 48));
- if (sc->sc_wire == UMASS_WPROTO_CBI_I) {
+ if (sc->proto & PROTO_CBI_I) {
sc->transfer_state = TSTATE_CBI_STATUS;
memset(&sc->sbl, 0, sizeof(sc->sbl));
- if (umass_setup_transfer(sc, sc->sc_pipe[UMASS_INTRIN],
+ if (umass_setup_transfer(sc, sc->intrin_pipe,
&sc->sbl, sizeof(sc->sbl),
0, /* fixed length transfer */
sc->transfer_xfer[XFER_CBI_STATUS])){
@@ -1527,8 +2162,9 @@ umass_cbi_state(usbd_xfer_handle xfer, usbd_private_handle priv,
*/
if (err == USBD_STALLED) {
- sc->transfer_state = TSTATE_CBI_SCLEAR;
- umass_clear_endpoint_stall(sc, UMASS_INTRIN,
+ 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);
@@ -1538,7 +2174,7 @@ umass_cbi_state(usbd_xfer_handle xfer, usbd_private_handle priv,
/* Dissect the information in the buffer */
- if (sc->sc_cmd == UMASS_CPROTO_UFI) {
+ if (sc->proto & PROTO_UFI) {
int status;
/* Section 3.4.3.1.3 specifies that the UFI command
@@ -1614,8 +2250,8 @@ umass_cbi_state(usbd_xfer_handle xfer, usbd_private_handle priv,
printf("%s: CBI reset failed, %s\n",
USBDEVNAME(sc->sc_dev), usbd_errstr(err));
- sc->transfer_state = TSTATE_CBI_RESET2;
- umass_clear_endpoint_stall(sc, UMASS_BULKIN,
+ umass_clear_endpoint_stall(sc,
+ sc->bulkin, sc->bulkin_pipe, TSTATE_CBI_RESET2,
sc->transfer_xfer[XFER_CBI_RESET2]);
return;
@@ -1625,8 +2261,8 @@ umass_cbi_state(usbd_xfer_handle xfer, usbd_private_handle priv,
USBDEVNAME(sc->sc_dev), usbd_errstr(err));
/* no error recovery, otherwise we end up in a loop */
- sc->transfer_state = TSTATE_CBI_RESET3;
- umass_clear_endpoint_stall(sc, UMASS_BULKOUT,
+ umass_clear_endpoint_stall(sc,
+ sc->bulkout, sc->bulkout_pipe, TSTATE_CBI_RESET3,
sc->transfer_xfer[XFER_CBI_RESET3]);
return;
@@ -1656,21 +2292,26 @@ umass_cbi_state(usbd_xfer_handle xfer, usbd_private_handle priv,
usbd_status
umass_bbb_get_max_lun(struct umass_softc *sc, u_int8_t *maxlun)
{
+ usbd_device_handle dev;
usb_device_request_t req;
usbd_status err;
+ usb_interface_descriptor_t *id;
*maxlun = 0; /* Default to 0. */
DPRINTF(UDMASS_BBB, ("%s: Get Max Lun\n", USBDEVNAME(sc->sc_dev)));
+ usbd_interface2device_handle(sc->iface, &dev);
+ 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, sc->sc_ifaceno);
+ USETW(req.wIndex, id->bInterfaceNumber);
USETW(req.wLength, 1);
- err = usbd_do_request(sc->sc_udev, &req, maxlun);
+ err = usbd_do_request(dev, &req, maxlun);
switch (err) {
case USBD_NORMAL_COMPLETION:
DPRINTF(UDMASS_BBB, ("%s: Max Lun %d\n",
@@ -1707,6 +2348,706 @@ umass_bbb_get_max_lun(struct umass_softc *sc, u_int8_t *maxlun)
+#if defined(__FreeBSD__)
+/*
+ * CAM specific functions (used by SCSI, UFI, 8070)
+ */
+
+Static int
+umass_cam_attach_sim()
+{
+ 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 devices is limitted to one.
+ */
+
+ /* SCSI transparent command set */
+
+ devq = cam_simq_alloc(1 /*maximum openings*/);
+ if (devq == NULL)
+ return(ENOMEM);
+
+ umass_sim = cam_sim_alloc(umass_cam_action, umass_cam_poll, DEVNAME,
+ NULL /*priv*/, 0 /*unit number*/,
+ 1 /*maximum device openings*/,
+ 0 /*maximum tagged device openings*/,
+ devq);
+ if (umass_sim == NULL) {
+ cam_simq_free(devq);
+ return(ENOMEM);
+ }
+
+ if(xpt_bus_register(umass_sim, 0) != CAM_SUCCESS)
+ return(ENOMEM);
+
+ if (xpt_create_path(&umass_path, NULL, cam_sim_path(umass_sim),
+ UMASS_SCSIID_HOST, 0)
+ != CAM_REQ_CMP)
+ return(ENOMEM);
+
+ return(0);
+}
+
+#ifdef UMASS_DO_CAM_RESCAN
+/* this function is only used from umass_cam_rescan, so mention
+ * prototype down here.
+ */
+Static void umass_cam_rescan_callback(struct cam_periph *periph,union ccb *ccb);
+
+Static void
+umass_cam_rescan_callback(struct cam_periph *periph, union ccb *ccb)
+{
+#ifdef UMASS_DEBUG
+ struct umass_softc *sc = devclass_get_softc(umass_devclass,
+ ccb->ccb_h.target_id);
+
+ if (ccb->ccb_h.status != CAM_REQ_CMP) {
+ DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d: Rescan failed, 0x%04x\n",
+ USBDEVNAME(sc->sc_dev), UMASS_SCSI_BUS,
+ ccb->ccb_h.target_id, ccb->ccb_h.target_lun,
+ ccb->ccb_h.status));
+ } else {
+ DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d: Rescan succeeded, freeing resources.\n",
+ USBDEVNAME(sc->sc_dev), UMASS_SCSI_BUS,
+ ccb->ccb_h.target_id, ccb->ccb_h.target_lun));
+ }
+#endif
+
+ xpt_free_path(ccb->ccb_h.path);
+ free(ccb, M_USBDEV);
+}
+
+Static void
+umass_cam_rescan(struct umass_softc *sc)
+{
+ struct cam_path *path;
+ union ccb *ccb = malloc(sizeof(union ccb), M_USBDEV, M_WAITOK);
+
+ memset(ccb, 0, sizeof(union ccb));
+
+ DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d: scanning bus for new device %d\n",
+ USBDEVNAME(sc->sc_dev), cam_sim_path(umass_sim),
+ device_get_unit(sc->sc_dev), 0,
+ device_get_unit(sc->sc_dev)));
+
+ if (xpt_create_path(&path, xpt_periph, cam_sim_path(umass_sim),
+ device_get_unit(sc->sc_dev), 0)
+ != CAM_REQ_CMP)
+ 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. */
+}
+#endif
+
+Static int
+umass_cam_attach(struct umass_softc *sc)
+{
+ /* SIM already attached at module load. The device is a target on the
+ * one SIM we registered: target device_get_unit(self).
+ */
+
+ /* The artificial limit UMASS_SCSIID_MAX is there because CAM expects
+ * a limit to the number of targets that are present on a SIM.
+ */
+ if (device_get_unit(sc->sc_dev) > UMASS_SCSIID_MAX) {
+ printf("%s: Increase UMASS_SCSIID_MAX (currently %d) in %s "
+ "and try again.\n", USBDEVNAME(sc->sc_dev),
+ UMASS_SCSIID_MAX, __FILE__);
+ return(1);
+ }
+
+#ifdef UMASS_DO_CAM_RESCAN
+ if (!cold) {
+ /* Notify CAM of the new device. 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.
+ */
+ umass_cam_rescan(sc);
+ }
+#endif
+
+ return(0); /* always succesful */
+}
+
+/* umass_cam_detach
+ * detach from the CAM layer
+ */
+
+Static int
+umass_cam_detach_sim()
+{
+ if (umass_sim)
+ return(EBUSY); /* XXX CAM can't handle disappearing SIMs yet */
+
+ if (umass_path) {
+ /* XXX do we need to send an asynchroneous event for the SIM?
+ xpt_async(AC_LOST_DEVICE, umass_path, NULL);
+ */
+ xpt_free_path(umass_path);
+ umass_path = NULL;
+ }
+
+ if (umass_sim) {
+ if (xpt_bus_deregister(cam_sim_path(umass_sim)))
+ cam_sim_free(umass_sim, /*free_devq*/TRUE);
+ else
+ return(EBUSY);
+
+ umass_sim = NULL;
+ }
+
+ return(0);
+}
+
+Static int
+umass_cam_detach(struct umass_softc *sc)
+{
+ struct cam_path *path;
+
+ /* detach of sim not done until module unload */
+ DPRINTF(UDMASS_SCSI, ("%s: losing CAM device entry\n",
+ USBDEVNAME(sc->sc_dev)));
+
+ if (xpt_create_path(&path, NULL, cam_sim_path(umass_sim),
+ device_get_unit(sc->sc_dev), CAM_LUN_WILDCARD)
+ != CAM_REQ_CMP)
+ return(ENOMEM);
+ xpt_async(AC_LOST_DEVICE, path, NULL);
+ xpt_free_path(path);
+
+ 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 = devclass_get_softc(umass_devclass,
+ ccb->ccb_h.target_id);
+
+ /* 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->sc_dying) {
+ DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d:func_code 0x%04x: "
+ "Invalid target (gone)\n",
+ USBDEVNAME(sc->sc_dev), UMASS_SCSI_BUS,
+ 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\n",
+ DEVNAME_SIM, UMASS_SCSI_BUS,
+ 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\n",
+ DEVNAME_SIM, UMASS_SCSI_BUS,
+ 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 */
+ }
+
+ /* 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;
+
+ DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d:XPT_SCSI_IO: "
+ "cmd: 0x%02x, flags: 0x%02x, "
+ "%db cmd/%db data/%db sense\n",
+ USBDEVNAME(sc->sc_dev), UMASS_SCSI_BUS,
+ 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 requested while busy (state %d, %s)\n",
+ USBDEVNAME(sc->sc_dev), UMASS_SCSI_BUS,
+ 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 (sc->transform(sc, csio->cdb_io.cdb_bytes, csio->cdb_len,
+ &cmd, &cmdlen)) {
+ sc->transfer(sc, ccb->ccb_h.target_lun, cmd, cmdlen,
+ csio->data_ptr,
+ csio->dxfer_len, dir,
+ umass_cam_cb, (void *) ccb);
+ } else {
+ ccb->ccb_h.status = CAM_REQ_INVALID;
+ xpt_done(ccb);
+ }
+
+ 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:USBDEVNAME(sc->sc_dev)),
+ UMASS_SCSI_BUS,
+ 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 = 0;
+ cpi->hba_eng_cnt = 0;
+ cpi->max_target = UMASS_SCSIID_MAX; /* one target */
+ cpi->max_lun = 0; /* no LUN's supported */
+ 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 = UMASS_SCSI_BUS;
+ if (sc) {
+ cpi->base_transfer_speed = sc->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",
+ USBDEVNAME(sc->sc_dev), UMASS_SCSI_BUS,
+ 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;
+
+ DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d:XPT_GET_TRAN_SETTINGS:.\n",
+ USBDEVNAME(sc->sc_dev), UMASS_SCSI_BUS,
+ ccb->ccb_h.target_id, ccb->ccb_h.target_lun));
+
+ cts->valid = 0;
+ cts->flags = 0; /* no disconnection, tagging */
+
+ 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",
+ USBDEVNAME(sc->sc_dev), UMASS_SCSI_BUS,
+ 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:
+ {
+ struct ccb_calc_geometry *ccg = &ccb->ccg;
+
+ DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d:XPT_CALC_GEOMETRY: "
+ "Volume size = %d\n",
+ USBDEVNAME(sc->sc_dev), UMASS_SCSI_BUS,
+ ccb->ccb_h.target_id, ccb->ccb_h.target_lun,
+ ccg->volume_size));
+
+ /* XXX We should probably ask the drive for the details
+ * instead of cluching them up ourselves
+ */
+ if (sc->drive == ZIP_100) {
+ ccg->heads = 64;
+ ccg->secs_per_track = 32;
+ ccg->cylinders = ccg->volume_size / ccg->heads
+ / ccg->secs_per_track;
+ ccb->ccb_h.status = CAM_REQ_CMP;
+ break;
+ } else if (sc->proto & PROTO_UFI) {
+ ccg->heads = 2;
+ if (ccg->volume_size == 2880)
+ ccg->secs_per_track = 18;
+ else
+ ccg->secs_per_track = 9;
+ ccg->cylinders = 80;
+ break;
+ } else {
+ ccb->ccb_h.status = CAM_REQ_CMP_ERR;
+ }
+
+ xpt_done(ccb);
+ break;
+ }
+ case XPT_NOOP:
+ {
+ DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d:XPT_NOOP:.\n",
+ (sc == NULL? DEVNAME_SIM:USBDEVNAME(sc->sc_dev)),
+ UMASS_SCSI_BUS,
+ 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:USBDEVNAME(sc->sc_dev)),
+ UMASS_SCSI_BUS,
+ 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;
+ }
+}
+
+/* umass_cam_poll
+ * all requests are handled through umass_cam_action, requests
+ * are never pending. So, nothing to do here.
+ */
+Static void
+umass_cam_poll(struct cam_sim *sim)
+{
+#ifdef UMASS_DEBUG
+ struct umass_softc *sc = (struct umass_softc *) sim->softc;
+
+ DPRINTF(UDMASS_SCSI, ("%s: CAM poll\n",
+ USBDEVNAME(sc->sc_dev)));
+#endif
+
+ /* nop */
+}
+
+
+/* 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 */
+
+ csio->resid = residue;
+
+ switch (status) {
+ case STATUS_CMD_OK:
+ ccb->ccb_h.status = CAM_REQ_CMP;
+ xpt_done(ccb);
+ break;
+
+ case STATUS_CMD_UNKNOWN:
+ case STATUS_CMD_FAILED:
+ switch (ccb->ccb_h.func_code) {
+ case XPT_SCSI_IO:
+ {
+ unsigned char *cmd;
+ int cmdlen;
+
+ /* fetch sense data */
+ DPRINTF(UDMASS_SCSI,("%s: Fetching %db sense data\n",
+ USBDEVNAME(sc->sc_dev),
+ sc->cam_scsi_sense.length));
+
+ sc->cam_scsi_sense.length = csio->sense_len;
+
+ if (sc->transform(sc, (char *) &sc->cam_scsi_sense,
+ sizeof(sc->cam_scsi_sense),
+ &cmd, &cmdlen)) {
+ sc->transfer(sc, ccb->ccb_h.target_lun,
+ cmd, cmdlen,
+ &csio->sense_data,
+ csio->sense_len, DIR_IN,
+ umass_cam_sense_cb, (void *) ccb);
+ } else {
+#ifdef UMASS_DEBUG
+ panic("transform(REQUEST_SENSE) failed\n");
+#else
+ csio->resid = sc->transfer_datalen;
+ ccb->ccb_h.status = CAM_REQ_CMP_ERR;
+ xpt_done(ccb);
+#endif
+ }
+ 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\n",
+ 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\n",
+ USBDEVNAME(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 */
+
+ switch (status) {
+ case STATUS_CMD_OK:
+ case STATUS_CMD_UNKNOWN:
+ /* Getting sense data succeeded. The length of the sense data
+ * is not returned in any way. The sense data itself contains
+ * the length of the sense data that is valid.
+ */
+ 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 {
+ 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",
+ USBDEVNAME(sc->sc_dev), status));
+ ccb->ccb_h.status = CAM_AUTOSENSE_FAIL;
+ xpt_done(ccb);
+ }
+}
+
+
+Static int
+umass_driver_load(module_t mod, int what, void *arg)
+{
+ int err;
+
+ switch (what) {
+ case MOD_UNLOAD:
+ err = umass_cam_detach_sim();
+ if (err)
+ return(err);
+ return(usbd_driver_load(mod, what, arg));
+ case MOD_LOAD:
+ /* We don't attach to CAM at this point, because it will try
+ * and malloc memory for it. This is not possible when the
+ * boot loader loads umass as a module before the kernel
+ * has been bootstrapped.
+ */
+ default:
+ return(usbd_driver_load(mod, what, arg));
+ }
+}
+
+
+
+/* (even the comment is missing) */
+
+DRIVER_MODULE(umass, uhub, umass_driver, umass_devclass, umass_driver_load, 0);
+
+
+/*
+ * SCSI specific functions
+ */
+
+Static int
+umass_scsi_transform(struct umass_softc *sc, unsigned char *cmd, int cmdlen,
+ unsigned char **rcmd, int *rcmdlen)
+{
+ *rcmd = cmd; /* trivial copy */
+ *rcmdlen = cmdlen;
+
+ switch (cmd[0]) {
+ case TEST_UNIT_READY:
+ if (sc->quirks & NO_TEST_UNIT_READY) {
+ DPRINTF(UDMASS_SCSI, ("%s: Converted TEST_UNIT_READY "
+ "to START_UNIT\n", USBDEVNAME(sc->sc_dev)));
+ cmd[0] = START_STOP_UNIT;
+ cmd[4] = SSS_START;
+ }
+ break;
+ }
+
+ return 1; /* success */
+}
+
+/*
+ * UFI specific functions
+ */
+
+Static int
+umass_ufi_transform(struct umass_softc *sc, unsigned char *cmd, int cmdlen,
+ unsigned char **rcmd, int *rcmdlen)
+{
+ *rcmd = cmd;
+ /* A UFI command is always 12 bytes in length */
+ /* XXX cmd[(cmdlen+1)..12] contains garbage */
+ *rcmdlen = 12;
+
+ switch (cmd[0]) {
+ case TEST_UNIT_READY:
+ if (sc->quirks & NO_TEST_UNIT_READY) {
+ DPRINTF(UDMASS_UFI, ("%s: Converted TEST_UNIT_READY "
+ "to START_UNIT\n", USBDEVNAME(sc->sc_dev)));
+ cmd[0] = START_STOP_UNIT;
+ cmd[4] = SSS_START;
+ }
+ return 1;
+ case INQUIRY:
+ case START_STOP_UNIT:
+ case MODE_SENSE:
+ case PREVENT_ALLOW:
+ case READ_10:
+ case READ_12:
+ case READ_CAPACITY:
+ case REQUEST_SENSE:
+ case REZERO_UNIT:
+ case POSITION_TO_ELEMENT: /* SEEK_10 */
+ case SEND_DIAGNOSTIC:
+ case WRITE_10:
+ case WRITE_12:
+ /* FORMAT_UNIT */
+ /* MODE_SELECT */
+ /* READ_FORMAT_CAPACITY */
+ /* VERIFY */
+ /* WRITE_AND_VERIFY */
+ return 1; /* success */
+ default:
+ return 0; /* success */
+ }
+}
+
+/*
+ * 8070 specific functions
+ */
+Static int
+umass_8070_transform(struct umass_softc *sc, unsigned char *cmd, int cmdlen,
+ unsigned char **rcmd, int *rcmdlen)
+{
+ return 0; /* failure */
+}
+
+#endif /* __FreeBSD__ */
+
#ifdef UMASS_DEBUG
Static void
@@ -1718,13 +3059,11 @@ umass_bbb_dump_cbw(struct umass_softc *sc, umass_bbb_cbw_t *cbw)
int tag = UGETDW(cbw->dCBWTag);
int flags = cbw->bCBWFlags;
- DPRINTF(UDMASS_BBB, ("%s: CBW %d: cmdlen=%d "
- "(0x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%s), "
+ DPRINTF(UDMASS_BBB, ("%s: CBW %d: cmd = %db "
+ "(0x%02x%02x%02x%02x%02x%02x%s), "
"data = %d bytes, dir = %s\n",
USBDEVNAME(sc->sc_dev), tag, clen,
- c[0], c[1], c[2], c[3], c[4], c[5],
- c[6], c[7], c[8], c[9],
- (clen > 10? "...":""),
+ c[0], c[1], c[2], c[3], c[4], c[5], (clen > 6? "...":""),
dlen, (flags == CBWFLAGS_IN? "in":
(flags == CBWFLAGS_OUT? "out":"<invalid>"))));
}
@@ -1774,3 +3113,482 @@ umass_dump_buffer(struct umass_softc *sc, u_int8_t *buffer, int buflen,
USBDEVNAME(sc->sc_dev), s1, s2, s3));
}
#endif
+
+
+
+
+
+
+
+
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+Static int
+umass_scsipi_cmd(xs)
+ struct scsipi_xfer *xs;
+{
+ struct scsipi_link *sc_link = xs->sc_link;
+ struct umass_softc *sc = sc_link->adapter_softc;
+ struct scsipi_generic *cmd, trcmd;
+ int cmdlen;
+ int dir;
+#ifdef UMASS_DEBUG
+ microtime(&sc->tv);
+#endif
+
+ memset(&trcmd, 0, sizeof(trcmd));
+
+#if defined(__NetBSD__)
+ DIF(UDMASS_UPPER, sc_link->flags |= DEBUGLEVEL);
+#endif
+#if defined(__OpenBSD__)
+ DIF(UDMASS_UPPER, sc_link->flags |= SCSIDEBUG_LEVEL);
+#endif
+
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+ DPRINTF(UDMASS_CMD, ("%s: umass_scsi_cmd: %d:%d xs=%p cmd=0x%02x "
+ "(quirks=0x%x, poll=%d)\n", USBDEVNAME(sc->sc_dev),
+ SCSI_LINK_TARGET(sc_link), SCSI_LINK_LUN(sc_link),
+ xs, xs->cmd->opcode, sc_link->quirks,
+ xs->xs_control & XS_CTL_POLL));
+#endif
+
+#if defined(USB_DEBUG) && defined(SCSIDEBUG)
+ if (umassdebug & UDMASS_SCSI)
+ show_scsipi_xs(xs);
+ else if (umassdebug & ~UDMASS_CMD)
+ show_scsipi_cmd(xs);
+#endif
+
+ if (sc->sc_dying) {
+ xs->error = XS_DRIVER_STUFFUP;
+ goto done;
+ }
+
+#ifdef UMASS_DEBUG
+#if defined(__NetBSD__)
+ if ((sc_link->type == BUS_ATAPI ?
+ sc_link->scsipi_atapi.drive : SCSI_LINK_TARGET(sc_link))
+ != UMASS_SCSIID_DEVICE) {
+ DPRINTF(UDMASS_SCSI, ("%s: wrong SCSI ID %d\n",
+ USBDEVNAME(sc->sc_dev),
+ SCSI_LINK_TARGET(sc_link)));
+ xs->error = XS_DRIVER_STUFFUP;
+ goto done;
+ }
+#endif
+#if defined(__OpenBSD__)
+ if (sc_link->target != UMASS_SCSIID_DEVICE) {
+ DPRINTF(UDMASS_SCSI, ("%s: wrong SCSI ID %d\n",
+ USBDEVNAME(sc->sc_dev),
+ sc_link->target));
+ xs->error = XS_DRIVER_STUFFUP;
+ goto done;
+ }
+#endif
+#endif
+
+ cmd = xs->cmd;
+
+ if (xs->cmd->opcode == SCSI_MODE_SENSE &&
+ (sc_link->quirks & SDEV_NOMODESENSE)) {
+ /*printf("%s: SCSI_MODE_SENSE\n", USBDEVNAME(sc->sc_dev));*/
+ xs->error = XS_TIMEOUT;
+ goto done;
+ }
+
+ if (xs->cmd->opcode == START_STOP &&
+ (sc->quirks & NO_START_STOP)) {
+ /*printf("%s: START_STOP\n", USBDEVNAME(sc->sc_dev));*/
+ xs->error = XS_NOERROR;
+ goto done;
+ }
+
+ if (xs->cmd->opcode == INQUIRY &&
+ (sc->quirks & FORCE_SHORT_INQUIRY)) {
+ memcpy(&trcmd, cmd, sizeof trcmd);
+ trcmd.bytes[4] = SHORT_INQUIRY_LENGTH;
+ cmd = &trcmd;
+ }
+
+ dir = DIR_NONE;
+ if (xs->datalen) {
+ switch (xs->xs_control & (XS_CTL_DATA_IN | XS_CTL_DATA_OUT)) {
+ case XS_CTL_DATA_IN:
+ dir = DIR_IN;
+ break;
+ case XS_CTL_DATA_OUT:
+ dir = DIR_OUT;
+ break;
+ }
+ }
+
+ if (xs->datalen > UMASS_MAX_TRANSFER_SIZE) {
+ printf("umass_cmd: large datalen, %d\n", xs->datalen);
+ xs->error = XS_DRIVER_STUFFUP;
+ goto done;
+ }
+
+ cmdlen = xs->cmdlen;
+ if (sc->proto & PROTO_UFI) {
+ if (!umass_ufi_transform(sc, cmd, cmdlen, &trcmd, &cmdlen)) {
+ xs->error = XS_DRIVER_STUFFUP;
+ goto done;
+ }
+ cmd= &trcmd;
+ }
+
+ if (sc->proto & PROTO_ATAPI) {
+ bcopy(cmd, &trcmd, cmdlen);
+ cmd = &trcmd;
+ cmdlen = ATAPI_COMMAND_LENGTH;
+ }
+
+ if (xs->xs_control & XS_CTL_POLL) {
+ /* Use sync transfer. XXX Broken! */
+ DPRINTF(UDMASS_SCSI, ("umass_scsi_cmd: sync dir=%d\n", dir));
+ sc->sc_xfer_flags = USBD_SYNCHRONOUS;
+ sc->sc_sync_status = USBD_INVAL;
+ sc->transfer(sc, SCSI_LINK_LUN(sc_link), cmd, cmdlen,
+ xs->data, xs->datalen, dir, 0, xs);
+ sc->sc_xfer_flags = 0;
+ DPRINTF(UDMASS_SCSI, ("umass_scsi_cmd: done err=%d\n",
+ sc->sc_sync_status));
+ switch (sc->sc_sync_status) {
+ case USBD_NORMAL_COMPLETION:
+ xs->error = XS_NOERROR;
+ break;
+ case USBD_TIMEOUT:
+ xs->error = XS_TIMEOUT;
+ break;
+ default:
+ xs->error = XS_DRIVER_STUFFUP;
+ break;
+ }
+ goto done;
+ } else {
+ DPRINTF(UDMASS_SCSI, ("umass_scsi_cmd: async dir=%d, cmdlen=%d"
+ " datalen=%d\n",
+ dir, cmdlen, xs->datalen));
+ sc->transfer(sc, SCSI_LINK_LUN(sc_link), cmd, cmdlen,
+ xs->data, xs->datalen, dir, umass_scsipi_cb, xs);
+ return (SUCCESSFULLY_QUEUED);
+ }
+
+ /* Return if command finishes early. */
+ done:
+#if defined(__NetBSD__)
+ xs->xs_status |= XS_STS_DONE;
+#endif
+#if defined(__OpenBSD__)
+ xs->flags |= ITSDONE;
+#endif
+
+ scsipi_done(xs);
+ if (xs->xs_control & XS_CTL_POLL)
+ return (COMPLETE);
+ else
+ return (SUCCESSFULLY_QUEUED);
+}
+
+Static void
+umass_scsipi_minphys(bp)
+ struct buf *bp;
+{
+ if (bp->b_bcount > UMASS_MAX_TRANSFER_SIZE)
+ bp->b_bcount = UMASS_MAX_TRANSFER_SIZE;
+ minphys(bp);
+}
+
+int
+umass_scsipi_ioctl(link, cmd, arg, flag, p)
+ struct scsipi_link *link;
+ u_long cmd;
+ caddr_t arg;
+ int flag;
+ struct proc *p;
+{
+ /*struct umass_softc *sc = link->adapter_softc;*/
+
+ switch (cmd) {
+#if 0
+ case SCBUSIORESET:
+ ccb->ccb_h.status = CAM_REQ_INPROG;
+ umass_reset(sc, umass_cam_cb, (void *) ccb);
+ return (0);
+#endif
+ default:
+ return (ENOTTY);
+ }
+}
+
+Static void
+umass_scsipi_cb(struct umass_softc *sc, void *priv, int residue, int status)
+{
+ struct scsipi_xfer *xs = priv;
+ struct scsipi_link *sc_link = xs->sc_link;
+ int cmdlen;
+ int s;
+#ifdef UMASS_DEBUG
+ struct timeval tv;
+ u_int delta;
+ microtime(&tv);
+ delta = (tv.tv_sec - sc->tv.tv_sec) * 1000000 + tv.tv_usec - sc->tv.tv_usec;
+#endif
+
+ DPRINTF(UDMASS_CMD,("umass_scsipi_cb: at %lu.%06lu, delta=%u: xs=%p residue=%d"
+ " status=%d\n", tv.tv_sec, tv.tv_usec, delta, xs, residue, status));
+ xs->resid = residue;
+
+ switch (status) {
+ case STATUS_CMD_OK:
+ xs->error = XS_NOERROR;
+ break;
+
+ case STATUS_CMD_UNKNOWN:
+ case STATUS_CMD_FAILED:
+ /* fetch sense data */
+ memset(&sc->sc_sense_cmd, 0, sizeof(sc->sc_sense_cmd));
+ sc->sc_sense_cmd.opcode = REQUEST_SENSE;
+ sc->sc_sense_cmd.byte2 = SCSI_LINK_LUN(sc_link) <<
+ SCSI_CMD_LUN_SHIFT;
+ sc->sc_sense_cmd.length = sizeof(xs->sense);
+
+ cmdlen = sizeof(sc->sc_sense_cmd);
+ if (sc->proto & PROTO_UFI)
+ cmdlen = UFI_COMMAND_LENGTH;
+ else if (sc->proto & PROTO_ATAPI)
+ cmdlen = ATAPI_COMMAND_LENGTH;
+
+ sc->transfer(sc, SCSI_LINK_LUN(sc_link),
+ &sc->sc_sense_cmd, cmdlen,
+ &xs->sense, sizeof(xs->sense), DIR_IN,
+ umass_scsipi_sense_cb, xs);
+ return;
+
+ case STATUS_WIRE_FAILED:
+ xs->error = XS_RESET;
+ break;
+
+ default:
+ panic("%s: Unknown status %d in umass_scsipi_cb\n",
+ USBDEVNAME(sc->sc_dev), status);
+ }
+
+#if defined(__NetBSD__)
+ xs->xs_status |= XS_STS_DONE;
+#endif
+#if defined(__OpenBSD__)
+ xs->flags |= ITSDONE;
+#endif
+
+ DPRINTF(UDMASS_CMD,("umass_scsipi_cb: at %lu.%06lu: return xs->error="
+ "%d, xs->xs_status=0x%x xs->resid=%d\n",
+ tv.tv_sec, tv.tv_usec,
+ xs->error, xs->xs_status, xs->resid));
+
+ s = splbio();
+ scsipi_done(xs);
+ splx(s);
+}
+
+/*
+ * Finalise a completed autosense operation
+ */
+Static void
+umass_scsipi_sense_cb(struct umass_softc *sc, void *priv, int residue,
+ int status)
+{
+ struct scsipi_xfer *xs = priv;
+ int s;
+ int bytes_received;
+
+ DPRINTF(UDMASS_CMD,("umass_scsipi_sense_cb: xs=%p residue=%d "
+ "status=%d\n", xs, residue, status));
+
+ switch (status) {
+ case STATUS_CMD_OK:
+ case STATUS_CMD_UNKNOWN:
+ /* getting sense data succeeded */
+ if ((xs->cmd->opcode == INQUIRY)
+ && (xs->resid < xs->datalen)) {
+ /* Some drivers return SENSE errors even after INQUIRY
+ * The upper layer doesn't like that.
+ */
+ xs->error = XS_NOERROR;
+ break;
+ }
+
+ bytes_received = sizeof(xs->sense) - residue;
+
+ if (bytes_received < 8 ||
+ (bytes_received < xs->sense.extra_len + 8))
+ xs->error = XS_SHORTSENSE;
+ else
+ xs->error = XS_SENSE;
+
+#if defined(__OpenBSD__)
+ /* Note that this test may need to be revised
+ with QIC-157a/SCSI tape drives that return
+ ILI, EOM in the high bits of flags.
+ */
+ if ((xs->sense.error_code & SSD_ERRCODE) == 0x70 &&
+ (xs->sense.flags == 0))
+ xs->error = XS_NOERROR;
+#endif
+
+ break;
+ default:
+ DPRINTF(UDMASS_SCSI, ("%s: Autosense failed, status %d\n",
+ USBDEVNAME(sc->sc_dev), status));
+ xs->error = XS_DRIVER_STUFFUP;
+ break;
+ }
+
+#if defined(__NetBSD__)
+ xs->xs_status |= XS_STS_DONE;
+#endif
+#if defined(__OpenBSD__)
+ xs->flags |= ITSDONE;
+#endif
+
+ DPRINTF(UDMASS_CMD,("umass_scsipi_sense_cb: return xs->error=%d, "
+ "xs->xs_status=0x%x xs->resid=%d\n", xs->error, xs->xs_status,
+ xs->resid));
+
+ s = splbio();
+ scsipi_done(xs);
+ splx(s);
+}
+
+/*
+ * UFI specific functions
+ */
+
+Static int
+umass_ufi_transform(struct umass_softc *sc, struct scsipi_generic *cmd,
+ int cmdlen, struct scsipi_generic *rcmd, int *rcmdlen)
+{
+ *rcmdlen = UFI_COMMAND_LENGTH;
+ memset(rcmd, 0, sizeof *rcmd);
+
+ /* Handle any quirks */
+ if (cmd->opcode == TEST_UNIT_READY
+ && (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", USBDEVNAME(sc->sc_dev)));
+ rcmd->opcode = START_STOP;
+ rcmd->bytes[3] = SSS_START;
+ return 1;
+ }
+
+ switch (cmd->opcode) {
+ /* Commands of which the format has been verified. They should work. */
+ case TEST_UNIT_READY:
+ case SCSI_REZERO_UNIT:
+ case REQUEST_SENSE:
+ case INQUIRY:
+ case START_STOP:
+ /*case SEND_DIAGNOSTIC: ??*/
+ case PREVENT_ALLOW:
+ case READ_CAPACITY:
+ case READ_BIG:
+ case WRITE_BIG:
+ case POSITION_TO_ELEMENT: /* SEEK_10 */
+ case SCSI_MODE_SELECT_BIG:
+ case SCSI_MODE_SENSE_BIG:
+ default:
+ /* Copy the command into the (zeroed out) destination buffer */
+ memcpy(rcmd, cmd, cmdlen);
+ return (1); /* success */
+
+ /*
+ * Other UFI commands: FORMAT_UNIT, MODE_SELECT, READ_FORMAT_CAPACITY,
+ * VERIFY, WRITE_AND_VERIFY.
+ * These should be checked whether they somehow can be made to fit.
+ */
+
+ /* These commands are known _not_ to work. They should be converted. */
+ case SCSI_READ_COMMAND:
+ case SCSI_WRITE_COMMAND:
+ case SCSI_MODE_SENSE:
+ case SCSI_MODE_SELECT:
+ printf("%s: Unsupported UFI command 0x%02x",
+ USBDEVNAME(sc->sc_dev), cmd->opcode);
+ if (cmdlen == 6)
+ printf(", 6 byte command should have been converted");
+ printf("\n");
+ return (0); /* failure */
+ }
+}
+
+
+#if NATAPIBUS > 0
+Static void
+umass_atapi_probedev(atapi, target)
+ struct atapibus_softc *atapi;
+ int target;
+{
+ struct scsipi_link *sc_link;
+ struct scsipibus_attach_args sa;
+ struct ata_drive_datas *drvp = &atapi->sc_drvs[target];
+ char vendor[33], product[65], revision[17];
+ struct scsipi_inquiry_data inqbuf;
+
+ DPRINTF(UDMASS_SCSI,("umass_atapi_probedev: atapi=%p target=%d\n",
+ atapi, target));
+
+ if (atapi->sc_link[target])
+ return;
+
+ sc_link = malloc(sizeof(*sc_link), M_DEVBUF, M_NOWAIT);
+ if (sc_link == NULL) {
+ printf("%s: can't allocate link for drive %d\n",
+ atapi->sc_dev.dv_xname, target);
+ return;
+ }
+ *sc_link = *atapi->adapter_link;
+
+ DIF(UDMASS_UPPER, sc_link->flags |= DEBUGLEVEL);
+
+ /* Fill generic parts of the link. */
+ sc_link->active = 0;
+ sc_link->scsipi_atapi.drive = target;
+ sc_link->device = &umass_dev;
+ TAILQ_INIT(&sc_link->pending_xfers);
+
+ DPRINTF(UDMASS_SCSI, ("umass_atapi_probedev: doing inquiry\n"));
+ /* Now go ask the device all about itself. */
+ memset(&inqbuf, 0, sizeof(inqbuf));
+ if (scsipi_inquire(sc_link, &inqbuf, XS_CTL_DISCOVERY) != 0)
+ goto bad;
+
+ scsipi_strvis(vendor, 33, inqbuf.vendor, 8);
+ scsipi_strvis(product, 65, inqbuf.product, 16);
+ scsipi_strvis(revision, 17, inqbuf.revision, 4);
+
+ sa.sa_sc_link = sc_link;
+ sa.sa_inqbuf.type = inqbuf.device;
+ sa.sa_inqbuf.removable = inqbuf.dev_qual2 & SID_REMOVABLE ?
+ T_REMOV : T_FIXED;
+ if (sa.sa_inqbuf.removable)
+ sc_link->flags |= SDEV_REMOVABLE;
+ /* XXX how? sc_link->scsipi_atapi.cap |= ACAP_LEN;*/
+ sa.sa_inqbuf.vendor = vendor;
+ sa.sa_inqbuf.product = product;
+ sa.sa_inqbuf.revision = revision;
+ sa.sa_inqptr = NULL;
+
+ drvp->drv_softc = atapi_probedev(atapi, target, sc_link, &sa);
+ /* atapi_probedev() frees the scsipi_link when there is no device. */
+ return;
+
+bad:
+ free(sc_link, M_DEVBUF);
+ return;
+}
+#endif
+#endif
diff --git a/sys/dev/usb/umass_isdata.c b/sys/dev/usb/umass_isdata.c
deleted file mode 100644
index bd5a73562dd..00000000000
--- a/sys/dev/usb/umass_isdata.c
+++ /dev/null
@@ -1,589 +0,0 @@
-/* $NetBSD: umass_isdata.c,v 1.1 2001/12/24 13:43:25 augustss Exp $ */
-
-/*
- * TODO:
- * get ATA registers on any kind of error
- * implement more commands (what is needed)
- */
-
-/*
- * 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) 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>
-__KERNEL_RCSID(0, "$NetBSD: umass_isdata.c,v 1.1 2001/12/24 13:43:25 augustss Exp $");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/conf.h>
-#include <sys/buf.h>
-#include <sys/device.h>
-#include <sys/proc.h>
-#include <sys/disklabel.h>
-#include <sys/malloc.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-
-#include <dev/usb/umassvar.h>
-#include <dev/usb/umass_isdata.h>
-
-int umass_wd_attach(struct umass_softc *);
-
-#include <dev/ata/atareg.h>
-#include <dev/ata/atavar.h>
-#include <dev/ata/wdvar.h>
-#include <dev/ic/wdcreg.h>
-
-/* XXX move this */
-struct isd200_config {
- uByte EventNotification;
- uByte ExternalClock;
- uByte ATAInitTimeout;
- uByte ATAMisc1;
-#define ATATiming 0x0f
-#define ATAPIReset 0x10
-#define MasterSlaveSelection 0x20
-#define ATAPICommandBlockSize 0xc0
- uByte ATAMajorCommand;
- uByte ATAMinorCommand;
- uByte ATAMisc2;
-#define LastLUNIdentifier 0x07
-#define DescriptOverride 0x08
-#define ATA3StateSuspend 0x10
-#define SkipDeviceBoot 0x20
-#define ConfigDescriptor2 0x40
-#define InitStatus 0x80
- uByte ATAMisc3;
-#define SRSTEnable 0x01
-};
-
-struct uisdata_softc {
- struct umassbus_softc base;
-
- struct ata_drive_datas sc_drv_data;
- struct isd200_config sc_isd_config;
- void *sc_ata_bio;
- u_long sc_skip;
-};
-
-#undef DPRINTF
-#undef DPRINTFN
-#ifdef UISDATA_DEBUG
-#define DPRINTF(x) if (uisdatadebug) logprintf x
-#define DPRINTFN(n,x) if (uisdatadebug>(n)) logprintf x
-int uisdatadebug = 0;
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-int uisdata_bio(struct ata_drive_datas *, struct ata_bio *);
-int uisdata_bio1(struct ata_drive_datas *, struct ata_bio *);
-void uisdata_reset_channel(struct ata_drive_datas *);
-int uisdata_exec_command(struct ata_drive_datas *, struct wdc_command *);
-int uisdata_get_params(struct ata_drive_datas *, u_int8_t, struct ataparams *);
-int uisdata_addref(struct ata_drive_datas *);
-void uisdata_delref(struct ata_drive_datas *);
-void uisdata_kill_pending(struct ata_drive_datas *);
-
-void uisdata_bio_cb(struct umass_softc *, void *, int, int);
-void uisdata_exec_cb(struct umass_softc *, void *, int, int);
-int uwdprint(void *, const char *);
-
-const struct ata_bustype uisdata_bustype = {
- SCSIPI_BUSTYPE_ATA,
- uisdata_bio,
- uisdata_reset_channel,
- uisdata_exec_command,
- uisdata_get_params,
- uisdata_addref,
- uisdata_delref,
- uisdata_kill_pending,
-};
-
-struct ata_cmd {
- u_int8_t ac_signature0;
- u_int8_t ac_signature1;
-
- u_int8_t ac_action_select;
-#define AC_ReadRegisterAccess 0x01
-#define AC_NoDeviceSelectionBit 0x02
-#define AC_NoBSYPollBit 0x04
-#define AC_IgnorePhaseErrorBit 0x08
-#define AC_IgnoreDeviceErrorBit 0x10
-
- u_int8_t ac_register_select;
-#define AC_SelectAlternateStatus 0x01 /* R */
-#define AC_SelectDeviceControl 0x01 /* W */
-#define AC_SelectError 0x02 /* R */
-#define AC_SelectFeatures 0x02 /* W */
-#define AC_SelectSectorCount 0x04 /* RW */
-#define AC_SelectSectorNumber 0x08 /* RW */
-#define AC_SelectCylinderLow 0x10 /* RW */
-#define AC_SelectCylinderHigh 0x20 /* RW */
-#define AC_SelectDeviceHead 0x40 /* RW */
-#define AC_SelectStatus 0x80 /* R */
-#define AC_SelectCommand 0x80 /* W */
-
- u_int8_t ac_transfer_blocksize;
-
- u_int8_t ac_alternate_status;
-#define ac_device_control ac_alternate_status
- u_int8_t ac_error;
-#define ac_features ac_error
-
- u_int8_t ac_sector_count;
- u_int8_t ac_sector_number;
- u_int8_t ac_cylinder_low;
- u_int8_t ac_cylinder_high;
- u_int8_t ac_device_head;
-
- u_int8_t ac_status;
-#define ac_command ac_status
-
- u_int8_t ac_reserved[3];
-};
-
-#define ATA_DELAY 10000 /* 10s for a drive I/O */
-
-int
-umass_isdata_attach(struct umass_softc *sc)
-{
- usb_device_request_t req;
- usbd_status err;
- struct ata_device adev;
- struct uisdata_softc *scbus;
- struct isd200_config *cf;
-
- scbus = malloc(sizeof *scbus, M_DEVBUF, M_WAITOK | M_ZERO);
- sc->bus = &scbus->base;
- cf = &scbus->sc_isd_config;
-
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = 0x02;
- USETW(req.wValue, 0);
- USETW(req.wIndex, 2);
- USETW(req.wLength, sizeof *cf);
-
- err = usbd_do_request(sc->sc_udev, &req, cf);
- if (err)
- return (EIO);
- DPRINTF(("umass_wd_attach info:\n EventNotification=0x%02x "
- "ExternalClock=0x%02x ATAInitTimeout=0x%02x\n"
- " ATAMisc1=0x%02x ATAMajorCommand=0x%02x "
- "ATAMinorCommand=0x%02x\n"
- " ATAMisc2=0x%02x ATAMisc3=0x%02x\n",
- cf->EventNotification, cf->ExternalClock, cf->ATAInitTimeout,
- cf->ATAMisc1, cf->ATAMajorCommand, cf->ATAMinorCommand,
- cf->ATAMisc2, cf->ATAMisc3));
-
- memset(&adev, 0, sizeof(struct ata_device));
- adev.adev_bustype = &uisdata_bustype;
- adev.adev_channel = 1; /* XXX */
- adev.adev_openings = 1;
- adev.adev_drv_data = &scbus->sc_drv_data;
- scbus->sc_drv_data.drive_flags = DRIVE_ATA;
- scbus->sc_drv_data.chnl_softc = sc;
- scbus->base.sc_child = config_found(&sc->sc_dev, &adev, uwdprint);
-
- return (0);
-}
-
-
-void
-uisdata_bio_cb(struct umass_softc *sc, void *priv, int residue, int status)
-{
- struct uisdata_softc *scbus = (struct uisdata_softc *)sc->bus;
- struct ata_bio *ata_bio = priv;
- int s;
-
- DPRINTF(("%s: residue=%d status=%d\n", __FUNCTION__, residue, status));
-
- s = splbio();
- scbus->sc_ata_bio = NULL;
- if (status != STATUS_CMD_OK)
- ata_bio->error = ERR_DF; /* ??? */
- else
- ata_bio->error = NOERROR;
- ata_bio->flags |= ATA_ITSDONE;
-
- ata_bio->blkdone += ata_bio->nblks;
- ata_bio->blkno += ata_bio->nblks;
- ata_bio->bcount -= ata_bio->nbytes;
- scbus->sc_skip += ata_bio->nbytes;
- if (residue != 0) {
- ata_bio->bcount += residue;
- } else if (ata_bio->bcount > 0) {
- DPRINTF(("%s: continue\n", __FUNCTION__));
- (void)uisdata_bio1(&scbus->sc_drv_data, ata_bio); /*XXX save drv*/
- splx(s);
- return;
- }
-
- if (ata_bio->flags & ATA_POLL) {
- DPRINTF(("%s: wakeup %p\n", __FUNCTION__, ata_bio));
- wakeup(ata_bio);
- } else {
- wddone(scbus->sc_drv_data.drv_softc);
- }
- splx(s);
-}
-
-int
-uisdata_bio(struct ata_drive_datas *drv, struct ata_bio *ata_bio)
-{
- struct umass_softc *sc = drv->chnl_softc;
- struct uisdata_softc *scbus = (struct uisdata_softc *)sc->bus;
-
- scbus->sc_skip = 0;
- return (uisdata_bio1(drv, ata_bio));
-}
-
-int
-uisdata_bio1(struct ata_drive_datas *drv, struct ata_bio *ata_bio)
-{
- struct umass_softc *sc = drv->chnl_softc;
- struct uisdata_softc *scbus = (struct uisdata_softc *)sc->bus;
- struct isd200_config *cf = &scbus->sc_isd_config;
- struct ata_cmd ata;
- u_int16_t cyl;
- u_int8_t head, sect;
- int dir;
- long nbytes;
- u_int nblks;
-
- DPRINTF(("%s\n", __FUNCTION__));
- /* XXX */
-
- if (ata_bio->flags & ATA_NOSLEEP) {
- printf("%s: ATA_NOSLEEP not supported\n", __FUNCTION__);
- ata_bio->error = TIMEOUT;
- ata_bio->flags |= ATA_ITSDONE;
- return (WDC_COMPLETE);
- }
-
- if (scbus->sc_ata_bio != NULL) {
- printf("%s: multiple uisdata_bio\n", __FUNCTION__);
- return (WDC_TRY_AGAIN);
- } else
- scbus->sc_ata_bio = ata_bio;
-
- if (ata_bio->flags & ATA_LBA) {
- sect = (ata_bio->blkno >> 0) & 0xff;
- cyl = (ata_bio->blkno >> 8) & 0xffff;
- head = (ata_bio->blkno >> 24) & 0x0f;
- head |= WDSD_LBA;
- } else {
- int blkno = ata_bio->blkno;
- sect = blkno % ata_bio->lp->d_nsectors;
- sect++; /* Sectors begin with 1, not 0. */
- blkno /= ata_bio->lp->d_nsectors;
- head = blkno % ata_bio->lp->d_ntracks;
- blkno /= ata_bio->lp->d_ntracks;
- cyl = blkno;
- head |= WDSD_CHS;
- }
-
- nbytes = ata_bio->bcount;
- if (ata_bio->flags & ATA_SINGLE)
- nblks = 1;
- else
- nblks = min(ata_bio->multi, nbytes / ata_bio->lp->d_secsize);
- nbytes = nblks * ata_bio->lp->d_secsize;
- ata_bio->nblks = nblks;
- ata_bio->nbytes = nbytes;
-
- memset(&ata, 0, sizeof ata);
- ata.ac_signature0 = cf->ATAMajorCommand;
- ata.ac_signature1 = cf->ATAMinorCommand;
- ata.ac_transfer_blocksize = 1;
- ata.ac_sector_count = nblks;
- ata.ac_sector_number = sect;
- ata.ac_cylinder_high = cyl >> 8;
- ata.ac_cylinder_low = cyl;
- ata.ac_device_head = head;
- ata.ac_register_select = AC_SelectSectorCount | AC_SelectSectorNumber |
- AC_SelectCylinderLow | AC_SelectCylinderHigh | AC_SelectDeviceHead |
- AC_SelectCommand;
-
- dir = DIR_NONE;
- if (ata_bio->bcount != 0) {
- if (ata_bio->flags & ATA_READ)
- dir = DIR_IN;
- else
- dir = DIR_OUT;
- }
-
- if (ata_bio->flags & ATA_READ) {
- ata.ac_command = WDCC_READ;
- } else {
- ata.ac_command = WDCC_WRITE;
- }
- DPRINTF(("%s: bno=%d LBA=%d cyl=%d head=%d sect=%d count=%d multi=%d\n",
- __FUNCTION__, ata_bio->blkno,
- (ata_bio->flags & ATA_LBA) != 0, cyl, head, sect,
- ata.ac_sector_count, ata_bio->multi));
- DPRINTF((" data=%p bcount=%ld, drive=%d\n", ata_bio->databuf,
- ata_bio->bcount, drv->drive));
- sc->sc_methods->wire_xfer(sc, drv->drive, &ata, sizeof ata,
- ata_bio->databuf + scbus->sc_skip, nbytes,
- dir, ATA_DELAY, uisdata_bio_cb, ata_bio);
-
- while (ata_bio->flags & ATA_POLL) {
- DPRINTF(("%s: tsleep %p\n", __FUNCTION__, ata_bio));
- if (tsleep(ata_bio, PZERO, "uisdatabl", 0)) {
- ata_bio->error = TIMEOUT;
- ata_bio->flags |= ATA_ITSDONE;
- return (WDC_COMPLETE);
- }
- }
-
- return (ata_bio->flags & ATA_ITSDONE) ? WDC_COMPLETE : WDC_QUEUED;
-}
-
-void
-uisdata_reset_channel(struct ata_drive_datas *drv)
-{
- DPRINTFN(-1,("%s\n", __FUNCTION__));
- /* XXX what? */
-}
-
-void
-uisdata_exec_cb(struct umass_softc *sc, void *priv, int residue, int status)
-{
- struct wdc_command *cmd = priv;
-
- DPRINTF(("%s: status=%d\n", __FUNCTION__, status));
- if (status != STATUS_CMD_OK)
- cmd->flags |= AT_DF; /* XXX */
- cmd->flags |= AT_DONE;
- if (cmd->flags & (AT_POLL | AT_WAIT)) {
- DPRINTF(("%s: wakeup %p\n", __FUNCTION__, cmd));
- wakeup(cmd);
- }
-}
-
-int
-uisdata_exec_command(struct ata_drive_datas *drv, struct wdc_command *cmd)
-{
- struct umass_softc *sc = drv->chnl_softc;
- struct uisdata_softc *scbus = (struct uisdata_softc *)sc->bus;
- struct isd200_config *cf = &scbus->sc_isd_config;
- int dir;
- struct ata_cmd ata;
-
- DPRINTF(("%s\n", __FUNCTION__));
- DPRINTF((" r_command=0x%02x timeout=%d flags=0x%x bcount=%d\n",
- cmd->r_command, cmd->timeout, cmd->flags, cmd->bcount));
-
- dir = DIR_NONE;
- if (cmd->bcount != 0) {
- if (cmd->flags & AT_READ)
- dir = DIR_IN;
- else
- dir = DIR_OUT;
- }
-
- if (cmd->bcount > UMASS_MAX_TRANSFER_SIZE) {
- printf("uisdata_exec_command: large datalen %d\n", cmd->bcount);
- cmd->flags |= AT_ERROR;
- goto done;
- }
-
- memset(&ata, 0, sizeof ata);
- ata.ac_signature0 = cf->ATAMajorCommand;
- ata.ac_signature1 = cf->ATAMinorCommand;
- ata.ac_transfer_blocksize = 1;
-
- switch (cmd->r_command) {
- case WDCC_IDENTIFY:
- ata.ac_register_select |= AC_SelectCommand;
- ata.ac_command = WDCC_IDENTIFY;
- break;
- default:
- printf("uisdata_exec_command: bad command 0x%02x\n",
- cmd->r_command);
- cmd->flags |= AT_ERROR;
- goto done;
- }
-
- DPRINTF(("%s: execute ATA command 0x%02x, drive=%d\n", __FUNCTION__,
- ata.ac_command, drv->drive));
- sc->sc_methods->wire_xfer(sc, drv->drive, &ata,
- sizeof ata, cmd->data, cmd->bcount, dir,
- cmd->timeout, uisdata_exec_cb, cmd);
- if (cmd->flags & (AT_POLL | AT_WAIT)) {
-#if 0
- if (cmd->flags & AT_POLL)
- printf("%s: AT_POLL not supported\n", __FUNCTION__);
-#endif
- DPRINTF(("%s: tsleep %p\n", __FUNCTION__, cmd));
- if (tsleep(cmd, PZERO, "uisdataex", 0)) {
- cmd->flags |= AT_ERROR;
- goto done;
- }
- }
-
-done:
- return (WDC_COMPLETE);
-}
-
-int
-uisdata_addref(struct ata_drive_datas *drv)
-{
- DPRINTF(("%s\n", __FUNCTION__));
- /* Nothing to do */
- return (0);
-}
-
-void
-uisdata_delref(struct ata_drive_datas *drv)
-{
- DPRINTF(("%s\n", __FUNCTION__));
- /* Nothing to do */
-}
-
-void
-uisdata_kill_pending(struct ata_drive_datas *drv)
-{
- struct umass_softc *sc = drv->chnl_softc;
- struct uisdata_softc *scbus = (struct uisdata_softc *)sc->bus;
- struct ata_bio *ata_bio = scbus->sc_ata_bio;
-
- DPRINTFN(-1,("%s\n", __FUNCTION__));
-
- if (ata_bio == NULL)
- return;
- scbus->sc_ata_bio = NULL;
- ata_bio->flags |= ATA_ITSDONE;
- ata_bio->error = ERR_NODEV;
- ata_bio->r_error = WDCE_ABRT;
- wddone(scbus->sc_drv_data.drv_softc);
-}
-
-int
-uisdata_get_params(struct ata_drive_datas *drvp, u_int8_t flags,
- struct ataparams *prms)
-{
- char tb[DEV_BSIZE];
- struct wdc_command wdc_c;
-
-#if BYTE_ORDER == LITTLE_ENDIAN
- int i;
- u_int16_t *p;
-#endif
-
- DPRINTF(("%s\n", __FUNCTION__));
-
- memset(tb, 0, DEV_BSIZE);
- memset(prms, 0, sizeof(struct ataparams));
- memset(&wdc_c, 0, sizeof(struct wdc_command));
-
- wdc_c.r_command = WDCC_IDENTIFY;
- wdc_c.timeout = 1000; /* 1s */
- wdc_c.flags = AT_READ | flags;
- wdc_c.data = tb;
- wdc_c.bcount = DEV_BSIZE;
- if (uisdata_exec_command(drvp, &wdc_c) != WDC_COMPLETE) {
- DPRINTF(("uisdata_get_parms: wdc_exec_command failed\n"));
- return (CMD_AGAIN);
- }
- if (wdc_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
- DPRINTF(("uisdata_get_parms: wdc_c.flags=0x%x\n",
- wdc_c.flags));
- return (CMD_ERR);
- } else {
- /* Read in parameter block. */
- memcpy(prms, tb, sizeof(struct ataparams));
-#if BYTE_ORDER == LITTLE_ENDIAN
- /* XXX copied from ata.c */
- /*
- * Shuffle string byte order.
- * ATAPI Mitsumi and NEC drives don't need this.
- */
- if ((prms->atap_config & WDC_CFG_ATAPI_MASK) ==
- WDC_CFG_ATAPI &&
- ((prms->atap_model[0] == 'N' &&
- prms->atap_model[1] == 'E') ||
- (prms->atap_model[0] == 'F' &&
- prms->atap_model[1] == 'X')))
- return 0;
- for (i = 0; i < sizeof(prms->atap_model); i += 2) {
- p = (u_short *)(prms->atap_model + i);
- *p = ntohs(*p);
- }
- for (i = 0; i < sizeof(prms->atap_serial); i += 2) {
- p = (u_short *)(prms->atap_serial + i);
- *p = ntohs(*p);
- }
- for (i = 0; i < sizeof(prms->atap_revision); i += 2) {
- p = (u_short *)(prms->atap_revision + i);
- *p = ntohs(*p);
- }
-#endif
- return CMD_OK;
- }
-}
-
-
-/* XXX join with wdc.c routine? */
-int
-uwdprint(void *aux, const char *pnp)
-{
- //struct ata_device *adev = aux;
- if (pnp)
- printf("wd at %s", pnp);
-#if 0
- printf(" channel %d drive %d", adev->adev_channel,
- adev->adev_drv_data->drive);
-#endif
- return (UNCONF);
-}
-
-
-#if 0
-
-int umass_wd_attach(struct umass_softc *);
-
-#if NWD > 0
- case UMASS_CPROTO_ISD_ATA:
- return (umass_wd_attach(sc));
-#endif
-
-#endif
diff --git a/sys/dev/usb/umass_isdata.h b/sys/dev/usb/umass_isdata.h
deleted file mode 100644
index 665922192a4..00000000000
--- a/sys/dev/usb/umass_isdata.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* $NetBSD: umass_isdata.h,v 1.1 2001/12/24 13:43:25 augustss Exp $ */
-
-/*
- * 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) 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.
- */
-
-int umass_isdata_attach(struct umass_softc *sc);
diff --git a/sys/dev/usb/umass_quirks.c b/sys/dev/usb/umass_quirks.c
deleted file mode 100644
index 5cf42653814..00000000000
--- a/sys/dev/usb/umass_quirks.c
+++ /dev/null
@@ -1,333 +0,0 @@
-/* $OpenBSD: umass_quirks.c,v 1.1 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: umass_quirks.c,v 1.13 2002/04/22 12:48:40 augustss Exp $ */
-
-/*
- * Copyright (c) 2001 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by MAEKAWA Masahide (gehenna@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/param.h>
-#include <sys/systm.h>
-#include <sys/device.h>
-#include <sys/buf.h>
-
-#if defined(__NetBSD__)
-#include <dev/scsipi/scsipi_all.h> /* for scsiconf.h below */
-#include <dev/scsipi/scsiconf.h> /* for quirks defines */
-#endif
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdevs.h>
-
-#include <dev/usb/umassvar.h>
-#include <dev/usb/umass_quirks.h>
-
-Static usbd_status umass_init_insystem(struct umass_softc *);
-Static usbd_status umass_init_shuttle(struct umass_softc *);
-
-Static void umass_fixup_sony(struct umass_softc *);
-Static void umass_fixup_yedata(struct umass_softc *);
-
-Static const struct umass_quirk umass_quirks[] = {
- { { USB_VENDOR_FUJIPHOTO, USB_PRODUCT_FUJIPHOTO_MASS0100 },
- UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
- UMASS_QUIRK_NO_START_STOP,
- PQUIRK_NOTUR | PQUIRK_NOSENSE,
- UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
- NULL, NULL
- },
-
- { { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_USBCABLE },
- UMASS_WPROTO_CBI, UMASS_CPROTO_ATAPI,
- UMASS_QUIRK_NO_START_STOP,
- PQUIRK_NOTUR,
- UMATCH_VENDOR_PRODUCT,
- umass_init_insystem, NULL
- },
-
- { { USB_VENDOR_IOMEGA, USB_PRODUCT_IOMEGA_ZIP100 },
- UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
- 0,
- PQUIRK_NOTUR,
- UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
- NULL, NULL
- },
-
- { { USB_VENDOR_IOMEGA, USB_PRODUCT_IOMEGA_ZIP250 },
- UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
- 0,
- PQUIRK_NOTUR,
- UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
- NULL, NULL
- },
-
- { { USB_VENDOR_MICROTECH, USB_PRODUCT_MICROTECH_DPCM },
- UMASS_WPROTO_CBI, UMASS_CPROTO_ATAPI,
- 0,
- 0,
- UMATCH_VENDOR_PRODUCT,
- NULL, NULL
- },
-
- { { USB_VENDOR_MSYSTEMS, USB_PRODUCT_MSYSTEMS_DISKONKEY },
- UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
- 0,
- PQUIRK_NOMODESENSE | PQUIRK_NODOORLOCK | PQUIRK_NOBIGMODESENSE,
- UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
- NULL, NULL
- },
-
- { { USB_VENDOR_OLYMPUS, USB_PRODUCT_OLYMPUS_C1 },
- UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
- UMASS_QUIRK_WRONG_CSWSIG,
- 0,
- UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
- NULL, NULL
- },
-
- { { USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_MD2 },
- UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
- 0,
- PQUIRK_NOMODESENSE,
- UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
- NULL, NULL
- },
-
- { { USB_VENDOR_ONSPEC, USB_PRODUCT_ONSPEC_MD1II },
- UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
- UMASS_QUIRK_NO_MAX_LUN | UMASS_QUIRK_NO_START_STOP,
- PQUIRK_NOMODESENSE,
- UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
- NULL, NULL
- },
-
- { { USB_VENDOR_SCANLOGIC, USB_PRODUCT_SCANLOGIC_SL11R },
- UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UFI,
- 0,
- 0,
- UMATCH_VENDOR_PRODUCT,
- NULL, NULL
- },
-
- { { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSB },
- UMASS_WPROTO_CBI_I, UMASS_CPROTO_ATAPI,
- UMASS_QUIRK_NO_START_STOP,
- PQUIRK_NOTUR,
- UMATCH_VENDOR_PRODUCT,
- umass_init_shuttle, NULL
- },
-
- { { USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_ZIOMMC },
- UMASS_WPROTO_CBI_I, UMASS_CPROTO_ATAPI,
- UMASS_QUIRK_NO_START_STOP,
- PQUIRK_NOTUR,
- UMATCH_VENDOR_PRODUCT,
- NULL, NULL
- },
-
- { { USB_VENDOR_SONY, USB_PRODUCT_SONY_MSC },
- UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
- UMASS_QUIRK_FORCE_SHORT_INQUIRY,
- 0,
- UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
- NULL, umass_fixup_sony
- },
-
- { { USB_VENDOR_SONY, USB_PRODUCT_ANY },
- UMASS_WPROTO_UNSPEC, UMASS_CPROTO_RBC,
- 0,
- 0,
- UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
- NULL, umass_fixup_sony
- },
-
- { { USB_VENDOR_TEAC, USB_PRODUCT_TEAC_FD05PUB },
- UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
- 0,
- PQUIRK_NOMODESENSE,
- UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
- NULL, NULL
- },
-
- { { USB_VENDOR_YANO, USB_PRODUCT_YANO_U640MO },
- UMASS_WPROTO_CBI_I, UMASS_CPROTO_ATAPI,
- UMASS_QUIRK_FORCE_SHORT_INQUIRY,
- 0,
- UMATCH_VENDOR_PRODUCT,
- NULL, NULL
- },
-
- { { USB_VENDOR_YEDATA, USB_PRODUCT_YEDATA_FLASHBUSTERU },
- UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UFI,
- UMASS_QUIRK_RS_NO_CLEAR_UA,
- PQUIRK_NOMODESENSE,
- UMATCH_VENDOR_PRODUCT_REV,
- NULL, umass_fixup_yedata
- },
-
- { { USB_VENDOR_MINOLTA, USB_PRODUCT_MINOLTA_S304 },
- UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
- UMASS_QUIRK_NO_MAX_LUN | UMASS_QUIRK_NO_START_STOP,
- 0,
- UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
- NULL, NULL
- },
-
- { { USB_VENDOR_MINOLTA, USB_PRODUCT_MINOLTA_X },
- UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
- UMASS_QUIRK_NO_MAX_LUN | UMASS_QUIRK_NO_START_STOP,
- 0,
- UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
- NULL, NULL
- },
-
- { { USB_VENDOR_PEN, USB_PRODUCT_PEN_USBDISK },
- UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC,
- UMASS_QUIRK_NO_MAX_LUN | UMASS_QUIRK_NO_START_STOP,
- 0,
- UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO,
- NULL, NULL
- },
-
- /* InSystem Design ATA over USB devices */
- { { USB_VENDOR_ATI, USB_PRODUCT_ATI2_205 },
- UMASS_WPROTO_BBB, UMASS_CPROTO_ISD_ATA,
- 0,
- 0,
- UMATCH_VENDOR_PRODUCT,
- NULL, NULL
- },
- { { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_ATAPI },
- UMASS_WPROTO_BBB, UMASS_CPROTO_ISD_ATA,
- 0,
- 0,
- UMATCH_VENDOR_PRODUCT,
- NULL, NULL
- },
- { { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_DRIVEV2_5 },
- UMASS_WPROTO_BBB, UMASS_CPROTO_ISD_ATA,
- 0,
- 0,
- UMATCH_VENDOR_PRODUCT,
- NULL, NULL
- },
- { { USB_VENDOR_INSYSTEM, USB_PRODUCT_INSYSTEM_ADAPTERV2 },
- UMASS_WPROTO_BBB, UMASS_CPROTO_ISD_ATA,
- 0,
- 0,
- UMATCH_VENDOR_PRODUCT,
- NULL, NULL
- },
- { { USB_VENDOR_SONY, USB_PRODUCT_SONY_DRIVEV2 },
- UMASS_WPROTO_BBB, UMASS_CPROTO_ISD_ATA,
- 0,
- 0,
- UMATCH_VENDOR_PRODUCT,
- NULL, NULL
- },
-};
-
-const struct umass_quirk *
-umass_lookup(u_int16_t vendor, u_int16_t product)
-{
- return ((const struct umass_quirk *)
- usb_lookup(umass_quirks, vendor, product));
-}
-
-Static usbd_status
-umass_init_insystem(struct umass_softc *sc)
-{
- usbd_status err;
-
- err = usbd_set_interface(sc->sc_iface, 1);
- if (err) {
- DPRINTF(UDMASS_USB,
- ("%s: could not switch to Alt Interface 1\n",
- USBDEVNAME(sc->sc_dev)));
- return (err);
- }
-
- return (USBD_NORMAL_COMPLETION);
-}
-
-Static usbd_status
-umass_init_shuttle(struct umass_softc *sc)
-{
- usb_device_request_t req;
- u_int8_t status[2];
-
- /* The Linux driver does this */
- req.bmRequestType = UT_READ_VENDOR_DEVICE;
- req.bRequest = 1;
- USETW(req.wValue, 0);
- USETW(req.wIndex, sc->sc_ifaceno);
- USETW(req.wLength, sizeof(status));
-
- return (usbd_do_request(sc->sc_udev, &req, &status));
-}
-
-Static void
-umass_fixup_sony(struct umass_softc *sc)
-{
- usb_interface_descriptor_t *id;
-
- id = usbd_get_interface_descriptor(sc->sc_iface);
- if (id->bInterfaceSubClass == 0xff) {
- sc->sc_cmd = UMASS_CPROTO_RBC;
- }
-}
-
-Static void
-umass_fixup_yedata(struct umass_softc *sc)
-{
- usb_device_descriptor_t *dd;
-
- dd = usbd_get_device_descriptor(sc->sc_udev);
-
- /*
- * Revisions < 1.28 do not handle the interrupt endpoint very well.
- */
- if (UGETW(dd->bcdDevice) < 0x128)
- sc->sc_wire = UMASS_WPROTO_CBI;
- else
- sc->sc_wire = UMASS_WPROTO_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->sc_busquirks |= PQUIRK_NOTUR;
-}
diff --git a/sys/dev/usb/umass_quirks.h b/sys/dev/usb/umass_quirks.h
deleted file mode 100644
index 5348583ba34..00000000000
--- a/sys/dev/usb/umass_quirks.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* $OpenBSD: umass_quirks.h,v 1.1 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: umass_quirks.h,v 1.3 2001/12/29 13:46:23 augustss Exp $ */
-
-/*
- * Copyright (c) 2001 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by MAEKAWA Masahide (gehenna@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.
- */
-
-
-#ifndef _DEV_USB_UMASS_QUIRKS_H_
-#define _DEV_USB_UMASS_QUIRKS_H_
-
-typedef usbd_status (*umass_init_quirk)(struct umass_softc *);
-typedef void (*umass_fixup_quirk)(struct umass_softc *);
-
-struct umass_quirk {
- struct usb_devno uq_dev;
-
- u_int8_t uq_wire;
- u_int8_t uq_cmd;
- u_int32_t uq_flags;
- u_int32_t uq_busquirks;
- int uq_match;
-
- umass_init_quirk uq_init;
- umass_fixup_quirk uq_fixup;
-};
-
-const struct umass_quirk *umass_lookup(u_int16_t, u_int16_t);
-
-#endif /* _DEV_USB_UMASS_QUIRKS_H_ */
diff --git a/sys/dev/usb/umass_scsi.c b/sys/dev/usb/umass_scsi.c
deleted file mode 100644
index 2c1f1c2ba50..00000000000
--- a/sys/dev/usb/umass_scsi.c
+++ /dev/null
@@ -1,488 +0,0 @@
-/* $OpenBSD: umass_scsi.c,v 1.1 2002/05/07 18:08:04 nate Exp $ */
-/*
- * Copyright (c) 2001 Nathan L. Binkert
- * All rights reserved.
- *
- * Permission to redistribute, use, copy, and modify this software
- * without fee is hereby granted, provided that the following
- * conditions are met:
- *
- * 1. This entire notice is included in all source code copies of any
- * software which is or includes a copy or modification of this
- * software.
- * 2. 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.
- */
-/*
- * 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) 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 "atapiscsi.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/conf.h>
-#include <sys/buf.h>
-#include <sys/device.h>
-#include <sys/ioctl.h>
-#include <sys/malloc.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include <dev/usb/usbdevs.h>
-
-#include <dev/usb/umassvar.h>
-#include <dev/usb/umass_scsi.h>
-
-#include <scsi/scsi_all.h>
-#include <scsi/scsiconf.h>
-#include <scsi/scsi_disk.h>
-#include <machine/bus.h>
-
-struct umass_scsi_softc {
- struct umassbus_softc base;
- struct scsi_link sc_link;
- struct scsi_adapter sc_adapter;
-
- usbd_status sc_sync_status;
- struct scsi_sense sc_sense_cmd;
-};
-
-
-#define SHORT_INQUIRY_LENGTH 36 /* XXX */
-
-#define UMASS_SCSIID_HOST 0x00
-#define UMASS_SCSIID_DEVICE 0x01
-
-#define UMASS_ATAPI_DRIVE 0
-
-int umass_scsi_cmd(struct scsi_xfer *);
-void umass_scsi_minphys(struct buf *);
-int umass_scsi_ioctl(struct scsi_link *, u_long cmd, caddr_t addrp, int flag,
- struct proc *p);
-
-void umass_scsi_cb(struct umass_softc *sc, void *priv, int residue,
- int status);
-void umass_scsi_sense_cb(struct umass_softc *sc, void *priv, int residue,
- int status);
-struct umass_scsi_softc *umass_scsi_setup(struct umass_softc *);
-
-struct scsi_device umass_scsi_dev = { NULL, NULL, NULL, NULL, };
-
-int
-umass_scsi_attach(struct umass_softc *sc)
-{
- struct umass_scsi_softc *scbus;
-
- scbus = umass_scsi_setup(sc);
- scbus->sc_link.adapter_target = UMASS_SCSIID_HOST;
- scbus->sc_link.luns = sc->maxlun + 1;
-
- scbus->sc_adapter.scsi_cmd = umass_scsi_cmd;
- scbus->sc_adapter.scsi_minphys = umass_scsi_minphys;
- scbus->sc_adapter.ioctl = umass_scsi_ioctl;
-
- DPRINTF(UDMASS_USB, ("%s: umass_attach_bus: SCSI\n"
- "sc = 0x%x, scbus = 0x%x\n",
- USBDEVNAME(sc->sc_dev), sc, scbus));
-
- scbus->base.sc_child =
- config_found((struct device *)sc, &scbus->sc_link, scsiprint);
-
- return (0);
-}
-
-#if NATAPISCSI > 0
-int
-umass_atapi_attach(struct umass_softc *sc)
-{
- struct umass_scsi_softc *scbus;
-
- scbus = umass_scsi_setup(sc);
- scbus->sc_link.adapter_target = UMASS_SCSIID_HOST;
- scbus->sc_link.luns = 1;
-
- scbus->sc_adapter.scsi_cmd = umass_scsi_cmd;
- scbus->sc_adapter.scsi_minphys = umass_scsi_minphys;
- scbus->sc_adapter.ioctl = umass_scsi_ioctl;
-
- DPRINTF(UDMASS_USB, ("%s: umass_attach_bus: ATAPI\n"
- "sc = 0x%x, scbus = 0x%x\n",
- USBDEVNAME(sc->sc_dev), sc, scbus));
-
- scbus->base.sc_child =
- config_found((struct device *)sc, &scbus->sc_link, scsiprint);
-
- return (0);
-}
-#endif
-
-struct umass_scsi_softc *
-umass_scsi_setup(struct umass_softc *sc)
-{
- struct umass_scsi_softc *scbus;
-
- scbus = malloc(sizeof(struct umass_scsi_softc), M_DEVBUF, M_WAITOK);
- memset(&scbus->sc_link, 0, sizeof(struct scsi_link));
- memset(&scbus->sc_adapter, 0, sizeof(struct scsi_adapter));
-
- sc->bus = (struct umassbus_softc *)scbus;
-
- scbus->sc_link.adapter_buswidth = 2;
- scbus->sc_link.openings = 1;
- scbus->sc_link.flags &= ~SDEV_ATAPI;
- scbus->sc_link.device = &umass_scsi_dev;
- scbus->sc_link.adapter = &scbus->sc_adapter;
- scbus->sc_link.adapter_softc = sc;
- scbus->sc_link.openings = 1;
-
- return (scbus);
-}
-
-int
-umass_scsi_cmd(struct scsi_xfer *xs)
-{
- struct scsi_link *sc_link = xs->sc_link;
- struct umass_softc *sc = sc_link->adapter_softc;
- struct umass_scsi_softc *scbus = (struct umass_scsi_softc *)sc->bus;
-
- struct scsi_generic *cmd, trcmd;
- int cmdlen, dir;
-
-#ifdef UMASS_DEBUG
- microtime(&sc->tv);
-#endif
-
- memset(&trcmd, 0, sizeof(trcmd));
-
- DIF(UDMASS_UPPER, sc_link->flags |= SCSIDEBUG_LEVEL);
-
- DPRINTF(UDMASS_CMD, ("%s: umass_scsi_cmd: at %lu.%06lu: %d:%d "
- "xs=%p cmd=0x%02x datalen=%d (quirks=0x%x, poll=%d)\n",
- USBDEVNAME(sc->sc_dev), sc->tv.tv_sec, sc->tv.tv_usec,
- sc_link->target, sc_link->lun, xs, xs->cmd->opcode,
- xs->datalen, sc_link->quirks, xs->flags & SCSI_POLL));
-
-#if defined(USB_DEBUG) && defined(SCSIDEBUG)
- if (umassdebug & UDMASS_SCSI)
- show_scsi_xs(xs);
- else if (umassdebug & ~UDMASS_CMD)
- show_scsi_cmd(xs);
-#endif
-
- if (sc->sc_dying) {
- xs->error = XS_DRIVER_STUFFUP;
- goto done;
- }
-
-#if defined(UMASS_DEBUG)
- if (sc_link->target != UMASS_SCSIID_DEVICE) {
- DPRINTF(UDMASS_SCSI, ("%s: wrong SCSI ID %d\n",
- USBDEVNAME(sc->sc_dev), sc_link->target));
- xs->error = XS_DRIVER_STUFFUP;
- goto done;
- }
-#endif
-
- cmd = xs->cmd;
- cmdlen = xs->cmdlen;
-
- if (cmd->opcode == MODE_SENSE &&
- (sc_link->quirks & SDEV_NOMODESENSE)) {
- xs->error = XS_TIMEOUT;
- goto done;
- }
-
- if (cmd->opcode == START_STOP &&
- (sc->sc_quirks & UMASS_QUIRK_NO_START_STOP)) {
- xs->error = XS_NOERROR;
- goto done;
- }
-
- if (cmd->opcode == INQUIRY &&
- (sc->sc_quirks & UMASS_QUIRK_FORCE_SHORT_INQUIRY)) {
- memcpy(&trcmd, cmd, sizeof(trcmd));
- trcmd.bytes[4] = SHORT_INQUIRY_LENGTH;
- cmd = &trcmd;
- }
-
- dir = DIR_NONE;
- if (xs->datalen) {
- switch (xs->flags & (SCSI_DATA_IN | SCSI_DATA_OUT)) {
- case SCSI_DATA_IN:
- dir = DIR_IN;
- break;
- case SCSI_DATA_OUT:
- dir = DIR_OUT;
- break;
- }
- }
-
- if (xs->datalen > UMASS_MAX_TRANSFER_SIZE) {
- printf("umass_cmd: large datalen, %d\n", xs->datalen);
- xs->error = XS_DRIVER_STUFFUP;
- goto done;
- }
-
- if (xs->flags & SCSI_POLL) {
- /* Use sync transfer. XXX Broken! */
- DPRINTF(UDMASS_SCSI, ("umass_scsi_cmd: sync dir=%d\n", dir));
- sc->sc_xfer_flags = USBD_SYNCHRONOUS;
- scbus->sc_sync_status = USBD_INVAL;
- sc->sc_methods->wire_xfer(sc, sc_link->lun, cmd, cmdlen,
- xs->data, xs->datalen, dir,
- xs->timeout, 0, xs);
- sc->sc_xfer_flags = 0;
- DPRINTF(UDMASS_SCSI, ("umass_scsi_cmd: done err=%d\n",
- scbus->sc_sync_status));
- switch (scbus->sc_sync_status) {
- case USBD_NORMAL_COMPLETION:
- xs->error = XS_NOERROR;
- break;
- case USBD_TIMEOUT:
- xs->error = XS_TIMEOUT;
- break;
- default:
- xs->error = XS_DRIVER_STUFFUP;
- break;
- }
- goto done;
- } else {
- DPRINTF(UDMASS_SCSI,
- ("umass_scsi_cmd: async dir=%d, cmdlen=%d"
- " datalen=%d\n",
- dir, cmdlen, xs->datalen));
- sc->sc_methods->wire_xfer(sc, sc_link->lun, cmd, cmdlen,
- xs->data, xs->datalen, dir,
- xs->timeout, umass_scsi_cb, xs);
- return (SUCCESSFULLY_QUEUED);
- }
-
- /* Return if command finishes early. */
- done:
- xs->flags |= ITSDONE;
-
- scsi_done(xs);
- if (xs->flags & SCSI_POLL)
- return (COMPLETE);
- else
- return (SUCCESSFULLY_QUEUED);
-}
-
-void
-umass_scsi_minphys(struct buf *bp)
-{
- if (bp->b_bcount > UMASS_MAX_TRANSFER_SIZE)
- bp->b_bcount = UMASS_MAX_TRANSFER_SIZE;
-
- minphys(bp);
-}
-
-int
-umass_scsi_ioctl(struct scsi_link *link, u_long cmd, caddr_t arg, int flag,
- struct proc *p)
-{
-#if 0
- struct umass_softc *sc = link->adapter_softc;
-#endif
-
- switch (cmd) {
-#if 0
- case SCBUSIORESET:
- ccb->ccb_h.status = CAM_REQ_INPROG;
- umass_reset(sc, umass_cam_cb, (void *) ccb);
- return (0);
-#endif
- default:
- return (ENOTTY);
- }
-}
-
-void
-umass_scsi_cb(struct umass_softc *sc, void *priv, int residue, int status)
-{
- struct umass_scsi_softc *scbus = (struct umass_scsi_softc *)sc->bus;
- struct scsi_xfer *xs = priv;
- struct scsi_link *link = xs->sc_link;
- int cmdlen;
- int s;
-#ifdef UMASS_DEBUG
- struct timeval tv;
- u_int delta;
- microtime(&tv);
- delta = (tv.tv_sec - sc->tv.tv_sec) * 1000000 +
- tv.tv_usec - sc->tv.tv_usec;
-#endif
-
- DPRINTF(UDMASS_CMD,
- ("umass_scsi_cb: at %lu.%06lu, delta=%u: xs=%p residue=%d"
- " status=%d\n", tv.tv_sec, tv.tv_usec, delta, xs, residue,
- status));
-
- xs->resid = residue;
-
- switch (status) {
- case STATUS_CMD_OK:
- xs->error = XS_NOERROR;
- break;
-
- case STATUS_CMD_UNKNOWN:
- /* we can't issue REQUEST SENSE */
- if (xs->sc_link->quirks & PQUIRK_NOSENSE) {
- /*
- * If no residue and no other USB error,
- * command succeeded.
- */
- if (residue == 0) {
- xs->error = XS_NOERROR;
- break;
- }
-
- /*
- * Some devices return a short INQUIRY
- * response, omitting response data from the
- * "vendor specific data" on...
- */
- if (xs->cmd->opcode == INQUIRY &&
- residue < xs->datalen) {
- xs->error = XS_NOERROR;
- break;
- }
-
- xs->error = XS_DRIVER_STUFFUP;
- break;
- }
- /* FALLTHROUGH */
- case STATUS_CMD_FAILED:
- /* fetch sense data */
- memset(&scbus->sc_sense_cmd, 0, sizeof(scbus->sc_sense_cmd));
- scbus->sc_sense_cmd.opcode = REQUEST_SENSE;
- scbus->sc_sense_cmd.byte2 = link->lun << SCSI_CMD_LUN_SHIFT;
- scbus->sc_sense_cmd.length = sizeof(xs->sense);
-
- cmdlen = sizeof(scbus->sc_sense_cmd);
- if (sc->sc_cmd == UMASS_CPROTO_UFI) /* XXX */
- cmdlen = UFI_COMMAND_LENGTH;
- sc->sc_methods->wire_xfer(sc, link->lun,
- &scbus->sc_sense_cmd, cmdlen,
- &xs->sense, sizeof(xs->sense),
- DIR_IN, xs->timeout,
- umass_scsi_sense_cb, xs);
- return;
-
- case STATUS_WIRE_FAILED:
- xs->error = XS_RESET;
- break;
-
- default:
- panic("%s: Unknown status %d in umass_scsi_cb\n",
- USBDEVNAME(sc->sc_dev), status);
- }
-
- DPRINTF(UDMASS_CMD,("umass_scsi_cb: at %lu.%06lu: return error=%d, "
- "status=0x%x resid=%d\n",
- tv.tv_sec, tv.tv_usec,
- xs->error, xs->status, xs->resid));
-
- s = splbio();
- scsi_done(xs);
- splx(s);
-}
-
-/*
- * Finalise a completed autosense operation
- */
-void
-umass_scsi_sense_cb(struct umass_softc *sc, void *priv, int residue,
- int status)
-{
- struct scsi_xfer *xs = priv;
- int s;
-
- DPRINTF(UDMASS_CMD,("umass_scsi_sense_cb: xs=%p residue=%d "
- "status=%d\n", xs, residue, status));
-
- switch (status) {
- case STATUS_CMD_OK:
- case STATUS_CMD_UNKNOWN:
- /* getting sense data succeeded */
- if (xs->cmd->opcode == INQUIRY && (xs->resid < xs->datalen ||
- (sc->sc_quirks & UMASS_QUIRK_RS_NO_CLEAR_UA /* XXX */))) {
- /*
- * Some drivers return SENSE errors even after INQUIRY.
- * The upper layer doesn't like that.
- */
- xs->error = XS_NOERROR;
- break;
- }
- /* XXX look at residue */
- if (residue == 0 || residue == 14)/* XXX */
- xs->error = XS_SENSE;
- else
- xs->error = XS_SHORTSENSE;
- break;
- default:
- DPRINTF(UDMASS_SCSI, ("%s: Autosense failed, status %d\n",
- USBDEVNAME(sc->sc_dev), status));
- xs->error = XS_DRIVER_STUFFUP;
- break;
- }
-
- xs->status |= ITSDONE;
-
- DPRINTF(UDMASS_CMD,("umass_scsi_sense_cb: return xs->error=%d, "
- "xs->status=0x%x xs->resid=%d\n", xs->error, xs->status,
- xs->resid));
-
- s = splbio();
- scsi_done(xs);
- splx(s);
-}
diff --git a/sys/dev/usb/umass_scsi.h b/sys/dev/usb/umass_scsi.h
deleted file mode 100644
index 9237f5d364c..00000000000
--- a/sys/dev/usb/umass_scsi.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* $OpenBSD: umass_scsi.h,v 1.1 2002/05/07 18:08:04 nate Exp $ */
-/*
- * Copyright (c) 2001 Nathan L. Binkert
- * All rights reserved.
- *
- * Permission to redistribute, use, copy, and modify this software
- * without fee is hereby granted, provided that the following
- * conditions are met:
- *
- * 1. This entire notice is included in all source code copies of any
- * software which is or includes a copy or modification of this
- * software.
- * 2. 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.
- */
-
-int umass_scsi_attach(struct umass_softc *sc);
-int umass_atapi_attach(struct umass_softc *sc);
diff --git a/sys/dev/usb/umass_scsipi.c b/sys/dev/usb/umass_scsipi.c
deleted file mode 100644
index a37fb3cb425..00000000000
--- a/sys/dev/usb/umass_scsipi.c
+++ /dev/null
@@ -1,636 +0,0 @@
-/* $NetBSD: umass_scsipi.c,v 1.4 2001/12/31 12:15:21 augustss Exp $ */
-
-/*
- * 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) 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>
-__KERNEL_RCSID(0, "$NetBSD: umass_scsipi.c,v 1.4 2001/12/31 12:15:21 augustss Exp $");
-
-#include "atapibus.h"
-#include "scsibus.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/conf.h>
-#include <sys/buf.h>
-#include <sys/device.h>
-#include <sys/ioctl.h>
-#include <sys/malloc.h>
-
-/* SCSI & ATAPI */
-#include <sys/scsiio.h>
-#include <dev/scsipi/scsi_all.h>
-#include <dev/scsipi/scsipi_all.h>
-#include <dev/scsipi/scsiconf.h>
-
-#include <dev/scsipi/atapiconf.h>
-
-#include <dev/scsipi/scsipi_disk.h>
-#include <dev/scsipi/scsi_disk.h>
-#include <dev/scsipi/scsi_changer.h>
-
-#include <dev/scsipi/atapi_disk.h>
-
-#include <sys/disk.h> /* XXX */
-#include <dev/scsipi/sdvar.h> /* XXX */
-
-/* USB */
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include <dev/usb/usbdevs.h>
-
-#include <dev/usb/umassvar.h>
-#include <dev/usb/umass_scsipi.h>
-
-struct umass_scsipi_softc {
- struct umassbus_softc base;
-
- struct atapi_adapter sc_atapi_adapter;
-#define sc_adapter sc_atapi_adapter._generic
- struct scsipi_channel sc_channel;
- usbd_status sc_sync_status;
- struct scsipi_sense sc_sense_cmd;
-};
-
-
-#define SHORT_INQUIRY_LENGTH 36 /* XXX */
-
-#define UMASS_SCSIID_HOST 0x00
-#define UMASS_SCSIID_DEVICE 0x01
-
-#define UMASS_ATAPI_DRIVE 0
-
-Static void umass_scsipi_request(struct scsipi_channel *,
- scsipi_adapter_req_t, void *);
-Static void umass_scsipi_minphys(struct buf *bp);
-Static int umass_scsipi_ioctl(struct scsipi_channel *, u_long,
- caddr_t, int, usb_proc_ptr);
-Static int umass_scsipi_getgeom(struct scsipi_periph *periph,
- struct disk_parms *, u_long sectors);
-
-Static void umass_scsipi_cb(struct umass_softc *sc, void *priv,
- int residue, int status);
-Static void umass_scsipi_sense_cb(struct umass_softc *sc, void *priv,
- int residue, int status);
-
-Static struct umass_scsipi_softc *umass_scsipi_setup(struct umass_softc *sc);
-
-Static int scsipiprint(void *aux, const char *pnp);
-
-#if NATAPIBUS > 0
-Static void umass_atapi_probe_device(struct atapibus_softc *, int);
-
-const struct scsipi_bustype umass_atapi_bustype = {
- SCSIPI_BUSTYPE_ATAPI,
- atapi_scsipi_cmd,
- atapi_interpret_sense,
- atapi_print_addr,
- scsi_kill_pending,
-};
-#endif
-
-
-#if NSCSIBUS > 0
-int
-umass_scsi_attach(struct umass_softc *sc)
-{
- struct umass_scsipi_softc *scbus;
-
- scbus = umass_scsipi_setup(sc);
-
- scbus->sc_channel.chan_bustype = &scsi_bustype;
- scbus->sc_channel.chan_ntargets = UMASS_SCSIID_DEVICE + 1;
- scbus->sc_channel.chan_nluns = sc->maxlun + 1;
- scbus->sc_channel.chan_id = UMASS_SCSIID_HOST;
- DPRINTF(UDMASS_USB, ("%s: umass_attach_bus: SCSI\n",
- USBDEVNAME(sc->sc_dev)));
- scbus->base.sc_child =
- config_found(&sc->sc_dev, &scbus->sc_channel, scsipiprint);
-
- return (0);
-}
-#endif
-
-#if NATAPIBUS > 0
-int
-umass_atapi_attach(struct umass_softc *sc)
-{
- struct umass_scsipi_softc *scbus;
-
- scbus = umass_scsipi_setup(sc);
- scbus->sc_atapi_adapter.atapi_probe_device = umass_atapi_probe_device;
-
- scbus->sc_channel.chan_bustype = &umass_atapi_bustype;
- scbus->sc_channel.chan_ntargets = 2;
- scbus->sc_channel.chan_nluns = 1;
-
- scbus->sc_channel.chan_defquirks |= sc->sc_busquirks;
- DPRINTF(UDMASS_USB, ("%s: umass_attach_bus: ATAPI\n",
- USBDEVNAME(sc->sc_dev)));
- scbus->base.sc_child =
- config_found(&sc->sc_dev, &scbus->sc_channel, scsipiprint);
-
- return (0);
-}
-#endif
-
-Static struct umass_scsipi_softc *
-umass_scsipi_setup(struct umass_softc *sc)
-{
- struct umass_scsipi_softc *scbus;
-
- scbus = malloc(sizeof *scbus, M_DEVBUF, M_WAITOK | M_ZERO);
- sc->bus = &scbus->base;
-
- /* Only use big commands for USB SCSI devices. */
- sc->sc_busquirks |= PQUIRK_ONLYBIG;
-
- /* Fill in the adapter. */
- memset(&scbus->sc_adapter, 0, sizeof(scbus->sc_adapter));
- scbus->sc_adapter.adapt_dev = &sc->sc_dev;
- scbus->sc_adapter.adapt_nchannels = 1;
- scbus->sc_adapter.adapt_request = umass_scsipi_request;
- scbus->sc_adapter.adapt_minphys = umass_scsipi_minphys;
- scbus->sc_adapter.adapt_ioctl = umass_scsipi_ioctl;
- scbus->sc_adapter.adapt_getgeom = umass_scsipi_getgeom;
-
- /* Fill in the channel. */
- memset(&scbus->sc_channel, 0, sizeof(scbus->sc_channel));
- scbus->sc_channel.chan_adapter = &scbus->sc_adapter;
- scbus->sc_channel.chan_channel = 0;
- scbus->sc_channel.chan_flags = SCSIPI_CHAN_OPENINGS;
- scbus->sc_channel.chan_openings = 1;
- scbus->sc_channel.chan_max_periph = 1;
- scbus->sc_channel.chan_defquirks |= sc->sc_busquirks;
-
- return (scbus);
-}
-
-Static int
-scsipiprint(void *aux, const char *pnp)
-{
- struct scsipi_channel *chan = aux;
-
- if (chan->chan_bustype->bustype_type == SCSIPI_BUSTYPE_SCSI) {
-#if NSCSIBUS > 0
- return (scsiprint(aux, pnp));
-#else
- if (pnp)
- printf("scsibus at %s", pnp);
- return (UNCONF);
-#endif
- } else {
-#if NATAPIBUS > 0
- return (atapiprint(aux, pnp));
-#else
- if (pnp)
- printf("atapibus at %s", pnp);
- return (UNCONF);
-#endif
- }
-}
-
-Static void
-umass_scsipi_request(struct scsipi_channel *chan,
- scsipi_adapter_req_t req, void *arg)
-{
- struct scsipi_adapter *adapt = chan->chan_adapter;
- struct scsipi_periph *periph;
- struct scsipi_xfer *xs;
- struct umass_softc *sc = (void *)adapt->adapt_dev;
- struct umass_scsipi_softc *scbus = (struct umass_scsipi_softc *)sc->bus;
- struct scsipi_generic *cmd, trcmd;
- int cmdlen;
- int dir;
-#ifdef UMASS_DEBUG
- microtime(&sc->tv);
-#endif
- switch(req) {
- case ADAPTER_REQ_RUN_XFER:
- xs = arg;
- periph = xs->xs_periph;
- DIF(UDMASS_UPPER, periph->periph_dbflags |= SCSIPI_DEBUG_FLAGS);
-
- DPRINTF(UDMASS_CMD, ("%s: umass_scsi_cmd: at %lu.%06lu: %d:%d "
- "xs=%p cmd=0x%02x datalen=%d (quirks=0x%x, poll=%d)\n",
- USBDEVNAME(sc->sc_dev), sc->tv.tv_sec, sc->tv.tv_usec,
- periph->periph_target, periph->periph_lun,
- xs, xs->cmd->opcode, xs->datalen,
- periph->periph_quirks, xs->xs_control & XS_CTL_POLL));
-#if defined(USB_DEBUG) && defined(SCSIPI_DEBUG)
- if (umassdebug & UDMASS_SCSI)
- show_scsipi_xs(xs);
- else if (umassdebug & ~UDMASS_CMD)
- show_scsipi_cmd(xs);
-#endif
-
- if (sc->sc_dying) {
- xs->error = XS_DRIVER_STUFFUP;
- goto done;
- }
-
-#ifdef UMASS_DEBUG
- if (chan->chan_bustype->bustype_type == SCSIPI_BUSTYPE_ATAPI ?
- periph->periph_target != UMASS_ATAPI_DRIVE :
- periph->periph_target != UMASS_SCSIID_DEVICE) {
- DPRINTF(UDMASS_SCSI, ("%s: wrong SCSI ID %d\n",
- USBDEVNAME(sc->sc_dev),
- periph->periph_target));
- xs->error = XS_DRIVER_STUFFUP;
- goto done;
- }
-#endif
-
- cmd = xs->cmd;
- cmdlen = xs->cmdlen;
-
- /* XXX should use transform */
-
- if (cmd->opcode == START_STOP &&
- (sc->sc_quirks & UMASS_QUIRK_NO_START_STOP)) {
- /*printf("%s: START_STOP\n", USBDEVNAME(sc->sc_dev));*/
- xs->error = XS_NOERROR;
- goto done;
- }
-
- if (cmd->opcode == INQUIRY &&
- (sc->sc_quirks & UMASS_QUIRK_FORCE_SHORT_INQUIRY)) {
- /*
- * some drives wedge when asked for full inquiry
- * information.
- */
- memcpy(&trcmd, cmd, sizeof trcmd);
- trcmd.bytes[4] = SHORT_INQUIRY_LENGTH;
- cmd = &trcmd;
- }
-
- dir = DIR_NONE;
- if (xs->datalen) {
- switch (xs->xs_control &
- (XS_CTL_DATA_IN | XS_CTL_DATA_OUT)) {
- case XS_CTL_DATA_IN:
- dir = DIR_IN;
- break;
- case XS_CTL_DATA_OUT:
- dir = DIR_OUT;
- break;
- }
- }
-
- if (xs->datalen > UMASS_MAX_TRANSFER_SIZE) {
- printf("umass_cmd: large datalen, %d\n", xs->datalen);
- xs->error = XS_DRIVER_STUFFUP;
- goto done;
- }
-
- if (xs->xs_control & XS_CTL_POLL) {
- /* Use sync transfer. XXX Broken! */
- DPRINTF(UDMASS_SCSI,
- ("umass_scsi_cmd: sync dir=%d\n", dir));
- sc->sc_xfer_flags = USBD_SYNCHRONOUS;
- scbus->sc_sync_status = USBD_INVAL;
- sc->sc_methods->wire_xfer(sc, periph->periph_lun, cmd,
- cmdlen, xs->data,
- xs->datalen, dir,
- xs->timeout, 0, xs);
- sc->sc_xfer_flags = 0;
- DPRINTF(UDMASS_SCSI, ("umass_scsi_cmd: done err=%d\n",
- scbus->sc_sync_status));
- switch (scbus->sc_sync_status) {
- case USBD_NORMAL_COMPLETION:
- xs->error = XS_NOERROR;
- break;
- case USBD_TIMEOUT:
- xs->error = XS_TIMEOUT;
- break;
- default:
- xs->error = XS_DRIVER_STUFFUP;
- break;
- }
- goto done;
- } else {
- DPRINTF(UDMASS_SCSI,
- ("umass_scsi_cmd: async dir=%d, cmdlen=%d"
- " datalen=%d\n",
- dir, cmdlen, xs->datalen));
- sc->sc_methods->wire_xfer(sc, periph->periph_lun, cmd,
- cmdlen, xs->data,
- xs->datalen, dir,
- xs->timeout,
- umass_scsipi_cb, xs);
- return;
- }
-
- /* Return if command finishes early. */
- done:
- scsipi_done(xs);
- return;
- default:
- /* Not supported, nothing to do. */
- ;
- }
-}
-
-Static void
-umass_scsipi_minphys(struct buf *bp)
-{
-#ifdef DIAGNOSTIC
- if (bp->b_bcount <= 0) {
- printf("umass_scsipi_minphys count(%ld) <= 0\n",
- bp->b_bcount);
- bp->b_bcount = UMASS_MAX_TRANSFER_SIZE;
- }
-#endif
- if (bp->b_bcount > UMASS_MAX_TRANSFER_SIZE)
- bp->b_bcount = UMASS_MAX_TRANSFER_SIZE;
- minphys(bp);
-}
-
-int
-umass_scsipi_ioctl(struct scsipi_channel *chan, u_long cmd, caddr_t arg,
- int flag, usb_proc_ptr p)
-{
- /*struct umass_softc *sc = link->adapter_softc;*/
- /*struct umass_scsipi_softc *scbus = sc->bus;*/
-
- switch (cmd) {
-#if 0
- case SCBUSIORESET:
- ccb->ccb_h.status = CAM_REQ_INPROG;
- umass_reset(sc, umass_cam_cb, (void *) ccb);
- return (0);
-#endif
- default:
- return (ENOTTY);
- }
-}
-
-Static int
-umass_scsipi_getgeom(struct scsipi_periph *periph, struct disk_parms *dp,
- u_long sectors)
-{
- struct umass_softc *sc =
- (void *)periph->periph_channel->chan_adapter->adapt_dev;
-
- /* If it's not a floppy, we don't know what to do. */
- if (sc->sc_cmd != UMASS_CPROTO_UFI)
- return (0);
-
- switch (sectors) {
- case 1440:
- /* Most likely a single density 3.5" floppy. */
- dp->heads = 2;
- dp->sectors = 9;
- dp->cyls = 80;
- return (1);
- case 2880:
- /* Most likely a double density 3.5" floppy. */
- dp->heads = 2;
- dp->sectors = 18;
- dp->cyls = 80;
- return (1);
- default:
- return (0);
- }
-}
-
-Static void
-umass_scsipi_cb(struct umass_softc *sc, void *priv, int residue, int status)
-{
- struct umass_scsipi_softc *scbus = (struct umass_scsipi_softc *)sc->bus;
- struct scsipi_xfer *xs = priv;
- struct scsipi_periph *periph = xs->xs_periph;
- int cmdlen;
- int s;
-#ifdef UMASS_DEBUG
- struct timeval tv;
- u_int delta;
- microtime(&tv);
- delta = (tv.tv_sec - sc->tv.tv_sec) * 1000000 + tv.tv_usec - sc->tv.tv_usec;
-#endif
-
- DPRINTF(UDMASS_CMD,("umass_scsipi_cb: at %lu.%06lu, delta=%u: xs=%p residue=%d"
- " status=%d\n", tv.tv_sec, tv.tv_usec, delta, xs, residue, status));
-
- xs->resid = residue;
-
- switch (status) {
- case STATUS_CMD_OK:
- xs->error = XS_NOERROR;
- break;
-
- case STATUS_CMD_UNKNOWN:
- /* we can't issue REQUEST SENSE */
- if (xs->xs_periph->periph_quirks & PQUIRK_NOSENSE) {
- /*
- * If no residue and no other USB error,
- * command succeeded.
- */
- if (residue == 0) {
- xs->error = XS_NOERROR;
- break;
- }
-
- /*
- * Some devices return a short INQUIRY
- * response, omitting response data from the
- * "vendor specific data" on...
- */
- if (xs->cmd->opcode == INQUIRY &&
- residue < xs->datalen) {
- xs->error = XS_NOERROR;
- break;
- }
-
- xs->error = XS_DRIVER_STUFFUP;
- break;
- }
- /* FALLTHROUGH */
- case STATUS_CMD_FAILED:
- /* fetch sense data */
- memset(&scbus->sc_sense_cmd, 0, sizeof(scbus->sc_sense_cmd));
- scbus->sc_sense_cmd.opcode = REQUEST_SENSE;
- scbus->sc_sense_cmd.byte2 = periph->periph_lun <<
- SCSI_CMD_LUN_SHIFT;
- scbus->sc_sense_cmd.length = sizeof(xs->sense);
-
- cmdlen = sizeof(scbus->sc_sense_cmd);
- if (sc->sc_cmd == UMASS_CPROTO_UFI) /* XXX */
- cmdlen = UFI_COMMAND_LENGTH;
- sc->sc_methods->wire_xfer(sc, periph->periph_lun,
- &scbus->sc_sense_cmd, cmdlen,
- &xs->sense, sizeof(xs->sense),
- DIR_IN, xs->timeout,
- umass_scsipi_sense_cb, xs);
- return;
-
- case STATUS_WIRE_FAILED:
- xs->error = XS_RESET;
- break;
-
- default:
- panic("%s: Unknown status %d in umass_scsipi_cb\n",
- USBDEVNAME(sc->sc_dev), status);
- }
-
- DPRINTF(UDMASS_CMD,("umass_scsipi_cb: at %lu.%06lu: return xs->error="
- "%d, xs->xs_status=0x%x xs->resid=%d\n",
- tv.tv_sec, tv.tv_usec,
- xs->error, xs->xs_status, xs->resid));
-
- s = splbio();
- scsipi_done(xs);
- splx(s);
-}
-
-/*
- * Finalise a completed autosense operation
- */
-Static void
-umass_scsipi_sense_cb(struct umass_softc *sc, void *priv, int residue,
- int status)
-{
- struct scsipi_xfer *xs = priv;
- int s;
-
- DPRINTF(UDMASS_CMD,("umass_scsipi_sense_cb: xs=%p residue=%d "
- "status=%d\n", xs, residue, status));
-
- switch (status) {
- case STATUS_CMD_OK:
- case STATUS_CMD_UNKNOWN:
- /* getting sense data succeeded */
- if (xs->cmd->opcode == INQUIRY && (xs->resid < xs->datalen ||
- (sc->sc_quirks & UMASS_QUIRK_RS_NO_CLEAR_UA /* XXX */))) {
- /*
- * Some drivers return SENSE errors even after INQUIRY.
- * The upper layer doesn't like that.
- */
- xs->error = XS_NOERROR;
- break;
- }
- /* XXX look at residue */
- if (residue == 0 || residue == 14)/* XXX */
- xs->error = XS_SENSE;
- else
- xs->error = XS_SHORTSENSE;
- break;
- default:
- DPRINTF(UDMASS_SCSI, ("%s: Autosense failed, status %d\n",
- USBDEVNAME(sc->sc_dev), status));
- xs->error = XS_DRIVER_STUFFUP;
- break;
- }
-
- xs->xs_status |= XS_STS_DONE;
-
- DPRINTF(UDMASS_CMD,("umass_scsipi_sense_cb: return xs->error=%d, "
- "xs->xs_status=0x%x xs->resid=%d\n", xs->error, xs->xs_status,
- xs->resid));
-
- s = splbio();
- scsipi_done(xs);
- splx(s);
-}
-
-#if NATAPIBUS > 0
-Static void
-umass_atapi_probe_device(struct atapibus_softc *atapi, int target)
-{
- struct scsipi_channel *chan = atapi->sc_channel;
- struct scsipi_periph *periph;
- struct scsipibus_attach_args sa;
- char vendor[33], product[65], revision[17];
- struct scsipi_inquiry_data inqbuf;
-
- DPRINTF(UDMASS_SCSI,("umass_atapi_probe_device: atapi=%p target=%d\n",
- atapi, target));
-
- if (target != UMASS_ATAPI_DRIVE) /* only probe drive 0 */
- return;
-
- /* skip if already attached */
- if (scsipi_lookup_periph(chan, target, 0) != NULL)
- return;
-
- periph = scsipi_alloc_periph(M_NOWAIT);
- if (periph == NULL) {
- printf("%s: can't allocate link for drive %d\n",
- atapi->sc_dev.dv_xname, target);
- return;
- }
-
- DIF(UDMASS_UPPER, periph->periph_dbflags |= 1); /* XXX 1 */
- periph->periph_channel = chan;
- periph->periph_switch = &atapi_probe_periphsw;
- periph->periph_target = target;
- periph->periph_quirks = chan->chan_defquirks;
-
- DPRINTF(UDMASS_SCSI, ("umass_atapi_probe_device: doing inquiry\n"));
- /* Now go ask the device all about itself. */
- memset(&inqbuf, 0, sizeof(inqbuf));
- if (scsipi_inquire(periph, &inqbuf,
- XS_CTL_DISCOVERY | XS_CTL_DATA_ONSTACK) != 0) {
- DPRINTF(UDMASS_SCSI, ("umass_atapi_probe_device: "
- "scsipi_inquire failed\n"));
- free(periph, M_DEVBUF);
- return;
- }
-
- scsipi_strvis(vendor, 33, inqbuf.vendor, 8);
- scsipi_strvis(product, 65, inqbuf.product, 16);
- scsipi_strvis(revision, 17, inqbuf.revision, 4);
-
- sa.sa_periph = periph;
- sa.sa_inqbuf.type = inqbuf.device;
- sa.sa_inqbuf.removable = inqbuf.dev_qual2 & SID_REMOVABLE ?
- T_REMOV : T_FIXED;
- if (sa.sa_inqbuf.removable)
- periph->periph_flags |= PERIPH_REMOVABLE;
- sa.sa_inqbuf.vendor = vendor;
- sa.sa_inqbuf.product = product;
- sa.sa_inqbuf.revision = revision;
- sa.sa_inqptr = NULL;
-
- DPRINTF(UDMASS_SCSI, ("umass_atapi_probedev: doing atapi_probedev on "
- "'%s' '%s' '%s'\n", vendor, product, revision));
- atapi_probe_device(atapi, target, periph, &sa);
- /* atapi_probe_device() frees the periph when there is no device.*/
-}
-#endif
diff --git a/sys/dev/usb/umass_scsipi.h b/sys/dev/usb/umass_scsipi.h
deleted file mode 100644
index 182b50f294b..00000000000
--- a/sys/dev/usb/umass_scsipi.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* $NetBSD: umass_scsipi.h,v 1.1 2001/12/24 13:25:53 augustss Exp $ */
-
-/*
- * 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) 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.
- */
-
-int umass_scsi_attach(struct umass_softc *sc);
-int umass_atapi_attach(struct umass_softc *sc);
diff --git a/sys/dev/usb/umassvar.h b/sys/dev/usb/umassvar.h
deleted file mode 100644
index 29e6b4a80cb..00000000000
--- a/sys/dev/usb/umassvar.h
+++ /dev/null
@@ -1,271 +0,0 @@
-/* $NetBSD: umassvar.h,v 1.15 2002/02/07 13:52:55 augustss Exp $ */
-/*-
- * 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: src/sys/dev/usb/umass.c,v 1.13 2000/03/26 01:39:12 n_hibma Exp $
- */
-
-#ifdef UMASS_DEBUG
-#define DIF(m, x) if (umassdebug & (m)) do { x ; } while (0)
-#define DPRINTF(m, x) if (umassdebug & (m)) logprintf x
-#define UDMASS_UPPER 0x00008000 /* upper layer */
-#define UDMASS_GEN 0x00010000 /* general */
-#define UDMASS_SCSI 0x00020000 /* scsi */
-#define UDMASS_UFI 0x00040000 /* ufi command set */
-#define UDMASS_8070 0x00080000 /* 8070i command set */
-#define UDMASS_USB 0x00100000 /* USB general */
-#define UDMASS_BBB 0x00200000 /* Bulk-Only transfers */
-#define UDMASS_CBI 0x00400000 /* CBI transfers */
-#define UDMASS_ALL 0xffff0000 /* all of the above */
-
-#define UDMASS_XFER 0x40000000 /* all transfers */
-#define UDMASS_CMD 0x80000000
-
-extern int umassdebug;
-#else
-#define DIF(m, x) /* nop */
-#define DPRINTF(m, x) /* nop */
-#endif
-
-/* Generic definitions */
-
-#define UFI_COMMAND_LENGTH 12
-
-/* Direction for umass_*_transfer */
-#define DIR_NONE 0
-#define DIR_IN 1
-#define DIR_OUT 2
-
-#define MS_TO_TICKS(ms) ((ms) * hz / 1000)
-
-/* Endpoints for umass */
-#define UMASS_BULKIN 0
-#define UMASS_BULKOUT 1
-#define UMASS_INTRIN 2
-#define UMASS_NEP 3
-
-/* Bulk-Only features */
-
-#define UR_BBB_RESET 0xff /* Bulk-Only reset */
-#define UR_BBB_GET_MAX_LUN 0xfe
-
-/* 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];
-} umass_bbb_cbw_t;
-#define UMASS_BBB_CBW_SIZE 31
-
-/* Command Status Wrapper */
-typedef struct {
- uDWord dCSWSignature;
-#define CSWSIGNATURE 0x53425355
-#define CSWSIGNATURE_OLYMPUS_C1 0x55425355
- uDWord dCSWTag;
- uDWord dCSWDataResidue;
- uByte bCSWStatus;
-#define CSWSTATUS_GOOD 0x0
-#define CSWSTATUS_FAILED 0x1
-#define CSWSTATUS_PHASE 0x2
-} 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 {
- uByte type;
-#define IDB_TYPE_CCI 0x00
- uByte 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 {
- uByte asc;
- uByte ascq;
- } ufi;
-} umass_cbi_sbl_t;
-
-struct umass_softc; /* see below */
-
-typedef void (*umass_callback)(struct umass_softc *, void *, int, int);
-#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 (*umass_wire_xfer)(struct umass_softc *, int, void *, int, void *,
- int, int, u_int, umass_callback, void *);
-typedef void (*umass_wire_reset)(struct umass_softc *, int);
-typedef void (*umass_wire_state)(usbd_xfer_handle, usbd_private_handle,
- usbd_status);
-
-struct umass_wire_methods {
- umass_wire_xfer wire_xfer;
- umass_wire_reset wire_reset;
- umass_wire_state wire_state;
-};
-
-struct umassbus_softc {
- device_ptr_t sc_child; /* child device, for detach */
-};
-
-/* the per device structure */
-struct umass_softc {
- USBBASEDEVICE sc_dev; /* base device */
- usbd_device_handle sc_udev; /* device */
- usbd_interface_handle sc_iface; /* interface */
- int sc_ifaceno; /* interface number */
-
- u_int8_t sc_epaddr[UMASS_NEP];
- usbd_pipe_handle sc_pipe[UMASS_NEP];
- usb_device_request_t sc_req;
-
- const struct umass_wire_methods *sc_methods;
-
- u_int8_t sc_wire; /* wire protocol */
-#define UMASS_WPROTO_UNSPEC 0
-#define UMASS_WPROTO_BBB 1
-#define UMASS_WPROTO_CBI 2
-#define UMASS_WPROTO_CBI_I 3
-
- u_int8_t sc_cmd; /* command protocol */
-#define UMASS_CPROTO_UNSPEC 0
-#define UMASS_CPROTO_SCSI 1
-#define UMASS_CPROTO_ATAPI 2
-#define UMASS_CPROTO_UFI 3
-#define UMASS_CPROTO_RBC 4
-#define UMASS_CPROTO_ISD_ATA 5
-
- u_int32_t sc_quirks;
-#define UMASS_QUIRK_RS_NO_CLEAR_UA 0x00000002
-#define UMASS_QUIRK_NO_START_STOP 0x00000004
-#define UMASS_QUIRK_FORCE_SHORT_INQUIRY 0x00000008
-#define UMASS_QUIRK_WRONG_CSWSIG 0x00000010
-#define UMASS_QUIRK_NO_MAX_LUN 0x00000020
-
- u_int32_t sc_busquirks;
-
- /* 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 */
-
- /* 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 */
-
- void *data_buffer;
-
- int transfer_dir; /* data direction */
- void *transfer_data; /* data buffer */
- int transfer_datalen; /* (maximum) length */
- int transfer_actlen; /* actual length */
- umass_callback transfer_cb; /* callback */
- void *transfer_priv; /* for callback */
- int transfer_status;
-
- int transfer_state;
-#define TSTATE_IDLE 0
-#define TSTATE_BBB_COMMAND 1 /* CBW transfer */
-#define TSTATE_BBB_DATA 2 /* Data transfer */
-#define TSTATE_BBB_DCLEAR 3 /* clear endpt stall */
-#define TSTATE_BBB_STATUS1 4 /* clear endpt stall */
-#define TSTATE_BBB_SCLEAR 5 /* clear endpt stall */
-#define TSTATE_BBB_STATUS2 6 /* CSW transfer */
-#define TSTATE_BBB_RESET1 7 /* reset command */
-#define TSTATE_BBB_RESET2 8 /* in clear stall */
-#define TSTATE_BBB_RESET3 9 /* out clear stall */
-#define TSTATE_CBI_COMMAND 10 /* command transfer */
-#define TSTATE_CBI_DATA 11 /* data transfer */
-#define TSTATE_CBI_STATUS 12 /* status transfer */
-#define TSTATE_CBI_DCLEAR 13 /* clear ep stall */
-#define TSTATE_CBI_SCLEAR 14 /* clear ep stall */
-#define TSTATE_CBI_RESET1 15 /* reset command */
-#define TSTATE_CBI_RESET2 16 /* in clear stall */
-#define TSTATE_CBI_RESET3 17 /* out clear stall */
-#define TSTATE_STATES 18 /* # of states above */
-
-
- int timeout; /* in msecs */
-
- u_int8_t maxlun; /* max lun supported */
-
-#ifdef UMASS_DEBUG
- struct timeval tv;
-#endif
-
- int sc_xfer_flags;
- char sc_dying;
-
- struct umassbus_softc *bus; /* bus dependent data */
-};
-
-#define UMASS_MAX_TRANSFER_SIZE MAXBSIZE
diff --git a/sys/dev/usb/umct.c b/sys/dev/usb/umct.c
deleted file mode 100644
index 954ce542c67..00000000000
--- a/sys/dev/usb/umct.c
+++ /dev/null
@@ -1,631 +0,0 @@
-/* $OpenBSD: umct.c,v 1.1 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: umct.c,v 1.7 2001/12/17 14:19:39 ichiro Exp $ */
-/*
- * 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.
- */
-
-/*
- * MCT USB-RS232 Interface Controller
- * http://www.mct.com.tw/p_u232.html
- * http://www.dlink.com/products/usb/dsbs25
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/ioctl.h>
-#include <sys/conf.h>
-#include <sys/tty.h>
-#include <sys/file.h>
-#include <sys/select.h>
-#include <sys/proc.h>
-#include <sys/vnode.h>
-#include <sys/device.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/usbdevs.h>
-#include <dev/usb/usb_quirks.h>
-
-#include <dev/usb/usbdevs.h>
-#include <dev/usb/ucomvar.h>
-
-#include <dev/usb/umct.h>
-
-#ifdef UMCT_DEBUG
-#define DPRINTFN(n, x) if (umctdebug > (n)) logprintf x
-int umctdebug = 0;
-#else
-#define DPRINTFN(n, x)
-#endif
-#define DPRINTF(x) DPRINTFN(0, x)
-
-#define UMCT_CONFIG_INDEX 0
-#define UMCT_IFACE_INDEX 0
-
-struct umct_softc {
- USBBASEDEVICE sc_dev; /* base device */
- usbd_device_handle sc_udev; /* USB device */
- usbd_interface_handle sc_iface; /* interface */
- int sc_iface_number; /* interface number */
- u_int16_t sc_product;
-
- 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_break; /* set break */
-
- u_char sc_status;
-
- device_ptr_t sc_subdev; /* ucom device */
-
- u_char sc_dying; /* disconnecting */
-
- u_char sc_lsr; /* Local status register */
- u_char sc_msr; /* umct status register */
-
- u_int last_lcr; /* keep lcr register */
-};
-
-/*
- * These are the maximum number of bytes transferred per frame.
- * The output buffer size cannot be increased due to the size encoding.
- */
-#define UMCTIBUFSIZE 256
-#define UMCTOBUFSIZE 256
-
-Static void umct_init(struct umct_softc *);
-Static void umct_set_baudrate(struct umct_softc *, u_int);
-Static void umct_set_lcr(struct umct_softc *, u_int);
-Static void umct_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
-
-Static void umct_set(void *, int, int, int);
-Static void umct_dtr(struct umct_softc *, int);
-Static void umct_rts(struct umct_softc *, int);
-Static void umct_break(struct umct_softc *, int);
-Static void umct_set_line_state(struct umct_softc *);
-Static void umct_get_status(void *, int portno, u_char *lsr, u_char *msr);
-Static int umct_param(void *, int, struct termios *);
-Static int umct_open(void *, int);
-Static void umct_close(void *, int);
-
-struct ucom_methods umct_methods = {
- umct_get_status,
- umct_set,
- umct_param,
- NULL,
- umct_open,
- umct_close,
- NULL,
- NULL,
-};
-
-static const struct usb_devno umct_devs[] = {
- /* MCT USB-232 Interface Products */
- { USB_VENDOR_MCT, USB_PRODUCT_MCT_USB232 },
- /* Sitecom USB-232 Products */
- { USB_VENDOR_MCT, USB_PRODUCT_MCT_SITECOM_USB232 },
- /* D-Link DU-H3SP USB BAY Hub Products */
- { USB_VENDOR_MCT, USB_PRODUCT_MCT_DU_H3SP_USB232 },
-};
-#define umct_lookup(v, p) usb_lookup(umct_devs, v, p)
-
-USB_DECLARE_DRIVER(umct);
-
-USB_MATCH(umct)
-{
- USB_MATCH_START(umct, uaa);
-
- if (uaa->iface != NULL)
- return (UMATCH_NONE);
-
- return (umct_lookup(uaa->vendor, uaa->product) != NULL ?
- UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
-}
-
-USB_ATTACH(umct)
-{
- USB_ATTACH_START(umct, sc, uaa);
- usbd_device_handle dev = uaa->device;
- usb_config_descriptor_t *cdesc;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
-
- char devinfo[1024];
- char *devname = USBDEVNAME(sc->sc_dev);
- usbd_status err;
- int i, found;
- struct ucom_attach_args uca;
-
- usbd_devinfo(dev, 0, devinfo);
- USB_ATTACH_SETUP;
- printf("%s: %s\n", devname, devinfo);
-
- sc->sc_udev = dev;
- sc->sc_product = uaa->product;
-
- DPRINTF(("\n\numct attach: sc=%p\n", sc));
-
- /* initialize endpoints */
- uca.bulkin = uca.bulkout = -1;
- sc->sc_intr_number = -1;
- sc->sc_intr_pipe = NULL;
-
- /* Move the device into the configured state. */
- err = usbd_set_config_index(dev, UMCT_CONFIG_INDEX, 1);
- if (err) {
- printf("\n%s: failed to set configuration, err=%s\n",
- devname, usbd_errstr(err));
- sc->sc_dying = 1;
- USB_ATTACH_ERROR_RETURN;
- }
-
- /* get the config descriptor */
- cdesc = usbd_get_config_descriptor(sc->sc_udev);
-
- if (cdesc == NULL) {
- printf("%s: failed to get configuration descriptor\n",
- USBDEVNAME(sc->sc_dev));
- sc->sc_dying = 1;
- USB_ATTACH_ERROR_RETURN;
- }
-
- /* get the interface */
- err = usbd_device2interface_handle(dev, UMCT_IFACE_INDEX,
- &sc->sc_iface);
- if (err) {
- printf("\n%s: failed to get interface, err=%s\n",
- devname, usbd_errstr(err));
- sc->sc_dying = 1;
- USB_ATTACH_ERROR_RETURN;
- }
-
- /* Find the bulk{in,out} and interrupt endpoints */
-
- id = usbd_get_interface_descriptor(sc->sc_iface);
- sc->sc_iface_number = id->bInterfaceNumber;
- found = 0;
-
- for (i = 0; i < id->bNumEndpoints; i++) {
- ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
- if (ed == NULL) {
- printf("%s: no endpoint descriptor for %d\n",
- USBDEVNAME(sc->sc_dev), i);
- sc->sc_dying = 1;
- USB_ATTACH_ERROR_RETURN;
- }
-
- if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT &&
- found == 0) {
- uca.bulkin = ed->bEndpointAddress;
- found = 1;
- } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
- UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
- uca.bulkout = 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 (uca.bulkin == -1) {
- printf("%s: Could not find data bulk in\n",
- USBDEVNAME(sc->sc_dev));
- sc->sc_dying = 1;
- USB_ATTACH_ERROR_RETURN;
- }
-
- if (uca.bulkout == -1) {
- printf("%s: Could not find data bulk out\n",
- USBDEVNAME(sc->sc_dev));
- sc->sc_dying = 1;
- USB_ATTACH_ERROR_RETURN;
- }
-
- if (sc->sc_intr_number== -1) {
- printf("%s: Could not find interrupt in\n",
- USBDEVNAME(sc->sc_dev));
- sc->sc_dying = 1;
- USB_ATTACH_ERROR_RETURN;
- }
-
- sc->sc_dtr = sc->sc_rts = 0;
- uca.portno = UCOM_UNK_PORTNO;
- /* bulkin, bulkout set above */
- uca.ibufsize = UMCTIBUFSIZE;
- if (sc->sc_product == USB_PRODUCT_MCT_SITECOM_USB232)
- uca.obufsize = 16; /* device is broken */
- else
- uca.obufsize = UMCTOBUFSIZE;
- uca.ibufsizepad = UMCTIBUFSIZE;
- uca.opkthdrlen = 0;
- uca.device = dev;
- uca.iface = sc->sc_iface;
- uca.methods = &umct_methods;
- uca.arg = sc;
- uca.info = NULL;
-
- umct_init(sc);
-
- usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
- USBDEV(sc->sc_dev));
-
- DPRINTF(("umct: in=0x%x out=0x%x intr=0x%x\n",
- uca.bulkin, uca.bulkout, sc->sc_intr_number ));
- sc->sc_subdev = config_found_sm(self, &uca, ucomprint, ucomsubmatch);
-
- USB_ATTACH_SUCCESS_RETURN;
-}
-
-USB_DETACH(umct)
-{
- USB_DETACH_START(umct, sc);
- int rv = 0;
-
- DPRINTF(("umct_detach: sc=%p flags=%d\n", sc, flags));
-
- 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_dying = 1;
- if (sc->sc_subdev != NULL) {
- rv = config_detach(sc->sc_subdev, flags);
- sc->sc_subdev = NULL;
- }
-
- usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
- USBDEV(sc->sc_dev));
-
- return (rv);
-}
-
-int
-umct_activate(device_ptr_t self, enum devact act)
-{
- struct umct_softc *sc = (struct umct_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);
-}
-
-void
-umct_set_line_state(struct umct_softc *sc)
-{
- usb_device_request_t req;
- uByte ls;
-
- ls = (sc->sc_dtr ? MCR_DTR : 0) |
- (sc->sc_rts ? MCR_RTS : 0);
-
- DPRINTF(("umct_set_line_state: DTR=%d,RTS=%d,ls=%02x\n",
- sc->sc_dtr, sc->sc_rts, ls));
-
- req.bmRequestType = UMCT_SET_REQUEST;
- req.bRequest = REQ_SET_MCR;
- USETW(req.wValue, 0);
- USETW(req.wIndex, sc->sc_iface_number);
- USETW(req.wLength, LENGTH_SET_MCR);
-
- (void)usbd_do_request(sc->sc_udev, &req, &ls);
-}
-
-void
-umct_set(void *addr, int portno, int reg, int onoff)
-{
- struct umct_softc *sc = addr;
-
- switch (reg) {
- case UCOM_SET_DTR:
- umct_dtr(sc, onoff);
- break;
- case UCOM_SET_RTS:
- umct_rts(sc, onoff);
- break;
- case UCOM_SET_BREAK:
- umct_break(sc, onoff);
- break;
- default:
- break;
- }
-}
-
-void
-umct_dtr(struct umct_softc *sc, int onoff)
-{
-
- DPRINTF(("umct_dtr: onoff=%d\n", onoff));
-
- if (sc->sc_dtr == onoff)
- return;
- sc->sc_dtr = onoff;
-
- umct_set_line_state(sc);
-}
-
-void
-umct_rts(struct umct_softc *sc, int onoff)
-{
- DPRINTF(("umct_rts: onoff=%d\n", onoff));
-
- if (sc->sc_rts == onoff)
- return;
- sc->sc_rts = onoff;
-
- umct_set_line_state(sc);
-}
-
-void
-umct_break(struct umct_softc *sc, int onoff)
-{
- DPRINTF(("umct_break: onoff=%d\n", onoff));
-
- umct_set_lcr(sc, onoff ? sc->last_lcr | LCR_SET_BREAK :
- sc->last_lcr);
-}
-
-void
-umct_set_lcr(struct umct_softc *sc, u_int data)
-{
- usb_device_request_t req;
- uByte adata;
-
- adata = data;
- req.bmRequestType = UMCT_SET_REQUEST;
- req.bRequest = REQ_SET_LCR;
- USETW(req.wValue, 0);
- USETW(req.wIndex, sc->sc_iface_number);
- USETW(req.wLength, LENGTH_SET_LCR);
-
- /* XXX should check */
- (void)usbd_do_request(sc->sc_udev, &req, &adata);
-}
-
-void
-umct_set_baudrate(struct umct_softc *sc, u_int rate)
-{
- usb_device_request_t req;
- uDWord arate;
- u_int val;
-
- if (sc->sc_product == USB_PRODUCT_MCT_SITECOM_USB232) {
- switch (rate) {
- case 300: val = 0x01; break;
- case 600: val = 0x02; break;
- case 1200: val = 0x03; break;
- case 2400: val = 0x04; break;
- case 4800: val = 0x06; break;
- case 9600: val = 0x08; break;
- case 19200: val = 0x09; break;
- case 38400: val = 0x0a; break;
- case 57600: val = 0x0b; break;
- case 115200: val = 0x0c; break;
- default: val = -1; break;
- }
- } else {
- val = UMCT_BAUD_RATE(rate);
- }
- USETDW(arate, val);
-
- req.bmRequestType = UMCT_SET_REQUEST;
- req.bRequest = REQ_SET_BAUD_RATE;
- USETW(req.wValue, 0);
- USETW(req.wIndex, sc->sc_iface_number);
- USETW(req.wLength, LENGTH_BAUD_RATE);
-
- /* XXX should check */
- (void)usbd_do_request(sc->sc_udev, &req, arate);
-}
-
-void
-umct_init(struct umct_softc *sc)
-{
- umct_set_baudrate(sc, 9600);
- umct_set_lcr(sc, LCR_DATA_BITS_8 | LCR_PARITY_NONE | LCR_STOP_BITS_1);
-}
-
-int
-umct_param(void *addr, int portno, struct termios *t)
-{
- struct umct_softc *sc = addr;
- u_int data = 0;
-
- DPRINTF(("umct_param: sc=%p\n", sc));
-
- DPRINTF(("umct_param: BAUDRATE=%d\n", t->c_ospeed));
-
- if (ISSET(t->c_cflag, CSTOPB))
- data |= LCR_STOP_BITS_2;
- else
- data |= LCR_STOP_BITS_1;
- if (ISSET(t->c_cflag, PARENB)) {
- if (ISSET(t->c_cflag, PARODD))
- data |= LCR_PARITY_ODD;
- else
- data |= LCR_PARITY_EVEN;
- } else
- data |= LCR_PARITY_NONE;
- switch (ISSET(t->c_cflag, CSIZE)) {
- case CS5:
- data |= LCR_DATA_BITS_5;
- break;
- case CS6:
- data |= LCR_DATA_BITS_6;
- break;
- case CS7:
- data |= LCR_DATA_BITS_7;
- break;
- case CS8:
- data |= LCR_DATA_BITS_8;
- break;
- }
-
- umct_set_baudrate(sc, t->c_ospeed);
-
- sc->last_lcr = data;
- umct_set_lcr(sc, data);
-
- return (0);
-}
-
-int
-umct_open(void *addr, int portno)
-{
- struct umct_softc *sc = addr;
- int err, lcr_data;
-
- if (sc->sc_dying)
- return (EIO);
-
- DPRINTF(("umct_open: sc=%p\n", sc));
-
- /* initialize LCR */
- lcr_data = LCR_DATA_BITS_8 | LCR_PARITY_NONE |
- LCR_STOP_BITS_1;
- umct_set_lcr(sc, lcr_data);
-
- 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_iface, sc->sc_intr_number,
- USBD_SHORT_XFER_OK, &sc->sc_intr_pipe, sc,
- sc->sc_intr_buf, sc->sc_isize,
- umct_intr, USBD_DEFAULT_INTERVAL);
- if (err) {
- DPRINTF(("%s: cannot open interrupt pipe (addr %d)\n",
- USBDEVNAME(sc->sc_dev), sc->sc_intr_number));
- return (EIO);
- }
- }
-
- return (0);
-}
-
-void
-umct_close(void *addr, int portno)
-{
- struct umct_softc *sc = addr;
- int err;
-
- if (sc->sc_dying)
- return;
-
- DPRINTF(("umct_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",
- USBDEVNAME(sc->sc_dev), usbd_errstr(err));
- err = usbd_close_pipe(sc->sc_intr_pipe);
- if (err)
- printf("%s: close interrupt pipe failed: %s\n",
- USBDEVNAME(sc->sc_dev), usbd_errstr(err));
- free(sc->sc_intr_buf, M_USBDEV);
- sc->sc_intr_pipe = NULL;
- }
-}
-
-void
-umct_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- struct umct_softc *sc = priv;
- u_char *buf = sc->sc_intr_buf;
- u_char mstatus, lstatus;
-
- if (sc->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: umct status = MSR:%02x, LSR:%02x\n",
- USBDEVNAME(sc->sc_dev), buf[0],buf[1]));
-
- sc->sc_lsr = sc->sc_msr = 0;
- mstatus = buf[0];
- lstatus = buf[1];
- if (ISSET(mstatus, MSR_DSR))
- sc->sc_msr |= UMSR_DSR;
- if (ISSET(mstatus, MSR_DCD))
- sc->sc_msr |= UMSR_DCD;
- ucom_status_change((struct ucom_softc *)sc->sc_subdev);
-}
-
-void
-umct_get_status(void *addr, int portno, u_char *lsr, u_char *msr)
-{
- struct umct_softc *sc = addr;
-
- DPRINTF(("umct_get_status:\n"));
-
- if (lsr != NULL)
- *lsr = sc->sc_lsr;
- if (msr != NULL)
- *msr = sc->sc_msr;
-}
diff --git a/sys/dev/usb/umct.h b/sys/dev/usb/umct.h
deleted file mode 100644
index e162280d74c..00000000000
--- a/sys/dev/usb/umct.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/* $OpenBSD: umct.h,v 1.1 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: umct.h,v 1.1 2001/03/28 18:42:13 ichiro Exp $ */
-/*
- * 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.
- */
-
-/*
- * Vendor Request Interface
- */
-#define UMCT_SET_REQUEST 0x40
-#define UMCT_GET_REQUEST 0xc0
-
-#define REQ_SET_BAUD_RATE 5 /* Set Baud Rate Divisor */
-#define LENGTH_BAUD_RATE 4
-
-#define REQ_GET_MSR 2 /* Get Modem Status Register (MSR) */
-#define LENGTH_GET_MSR 1
-
-#define REQ_GET_LCR 6 /* Get Line Control Register (LCR) */
-#define LENGTH_GET_LCR 1
-
-#define REQ_SET_LCR 7 /* Set Line Control Register (LCR) */
-#define LENGTH_SET_LCR 1
-
-#define REQ_SET_MCR 10 /* Set Modem Control Register (MCR) */
-#define LENGTH_SET_MCR 1
-
-/*
- * Baud rate (divisor)
- */
-#define UMCT_BAUD_RATE(b) (115200/b)
-
-/*
- * Line Control Register (LCR)
- */
-#define LCR_SET_BREAK 0x40
-#define LCR_PARITY_EVEN 0x18
-#define LCR_PARITY_ODD 0x08
-#define LCR_PARITY_NONE 0x00
-#define LCR_DATA_BITS_5 0x00
-#define LCR_DATA_BITS_6 0x01
-#define LCR_DATA_BITS_7 0x02
-#define LCR_DATA_BITS_8 0x03
-#define LCR_STOP_BITS_2 0x04
-#define LCR_STOP_BITS_1 0x00
-
-/*
- * Modem Control Register (MCR)
- */
-#define MCR_NONE 0x8
-#define MCR_RTS 0xa
-#define MCR_DTR 0x9
-
-/*
- * Modem Status Register (MSR)
- */
-#define MSR_CD 0x80 /* Current CD */
-#define MSR_RI 0x40 /* Current RI */
-#define MSR_DSR 0x20 /* Current DSR */
-#define MSR_CTS 0x10 /* Current CTS */
-#define MSR_DCD 0x08 /* Delta CD */
-#define MSR_DRI 0x04 /* Delta RI */
-#define MSR_DDSR 0x02 /* Delta DSR */
-#define MSR_DCTS 0x01 /* Delta CTS */
-
-/*
- * Line Status Register (LSR)
- */
-#define LSR_ERR 0x80 /* OE | PE | FE | BI */
-#define LSR_TEMT 0x40 /* transmit register empty */
-#define LSR_THRE 0x20 /* transmit holding register empty */
-#define LSR_BI 0x10 /* break indicator */
-#define LSR_FE 0x08 /* framing error */
-#define LSR_OE 0x02 /* overrun error */
-#define LSR_PE 0x04 /* parity error */
-#define LSR_OE 0x02 /* overrun error */
-#define LSR_DR 0x01 /* receive data ready */
diff --git a/sys/dev/usb/umidi.c b/sys/dev/usb/umidi.c
deleted file mode 100644
index 09b8df082a8..00000000000
--- a/sys/dev/usb/umidi.c
+++ /dev/null
@@ -1,1374 +0,0 @@
-/* $OpenBSD: umidi.c,v 1.1 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: umidi.c,v 1.14 2002/03/08 17:24:06 kent Exp $ */
-/*
- * Copyright (c) 2001 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/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/device.h>
-#include <sys/ioctl.h>
-#include <sys/conf.h>
-#include <sys/file.h>
-#include <sys/select.h>
-#include <sys/proc.h>
-#include <sys/vnode.h>
-#include <sys/poll.h>
-#include <sys/lock.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-
-#include <dev/usb/usbdevs.h>
-#include <dev/usb/uaudioreg.h>
-#include <dev/usb/umidireg.h>
-#include <dev/usb/umidivar.h>
-#include <dev/usb/umidi_quirks.h>
-
-#include <dev/midi_if.h>
-
-#ifdef UMIDI_DEBUG
-#define DPRINTF(x) if (umididebug) printf x
-#define DPRINTFN(n,x) if (umididebug >= (n)) printf x
-int umididebug = 0;
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-
-static int umidi_open(void *, int,
- void (*)(void *, int), void (*)(void *), void *);
-static void umidi_close(void *);
-static int umidi_output(void *, int);
-static void umidi_getinfo(void *, struct midi_info *);
-
-static usbd_status alloc_pipe(struct umidi_endpoint *);
-static void free_pipe(struct umidi_endpoint *);
-
-static usbd_status alloc_all_endpoints(struct umidi_softc *);
-static void free_all_endpoints(struct umidi_softc *);
-
-static usbd_status alloc_all_jacks(struct umidi_softc *);
-static void free_all_jacks(struct umidi_softc *);
-static usbd_status bind_jacks_to_mididev(struct umidi_softc *,
- struct umidi_jack *,
- struct umidi_jack *,
- struct umidi_mididev *);
-static void unbind_jacks_from_mididev(struct umidi_mididev *);
-static void unbind_all_jacks(struct umidi_softc *);
-static usbd_status assign_all_jacks_automatically(struct umidi_softc *);
-static usbd_status open_out_jack(struct umidi_jack *, void *,
- void (*)(void *));
-static usbd_status open_in_jack(struct umidi_jack *, void *,
- void (*)(void *, int));
-static void close_out_jack(struct umidi_jack *);
-static void close_in_jack(struct umidi_jack *);
-
-static usbd_status attach_mididev(struct umidi_softc *,
- struct umidi_mididev *);
-static usbd_status detach_mididev(struct umidi_mididev *, int);
-static usbd_status deactivate_mididev(struct umidi_mididev *);
-static usbd_status alloc_all_mididevs(struct umidi_softc *, int);
-static void free_all_mididevs(struct umidi_softc *);
-static usbd_status attach_all_mididevs(struct umidi_softc *);
-static usbd_status detach_all_mididevs(struct umidi_softc *, int);
-static usbd_status deactivate_all_mididevs(struct umidi_softc *);
-
-#ifdef UMIDI_DEBUG
-static void dump_sc(struct umidi_softc *);
-static void dump_ep(struct umidi_endpoint *);
-static void dump_jack(struct umidi_jack *);
-#endif
-
-static void init_packet(struct umidi_packet *);
-
-static usbd_status start_input_transfer(struct umidi_endpoint *);
-static usbd_status start_output_transfer(struct umidi_endpoint *);
-static int out_jack_output(struct umidi_jack *, int);
-static void in_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
-static void out_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
-static void out_build_packet(int, struct umidi_packet *, uByte);
-
-
-struct midi_hw_if umidi_hw_if = {
- umidi_open,
- umidi_close,
- umidi_output,
- umidi_getinfo,
- 0, /* ioctl */
-};
-
-USB_DECLARE_DRIVER(umidi);
-
-USB_MATCH(umidi)
-{
- USB_MATCH_START(umidi, uaa);
- usb_interface_descriptor_t *id;
-
- DPRINTFN(1,("umidi_match\n"));
-
- if (uaa->iface == NULL)
- return UMATCH_NONE;
-
- if (umidi_search_quirk(uaa->vendor, uaa->product, uaa->ifaceno))
- return UMATCH_IFACECLASS_IFACESUBCLASS;
-
- id = usbd_get_interface_descriptor(uaa->iface);
- if (id!=NULL &&
- id->bInterfaceClass==UICLASS_AUDIO &&
- id->bInterfaceSubClass==UISUBCLASS_MIDISTREAM)
- return UMATCH_IFACECLASS_IFACESUBCLASS;
-
- return UMATCH_NONE;
-}
-
-USB_ATTACH(umidi)
-{
- usbd_status err;
- USB_ATTACH_START(umidi, sc, uaa);
- char devinfo[1024];
-
- DPRINTFN(1,("umidi_attach\n"));
-
- usbd_devinfo(uaa->device, 0, devinfo);
- printf("\n%s: %s\n", USBDEVNAME(sc->sc_dev), devinfo);
-
- sc->sc_iface = uaa->iface;
- sc->sc_udev = uaa->device;
-
- sc->sc_quirk =
- umidi_search_quirk(uaa->vendor, uaa->product, uaa->ifaceno);
- printf("%s: ", USBDEVNAME(sc->sc_dev));
- umidi_print_quirk(sc->sc_quirk);
-
-
- err = alloc_all_endpoints(sc);
- if (err!=USBD_NORMAL_COMPLETION) {
- printf("%s: alloc_all_endpoints failed. (err=%d)\n",
- USBDEVNAME(sc->sc_dev), err);
- goto error;
- }
- err = alloc_all_jacks(sc);
- if (err!=USBD_NORMAL_COMPLETION) {
- free_all_endpoints(sc);
- printf("%s: alloc_all_jacks failed. (err=%d)\n",
- USBDEVNAME(sc->sc_dev), err);
- goto error;
- }
- printf("%s: out=%d, in=%d\n",
- USBDEVNAME(sc->sc_dev),
- sc->sc_out_num_jacks, sc->sc_in_num_jacks);
-
- err = assign_all_jacks_automatically(sc);
- if (err!=USBD_NORMAL_COMPLETION) {
- unbind_all_jacks(sc);
- free_all_jacks(sc);
- free_all_endpoints(sc);
- printf("%s: assign_all_jacks_automatically failed. (err=%d)\n",
- USBDEVNAME(sc->sc_dev), err);
- goto error;
- }
- err = attach_all_mididevs(sc);
- if (err!=USBD_NORMAL_COMPLETION) {
- free_all_jacks(sc);
- free_all_endpoints(sc);
- printf("%s: attach_all_mididevs failed. (err=%d)\n",
- USBDEVNAME(sc->sc_dev), err);
- }
-
-#ifdef UMIDI_DEBUG
- dump_sc(sc);
-#endif
-
- usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH,
- sc->sc_udev, USBDEV(sc->sc_dev));
-
- USB_ATTACH_SUCCESS_RETURN;
-error:
- printf("%s: disabled.\n", USBDEVNAME(sc->sc_dev));
- sc->sc_dying = 1;
- USB_ATTACH_ERROR_RETURN;
-}
-
-int
-umidi_activate(device_ptr_t self, enum devact act)
-{
- struct umidi_softc *sc = (struct umidi_softc *)self;
-
- switch (act) {
- case DVACT_ACTIVATE:
- DPRINTFN(1,("umidi_activate (activate)\n"));
-
- return EOPNOTSUPP;
- break;
- case DVACT_DEACTIVATE:
- DPRINTFN(1,("umidi_activate (deactivate)\n"));
- sc->sc_dying = 1;
- deactivate_all_mididevs(sc);
- break;
- }
- return 0;
-}
-
-USB_DETACH(umidi)
-{
- USB_DETACH_START(umidi, sc);
-
- DPRINTFN(1,("umidi_detach\n"));
-
- sc->sc_dying = 1;
- detach_all_mididevs(sc, flags);
- free_all_mididevs(sc);
- free_all_jacks(sc);
- free_all_endpoints(sc);
-
- usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
- USBDEV(sc->sc_dev));
-
- return 0;
-}
-
-
-/*
- * midi_if stuffs
- */
-int
-umidi_open(void *addr,
- int flags,
- void (*iintr)(void *, int),
- void (*ointr)(void *),
- void *arg)
-{
- struct umidi_mididev *mididev = addr;
- struct umidi_softc *sc = mididev->sc;
-
- DPRINTF(("umidi_open: sc=%p\n", sc));
-
- if (!sc)
- return ENXIO;
- if (mididev->opened)
- return EBUSY;
- if (sc->sc_dying)
- return EIO;
-
- mididev->opened = 1;
- mididev->flags = flags;
- if ((mididev->flags & FWRITE) && mididev->out_jack)
- open_out_jack(mididev->out_jack, arg, ointr);
- if ((mididev->flags & FREAD) && mididev->in_jack) {
- open_in_jack(mididev->in_jack, arg, iintr);
- }
-
- return 0;
-}
-
-void
-umidi_close(void *addr)
-{
- int s;
- struct umidi_mididev *mididev = addr;
-
- s = splusb();
- if ((mididev->flags & FWRITE) && mididev->out_jack)
- close_out_jack(mididev->out_jack);
- if ((mididev->flags & FREAD) && mididev->in_jack)
- close_in_jack(mididev->in_jack);
- mididev->opened = 0;
- splx(s);
-}
-
-int
-umidi_output(void *addr, int d)
-{
- struct umidi_mididev *mididev = addr;
-
- if (!mididev->out_jack || !mididev->opened)
- return EIO;
-
- return out_jack_output(mididev->out_jack, d);
-}
-
-void
-umidi_getinfo(void *addr, struct midi_info *mi)
-{
- struct umidi_mididev *mididev = addr;
-/* struct umidi_softc *sc = mididev->sc; */
-
- mi->name = "USB MIDI I/F"; /* XXX: model name */
- mi->props = MIDI_PROP_OUT_INTR;
- if (mididev->in_jack)
- mi->props |= MIDI_PROP_CAN_INPUT;
-}
-
-
-/*
- * each endpoint stuffs
- */
-
-/* alloc/free pipe */
-static usbd_status
-alloc_pipe(struct umidi_endpoint *ep)
-{
- struct umidi_softc *sc = ep->sc;
- usbd_status err;
-
- DPRINTF(("%s: alloc_pipe %p\n", USBDEVNAME(sc->sc_dev), ep));
- LIST_INIT(&ep->queue_head);
- ep->xfer = usbd_alloc_xfer(sc->sc_udev);
- if (ep->xfer == NULL) {
- err = USBD_NOMEM;
- goto quit;
- }
- ep->buffer = usbd_alloc_buffer(ep->xfer, UMIDI_PACKET_SIZE);
- if (ep->buffer == NULL) {
- usbd_free_xfer(ep->xfer);
- err = USBD_NOMEM;
- goto quit;
- }
- err = usbd_open_pipe(sc->sc_iface, ep->addr, 0, &ep->pipe);
- if (err)
- usbd_free_xfer(ep->xfer);
-quit:
- return err;
-}
-
-static void
-free_pipe(struct umidi_endpoint *ep)
-{
- DPRINTF(("%s: free_pipe %p\n", USBDEVNAME(ep->sc->sc_dev), ep));
- usbd_abort_pipe(ep->pipe);
- usbd_close_pipe(ep->pipe);
- usbd_free_xfer(ep->xfer);
-}
-
-
-/* alloc/free the array of endpoint structures */
-
-static usbd_status alloc_all_endpoints_fixed_ep(struct umidi_softc *);
-static usbd_status alloc_all_endpoints_yamaha(struct umidi_softc *);
-static usbd_status alloc_all_endpoints_genuine(struct umidi_softc *);
-
-static usbd_status
-alloc_all_endpoints(struct umidi_softc *sc)
-{
- usbd_status err;
- struct umidi_endpoint *ep;
- int i;
-
- if (UMQ_ISTYPE(sc, UMQ_TYPE_FIXED_EP)) {
- err = alloc_all_endpoints_fixed_ep(sc);
- } else if (UMQ_ISTYPE(sc, UMQ_TYPE_YAMAHA)) {
- err = alloc_all_endpoints_yamaha(sc);
- } else {
- err = alloc_all_endpoints_genuine(sc);
- }
- if (err!=USBD_NORMAL_COMPLETION)
- return err;
-
- ep = sc->sc_endpoints;
- for (i=sc->sc_out_num_endpoints+sc->sc_in_num_endpoints; i>0; i--) {
- err = alloc_pipe(ep++);
- if (err!=USBD_NORMAL_COMPLETION) {
- for (; ep!=sc->sc_endpoints; ep--)
- free_pipe(ep-1);
- free(sc->sc_endpoints, M_USBDEV);
- sc->sc_endpoints = sc->sc_out_ep = sc->sc_in_ep = NULL;
- break;
- }
- }
- return err;
-}
-
-static void
-free_all_endpoints(struct umidi_softc *sc)
-{
- int i;
- for (i=0; i<sc->sc_in_num_endpoints+sc->sc_out_num_endpoints; i++)
- free_pipe(&sc->sc_endpoints[i]);
- if (sc->sc_endpoints != NULL)
- free(sc->sc_endpoints, M_USBDEV);
- sc->sc_endpoints = sc->sc_out_ep = sc->sc_in_ep = NULL;
-}
-
-static usbd_status
-alloc_all_endpoints_fixed_ep(struct umidi_softc *sc)
-{
- usbd_status err;
- struct umq_fixed_ep_desc *fp;
- struct umidi_endpoint *ep;
- usb_endpoint_descriptor_t *epd;
- int i;
-
- fp = umidi_get_quirk_data_from_type(sc->sc_quirk,
- UMQ_TYPE_FIXED_EP);
- sc->sc_out_num_jacks = 0;
- sc->sc_in_num_jacks = 0;
- sc->sc_out_num_endpoints = fp->num_out_ep;
- sc->sc_in_num_endpoints = fp->num_in_ep;
- sc->sc_endpoints = malloc(sizeof(*sc->sc_out_ep)*
- (sc->sc_out_num_endpoints+
- sc->sc_in_num_endpoints),
- M_USBDEV, M_WAITOK);
- if (!sc->sc_endpoints) {
- return USBD_NOMEM;
- }
- sc->sc_out_ep = sc->sc_out_num_endpoints ? sc->sc_endpoints : NULL;
- sc->sc_in_ep =
- sc->sc_in_num_endpoints ?
- sc->sc_endpoints+sc->sc_out_num_endpoints : NULL;
-
- ep = &sc->sc_out_ep[0];
- for (i=0; i<sc->sc_out_num_endpoints; i++) {
- epd = usbd_interface2endpoint_descriptor(
- sc->sc_iface,
- fp->out_ep[i].ep);
- if (!epd) {
- printf("%s: cannot get endpoint descriptor(out:%d)\n",
- USBDEVNAME(sc->sc_dev), fp->out_ep[i].ep);
- err = USBD_INVAL;
- goto error;
- }
- if (UE_GET_XFERTYPE(epd->bmAttributes)!=UE_BULK ||
- UE_GET_DIR(epd->bEndpointAddress)!=UE_DIR_OUT) {
- printf("%s: illegal endpoint(out:%d)\n",
- USBDEVNAME(sc->sc_dev), fp->out_ep[i].ep);
- err = USBD_INVAL;
- goto error;
- }
- ep->sc = sc;
- ep->addr = epd->bEndpointAddress;
- ep->num_jacks = fp->out_ep[i].num_jacks;
- sc->sc_out_num_jacks += fp->out_ep[i].num_jacks;
- ep->num_open = 0;
- memset(ep->jacks, 0, sizeof(ep->jacks));
- LIST_INIT(&ep->queue_head);
- ep++;
- }
- ep = &sc->sc_in_ep[0];
- for (i=0; i<sc->sc_in_num_endpoints; i++) {
- epd = usbd_interface2endpoint_descriptor(
- sc->sc_iface,
- fp->in_ep[i].ep);
- if (!epd) {
- printf("%s: cannot get endpoint descriptor(in:%d)\n",
- USBDEVNAME(sc->sc_dev), fp->in_ep[i].ep);
- err = USBD_INVAL;
- goto error;
- }
- if (UE_GET_XFERTYPE(epd->bmAttributes)!=UE_BULK ||
- UE_GET_DIR(epd->bEndpointAddress)!=UE_DIR_IN) {
- printf("%s: illegal endpoint(in:%d)\n",
- USBDEVNAME(sc->sc_dev), fp->in_ep[i].ep);
- err = USBD_INVAL;
- goto error;
- }
- ep->sc = sc;
- ep->addr = epd->bEndpointAddress;
- ep->num_jacks = fp->in_ep[i].num_jacks;
- sc->sc_in_num_jacks += fp->in_ep[i].num_jacks;
- ep->num_open = 0;
- memset(ep->jacks, 0, sizeof(ep->jacks));
- ep++;
- }
-
- return USBD_NORMAL_COMPLETION;
-error:
- free(sc->sc_endpoints, M_USBDEV);
- sc->sc_endpoints = NULL;
- return err;
-}
-
-static usbd_status
-alloc_all_endpoints_yamaha(struct umidi_softc *sc)
-{
- /* This driver currently supports max 1in/1out bulk endpoints */
- usb_descriptor_t *desc;
- usb_endpoint_descriptor_t *epd;
- int out_addr, in_addr, i;
- int dir;
- size_t remain, descsize;
-
- sc->sc_out_num_jacks = sc->sc_in_num_jacks = 0;
- out_addr = in_addr = 0;
-
- /* detect endpoints */
- desc = TO_D(usbd_get_interface_descriptor(sc->sc_iface));
- for (i=(int)TO_IFD(desc)->bNumEndpoints-1; i>=0; i--) {
- epd = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
- if (UE_GET_XFERTYPE(epd->bmAttributes) == UE_BULK) {
- dir = UE_GET_DIR(epd->bEndpointAddress);
- if (dir==UE_DIR_OUT && !out_addr)
- out_addr = epd->bEndpointAddress;
- else if (dir==UE_DIR_IN && !in_addr)
- in_addr = epd->bEndpointAddress;
- }
- }
- desc = NEXT_D(desc);
-
- /* count jacks */
- if (!(desc->bDescriptorType==UDESC_CS_INTERFACE &&
- desc->bDescriptorSubtype==UMIDI_MS_HEADER))
- return USBD_INVAL;
- remain = (size_t)UGETW(TO_CSIFD(desc)->wTotalLength) -
- (size_t)desc->bLength;
- desc = NEXT_D(desc);
-
- while (remain>=sizeof(usb_descriptor_t)) {
- descsize = desc->bLength;
- if (descsize>remain || descsize==0)
- break;
- if (desc->bDescriptorType==UDESC_CS_INTERFACE &&
- remain>=UMIDI_JACK_DESCRIPTOR_SIZE) {
- if (desc->bDescriptorSubtype==UMIDI_OUT_JACK)
- sc->sc_out_num_jacks++;
- else if (desc->bDescriptorSubtype==UMIDI_IN_JACK)
- sc->sc_in_num_jacks++;
- }
- desc = NEXT_D(desc);
- remain-=descsize;
- }
-
- /* validate some parameters */
- if (sc->sc_out_num_jacks>UMIDI_MAX_EPJACKS)
- sc->sc_out_num_jacks = UMIDI_MAX_EPJACKS;
- if (sc->sc_in_num_jacks>UMIDI_MAX_EPJACKS)
- sc->sc_in_num_jacks = UMIDI_MAX_EPJACKS;
- if (sc->sc_out_num_jacks && out_addr) {
- sc->sc_out_num_endpoints = 1;
- } else {
- sc->sc_out_num_endpoints = 0;
- sc->sc_out_num_jacks = 0;
- }
- if (sc->sc_in_num_jacks && in_addr) {
- sc->sc_in_num_endpoints = 1;
- } else {
- sc->sc_in_num_endpoints = 0;
- sc->sc_in_num_jacks = 0;
- }
- sc->sc_endpoints = malloc(sizeof(struct umidi_endpoint)*
- (sc->sc_out_num_endpoints+
- sc->sc_in_num_endpoints),
- M_USBDEV, M_WAITOK);
- if (!sc->sc_endpoints)
- return USBD_NOMEM;
- if (sc->sc_out_num_endpoints) {
- sc->sc_out_ep = sc->sc_endpoints;
- sc->sc_out_ep->sc = sc;
- sc->sc_out_ep->addr = out_addr;
- sc->sc_out_ep->num_jacks = sc->sc_out_num_jacks;
- sc->sc_out_ep->num_open = 0;
- memset(sc->sc_out_ep->jacks, 0, sizeof(sc->sc_out_ep->jacks));
- } else
- sc->sc_out_ep = NULL;
-
- if (sc->sc_in_num_endpoints) {
- sc->sc_in_ep = sc->sc_endpoints+sc->sc_out_num_endpoints;
- sc->sc_in_ep->sc = sc;
- sc->sc_in_ep->addr = in_addr;
- sc->sc_in_ep->num_jacks = sc->sc_in_num_jacks;
- sc->sc_in_ep->num_open = 0;
- memset(sc->sc_in_ep->jacks, 0, sizeof(sc->sc_in_ep->jacks));
- } else
- sc->sc_in_ep = NULL;
-
- return USBD_NORMAL_COMPLETION;
-}
-
-static usbd_status
-alloc_all_endpoints_genuine(struct umidi_softc *sc)
-{
- usb_descriptor_t *desc;
- int num_ep;
- size_t remain, descsize;
- struct umidi_endpoint *p, *q, *lowest, *endep, tmpep;
- int epaddr;
-
- desc = TO_D(usbd_get_interface_descriptor(sc->sc_iface));
- num_ep = TO_IFD(desc)->bNumEndpoints;
- desc = NEXT_D(desc); /* ifd -> csifd */
- remain = ((size_t)UGETW(TO_CSIFD(desc)->wTotalLength) -
- (size_t)desc->bLength);
- desc = NEXT_D(desc);
-
- sc->sc_endpoints = p = malloc(sizeof(struct umidi_endpoint)*num_ep,
- M_USBDEV, M_WAITOK);
- if (!p)
- return USBD_NOMEM;
-
- sc->sc_out_num_jacks = sc->sc_in_num_jacks = 0;
- sc->sc_out_num_endpoints = sc->sc_in_num_endpoints = 0;
- epaddr = -1;
-
- /* get the list of endpoints for midi stream */
- while (remain>=sizeof(usb_descriptor_t)) {
- descsize = desc->bLength;
- if (descsize>remain || descsize==0)
- break;
- if (desc->bDescriptorType==UDESC_ENDPOINT &&
- remain>=USB_ENDPOINT_DESCRIPTOR_SIZE &&
- UE_GET_XFERTYPE(TO_EPD(desc)->bmAttributes) == UE_BULK) {
- epaddr = TO_EPD(desc)->bEndpointAddress;
- } else if (desc->bDescriptorType==UDESC_CS_ENDPOINT &&
- remain>=UMIDI_CS_ENDPOINT_DESCRIPTOR_SIZE &&
- epaddr!=-1) {
- if (num_ep>0) {
- num_ep--;
- p->sc = sc;
- p->addr = epaddr;
- p->num_jacks = TO_CSEPD(desc)->bNumEmbMIDIJack;
- if (UE_GET_DIR(epaddr)==UE_DIR_OUT) {
- sc->sc_out_num_endpoints++;
- sc->sc_out_num_jacks += p->num_jacks;
- } else {
- sc->sc_in_num_endpoints++;
- sc->sc_in_num_jacks += p->num_jacks;
- }
- p++;
- }
- } else
- epaddr = -1;
- desc = NEXT_D(desc);
- remain-=descsize;
- }
-
- /* sort endpoints */
- num_ep = sc->sc_out_num_endpoints + sc->sc_in_num_endpoints;
- p = sc->sc_endpoints;
- endep = p + num_ep;
- while (p<endep) {
- lowest = p;
- for (q=p+1; q<endep; q++) {
- if ((UE_GET_DIR(lowest->addr)==UE_DIR_IN &&
- UE_GET_DIR(q->addr)==UE_DIR_OUT) ||
- ((UE_GET_DIR(lowest->addr)==
- UE_GET_DIR(q->addr)) &&
- (UE_GET_ADDR(lowest->addr)>
- UE_GET_ADDR(q->addr))))
- lowest = q;
- }
- if (lowest != p) {
- memcpy((void *)&tmpep, (void *)p, sizeof(tmpep));
- memcpy((void *)p, (void *)lowest, sizeof(tmpep));
- memcpy((void *)lowest, (void *)&tmpep, sizeof(tmpep));
- }
- p->num_open = 0;
- p++;
- }
-
- sc->sc_out_ep = sc->sc_out_num_endpoints ? sc->sc_endpoints : NULL;
- sc->sc_in_ep =
- sc->sc_in_num_endpoints ?
- sc->sc_endpoints+sc->sc_out_num_endpoints : NULL;
-
- return USBD_NORMAL_COMPLETION;
-}
-
-
-/*
- * jack stuffs
- */
-
-static usbd_status
-alloc_all_jacks(struct umidi_softc *sc)
-{
- int i, j;
- struct umidi_endpoint *ep;
- struct umidi_jack *jack, **rjack;
-
- /* allocate/initialize structures */
- sc->sc_jacks =
- malloc(sizeof(*sc->sc_out_jacks)*(sc->sc_in_num_jacks+
- sc->sc_out_num_jacks),
- M_USBDEV, M_WAITOK);
- if (!sc->sc_jacks)
- return USBD_NOMEM;
- sc->sc_out_jacks =
- sc->sc_out_num_jacks ? sc->sc_jacks : NULL;
- sc->sc_in_jacks =
- sc->sc_in_num_jacks ? sc->sc_jacks+sc->sc_out_num_jacks : NULL;
-
- jack = &sc->sc_out_jacks[0];
- for (i=0; i<sc->sc_out_num_jacks; i++) {
- jack->opened = 0;
- jack->binded = 0;
- jack->arg = NULL;
- jack->u.out.intr = NULL;
- jack->cable_number = i;
- jack++;
- }
- jack = &sc->sc_in_jacks[0];
- for (i=0; i<sc->sc_in_num_jacks; i++) {
- jack->opened = 0;
- jack->binded = 0;
- jack->arg = NULL;
- jack->u.in.intr = NULL;
- jack->cable_number = i;
- jack++;
- }
-
- /* assign each jacks to each endpoints */
- jack = &sc->sc_out_jacks[0];
- ep = &sc->sc_out_ep[0];
- for (i=0; i<sc->sc_out_num_endpoints; i++) {
- rjack = &ep->jacks[0];
- for (j=0; j<ep->num_jacks; j++) {
- *rjack = jack;
- jack->endpoint = ep;
- jack++;
- rjack++;
- }
- ep++;
- }
- jack = &sc->sc_in_jacks[0];
- ep = &sc->sc_in_ep[0];
- for (i=0; i<sc->sc_in_num_endpoints; i++) {
- rjack = &ep->jacks[0];
- for (j=0; j<ep->num_jacks; j++) {
- *rjack = jack;
- jack->endpoint = ep;
- jack++;
- rjack++;
- }
- ep++;
- }
-
- return USBD_NORMAL_COMPLETION;
-}
-
-static void
-free_all_jacks(struct umidi_softc *sc)
-{
- int s;
-
- s = splaudio();
- if (sc->sc_out_jacks) {
- free(sc->sc_jacks, M_USBDEV);
- sc->sc_jacks = sc->sc_in_jacks = sc->sc_out_jacks = NULL;
- }
- splx(s);
-}
-
-static usbd_status
-bind_jacks_to_mididev(struct umidi_softc *sc,
- struct umidi_jack *out_jack,
- struct umidi_jack *in_jack,
- struct umidi_mididev *mididev)
-{
- if ((out_jack && out_jack->binded) || (in_jack && in_jack->binded))
- return USBD_IN_USE;
- if (mididev->out_jack || mididev->in_jack)
- return USBD_IN_USE;
-
- if (out_jack)
- out_jack->binded = 1;
- if (in_jack)
- in_jack->binded = 1;
- mididev->in_jack = in_jack;
- mididev->out_jack = out_jack;
-
- return USBD_NORMAL_COMPLETION;
-}
-
-static void
-unbind_jacks_from_mididev(struct umidi_mididev *mididev)
-{
- if ((mididev->flags&FWRITE) && mididev->out_jack)
- close_out_jack(mididev->out_jack);
- if ((mididev->flags&FWRITE) && mididev->in_jack)
- close_in_jack(mididev->in_jack);
-
- if (mididev->out_jack)
- mididev->out_jack->binded = 0;
- if (mididev->in_jack)
- mididev->in_jack->binded = 0;
- mididev->out_jack = mididev->in_jack = NULL;
-}
-
-static void
-unbind_all_jacks(struct umidi_softc *sc)
-{
- int i;
-
- if (sc->sc_mididevs)
- for (i=0; i<sc->sc_num_mididevs; i++) {
- unbind_jacks_from_mididev(&sc->sc_mididevs[i]);
- }
-}
-
-static usbd_status
-assign_all_jacks_automatically(struct umidi_softc *sc)
-{
- usbd_status err;
- int i;
- struct umidi_jack *out, *in;
-
- err =
- alloc_all_mididevs(sc,
- max(sc->sc_out_num_jacks, sc->sc_in_num_jacks));
- if (err!=USBD_NORMAL_COMPLETION)
- return err;
-
- for (i=0; i<sc->sc_num_mididevs; i++) {
- out = (i<sc->sc_out_num_jacks) ? &sc->sc_out_jacks[i]:NULL;
- in = (i<sc->sc_in_num_jacks) ? &sc->sc_in_jacks[i]:NULL;
- err = bind_jacks_to_mididev(sc, out, in, &sc->sc_mididevs[i]);
- if (err!=USBD_NORMAL_COMPLETION) {
- free_all_mididevs(sc);
- return err;
- }
- }
-
- return USBD_NORMAL_COMPLETION;
-}
-
-static usbd_status
-open_out_jack(struct umidi_jack *jack, void *arg, void (*intr)(void *))
-{
- struct umidi_endpoint *ep = jack->endpoint;
-
- if (jack->opened)
- return USBD_IN_USE;
-
- jack->arg = arg;
- jack->u.out.intr = intr;
- init_packet(&jack->packet);
- jack->opened = 1;
- ep->num_open++;
-
- return USBD_NORMAL_COMPLETION;
-}
-
-static usbd_status
-open_in_jack(struct umidi_jack *jack, void *arg, void (*intr)(void *, int))
-{
- usbd_status err = USBD_NORMAL_COMPLETION;
- struct umidi_endpoint *ep = jack->endpoint;
-
- if (jack->opened)
- return USBD_IN_USE;
-
- jack->arg = arg;
- jack->u.in.intr = intr;
- jack->opened = 1;
- if (ep->num_open++==0 && UE_GET_DIR(ep->addr)==UE_DIR_IN) {
- err = start_input_transfer(ep);
- if (err!=USBD_NORMAL_COMPLETION) {
- ep->num_open--;
- }
- }
-
- return err;
-}
-
-static void
-close_out_jack(struct umidi_jack *jack)
-{
- struct umidi_jack *tail;
- int s;
-
- if (jack->opened) {
- s = splusb();
- LIST_REMOVE(jack, u.out.queue_entry);
- if (jack==jack->endpoint->queue_tail) {
- /* find tail */
- LIST_FOREACH(tail,
- &jack->endpoint->queue_head,
- u.out.queue_entry) {
- if (!LIST_NEXT(tail, u.out.queue_entry)) {
- jack->endpoint->queue_tail = tail;
- }
- }
- }
- splx(s);
- jack->opened = 0;
- jack->endpoint->num_open--;
- }
-}
-
-static void
-close_in_jack(struct umidi_jack *jack)
-{
- if (jack->opened) {
- jack->opened = 0;
- jack->endpoint->num_open--;
- }
-}
-
-static usbd_status
-attach_mididev(struct umidi_softc *sc, struct umidi_mididev *mididev)
-{
- if (mididev->sc)
- return USBD_IN_USE;
-
- mididev->sc = sc;
-
- mididev->mdev = midi_attach_mi(&umidi_hw_if, mididev, &sc->sc_dev);
-
- return USBD_NORMAL_COMPLETION;
-}
-
-static usbd_status
-detach_mididev(struct umidi_mididev *mididev, int flags)
-{
- if (!mididev->sc)
- return USBD_NO_ADDR;
-
- if (mididev->opened) {
- umidi_close(mididev);
- }
- unbind_jacks_from_mididev(mididev);
-
- if (mididev->mdev)
- config_detach(mididev->mdev, flags);
-
- mididev->sc = NULL;
-
- return USBD_NORMAL_COMPLETION;
-}
-
-static usbd_status
-deactivate_mididev(struct umidi_mididev *mididev)
-{
- if (mididev->out_jack)
- mididev->out_jack->binded = 0;
- if (mididev->in_jack)
- mididev->in_jack->binded = 0;
- config_deactivate(mididev->mdev);
-
- return USBD_NORMAL_COMPLETION;
-}
-
-static usbd_status
-alloc_all_mididevs(struct umidi_softc *sc, int nmidi)
-{
- sc->sc_num_mididevs = nmidi;
- sc->sc_mididevs = malloc(sizeof(*sc->sc_mididevs)*nmidi,
- M_USBDEV, M_WAITOK|M_ZERO);
- if (!sc->sc_mididevs)
- return USBD_NOMEM;
-
- return USBD_NORMAL_COMPLETION;
-}
-
-static void
-free_all_mididevs(struct umidi_softc *sc)
-{
- sc->sc_num_mididevs = 0;
- if (sc->sc_mididevs)
- free(sc->sc_mididevs, M_USBDEV);
-}
-
-static usbd_status
-attach_all_mididevs(struct umidi_softc *sc)
-{
- usbd_status err;
- int i;
-
- if (sc->sc_mididevs)
- for (i=0; i<sc->sc_num_mididevs; i++) {
- err = attach_mididev(sc, &sc->sc_mididevs[i]);
- if (err!=USBD_NORMAL_COMPLETION)
- return err;
- }
-
- return USBD_NORMAL_COMPLETION;
-}
-
-static usbd_status
-detach_all_mididevs(struct umidi_softc *sc, int flags)
-{
- usbd_status err;
- int i;
-
- if (sc->sc_mididevs)
- for (i=0; i<sc->sc_num_mididevs; i++) {
- err = detach_mididev(&sc->sc_mididevs[i], flags);
- if (err!=USBD_NORMAL_COMPLETION)
- return err;
- }
-
- return USBD_NORMAL_COMPLETION;
-}
-
-static usbd_status
-deactivate_all_mididevs(struct umidi_softc *sc)
-{
- usbd_status err;
- int i;
-
- if (sc->sc_mididevs)
- for (i=0; i<sc->sc_num_mididevs; i++) {
- err = deactivate_mididev(&sc->sc_mididevs[i]);
- if (err!=USBD_NORMAL_COMPLETION)
- return err;
- }
-
- return USBD_NORMAL_COMPLETION;
-}
-
-#ifdef UMIDI_DEBUG
-static void
-dump_sc(struct umidi_softc *sc)
-{
- int i;
-
- DPRINTFN(10, ("%s: dump_sc\n", USBDEVNAME(sc->sc_dev)));
- for (i=0; i<sc->sc_out_num_endpoints; i++) {
- DPRINTFN(10, ("\tout_ep(%p):\n", &sc->sc_out_ep[i]));
- dump_ep(&sc->sc_out_ep[i]);
- }
- for (i=0; i<sc->sc_in_num_endpoints; i++) {
- DPRINTFN(10, ("\tin_ep(%p):\n", &sc->sc_in_ep[i]));
- dump_ep(&sc->sc_in_ep[i]);
- }
-}
-
-static void
-dump_ep(struct umidi_endpoint *ep)
-{
- int i;
- for (i=0; i<ep->num_jacks; i++) {
- DPRINTFN(10, ("\t\tjack(%p):\n", ep->jacks[i]));
- dump_jack(ep->jacks[i]);
- }
-}
-static void
-dump_jack(struct umidi_jack *jack)
-{
- DPRINTFN(10, ("\t\t\tep=%p, mididev=%p\n",
- jack->endpoint, jack->mididev));
-}
-
-#endif /* UMIDI_DEBUG */
-
-
-
-/*
- * MUX MIDI PACKET
- */
-
-static const int packet_length[16] = {
- /*0*/ -1,
- /*1*/ -1,
- /*2*/ 2,
- /*3*/ 3,
- /*4*/ 3,
- /*5*/ 1,
- /*6*/ 2,
- /*7*/ 3,
- /*8*/ 3,
- /*9*/ 3,
- /*A*/ 3,
- /*B*/ 3,
- /*C*/ 2,
- /*D*/ 2,
- /*E*/ 3,
- /*F*/ 1,
-};
-
-static const struct {
- int cin;
- packet_state_t next;
-} packet_0xFX[16] = {
- /*F0: SysEx */ { 0x04, PS_EXCL_1 },
- /*F1: MTC */ { 0x02, PS_NORMAL_1OF2 },
- /*F2: S.POS */ { 0x03, PS_NORMAL_1OF3 },
- /*F3: S.SEL */ { 0x02, PS_NORMAL_1OF2 },
- /*F4: UNDEF */ { 0x00, PS_INITIAL },
- /*F5: UNDEF */ { 0x00, PS_INITIAL },
- /*F6: Tune */ { 0x0F, PS_END },
- /*F7: EofEx */ { 0x00, PS_INITIAL },
- /*F8: Timing */ { 0x0F, PS_END },
- /*F9: UNDEF */ { 0x00, PS_INITIAL },
- /*FA: Start */ { 0x0F, PS_END },
- /*FB: Cont */ { 0x0F, PS_END },
- /*FC: Stop */ { 0x0F, PS_END },
- /*FD: UNDEF */ { 0x00, PS_INITIAL },
- /*FE: ActS */ { 0x0F, PS_END },
- /*FF: Reset */ { 0x0F, PS_END },
-};
-
-#define GET_CN(p) (((unsigned char)(p)>>4)&0x0F)
-#define GET_CIN(p) ((unsigned char)(p)&0x0F)
-#define MIX_CN_CIN(cn, cin) \
- ((unsigned char)((((unsigned char)(cn)&0x0F)<<4)| \
- ((unsigned char)(cin)&0x0F)))
-
-static void
-init_packet(struct umidi_packet *packet)
-{
- memset(packet->buffer, 0, UMIDI_PACKET_SIZE);
- packet->state = PS_INITIAL;
-}
-
-static usbd_status
-start_input_transfer(struct umidi_endpoint *ep)
-{
- usbd_setup_xfer(ep->xfer, ep->pipe,
- (usbd_private_handle)ep,
- ep->buffer, UMIDI_PACKET_SIZE,
- USBD_NO_COPY, USBD_NO_TIMEOUT, in_intr);
- return usbd_transfer(ep->xfer);
-}
-
-static usbd_status
-start_output_transfer(struct umidi_endpoint *ep)
-{
- usbd_setup_xfer(ep->xfer, ep->pipe,
- (usbd_private_handle)ep,
- ep->buffer, UMIDI_PACKET_SIZE,
- USBD_NO_COPY, USBD_NO_TIMEOUT, out_intr);
- return usbd_transfer(ep->xfer);
-}
-
-#ifdef UMIDI_DEBUG
-#define DPR_PACKET(dir, sc, p) \
-if ((unsigned char)(p)->buffer[1]!=0xFE) \
- DPRINTFN(500, \
- ("%s: umidi packet(" #dir "): %02X %02X %02X %02X\n", \
- USBDEVNAME(sc->sc_dev), \
- (unsigned char)(p)->buffer[0], \
- (unsigned char)(p)->buffer[1], \
- (unsigned char)(p)->buffer[2], \
- (unsigned char)(p)->buffer[3]));
-#else
-#define DPR_PACKET(dir, sc, p)
-#endif
-
-static int
-out_jack_output(struct umidi_jack *out_jack, int d)
-{
- struct umidi_endpoint *ep = out_jack->endpoint;
- struct umidi_softc *sc = ep->sc;
- int error;
- int s;
-
- if (sc->sc_dying)
- return EIO;
-
- error = 0;
- if (out_jack->opened) {
- DPRINTFN(1000, ("umidi_output: ep=%p 0x%02x\n", ep, d));
- out_build_packet(out_jack->cable_number, &out_jack->packet, d);
- switch (out_jack->packet.state) {
- case PS_EXCL_0:
- case PS_END:
- DPR_PACKET(out, sc, &out_jack->packet);
- s = splusb();
- if (LIST_EMPTY(&ep->queue_head)) {
- memcpy(ep->buffer,
- out_jack->packet.buffer,
- UMIDI_PACKET_SIZE);
- start_output_transfer(ep);
- }
- if (LIST_EMPTY(&ep->queue_head))
- LIST_INSERT_HEAD(&ep->queue_head,
- out_jack, u.out.queue_entry);
- else
- LIST_INSERT_AFTER(ep->queue_tail,
- out_jack, u.out.queue_entry);
- ep->queue_tail = out_jack;
- splx(s);
- break;
- default:
- error = EINPROGRESS;
- }
- } else
- error = ENODEV;
-
- return error;
-}
-
-static void
-in_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- int cn, len, i;
- struct umidi_endpoint *ep = (struct umidi_endpoint *)priv;
- struct umidi_jack *jack;
-
- if (ep->sc->sc_dying || !ep->num_open)
- return;
-
- cn = GET_CN(ep->buffer[0]);
- len = packet_length[GET_CIN(ep->buffer[0])];
- jack = ep->jacks[cn];
- if (cn>=ep->num_jacks || !jack) {
- DPRINTF(("%s: stray umidi packet (in): %02X %02X %02X %02X\n",
- USBDEVNAME(ep->sc->sc_dev),
- (unsigned)ep->buffer[0],
- (unsigned)ep->buffer[1],
- (unsigned)ep->buffer[2],
- (unsigned)ep->buffer[3]));
- return;
- }
- if (!jack->binded || !jack->opened)
- return;
- DPR_PACKET(in, ep->sc, &jack->buffer);
- if (jack->u.in.intr) {
- for (i=0; i<len; i++) {
- (*jack->u.in.intr)(jack->arg, ep->buffer[i+1]);
- }
- }
-
- (void)start_input_transfer(ep);
-}
-
-static void
-out_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
-{
- struct umidi_endpoint *ep = (struct umidi_endpoint *)priv;
- struct umidi_softc *sc = ep->sc;
- struct umidi_jack *jack;
-
- if (sc->sc_dying || !ep->num_open)
- return;
-
- jack = LIST_FIRST(&ep->queue_head);
- if (jack && jack->opened) {
- LIST_REMOVE(jack, u.out.queue_entry);
- if (!LIST_EMPTY(&ep->queue_head)) {
- memcpy(ep->buffer,
- LIST_FIRST(&ep->queue_head)->packet.buffer,
- UMIDI_PACKET_SIZE);
- (void)start_output_transfer(ep);
- }
- if (jack->u.out.intr) {
- (*jack->u.out.intr)(jack->arg);
- }
- }
-}
-
-static void
-out_build_packet(int cable_number, struct umidi_packet *packet, uByte in)
-{
- int cin;
- uByte prev;
-
-retry:
- switch (packet->state) {
- case PS_END:
- case PS_INITIAL:
- prev = packet->buffer[1];
- memset(packet->buffer, 0, UMIDI_PACKET_SIZE);
- if (in<0x80) {
- if (prev>=0x80 && prev<0xf0) {
- /* running status */
- out_build_packet(cable_number, packet, prev);
- goto retry;
- }
- /* ??? */
- break;
- }
- if (in>=0xf0) {
- cin=packet_0xFX[in&0x0F].cin;
- packet->state=packet_0xFX[in&0x0F].next;
- } else {
- cin=(unsigned char)in>>4;
- switch (packet_length[cin]) {
- case 2:
- packet->state = PS_NORMAL_1OF2;
- break;
- case 3:
- packet->state = PS_NORMAL_1OF3;
- break;
- default:
- /* ??? */
- packet->state = PS_INITIAL;
- }
- }
- packet->buffer[0] = MIX_CN_CIN(cable_number, cin);
- packet->buffer[1] = in;
- break;
- case PS_NORMAL_1OF3:
- if (in>=0x80) { /* ??? */ packet->state = PS_END; break; }
- packet->buffer[2] = in;
- packet->state = PS_NORMAL_2OF3;
- break;
- case PS_NORMAL_2OF3:
- if (in>=0x80) { /* ??? */ packet->state = PS_END; break; }
- packet->buffer[3] = in;
- packet->state = PS_END;
- break;
- case PS_NORMAL_1OF2:
- if (in>=0x80) { /* ??? */ packet->state = PS_END; break; }
- packet->buffer[2] = in;
- packet->state = PS_END;
- break;
- case PS_EXCL_0:
- memset(packet->buffer, 0, UMIDI_PACKET_SIZE);
- if (in==0xF7) {
- packet->buffer[0] = MIX_CN_CIN(cable_number, 0x05);
- packet->buffer[1] = 0xF7;
- packet->state = PS_END;
- break;
- }
- if (in>=0x80) { /* ??? */ packet->state = PS_END; break; }
- packet->buffer[1] = in;
- packet->state = PS_EXCL_1;
- break;
- case PS_EXCL_1:
- if (in==0xF7) {
- packet->buffer[0] = MIX_CN_CIN(cable_number, 0x06);
- packet->buffer[2] = 0xF7;
- packet->state = PS_END;
- break;
- }
- if (in>=0x80) { /* ??? */ packet->state = PS_END; break; }
- packet->buffer[2] = in;
- packet->state = PS_EXCL_2;
- break;
- case PS_EXCL_2:
- if (in==0xF7) {
- packet->buffer[0] = MIX_CN_CIN(cable_number, 0x07);
- packet->buffer[3] = 0xF7;
- packet->state = PS_END;
- break;
- }
- if (in>=0x80) { /* ??? */ packet->state = PS_END; break; }
- packet->buffer[0] = MIX_CN_CIN(cable_number, 0x04);
- packet->buffer[3] = in;
- packet->state = PS_EXCL_0;
- break;
- default:
- printf("umidi: ambiguous state.\n");
- packet->state = PS_INITIAL;
- goto retry;
- }
-}
-
diff --git a/sys/dev/usb/umidi_quirks.c b/sys/dev/usb/umidi_quirks.c
deleted file mode 100644
index a7ae1ee27f4..00000000000
--- a/sys/dev/usb/umidi_quirks.c
+++ /dev/null
@@ -1,215 +0,0 @@
-/* $OpenBSD: umidi_quirks.c,v 1.1 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: umidi_quirks.c,v 1.3 2001/11/13 06:24:56 lukem Exp $ */
-
-/*
- * Copyright (c) 2001 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/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/device.h>
-#include <sys/ioctl.h>
-#include <sys/conf.h>
-#include <sys/file.h>
-#include <sys/select.h>
-#include <sys/proc.h>
-#include <sys/vnode.h>
-#include <sys/poll.h>
-#include <sys/lock.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-
-#include <dev/usb/usbdevs.h>
-#include <dev/usb/uaudioreg.h>
-#include <dev/usb/umidireg.h>
-#include <dev/usb/umidivar.h>
-#include <dev/usb/umidi_quirks.h>
-
-/*
- * quirk codes for UMIDI
- */
-
-#ifdef UMIDIQUIRK_DEBUG
-#define DPRINTF(x) if (umidiquirkdebug) printf x
-#define DPRINTFN(n,x) if (umidiquirkdebug >= (n)) printf x
-int umidiquirkdebug = 1;
-#else
-#define DPRINTF(x)
-#define DPRINTFN(n,x)
-#endif
-
-
-/*
- * YAMAHA UX-256
- * --- this is a typical yamaha device, but has a broken descriptor :-<
- */
-
-UMQ_FIXED_EP_DEF(YAMAHA, YAMAHA_UX256, ANYIFACE, 1, 1) = {
- /* out */
- { 0, 16 },
- /* in */
- { 1, 8 }
-};
-
-UMQ_DEF(YAMAHA, YAMAHA_UX256, ANYIFACE) = {
- UMQ_FIXED_EP_REG(YAMAHA, YAMAHA_UX256, ANYIFACE),
-#if 0
- UMQ_YAMAHA_REG(YAMAHA, ANYPRODUCT, ANYIFACE),
-#endif
- UMQ_TERMINATOR
-};
-
-
-/*
- * YAMAHA generic
- */
-UMQ_DEF(YAMAHA, ANYPRODUCT, ANYIFACE) = {
- UMQ_YAMAHA_REG(YAMAHA, ANYPRODUCT, ANYIFACE),
- UMQ_TERMINATOR
-};
-
-
-/*
- * ROLAND UM-1
- */
-UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM1, 2, 1, 1) = {
- /* out */
- { 0, 1 },
- /* in */
- { 1, 1 }
-};
-
-UMQ_DEF(ROLAND, ROLAND_UM1, 2) = {
- UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM1, 2),
- UMQ_TERMINATOR
-};
-
-
-/*
- * ROLAND UM-880 (native mode)
- */
-UMQ_FIXED_EP_DEF(ROLAND, ROLAND_UM880N, 0, 1, 1) = {
- /* out */
- { 0, 9 },
- /* in */
- { 1, 9 }
-};
-
-UMQ_DEF(ROLAND, ROLAND_UM880N, 0) = {
- UMQ_FIXED_EP_REG(ROLAND, ROLAND_UM880N, 0),
- UMQ_TERMINATOR
-};
-
-
-
-/*
- * quirk list
- */
-struct umidi_quirk umidi_quirklist[] = {
- UMQ_REG(YAMAHA, YAMAHA_UX256, ANYIFACE),
- UMQ_REG(YAMAHA, ANYPRODUCT, ANYIFACE),
- UMQ_REG(ROLAND, ROLAND_UM1, 2),
- UMQ_REG(ROLAND, ROLAND_UM880N, 0),
- UMQ_TERMINATOR
-};
-
-
-/*
- * quirk utilities
- */
-
-struct umidi_quirk *
-umidi_search_quirk(int vendor, int product, int ifaceno)
-{
- struct umidi_quirk *p;
- struct umq_data *q;
-
- DPRINTF(("umidi_search_quirk: v=%d, p=%d, i=%d\n",
- vendor, product, ifaceno));
-
- for (p=&umidi_quirklist[0]; p->vendor; p++) {
- DPRINTFN(10, ("\tv=%d, p=%d, i=%d",
- p->vendor, p->product, p->iface));
- if ((p->vendor==vendor || p->vendor==ANYVENDOR) &&
- (p->product==product || p->product==ANYPRODUCT) &&
- (p->iface==ifaceno || p->iface==ANYIFACE)) {
- DPRINTFN(10, (" found\n"));
- if (!p->type_mask)
- /* make quirk mask */
- for (q=p->quirks; q->type; q++)
- p->type_mask |= 1<<(q->type-1);
- return p;
- }
- DPRINTFN(10, ("\n"));
- }
-
- return NULL;
-}
-
-static char *quirk_name[] = {
- "NULL",
- "Fixed Endpoint",
- "Yamaha Specific",
-};
-
-void
-umidi_print_quirk(struct umidi_quirk *q)
-{
- struct umq_data *qd;
- if (q) {
- printf("(");
- for (qd=q->quirks; qd->type; qd++)
- printf("%s%s", quirk_name[qd->type],
- (qd+1)->type?", ":")\n");
- } else {
- printf("(genuine USB-MIDI)\n");
- }
-}
-
-void *
-umidi_get_quirk_data_from_type(struct umidi_quirk *q, u_int32_t type)
-{
- struct umq_data *qd;
- if (q) {
- for (qd=q->quirks; qd->type; qd++)
- if (qd->type == type)
- return qd->data;
- }
- return NULL;
-}
diff --git a/sys/dev/usb/umidi_quirks.h b/sys/dev/usb/umidi_quirks.h
deleted file mode 100644
index ea1f503d756..00000000000
--- a/sys/dev/usb/umidi_quirks.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/* $OpenBSD: umidi_quirks.h,v 1.1 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: umidi_quirks.h,v 1.2 2001/09/29 22:00:47 tshiozak Exp $ */
-
-/*
- * Copyright (c) 2001 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.
- */
-
-
-/*
- * quirk code for UMIDI
- */
-
-#ifndef _DEV_USB_UMIDI_QUIRKS_H_
-#define _DEV_USB_UMIDI_QUIRKS_H_
-
-struct umq_data {
- int type;
-#define UMQ_TYPE_FIXED_EP 1
-#define UMQ_TYPE_YAMAHA 2
- void *data;
-};
-
-struct umidi_quirk {
- int vendor;
- int product;
- int iface;
- struct umq_data *quirks;
- u_int32_t type_mask;
-};
-#define UMQ_ISTYPE(q, type) \
- ((q)->sc_quirk && ((q)->sc_quirk->type_mask & (1<<((type)-1))))
-
-#define UMQ_TERMINATOR { 0, }
-#define UMQ_DEF(v, p, i) \
-static struct umq_data umq_##v##_##p##_##i[]
-#define UMQ_REG(v, p, i) \
- { USB_VENDOR_##v, USB_PRODUCT_##p, i, \
- umq_##v##_##p##_##i, 0 }
-#define ANYIFACE -1
-#define ANYVENDOR -1
-#define USB_VENDOR_ANYVENDOR ANYVENDOR
-#define ANYPRODUCT -1
-#define USB_PRODUCT_ANYPRODUCT ANYPRODUCT
-
-/*
- * quirk - fixed port
- */
-
-struct umq_fixed_ep_endpoint {
- int ep;
- int num_jacks;
-};
-struct umq_fixed_ep_desc {
- int num_out_ep;
- int num_in_ep;
- struct umq_fixed_ep_endpoint *out_ep;
- struct umq_fixed_ep_endpoint *in_ep;
-};
-
-#define UMQ_FIXED_EP_DEF(v, p, i, noep, niep) \
-static struct umq_fixed_ep_endpoint \
-umq_##v##_##p##_##i##_fixed_ep_endpoints[noep+niep]; \
-static struct umq_fixed_ep_desc \
-umq_##v##_##p##_##i##_fixed_ep_desc = { \
- noep, niep, \
- &umq_##v##_##p##_##i##_fixed_ep_endpoints[0], \
- &umq_##v##_##p##_##i##_fixed_ep_endpoints[noep], \
-}; \
-static struct umq_fixed_ep_endpoint \
-umq_##v##_##p##_##i##_fixed_ep_endpoints[noep+niep]
-
-#define UMQ_FIXED_EP_REG(v, p, i) \
-{ UMQ_TYPE_FIXED_EP, (void *)&umq_##v##_##p##_##i##_fixed_ep_desc }
-
-
-/*
- * quirk - yamaha style midi I/F
- */
-#define UMQ_YAMAHA_REG(v, p, i) \
-{ UMQ_TYPE_YAMAHA, NULL }
-
-
-/* extern struct umidi_quirk umidi_quirklist[]; */
-struct umidi_quirk *umidi_search_quirk(int, int, int);
-void umidi_print_quirk(struct umidi_quirk *);
-void *umidi_get_quirk_data_from_type(struct umidi_quirk *, u_int32_t);
-
-#endif
diff --git a/sys/dev/usb/umidireg.h b/sys/dev/usb/umidireg.h
deleted file mode 100644
index f9fd240a1f6..00000000000
--- a/sys/dev/usb/umidireg.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/* $OpenBSD: umidireg.h,v 1.1 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: umidireg.h,v 1.2 2001/05/28 20:52:06 tshiozak Exp $ */
-/*
- * Copyright (c) 2001 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.
- */
-
-/* Jack Descriptor */
-#define UMIDI_MS_HEADER 0x01
-#define UMIDI_IN_JACK 0x02
-#define UMIDI_OUT_JACK 0x03
-
-/* Jack Type */
-#define UMIDI_EMBEDDED 0x01
-#define UMIDI_EXTERNAL 0x02
-
-typedef struct {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDescriptorSubtype;
- uWord bcdMSC;
- uWord wTotalLength;
-} UPACKED umidi_cs_interface_descriptor_t;
-#define UMIDI_CS_INTERFACE_DESCRIPTOR_SIZE 7
-
-typedef struct {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDescriptorSubType;
- uByte bNumEmbMIDIJack;
-} UPACKED umidi_cs_endpoint_descriptor_t;
-#define UMIDI_CS_ENDPOINT_DESCRIPTOR_SIZE 4
-
-typedef struct {
- uByte bLength;
- uByte bDescriptorType;
- uByte bDescriptorSubtype;
- uByte bJackType;
- uByte bJackID;
-} UPACKED umidi_jack_descriptor_t;
-#define UMIDI_JACK_DESCRIPTOR_SIZE 5
-
-
-#define TO_D(p) ((usb_descriptor_t *)(p))
-#define NEXT_D(desc) TO_D((caddr_t)(desc)+(desc)->bLength)
-#define TO_IFD(desc) ((usb_interface_descriptor_t *)(desc))
-#define TO_CSIFD(desc) ((umidi_cs_interface_descriptor_t *)(desc))
-#define TO_EPD(desc) ((usb_endpoint_descriptor_t *)(desc))
-#define TO_CSEPD(desc) ((umidi_cs_endpoint_descriptor_t *)(desc))
diff --git a/sys/dev/usb/umidivar.h b/sys/dev/usb/umidivar.h
deleted file mode 100644
index d11d69b0303..00000000000
--- a/sys/dev/usb/umidivar.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/* $OpenBSD: umidivar.h,v 1.1 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: umidivar.h,v 1.3 2001/02/03 18:50:32 tshiozak Exp $ */
-/*
- * Copyright (c) 2001 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.
- */
-
-/* pending MUX-MIDI packet */
-typedef enum {
- PS_EXCL_0=-2, /* put, and next state is PS_EXCL_0 */
- PS_END=-1, /* put, and next state is PS_INITIAL */
- PS_INITIAL=0, /* 0>= : not put, and state is keeped */
- PS_NORMAL_1OF3=1,
- PS_NORMAL_2OF3=2,
- PS_NORMAL_1OF2=3,
- PS_EXCL_1=4,
- PS_EXCL_2=5,
-} packet_state_t;
-
-#define UMIDI_PACKET_SIZE 4
-struct umidi_packet {
- char buffer[UMIDI_PACKET_SIZE];
- packet_state_t state;
-};
-
-/*
- * hierarchie
- *
- * <-- parent child -->
- *
- * umidi(sc) -> endpoint -> jack <- (dynamically assignable) - mididev
- * ^ | ^ |
- * +-----+ +-----+
- */
-
-/* midi device */
-struct umidi_mididev {
- struct umidi_softc *sc;
- struct device *mdev;
- /* */
- struct umidi_jack *in_jack;
- struct umidi_jack *out_jack;
- /* */
- int opened;
- int flags;
-};
-
-/* Jack Information */
-struct umidi_jack {
- struct umidi_endpoint *endpoint;
- /* */
- int cable_number;
- struct umidi_packet packet;
- void *arg;
- int binded;
- int opened;
- union {
- struct {
- void (*intr)(void *);
- LIST_ENTRY(umidi_jack) queue_entry;
- } out;
- struct {
- void (*intr)(void *, int);
- } in;
- } u;
-};
-
-#define UMIDI_MAX_EPJACKS 16
-/* endpoint data */
-struct umidi_endpoint {
- struct umidi_softc *sc;
- /* */
- int addr;
- usbd_pipe_handle pipe;
- usbd_xfer_handle xfer;
- char *buffer;
- int num_open;
- int num_jacks;
- struct umidi_jack *jacks[UMIDI_MAX_EPJACKS];
- LIST_HEAD(, umidi_jack) queue_head;
- struct umidi_jack *queue_tail;
-};
-
-/* software context */
-struct umidi_softc {
- USBBASEDEVICE sc_dev;
- usbd_device_handle sc_udev;
- usbd_interface_handle sc_iface;
- struct umidi_quirk *sc_quirk;
-
- int sc_dying;
-
- int sc_out_num_jacks;
- struct umidi_jack *sc_out_jacks;
- int sc_in_num_jacks;
- struct umidi_jack *sc_in_jacks;
- struct umidi_jack *sc_jacks;
-
- int sc_num_mididevs;
- struct umidi_mididev *sc_mididevs;
-
- int sc_out_num_endpoints;
- struct umidi_endpoint *sc_out_ep;
- int sc_in_num_endpoints;
- struct umidi_endpoint *sc_in_ep;
- struct umidi_endpoint *sc_endpoints;
-};
diff --git a/sys/dev/usb/umodem.c b/sys/dev/usb/umodem.c
index 9dbd15e2166..9a7aec9aa63 100644
--- a/sys/dev/usb/umodem.c
+++ b/sys/dev/usb/umodem.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: umodem.c,v 1.8 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: umodem.c,v 1.41 2001/11/13 06:24:56 lukem Exp $ */
+/* $OpenBSD: umodem.c,v 1.9 2002/05/07 18:29:18 nate Exp $ */
+/* $NetBSD: umodem.c,v 1.40 2001/03/25 23:02:34 augustss Exp $ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -137,7 +137,7 @@ 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, int, usb_proc_ptr);
+Static int umodem_ioctl(void *, int, u_long, caddr_t, int, struct proc *);
Static int umodem_open(void *, int portno);
Static void umodem_close(void *, int portno);
Static void umodem_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
@@ -524,7 +524,7 @@ umodem_param(void *addr, int portno, struct termios *t)
int
umodem_ioctl(void *addr, int portno, u_long cmd, caddr_t data, int flag,
- usb_proc_ptr p)
+ struct proc *p)
{
struct umodem_softc *sc = addr;
int error = 0;
diff --git a/sys/dev/usb/ums.c b/sys/dev/usb/ums.c
index d2b058ca11e..8bd88b43c81 100644
--- a/sys/dev/usb/ums.c
+++ b/sys/dev/usb/ums.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: ums.c,v 1.7 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: ums.c,v 1.55 2001/12/31 12:15:22 augustss Exp $ */
+/* $OpenBSD: ums.c,v 1.8 2002/05/07 18:29:18 nate Exp $ */
+/* $NetBSD: ums.c,v 1.49 2001/10/26 17:58:21 augustss Exp $ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -42,6 +42,8 @@
* HID spec: http://www.usb.org/developers/data/devclass/hid1_1.pdf
*/
+/* XXX complete SPUR_UP change */
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
@@ -62,7 +64,6 @@
#include <dev/usb/usbdi_util.h>
#include <dev/usb/usbdevs.h>
#include <dev/usb/usb_quirks.h>
-#include <dev/usb/uhidev.h>
#include <dev/usb/hid.h>
#include <dev/wscons/wsconsio.h>
@@ -86,13 +87,18 @@ int umsdebug = 0;
#define PS2MBUTMASK x04
#define PS2BUTMASK 0x0f
-#define MAX_BUTTONS 7 /* must not exceed size of sc_buttons */
-
struct ums_softc {
- struct uhidev sc_hdev;
-
+ USBBASEDEVICE 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;
+
+ u_char *sc_ibuf;
+ u_int8_t sc_iid;
+ int sc_isize;
struct hid_location sc_loc_x, sc_loc_y, sc_loc_z;
- struct hid_location sc_loc_btn[MAX_BUTTONS];
+ struct hid_location *sc_loc_btn;
int sc_enabled;
@@ -102,6 +108,7 @@ struct ums_softc {
#define UMS_REVZ 0x04 /* Z-axis is reversed */
int nbuttons;
+#define MAX_BUTTONS 31 /* chosen because sc_buttons is u_int32_t */
u_int32_t sc_buttons; /* mouse button status */
struct device *sc_wsmousedev;
@@ -112,11 +119,11 @@ struct ums_softc {
#define MOUSE_FLAGS_MASK (HIO_CONST|HIO_RELATIVE)
#define MOUSE_FLAGS (HIO_RELATIVE)
-Static void ums_intr(struct uhidev *addr, void *ibuf, u_int len);
+Static void ums_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
Static int ums_enable(void *);
Static void ums_disable(void *);
-Static int ums_ioctl(void *, u_long, caddr_t, int, usb_proc_ptr);
+Static int ums_ioctl(void *, u_long, caddr_t, int, struct proc *);
const struct wsmouse_accessops ums_accessops = {
ums_enable,
@@ -129,72 +136,115 @@ USB_DECLARE_DRIVER(ums);
USB_MATCH(ums)
{
USB_MATCH_START(ums, uaa);
- struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)uaa;
- int size;
+ usb_interface_descriptor_t *id;
+ int size, ret;
void *desc;
+ usbd_status err;
- uhidev_get_report_desc(uha->parent, &desc, &size);
- if (!hid_is_collection(desc, size, uha->reportid,
- HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_MOUSE)))
+ if (uaa->iface == NULL)
+ return (UMATCH_NONE);
+ id = usbd_get_interface_descriptor(uaa->iface);
+ if (id == NULL || id->bInterfaceClass != UICLASS_HID)
return (UMATCH_NONE);
- return (UMATCH_IFACECLASS);
+ 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
+ ret = UMATCH_NONE;
+
+ free(desc, M_TEMP);
+ return (ret);
}
USB_ATTACH(ums)
{
USB_ATTACH_START(ums, sc, uaa);
- struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)uaa;
+ usbd_interface_handle iface = uaa->iface;
+ usb_interface_descriptor_t *id;
+ usb_endpoint_descriptor_t *ed;
struct wsmousedev_attach_args a;
int size;
void *desc;
+ usbd_status err;
+ char devinfo[1024];
u_int32_t flags, quirks;
int i, wheel;
struct hid_location loc_btn;
+
+ sc->sc_udev = uaa->device;
+ sc->sc_iface = iface;
+ id = usbd_get_interface_descriptor(iface);
+ usbd_devinfo(uaa->device, 0, devinfo);
+ USB_ATTACH_SETUP;
+ printf("%s: %s, iclass %d/%d\n", USBDEVNAME(sc->sc_dev),
+ devinfo, id->bInterfaceClass, id->bInterfaceSubClass);
+ ed = usbd_interface2endpoint_descriptor(iface, 0);
+ if (ed == NULL) {
+ printf("%s: could not read endpoint descriptor\n",
+ USBDEVNAME(sc->sc_dev));
+ USB_ATTACH_ERROR_RETURN;
+ }
- sc->sc_hdev.sc_intr = ums_intr;
- sc->sc_hdev.sc_parent = uha->parent;
- sc->sc_hdev.sc_report_id = uha->reportid;
+ DPRINTFN(10,("ums_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",
+ USBDEVNAME(sc->sc_dev));
+ USB_ATTACH_ERROR_RETURN;
+ }
- quirks = usbd_get_quirks(uha->parent->sc_udev)->uq_flags;
+ quirks = usbd_get_quirks(uaa->device)->uq_flags;
if (quirks & UQ_MS_REVZ)
sc->flags |= UMS_REVZ;
if (quirks & UQ_SPUR_BUT_UP)
sc->flags |= UMS_SPUR_BUT_UP;
- uhidev_get_report_desc(uha->parent, &desc, &size);
+ err = usbd_read_report_desc(uaa->iface, &desc, &size, M_TEMP);
+ if (err)
+ USB_ATTACH_ERROR_RETURN;
if (!hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X),
- uha->reportid, hid_input, &sc->sc_loc_x, &flags)) {
- printf("\n%s: mouse has no X report\n",
- USBDEVNAME(sc->sc_hdev.sc_dev));
+ hid_input, &sc->sc_loc_x, &flags)) {
+ printf("%s: mouse has no X report\n", USBDEVNAME(sc->sc_dev));
USB_ATTACH_ERROR_RETURN;
}
if ((flags & MOUSE_FLAGS_MASK) != MOUSE_FLAGS) {
- printf("\n%s: X report 0x%04x not supported\n",
- USBDEVNAME(sc->sc_hdev.sc_dev), flags);
+ printf("%s: X report 0x%04x not supported\n",
+ USBDEVNAME(sc->sc_dev), flags);
USB_ATTACH_ERROR_RETURN;
}
if (!hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Y),
- uha->reportid, hid_input, &sc->sc_loc_y, &flags)) {
- printf("\n%s: mouse has no Y report\n",
- USBDEVNAME(sc->sc_hdev.sc_dev));
+ hid_input, &sc->sc_loc_y, &flags)) {
+ printf("%s: mouse has no Y report\n", USBDEVNAME(sc->sc_dev));
USB_ATTACH_ERROR_RETURN;
}
if ((flags & MOUSE_FLAGS_MASK) != MOUSE_FLAGS) {
- printf("\n%s: Y report 0x%04x not supported\n",
- USBDEVNAME(sc->sc_hdev.sc_dev), flags);
+ printf("%s: Y report 0x%04x not supported\n",
+ USBDEVNAME(sc->sc_dev), flags);
USB_ATTACH_ERROR_RETURN;
}
/* Try to guess the Z activator: first check Z, then WHEEL. */
wheel = 0;
if (hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Z),
- uha->reportid, hid_input, &sc->sc_loc_z, &flags) ||
+ hid_input, &sc->sc_loc_z, &flags) ||
(wheel = hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP,
HUG_WHEEL),
- uha->reportid, hid_input, &sc->sc_loc_z, &flags))) {
+ hid_input, &sc->sc_loc_z, &flags))) {
if ((flags & MOUSE_FLAGS_MASK) != MOUSE_FLAGS) {
sc->sc_loc_z.size = 0; /* Bad Z coord, ignore it */
} else {
@@ -208,18 +258,34 @@ USB_ATTACH(ums)
/* figure out the number of buttons */
for (i = 1; i <= MAX_BUTTONS; i++)
if (!hid_locate(desc, size, HID_USAGE2(HUP_BUTTON, i),
- uha->reportid, hid_input, &loc_btn, 0))
+ 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", USBDEVNAME(sc->sc_dev));
+ USB_ATTACH_ERROR_RETURN;
+ }
- printf(": %d button%s%s\n",
+ printf("%s: %d button%s%s\n", USBDEVNAME(sc->sc_dev),
sc->nbuttons, sc->nbuttons == 1 ? "" : "s",
sc->flags & UMS_Z ? " and Z dir." : "");
for (i = 1; i <= sc->nbuttons; i++)
hid_locate(desc, size, HID_USAGE2(HUP_BUTTON, i),
- uha->reportid, hid_input,
- &sc->sc_loc_btn[i-1], 0);
+ hid_input, &sc->sc_loc_btn[i-1], 0);
+
+ sc->sc_isize = hid_report_size(desc, size, hid_input, &sc->sc_iid);
+ sc->sc_ibuf = malloc(sc->sc_isize, M_USBDEV, M_NOWAIT);
+ if (sc->sc_ibuf == NULL) {
+ printf("%s: no memory\n", USBDEVNAME(sc->sc_dev));
+ free(sc->sc_loc_btn, M_USBDEV);
+ USB_ATTACH_ERROR_RETURN;
+ }
+
+ sc->sc_ep_addr = ed->bEndpointAddress;
+ free(desc, M_TEMP);
#ifdef USB_DEBUG
DPRINTF(("ums_attach: sc=%p\n", sc));
@@ -234,11 +300,15 @@ USB_ATTACH(ums)
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
a.accessops = &ums_accessops;
a.accesscookie = sc;
+ usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
+ USBDEV(sc->sc_dev));
+
sc->sc_wsmousedev = config_found(self, &a, wsmousedevprint);
USB_ATTACH_SUCCESS_RETURN;
@@ -274,21 +344,45 @@ USB_DETACH(ums)
/* No need to do reference counting of ums, wsmouse has all the goo. */
if (sc->sc_wsmousedev != NULL)
rv = config_detach(sc->sc_wsmousedev, flags);
+ if (rv == 0) {
+ free(sc->sc_loc_btn, M_USBDEV);
+ free(sc->sc_ibuf, M_USBDEV);
+ }
+
+ usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
+ USBDEV(sc->sc_dev));
return (rv);
}
void
-ums_intr(struct uhidev *addr, void *ibuf, u_int len)
+ums_intr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status)
{
- struct ums_softc *sc = (struct ums_softc *)addr;
+ struct ums_softc *sc = addr;
+ u_char *ibuf;
int dx, dy, dz;
u_int32_t buttons = 0;
int i;
int s;
- DPRINTFN(5,("ums_intr: len=%d\n", len));
+ DPRINTFN(5, ("ums_intr: sc=%p status=%d\n", sc, status));
+ DPRINTFN(5, ("ums_intr: data = %02x %02x %02x\n",
+ sc->sc_ibuf[0], sc->sc_ibuf[1], sc->sc_ibuf[2]));
+
+ if (status == USBD_CANCELLED)
+ return;
+
+ if (status) {
+ DPRINTF(("ums_intr: status=%d\n", status));
+ usbd_clear_endpoint_stall_async(sc->sc_intrpipe);
+ return;
+ }
+ ibuf = sc->sc_ibuf;
+ if (sc->sc_iid != 0) {
+ 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);
@@ -316,6 +410,8 @@ ums_enable(void *v)
{
struct ums_softc *sc = v;
+ usbd_status err;
+
DPRINTFN(1,("ums_enable: sc=%p\n", sc));
if (sc->sc_dying)
@@ -327,7 +423,17 @@ ums_enable(void *v)
sc->sc_enabled = 1;
sc->sc_buttons = 0;
- return (uhidev_open(&sc->sc_hdev));
+ /* 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
@@ -343,12 +449,15 @@ ums_disable(void *v)
}
#endif
+ /* Disable interrupts. */
+ usbd_abort_pipe(sc->sc_intrpipe);
+ usbd_close_pipe(sc->sc_intrpipe);
+
sc->sc_enabled = 0;
- return (uhidev_close(&sc->sc_hdev));
}
Static int
-ums_ioctl(void *v, u_long cmd, caddr_t data, int flag, usb_proc_ptr p)
+ums_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
{
switch (cmd) {
diff --git a/sys/dev/usb/uplcom.c b/sys/dev/usb/uplcom.c
index 25d26a8a871..b822f152b01 100644
--- a/sys/dev/usb/uplcom.c
+++ b/sys/dev/usb/uplcom.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: uplcom.c,v 1.3 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: uplcom.c,v 1.27 2002/03/16 16:10:19 ichiro Exp $ */
+/* $OpenBSD: uplcom.c,v 1.4 2002/05/07 18:29:18 nate Exp $ */
+/* $NetBSD: uplcom.c,v 1.20 2001/07/31 12:33:11 ichiro Exp $ */
/*
* Copyright (c) 2001 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -131,7 +131,7 @@ Static void uplcom_break(struct uplcom_softc *, int);
Static void uplcom_set_line_state(struct uplcom_softc *);
Static void uplcom_get_status(void *, int portno, u_char *lsr, u_char *msr);
#if TODO
-Static int uplcom_ioctl(void *, int, u_long, caddr_t, int, usb_proc_ptr);
+Static int uplcom_ioctl(void *, int, u_long, caddr_t, int, struct proc *);
#endif
Static int uplcom_param(void *, int, struct termios *);
Static int uplcom_open(void *, int);
@@ -148,7 +148,10 @@ struct ucom_methods uplcom_methods = {
NULL,
};
-static const struct usb_devno uplcom_devs[] = {
+static const struct uplcom_product {
+ uint16_t vendor;
+ uint16_t product;
+} uplcom_products [] = {
/* I/O DATA USB-RSAQ2 */
{ USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_RSAQ2 },
/* I/O DATA USB-RSAQ */
@@ -157,28 +160,26 @@ static const struct usb_devno uplcom_devs[] = {
{ USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC232A },
/* IOGEAR/ATEN UC-232A */
{ USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2303 },
- /* ELECOM UC-SGT */
- { USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_UCSGT },
- /* RATOC REX-USB60 */
- { USB_VENDOR_RATOC, USB_PRODUCT_RATOC_REXUSB60 },
- /* TDK USB-PHS Adapter UHA6400 */
- { USB_VENDOR_TDK, USB_PRODUCT_TDK_UHA6400 },
- /* TDK USB-PDC Adapter UPA9664 */
- { USB_VENDOR_TDK, USB_PRODUCT_TDK_UPA9664 },
+ { 0, 0 }
};
-#define uplcom_lookup(v, p) usb_lookup(uplcom_devs, v, p)
USB_DECLARE_DRIVER(uplcom);
USB_MATCH(uplcom)
{
USB_MATCH_START(uplcom, uaa);
+ int i;
if (uaa->iface != NULL)
return (UMATCH_NONE);
- return (uplcom_lookup(uaa->vendor, uaa->product) != NULL ?
- UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
+ for (i = 0; uplcom_products[i].vendor != 0; i++) {
+ if (uplcom_products[i].vendor == uaa->vendor &&
+ uplcom_products[i].product == uaa->product) {
+ return (UMATCH_VENDOR_PRODUCT);
+ }
+ }
+ return (UMATCH_NONE);
}
USB_ATTACH(uplcom)
@@ -714,7 +715,7 @@ uplcom_get_status(void *addr, int portno, u_char *lsr, u_char *msr)
#if TODO
int
uplcom_ioctl(void *addr, int portno, u_long cmd, caddr_t data, int flag,
- usb_proc_ptr p)
+ struct proc *p)
{
struct uplcom_softc *sc = addr;
int error = 0;
diff --git a/sys/dev/usb/urio.c b/sys/dev/usb/urio.c
index 89492aeb019..e01c78442c9 100644
--- a/sys/dev/usb/urio.c
+++ b/sys/dev/usb/urio.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: urio.c,v 1.7 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: urio.c,v 1.11 2002/02/11 15:11:49 augustss Exp $ */
+/* $OpenBSD: urio.c,v 1.8 2002/05/07 18:29:18 nate Exp $ */
+/* $NetBSD: urio.c,v 1.6 2001/09/25 21:08:44 jdolecek Exp $ */
/*
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -126,13 +126,6 @@ struct urio_softc {
#define URIO_RW_TIMEOUT 4000 /* ms */
-static const struct usb_devno urio_devs[] = {
- { USB_VENDOR_DIAMOND, USB_PRODUCT_DIAMOND_RIO500USB},
- { USB_VENDOR_DIAMOND2, USB_PRODUCT_DIAMOND2_RIO600USB},
- { USB_VENDOR_DIAMOND2, USB_PRODUCT_DIAMOND2_RIO800USB},
-};
-#define urio_lookup(v, p) usb_lookup(urio_devs, v, p)
-
USB_DECLARE_DRIVER(urio);
USB_MATCH(urio)
@@ -144,8 +137,15 @@ USB_MATCH(urio)
if (uaa->iface != NULL)
return (UMATCH_NONE);
- return (urio_lookup(uaa->vendor, uaa->product) != NULL ?
- UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
+ if ( ( uaa->vendor == USB_VENDOR_DIAMOND &&
+ uaa->product == USB_PRODUCT_DIAMOND_RIO500USB ) ||
+ ( uaa->vendor == USB_VENDOR_DIAMOND2 &&
+ ( uaa->product == USB_PRODUCT_DIAMOND2_RIO600USB ||
+ uaa->product == USB_PRODUCT_DIAMOND2_RIO800USB ) )
+ )
+ return (UMATCH_VENDOR_PRODUCT);
+ else
+ return (UMATCH_NONE);
}
USB_ATTACH(urio)
@@ -293,7 +293,7 @@ urio_activate(device_ptr_t self, enum devact act)
#endif
int
-urioopen(dev_t dev, int flag, int mode, usb_proc_ptr p)
+urioopen(dev_t dev, int flag, int mode, struct proc *p)
{
struct urio_softc *sc;
usbd_status err;
@@ -326,7 +326,7 @@ urioopen(dev_t dev, int flag, int mode, usb_proc_ptr p)
}
int
-urioclose(dev_t dev, int flag, int mode, usb_proc_ptr p)
+urioclose(dev_t dev, int flag, int mode, struct proc *p)
{
struct urio_softc *sc;
USB_GET_SC(urio, URIOUNIT(dev), sc);
@@ -379,7 +379,7 @@ urioread(dev_t dev, struct uio *uio, int flag)
while ((n = min(URIO_BSIZE, uio->uio_resid)) != 0) {
DPRINTFN(1, ("urioread: start transfer %d bytes\n", n));
tn = n;
- err = usbd_bulk_transfer(xfer, sc->sc_in_pipe, USBD_NO_COPY,
+ err = usbd_bulk_transfer(xfer, sc->sc_in_pipe, 0,
URIO_RW_TIMEOUT, bufp, &tn, "uriors");
if (err) {
if (err == USBD_INTERRUPTED)
@@ -441,7 +441,7 @@ uriowrite(dev_t dev, struct uio *uio, int flag)
DPRINTFN(1, ("uriowrite: transfer %d bytes\n", n));
- err = usbd_bulk_transfer(xfer, sc->sc_out_pipe, USBD_NO_COPY,
+ err = usbd_bulk_transfer(xfer, sc->sc_out_pipe, 0,
URIO_RW_TIMEOUT, bufp, &n, "uriowr");
DPRINTFN(2, ("uriowrite: err=%d\n", err));
if (err) {
@@ -468,7 +468,7 @@ uriowrite(dev_t dev, struct uio *uio, int flag)
int
-urioioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, usb_proc_ptr p)
+urioioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
{
struct urio_softc * sc;
int unit = URIOUNIT(dev);
@@ -544,7 +544,7 @@ urioioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, usb_proc_ptr p)
sc->sc_refcnt++;
err = usbd_do_request_flags(sc->sc_udev, &req, ptr, req_flags,
- &req_actlen, USBD_DEFAULT_TIMEOUT);
+ &req_actlen);
if (--sc->sc_refcnt < 0)
usb_detach_wakeup(USBDEV(sc->sc_dev));
@@ -563,7 +563,7 @@ ret:
}
int
-uriopoll(dev_t dev, int events, usb_proc_ptr p)
+uriopoll(dev_t dev, int events, struct proc *p)
{
return (0);
}
diff --git a/sys/dev/usb/usb.c b/sys/dev/usb/usb.c
index 3cc61c6bb74..cd8e4d0aa93 100644
--- a/sys/dev/usb/usb.c
+++ b/sys/dev/usb/usb.c
@@ -1,8 +1,9 @@
-/* $OpenBSD: usb.c,v 1.18 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: usb.c,v 1.69 2002/04/23 06:34:11 augustss Exp $ */
+/* $OpenBSD: usb.c,v 1.19 2002/05/07 18:29:18 nate Exp $ */
+/* $NetBSD: usb.c,v 1.53 2001/01/23 17:04:30 augustss Exp $ */
+/* $FreeBSD: src/sys/dev/usb/usb.c,v 1.20 1999/11/17 22:33:46 n_hibma Exp $ */
/*
- * Copyright (c) 1998, 2002 The NetBSD Foundation, Inc.
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@@ -52,7 +53,6 @@
#include <sys/kthread.h>
#include <sys/proc.h>
#include <sys/conf.h>
-#include <sys/fcntl.h>
#include <sys/poll.h>
#include <sys/select.h>
#include <sys/vnode.h>
@@ -79,7 +79,7 @@ int uhcidebug;
#ifdef OHCI_DEBUG
int ohcidebug;
#endif
-/*
+/*
* 0 - do usual exploration
* 1 - do not use timeout exploration
* >1 - do no exploration
@@ -95,31 +95,30 @@ struct usb_softc {
usbd_bus_handle sc_bus; /* USB controller */
struct usbd_port sc_port; /* dummy port for root hub */
- usb_proc_ptr sc_event_thread;
+ TAILQ_HEAD(, usb_task) sc_tasks;
+ struct proc *sc_event_thread;
+
+ struct usb_task sc_exp_task;
char sc_dying;
};
-TAILQ_HEAD(, usb_task) usb_all_tasks;
-
cdev_decl(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 usb_proc_ptr usb_task_thread_proc = NULL;
#define USB_MAX_EVENTS 100
struct usb_event_q {
struct usb_event ue;
SIMPLEQ_ENTRY(usb_event_q) next;
};
-Static SIMPLEQ_HEAD(, usb_event_q) usb_events =
+Static SIMPLEQ_HEAD(, usb_event_q) usb_events =
SIMPLEQ_HEAD_INITIALIZER(usb_events);
Static int usb_nevents = 0;
Static struct selinfo usb_selevent;
-Static usb_proc_ptr usb_async_proc; /* process that wants USB SIGIO */
+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 *);
@@ -141,29 +140,22 @@ USB_ATTACH(usb)
usbd_device_handle dev;
usbd_status err;
int usbrev;
- int speed;
struct usb_event ue;
-
+
DPRINTF(("usbd_attach\n"));
usbd_init();
sc->sc_bus = aux;
sc->sc_bus->usbctl = sc;
sc->sc_port.power = USB_MAX_POWER;
+ TAILQ_INIT(&sc->sc_tasks);
+
+ usb_init_task(&sc->sc_exp_task, usb_discover, sc);
usbrev = sc->sc_bus->usbrev;
printf(": USB revision %s", usbrev_str[usbrev]);
- 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:
+ if (usbrev != USBREV_1_0 && usbrev != USBREV_1_1) {
printf(", not supported\n");
- sc->sc_dying = 1;
USB_ATTACH_ERROR_RETURN;
}
printf("\n");
@@ -175,34 +167,19 @@ USB_ATTACH(usb)
ue.u.ue_ctrlr.ue_bus = USBDEVUNIT(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", USBDEVNAME(sc->sc_dev));
- sc->sc_dying = 1;
- USB_ATTACH_ERROR_RETURN;
- }
-#else
- usb_callout_init(&sc->sc_bus->softi);
-#endif
-#endif
-
- err = usbd_new_device(USBDEV(sc->sc_dev), sc->sc_bus, 0, speed, 0,
+ err = usbd_new_device(USBDEV(sc->sc_dev), sc->sc_bus, 0, 0, 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",
+ printf("%s: root device is not a hub\n",
USBDEVNAME(sc->sc_dev));
USB_ATTACH_ERROR_RETURN;
}
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.
@@ -211,8 +188,8 @@ USB_ATTACH(usb)
dev->hub->explore(sc->sc_bus->root_hub);
#endif
} else {
- printf("%s: root hub problem, error=%d\n",
- USBDEVNAME(sc->sc_dev), err);
+ printf("%s: root hub problem, error=%d\n",
+ USBDEVNAME(sc->sc_dev), err);
sc->sc_dying = 1;
}
if (cold)
@@ -229,7 +206,6 @@ void
usb_create_event_thread(void *arg)
{
struct usb_softc *sc = arg;
- static int created = 0;
if (usb_kthread_create1(usb_event_thread, sc, &sc->sc_event_thread,
"%s", sc->sc_dev.dv_xname)) {
@@ -237,47 +213,39 @@ usb_create_event_thread(void *arg)
sc->sc_dev.dv_xname);
panic("usb_create_event_thread");
}
- if (!created) {
- created = 1;
- TAILQ_INIT(&usb_all_tasks);
- if (usb_kthread_create1(usb_task_thread, NULL,
- &usb_task_thread_proc, "usbtask")) {
- 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
+ * Add a task to be performed by the event thread. This function can be
* called from any context and the task will be executed in a process
* context ASAP.
*/
void
usb_add_task(usbd_device_handle dev, struct usb_task *task)
{
+ struct usb_softc *sc = dev->bus->usbctl;
int s;
s = splusb();
if (!task->onqueue) {
- DPRINTFN(2,("usb_add_task: task=%p\n", task));
- TAILQ_INSERT_TAIL(&usb_all_tasks, task, next);
+ DPRINTFN(2,("usb_add_task: sc=%p task=%p\n", sc, task));
+ TAILQ_INSERT_TAIL(&sc->sc_tasks, task, next);
task->onqueue = 1;
- } else {
- DPRINTFN(3,("usb_add_task: task=%p on q\n", task));
- }
- wakeup(&usb_all_tasks);
+ } else
+ DPRINTFN(3,("usb_add_task: sc=%p task=%p on q\n", sc, task));
+ wakeup(&sc->sc_tasks);
splx(s);
}
void
usb_rem_task(usbd_device_handle dev, struct usb_task *task)
{
+ struct usb_softc *sc = dev->bus->usbctl;
int s;
s = splusb();
if (task->onqueue) {
- TAILQ_REMOVE(&usb_all_tasks, task, next);
+ TAILQ_REMOVE(&sc->sc_tasks, task, next);
task->onqueue = 0;
}
splx(s);
@@ -287,37 +255,31 @@ void
usb_event_thread(void *arg)
{
struct usb_softc *sc = arg;
+ struct usb_task *task;
+ int s;
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.
- * XXX It would be nicer to do this with a tsleep(), but I don't
- * know how to synchronize the creation of the threads so it
- * will work.
- */
- usb_delay_ms(sc->sc_bus, 500);
-
/* Make sure first discover does something. */
sc->sc_bus->needs_explore = 1;
usb_discover(sc);
config_pending_decr();
while (!sc->sc_dying) {
-#ifdef USB_DEBUG
- if (usb_noexplore < 2)
-#endif
- usb_discover(sc);
-#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"));
+ s = splusb();
+ task = TAILQ_FIRST(&sc->sc_tasks);
+ if (task == NULL) {
+ tsleep(&sc->sc_tasks, PWAIT, "usbevt", 0);
+ task = TAILQ_FIRST(&sc->sc_tasks);
+ }
+ DPRINTFN(2,("usb_event_thread: woke up task=%p\n", task));
+ if (task != NULL && !sc->sc_dying) {
+ TAILQ_REMOVE(&sc->sc_tasks, task, next);
+ task->onqueue = 0;
+ splx(s);
+ task->fun(task->arg);
+ } else
+ splx(s);
}
sc->sc_event_thread = NULL;
@@ -328,32 +290,6 @@ usb_event_thread(void *arg)
kthread_exit(0);
}
-void
-usb_task_thread(void *arg)
-{
- struct usb_task *task;
- int s;
-
- DPRINTF(("usb_task_thread: start\n"));
-
- s = splusb();
- for (;;) {
- task = TAILQ_FIRST(&usb_all_tasks);
- if (task == NULL) {
- tsleep(&usb_all_tasks, PWAIT, "usbtsk", 0);
- task = TAILQ_FIRST(&usb_all_tasks);
- }
- DPRINTFN(2,("usb_task_thread: woke up task=%p\n", task));
- if (task != NULL) {
- TAILQ_REMOVE(&usb_all_tasks, task, next);
- task->onqueue = 0;
- splx(s);
- task->fun(task->arg);
- s = splusb();
- }
- }
-}
-
int
usbctlprint(void *aux, const char *pnp)
{
@@ -366,7 +302,7 @@ usbctlprint(void *aux, const char *pnp)
#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */
int
-usbopen(dev_t dev, int flag, int mode, usb_proc_ptr p)
+usbopen(dev_t dev, int flag, int mode, struct proc *p)
{
int unit = minor(dev);
struct usb_softc *sc;
@@ -421,7 +357,7 @@ usbread(dev_t dev, struct uio *uio, int flag)
}
int
-usbclose(dev_t dev, int flag, int mode, usb_proc_ptr p)
+usbclose(dev_t dev, int flag, int mode, struct proc *p)
{
int unit = minor(dev);
@@ -434,7 +370,7 @@ usbclose(dev_t dev, int flag, int mode, usb_proc_ptr p)
}
int
-usbioctl(dev_t devt, u_long cmd, caddr_t data, int flag, usb_proc_ptr p)
+usbioctl(dev_t devt, u_long cmd, caddr_t data, int flag, struct proc *p)
{
struct usb_softc *sc;
int unit = minor(devt);
@@ -444,7 +380,7 @@ usbioctl(dev_t devt, u_long cmd, caddr_t data, int flag, usb_proc_ptr p)
case FIONBIO:
/* All handled in the upper FS layer. */
return (0);
-
+
case FIOASYNC:
if (*(int *)data)
usb_async_proc = p;
@@ -465,8 +401,6 @@ usbioctl(dev_t devt, u_long cmd, caddr_t data, int flag, usb_proc_ptr p)
switch (cmd) {
#ifdef USB_DEBUG
case USB_SETDEBUG:
- if (!(flag & FWRITE))
- return (EBADF);
usbdebug = ((*(int *)data) & 0x000000ff);
#ifdef UHCI_DEBUG
uhcidebug = ((*(int *)data) & 0x0000ff00) >> 8;
@@ -475,7 +409,7 @@ usbioctl(dev_t devt, u_long cmd, caddr_t data, int flag, usb_proc_ptr p)
ohcidebug = ((*(int *)data) & 0x00ff0000) >> 16;
#endif
break;
-#endif /* USB_DEBUG */
+#endif
case USB_REQUEST:
{
struct usb_ctl_request *ur = (void *)data;
@@ -487,13 +421,10 @@ usbioctl(dev_t devt, u_long cmd, caddr_t data, int flag, usb_proc_ptr p)
usbd_status err;
int error = 0;
- if (!(flag & FWRITE))
- return (EBADF);
-
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 ||
+ if (addr < 0 || addr >= USB_MAX_DEVICES ||
sc->sc_bus->devices[addr] == 0)
return (EINVAL);
if (len != 0) {
@@ -505,7 +436,7 @@ usbioctl(dev_t devt, u_long cmd, caddr_t data, int flag, usb_proc_ptr p)
uio.uio_offset = 0;
uio.uio_segflg = UIO_USERSPACE;
uio.uio_rw =
- ur->ucr_request.bmRequestType & UT_READ ?
+ ur->ucr_request.bmRequestType & UT_READ ?
UIO_READ : UIO_WRITE;
uio.uio_procp = p;
ptr = malloc(len, M_TEMP, M_WAITOK);
@@ -516,8 +447,8 @@ usbioctl(dev_t devt, u_long cmd, caddr_t data, int flag, usb_proc_ptr p)
}
}
err = usbd_do_request_flags(sc->sc_bus->devices[addr],
- &ur->ucr_request, ptr, ur->ucr_flags, &ur->ucr_actlen,
- USBD_DEFAULT_TIMEOUT);
+ &ur->ucr_request, ptr, ur->ucr_flags,
+ &ur->ucr_actlen);
if (err) {
error = EIO;
goto ret;
@@ -561,21 +492,21 @@ usbioctl(dev_t devt, u_long cmd, caddr_t data, int flag, usb_proc_ptr p)
}
int
-usbpoll(dev_t dev, int events, usb_proc_ptr p)
+usbpoll(dev_t dev, int events, struct proc *p)
{
int revents, mask, s;
if (minor(dev) == USB_DEV_MINOR) {
revents = 0;
mask = POLLIN | POLLRDNORM;
-
+
s = splusb();
if (events & mask && usb_nevents > 0)
revents |= events & mask;
if (revents == 0 && events & mask)
selrecord(p, &usb_selevent);
splx(s);
-
+
return (revents);
} else {
return (ENXIO);
@@ -593,7 +524,7 @@ usb_discover(void *v)
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.
@@ -609,7 +540,7 @@ usb_needs_explore(usbd_device_handle dev)
{
DPRINTFN(2,("usb_needs_explore\n"));
dev->bus->needs_explore = 1;
- wakeup(&dev->bus->needs_explore);
+ usb_add_task(dev, &dev->bus->usbctl->sc_exp_task);
}
/* Called at splusb() */
@@ -621,13 +552,6 @@ usb_get_next_event(struct usb_event *ue)
if (usb_nevents <= 0)
return (0);
ueq = SIMPLEQ_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;
SIMPLEQ_REMOVE_HEAD(&usb_events, ueq, next);
free(ueq, M_USBDEV);
@@ -650,7 +574,7 @@ usbd_add_drv_event(int type, usbd_device_handle udev, device_ptr_t dev)
struct usb_event ue;
ue.u.ue_driver.ue_cookie = udev->cookie;
- strncpy(ue.u.ue_driver.ue_devname, USBDEVPTRNAME(dev),
+ strncpy(ue.u.ue_driver.ue_devname, USBDEVPTRNAME(dev),
sizeof ue.u.ue_driver.ue_devname);
usb_add_event(type, &ue);
}
@@ -683,26 +607,10 @@ usb_add_event(int type, struct usb_event *uep)
psignal(usb_async_proc, SIGIO);
splx(s);
}
-
void
-usb_schedsoftintr(usbd_bus_handle bus)
+usb_schedsoftintr(struct usbd_bus *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 (!usb_callout_pending(bus->softi))
- usb_callout(bus->softi, 0, bus->methods->soft_intr,
- bus);
-#endif /* __HAVE_GENERIC_SOFT_INTERRUPTS */
- }
-#else
bus->methods->soft_intr(bus);
-#endif /* USB_USE_SOFTINTR */
}
int
@@ -719,8 +627,7 @@ usb_activate(device_ptr_t self, enum devact act)
case DVACT_DEACTIVATE:
sc->sc_dying = 1;
- if (dev != NULL && dev->cdesc != NULL &&
- dev->subdevs != NULL) {
+ if (dev && dev->cdesc && dev->subdevs) {
for (i = 0; dev->subdevs[i]; i++)
rv |= config_deactivate(dev->subdevs[i]);
}
@@ -740,12 +647,12 @@ usb_detach(device_ptr_t self, int flags)
sc->sc_dying = 1;
/* Make all devices disconnect. */
- if (sc->sc_port.device != NULL)
+ if (sc->sc_port.device)
usb_disconnect_port(&sc->sc_port, self);
/* Kill off event thread. */
- if (sc->sc_event_thread != NULL) {
- wakeup(&sc->sc_bus->needs_explore);
+ if (sc->sc_event_thread) {
+ wakeup(&sc->sc_tasks);
if (tsleep(sc, PWAIT, "usbdet", hz * 60))
printf("%s: event thread didn't die\n",
USBDEVNAME(sc->sc_dev));
@@ -754,17 +661,6 @@ usb_detach(device_ptr_t self, int flags)
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
- usb_uncallout(sc->sc_bus->softi, bus->methods->soft_intr, bus);
-#endif
-#endif
-
ue.u.ue_ctrlr.ue_bus = USBDEVUNIT(sc->sc_dev);
usb_add_event(USB_EVENT_CTRLR_DETACH, &ue);
diff --git a/sys/dev/usb/usb.h b/sys/dev/usb/usb.h
index c5dc2e8a72a..89121f65dec 100644
--- a/sys/dev/usb/usb.h
+++ b/sys/dev/usb/usb.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: usb.h,v 1.16 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: usb.h,v 1.65 2002/02/26 10:27:49 augustss Exp $ */
+/* $OpenBSD: usb.h,v 1.17 2002/05/07 18:29:18 nate Exp $ */
+/* $NetBSD: usb.h,v 1.52 2001/07/23 15:17:50 nathanw Exp $ */
/* $FreeBSD: src/sys/dev/usb/usb.h,v 1.14 1999/11/17 22:33:46 n_hibma Exp $ */
/*
@@ -48,18 +48,23 @@
#if defined(__NetBSD__) || defined(__OpenBSD__)
#include <sys/ioctl.h>
-#endif
-#if defined(__FreeBSD__)
-/* 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 */
-#endif
#if defined(_KERNEL)
#include <dev/usb/usb_port.h>
#endif /* _KERNEL */
-#define USB_STACK_VERSION 2
+#elif defined(__FreeBSD__)
+#if defined(KERNEL)
+#include <sys/malloc.h>
+
+MALLOC_DECLARE(M_USB);
+MALLOC_DECLARE(M_USBDEV);
+MALLOC_DECLARE(M_USBHC);
+
+#include <dev/usb/usb_port.h>
+#endif /* KERNEL */
+#endif /* __FreeBSD__ */
+
#define USB_MAX_DEVICES 128
#define USB_START_ADDR 0
@@ -154,10 +159,6 @@ typedef struct {
#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
@@ -174,13 +175,9 @@ typedef struct {
/* 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;
@@ -191,8 +188,6 @@ 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;
@@ -274,10 +269,6 @@ typedef struct {
/* 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
@@ -294,29 +285,21 @@ typedef struct {
#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
+#define UHD_PWR 0x03
+#define UHD_PWR_GANGED 0x00
+#define UHD_PWR_INDIVIDUAL 0x01
+#define UHD_PWR_NO_SWITCH 0x02
+#define UHD_COMPOUND 0x04
+#define UHD_OC 0x18
+#define UHD_OC_GLOBAL 0x00
+#define UHD_OC_INDIVIDUAL 0x08
+#define UHD_OC_NONE 0x10
uByte bPwrOn2PwrGood; /* delay in 2 ms units */
#define UHD_PWRON_FACTOR 2
uByte bHubContrCurrent;
@@ -328,32 +311,6 @@ typedef struct {
#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
@@ -378,9 +335,6 @@ typedef struct {
#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
@@ -395,9 +349,6 @@ typedef struct {
#define UDCLASS_HID 0x00
#define UDCLASS_HUB 0x09
#define UDSUBCLASS_HUB 0
-#define UDPROTO_FSHUB 0
-#define UDPROTO_HSHUBSTT 1
-#define UDPROTO_HSHUBMTT 2
#define UDCLASS_MASS 0x00
/* Interface class codes */
@@ -439,14 +390,11 @@ typedef struct {
#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 UIPROTO_MASS_BBB 2
+#define UIPROTO_MASS_BBB_P 80 /* 'P' for the Iomega Zip drive */
#define UICLASS_HUB 0x09
#define UISUBCLASS_HUB 0
-#define UIPROTO_FSHUB 0
-#define UIPROTO_HSHUBSTT 0 /* Yes, same as previous */
-#define UIPROTO_HSHUBMTT 1
#define UICLASS_CDC_DATA 0x0a
#define UISUBCLASS_DATA 0
@@ -467,10 +415,6 @@ typedef struct {
#define UICLASS_FIRM_UPD 0x0c
#define UICLASS_APPL_SPEC 0xfe
-#define UISUBCLASS_FIRMWARE_DOWNLOAD 1
-#define UISUBCLASS_IRDA 2
-#define UIPROTO_IRDA 0
-
#define UICLASS_VENDOR 0xff
@@ -486,7 +430,6 @@ typedef struct {
#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_SETTLE 10 /* ms */
#define USB_PORT_POWERUP_DELAY 100 /* ms */
#define USB_SET_ADDRESS_SETTLE 2 /* ms */
@@ -497,9 +440,8 @@ typedef struct {
#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 50 /* ms */
-#define USB_PORT_POWERUP_DELAY 300 /* ms */
+#define USB_PORT_POWERUP_DELAY 200 /* ms */
#define USB_SET_ADDRESS_SETTLE 10 /* ms */
#define USB_RESUME_DELAY (50*5) /* ms */
#define USB_RESUME_WAIT 50 /* ms */
@@ -591,10 +533,7 @@ struct usb_device_info {
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
+ u_int8_t udi_lowspeed;
int udi_power; /* power consumption in mA, 0 if selfpowered */
int udi_nports;
char udi_devnames[USB_MAX_DEVNAMES][USB_MAX_DEVNAMELEN];
@@ -624,7 +563,6 @@ struct usb_event {
#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 {
@@ -650,7 +588,6 @@ struct usb_event {
#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)
diff --git a/sys/dev/usb/usb_port.h b/sys/dev/usb/usb_port.h
index 66ceaddaf3f..bb15013ec29 100644
--- a/sys/dev/usb/usb_port.h
+++ b/sys/dev/usb/usb_port.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: usb_port.h,v 1.36 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: usb_port.h,v 1.54 2002/03/28 21:49:19 ichiro Exp $ */
+/* $OpenBSD: usb_port.h,v 1.37 2002/05/07 18:29:18 nate Exp $ */
+/* $NetBSD: usb_port.h,v 1.44 2001/05/14 20:35:29 bouyer Exp $ */
/* $FreeBSD: src/sys/dev/usb/usb_port.h,v 1.21 1999/11/17 22:33:47 n_hibma Exp $ */
/*
@@ -57,7 +57,6 @@
#ifdef USB_DEBUG
#define UKBD_DEBUG 1
-#define UHIDEV_DEBUG 1
#define UHID_DEBUG 1
#define OHCI_DEBUG 1
#define UGEN_DEBUG 1
@@ -66,36 +65,26 @@
#define ULPT_DEBUG 1
#define UCOM_DEBUG 1
#define UPLCOM_DEBUG 1
-#define UMCT_DEBUG 1
#define UMODEM_DEBUG 1
#define UAUDIO_DEBUG 1
#define AUE_DEBUG 1
#define CUE_DEBUG 1
#define KUE_DEBUG 1
-#define URL_DEBUG 1
#define UMASS_DEBUG 1
#define UVISOR_DEBUG 1
#define UPL_DEBUG 1
#define UZCOM_DEBUG 1
#define URIO_DEBUG 1
#define UFTDI_DEBUG 1
+#define UMCT_DEBUG 1
#define USCANNER_DEBUG 1
#define USSCANNER_DEBUG 1
-#define EHCI_DEBUG 1
-#define UIRDA_DEBUG 1
-#define USTIR_DEBUG 1
-#define UISDATA_DEBUG 1
-#define UDSBR_DEBUG 1
#define Static
#else
#define Static static
#endif
-#define SCSI_MODE_SENSE MODE_SENSE
-
-#define UMASS_ATAPISTR "atapibus"
-
-typedef struct proc *usb_proc_ptr;
+#define SCSI_MODE_SENSE MODE_SENSE
typedef struct device *device_ptr_t;
#define USBBASEDEVICE struct device
@@ -115,11 +104,8 @@ typedef struct device *device_ptr_t;
typedef struct callout usb_callout_t;
#define usb_callout_init(h) callout_init(&(h))
#define usb_callout(h, t, f, d) callout_reset(&(h), (t), (f), (d))
-#define usb_callout_pending(h) callout_pending(&(h))
#define usb_uncallout(h, f, d) callout_stop(&(h))
-#define usb_lockmgr(l, f, sl, p) lockmgr((l), (f), (sl))
-
#define usb_kthread_create1 kthread_create1
#define usb_kthread_create kthread_create
@@ -147,13 +133,21 @@ struct cfattach __CONCAT(dname,_ca) = { \
}
#define USB_MATCH(dname) \
-int __CONCAT(dname,_match)(struct device *parent, struct cfdata *match, void *aux)
+int \
+__CONCAT(dname,_match)(parent, match, aux) \
+ struct device *parent; \
+ struct cfdata *match; \
+ void *aux;
#define USB_MATCH_START(dname, uaa) \
struct usb_attach_arg *uaa = aux
#define USB_ATTACH(dname) \
-void __CONCAT(dname,_attach)(struct device *parent, struct device *self, void *aux)
+void \
+__CONCAT(dname,_attach)(parent, self, aux) \
+ struct device *parent; \
+ struct device *self; \
+ void *aux;
#define USB_ATTACH_START(dname, sc, uaa) \
struct __CONCAT(dname,_softc) *sc = \
@@ -167,7 +161,10 @@ void __CONCAT(dname,_attach)(struct device *parent, struct device *self, void *a
#define USB_ATTACH_SETUP printf("\n")
#define USB_DETACH(dname) \
-int __CONCAT(dname,_detach)(struct device *self, int flags)
+int \
+__CONCAT(dname,_detach)(self, flags) \
+ struct device *self; \
+ int flags;
#define USB_DETACH_START(dname, sc) \
struct __CONCAT(dname,_softc) *sc = \
@@ -187,17 +184,12 @@ int __CONCAT(dname,_detach)(struct device *self, int flags)
(config_found_sm(parent, args, print, sub))
#elif defined(__OpenBSD__)
+#include <sys/timeout.h>
/*
* OpenBSD
*/
-#include <sys/timeout.h>
-
-#define USB_USE_SOFTINTR
-
-#define USB_DEBUG
#ifdef USB_DEBUG
#define UKBD_DEBUG 1
-#define UHIDEV_DEBUG 1
#define UHID_DEBUG 1
#define OHCI_DEBUG 1
#define UGEN_DEBUG 1
@@ -205,8 +197,6 @@ int __CONCAT(dname,_detach)(struct device *self, int flags)
#define UHUB_DEBUG 1
#define ULPT_DEBUG 1
#define UCOM_DEBUG 1
-#define UPLCOM_DEBUG 1
-#define UMCT_DEBUG 1
#define UMODEM_DEBUG 1
#define UAUDIO_DEBUG 1
#define AUE_DEBUG 1
@@ -218,49 +208,33 @@ int __CONCAT(dname,_detach)(struct device *self, int flags)
#define UZCOM_DEBUG 1
#define URIO_DEBUG 1
#define UFTDI_DEBUG 1
+#define UMCT_DEBUG 1
#define USCANNER_DEBUG 1
#define USSCANNER_DEBUG 1
-#define EHCI_DEBUG 1
-#define UISDATA_DEBUG 1
-#define UDSBR_DEBUG 1
#endif
#define Static
-#define UMASS_ATAPISTR "atapiscsi"
-
-/* periph_quirks */
-#define PQUIRK_AUTOSAVE 0x00000001 /* do implicit SAVE POINTERS */
-#define PQUIRK_NOSYNC 0x00000002 /* does not grok SDTR */
-#define PQUIRK_NOWIDE 0x00000004 /* does not grok WDTR */
-#define PQUIRK_NOTAG 0x00000008 /* does not grok tagged cmds */
-#define PQUIRK_NOLUNS 0x00000010 /* DTWT with LUNs */
-#define PQUIRK_FORCELUNS 0x00000020 /* prehistoric device groks
- LUNs */
-#define PQUIRK_NOMODESENSE 0x00000040 /* device doesn't do MODE SENSE
- properly */
-#define PQUIRK_NOSTARTUNIT 0x00000080 /* do not issue START UNIT */
-#define PQUIRK_NOSYNCCACHE 0x00000100 /* do not issue SYNC CACHE */
-#define PQUIRK_CDROM 0x00000200 /* device is a CD-ROM, no
- matter what else it claims */
-#define PQUIRK_LITTLETOC 0x00000400 /* audio TOC is little-endian */
-#define PQUIRK_NOCAPACITY 0x00000800 /* no READ CD CAPACITY */
-#define PQUIRK_NOTUR 0x00001000 /* no TEST UNIT READY */
-#define PQUIRK_NODOORLOCK 0x00002000 /* can't lock door */
-#define PQUIRK_NOSENSE 0x00004000 /* can't REQUEST SENSE */
-#define PQUIRK_ONLYBIG 0x00008000 /* only use SCSI_{R,W}_BIG */
-#define PQUIRK_BYTE5_ZERO 0x00010000 /* byte5 in capacity is wrong */
-#define PQUIRK_NO_FLEX_PAGE 0x00020000 /* does not support flex geom
- page */
-#define PQUIRK_NOBIGMODESENSE 0x00040000 /* has no big mode-sense op */
-#define PQUIRK_CAP_SYNC 0x00080000 /* SCSI1 device with sync op */
-
-typedef struct proc *usb_proc_ptr;
-
#define UCOMBUSCF_PORTNO -1
#define UCOMBUSCF_PORTNO_DEFAULT -1
-#define UHIDBUSCF_REPORTID -1
-#define UHIDBUSCF_REPORTID_DEFAULT -1
+
+#define SCSI_MODE_SENSE MODE_SENSE
+#define XS_STS_DONE ITSDONE
+#define XS_CTL_POLL SCSI_POLL
+#define XS_CTL_DATA_IN SCSI_DATA_IN
+#define XS_CTL_DATA_OUT SCSI_DATA_OUT
+#define scsipi_adapter scsi_adapter
+#define scsipi_cmd scsi_cmd
+#define scsipi_device scsi_device
+#define scsipi_done scsi_done
+#define scsipi_link scsi_link
+#define scsipi_minphys scsi_minphys
+#define scsipi_sense scsi_sense
+#define scsipi_xfer scsi_xfer
+#define show_scsipi_xs show_scsi_xs
+#define show_scsipi_cmd show_scsi_cmd
+#define xs_control flags
+#define xs_status status
#define bswap32(x) swap32(x)
#define bswap16(x) swap16(x)
@@ -327,7 +301,6 @@ typedef struct timeout usb_callout_t;
#define usb_callout_init(h)
#define usb_callout(h, t, f, d) \
{ timeout_set(&(h), (f), (d)); timeout_add(&(h), (t)); }
-#define usb_callout_pending(h) timeout_pending(&(h))
#define usb_uncallout(h, f, d) timeout_del(&(h))
#define usb_lockmgr(l, f, sl, p) lockmgr((l), (f), (sl), (p))
@@ -408,15 +381,6 @@ __CONCAT(dname,_detach)(self, flags) \
#include "opt_usb.h"
-#if defined(_KERNEL)
-#include <sys/malloc.h>
-
-MALLOC_DECLARE(M_USB);
-MALLOC_DECLARE(M_USBDEV);
-MALLOC_DECLARE(M_USBHC);
-
-#endif
-
#define Static
#define USBVERBOSE
@@ -431,15 +395,14 @@ MALLOC_DECLARE(M_USBHC);
#define DECLARE_USB_DMA_T typedef void * usb_dma_t
-typedef struct proc *usb_proc_ptr;
-
/* XXX Change this when FreeBSD has memset
*/
#define memcpy(d, s, l) bcopy((s),(d),(l))
#define memset(d, v, l) bzero((d),(l))
#define bswap32(x) swap32(x)
-#define kthread_create1(f, s, p, a0, a1) \
- kthread_create((f), (s), (p), RFHIGHPID, (a0), (a1))
+#define usb_kthread_create1(function, sc, priv, string, name)
+#define usb_kthread_create(create_function, sc)
+#define usb_kthread_exit(err)
typedef struct callout_handle usb_callout_t;
#define usb_callout_init(h) callout_handle_init(&(h))
@@ -453,8 +416,6 @@ typedef struct callout_handle usb_callout_t;
#define powerhook_disestablish(hdl)
#define PWR_RESUME 0
-#define config_detach(dev, flag) device_delete_child(device_get_parent(dev), dev)
-
typedef struct malloc_type *usb_malloc_type;
#define USB_DECLARE_DRIVER_INIT(dname, init) \
diff --git a/sys/dev/usb/usb_quirks.c b/sys/dev/usb/usb_quirks.c
index 0abf050b1a6..30dde29cafd 100644
--- a/sys/dev/usb/usb_quirks.c
+++ b/sys/dev/usb/usb_quirks.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: usb_quirks.c,v 1.11 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: usb_quirks.c,v 1.39 2001/11/13 06:24:56 lukem Exp $ */
+/* $OpenBSD: usb_quirks.c,v 1.12 2002/05/07 18:29:18 nate Exp $ */
+/* $NetBSD: usb_quirks.c,v 1.38 2001/04/15 10:26:36 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/usb_quirks.c,v 1.13 1999/11/17 22:33:47 n_hibma Exp $ */
/*
@@ -74,6 +74,8 @@ Static const struct usbd_quirk_entry {
{ 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_MCT, USB_PRODUCT_MCT_SITECOM_USB232, 0x102, { UQ_BUS_POWERED }},
+ { USB_VENDOR_MCT, USB_PRODUCT_MCT_DU_H3SP_USB232, 0x102, { UQ_BUS_POWERED }},
{ USB_VENDOR_METRICOM, USB_PRODUCT_METRICOM_RICOCHET_GS,
0x100, { UQ_ASSUME_CM_OVER_DATA | UQ_NO_STRINGS }},
{ USB_VENDOR_TI, USB_PRODUCT_TI_UTUSB41, 0x110, { UQ_POWER_CLAIM }},
diff --git a/sys/dev/usb/usb_subr.c b/sys/dev/usb/usb_subr.c
index 66cb1fd6248..2845b2ddafc 100644
--- a/sys/dev/usb/usb_subr.c
+++ b/sys/dev/usb/usb_subr.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: usb_subr.c,v 1.20 2002/05/07 18:08:04 nate Exp $ */
-/* $NetBSD: usb_subr.c,v 1.98 2002/02/20 20:30:13 christos Exp $ */
+/* $OpenBSD: usb_subr.c,v 1.21 2002/05/07 18:29:18 nate Exp $ */
+/* $NetBSD: usb_subr.c,v 1.87 2001/08/15 00:04:59 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/usb_subr.c,v 1.18 1999/11/17 22:33:47 n_hibma Exp $ */
/*
@@ -352,9 +352,6 @@ usbd_reset_port(usbd_device_handle dev, int port, usb_port_status_t *ps)
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);
@@ -478,36 +475,13 @@ usbd_fill_iface_data(usbd_device_handle dev, int ifaceidx, int altidx)
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");
+ DPRINTF(("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;
p += ed->bLength;
}
@@ -751,6 +725,7 @@ usbd_setup_pipe(usbd_device_handle dev, usbd_interface_handle iface,
p->repeat = 0;
p->interval = ival;
SIMPLEQ_INIT(&p->queue);
+ usb_callout_init(p->abort_handle);
err = dev->bus->methods->open_pipe(p);
if (err) {
DPRINTFN(-1,("usbd_setup_pipe: endpoint=0x%x failed, error="
@@ -770,7 +745,6 @@ usbd_setup_pipe(usbd_device_handle dev, usbd_interface_handle iface,
void
usbd_kill_pipe(usbd_pipe_handle pipe)
{
- usbd_abort_pipe(pipe);
pipe->methods->close(pipe);
pipe->endpoint->refcnt--;
free(pipe, M_USB);
@@ -953,17 +927,16 @@ usbd_probe_and_attach(device_ptr_t parent, usbd_device_handle dev,
*/
usbd_status
usbd_new_device(device_ptr_t parent, usbd_bus_handle bus, int depth,
- int speed, int port, struct usbd_port *up)
+ int lowspeed, int port, struct usbd_port *up)
{
usbd_device_handle dev;
- struct usbd_device *hub;
usb_device_descriptor_t *dd;
usbd_status err;
int addr;
int i;
- DPRINTF(("usbd_new_device bus=%p port=%d depth=%d speed=%d\n",
- bus, port, depth, speed));
+ DPRINTF(("usbd_new_device bus=%p port=%d depth=%d lowspeed=%d\n",
+ bus, port, depth, lowspeed));
addr = usbd_getnewaddr(bus);
if (addr < 0) {
printf("%s: No free USB addresses, new device ignored.\n",
@@ -974,7 +947,7 @@ usbd_new_device(device_ptr_t parent, usbd_bus_handle bus, int depth,
dev = malloc(sizeof *dev, M_USB, M_NOWAIT);
if (dev == NULL)
return (USBD_NOMEM);
- memset(dev, 0, sizeof *dev);
+ memset(dev, 0, sizeof(*dev));
dev->bus = bus;
@@ -992,15 +965,9 @@ usbd_new_device(device_ptr_t parent, usbd_bus_handle bus, int depth,
dev->quirks = &usbd_no_quirk;
dev->address = USB_START_ADDR;
dev->ddesc.bMaxPacketSize = 0;
+ dev->lowspeed = lowspeed != 0;
dev->depth = depth;
dev->powersrc = up;
- dev->myhub = up->parent;
- for (hub = up->parent;
- hub != NULL && hub->speed != USB_SPEED_HIGH;
- hub = hub->myhub)
- ;
- dev->myhighhub = hub;
- dev->speed = speed;
dev->langid = USBD_NOLANG;
dev->cookie.cookie = ++usb_cookie_no;
@@ -1029,22 +996,11 @@ usbd_new_device(device_ptr_t parent, usbd_bus_handle bus, int depth,
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",
+ "subclass=%d, protocol=%d, maxpacket=%d, len=%d, ls=%d\n",
addr,UGETW(dd->bcdUSB), dd->bDeviceClass, dd->bDeviceSubClass,
dd->bDeviceProtocol, dd->bMaxPacketSize, dd->bLength,
- dev->speed));
+ dev->lowspeed));
if (dd->bDescriptorType != UDESC_DEVICE) {
/* Illegal device descriptor */
@@ -1247,7 +1203,7 @@ usbd_fill_deviceinfo(usbd_device_handle dev, struct usb_device_info *di,
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;
+ di->udi_lowspeed = dev->lowspeed;
if (dev->subdevs != NULL) {
for (i = 0; dev->subdevs[i] &&
@@ -1350,7 +1306,13 @@ usb_disconnect_port(struct usbd_port *up, device_ptr_t parent)
if (up->portno != 0)
printf(" port %d", up->portno);
printf(" (addr %d) disconnected\n", dev->address);
+#if defined(__NetBSD__) || defined(__OpenBSD__)
config_detach(dev->subdevs[i], DETACH_FORCE);
+#elif defined(__FreeBSD__)
+ device_delete_child(device_get_parent(dev->subdevs[i]),
+ dev->subdevs[i]);
+#endif
+
}
}
diff --git a/sys/dev/usb/usbdevs.h b/sys/dev/usb/usbdevs.h
index 875ba4dfa7a..fef26f39c7b 100644
--- a/sys/dev/usb/usbdevs.h
+++ b/sys/dev/usb/usbdevs.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: usbdevs.h,v 1.44 2002/05/07 18:08:05 nate Exp $ */
+/* $OpenBSD: usbdevs.h,v 1.45 2002/05/07 18:29:18 nate Exp $ */
/*
* THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.
diff --git a/sys/dev/usb/usbdevs_data.h b/sys/dev/usb/usbdevs_data.h
index e7096569e4c..a4715eb8da9 100644
--- a/sys/dev/usb/usbdevs_data.h
+++ b/sys/dev/usb/usbdevs_data.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: usbdevs_data.h,v 1.44 2002/05/07 18:08:05 nate Exp $ */
+/* $OpenBSD: usbdevs_data.h,v 1.45 2002/05/07 18:29:18 nate Exp $ */
/*
* THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.
diff --git a/sys/dev/usb/usbdi.c b/sys/dev/usb/usbdi.c
index 856a20cd905..012409d05d3 100644
--- a/sys/dev/usb/usbdi.c
+++ b/sys/dev/usb/usbdi.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: usbdi.c,v 1.17 2002/05/07 18:08:05 nate Exp $ */
-/* $NetBSD: usbdi.c,v 1.99 2002/02/28 04:49:16 thorpej Exp $ */
+/* $OpenBSD: usbdi.c,v 1.18 2002/05/07 18:29:19 nate Exp $ */
+/* $NetBSD: usbdi.c,v 1.81 2001/04/17 00:05:33 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/usbdi.c,v 1.28 1999/11/17 22:33:49 n_hibma Exp $ */
/*
@@ -79,10 +79,10 @@ extern int usbdebug;
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);
+(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);
+(usbd_interface_handle, u_int8_t, u_int8_t, usbd_pipe_handle *, int);
Static int usbd_nbuses = 0;
@@ -109,42 +109,7 @@ usbd_xfer_isread(usbd_xfer_handle xfer)
}
#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);
void
usbd_dump_queue(usbd_pipe_handle pipe)
{
@@ -157,21 +122,6 @@ usbd_dump_queue(usbd_pipe_handle pipe)
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
@@ -271,6 +221,12 @@ usbd_close_pipe(usbd_pipe_handle pipe)
LIST_REMOVE(pipe, next);
pipe->endpoint->refcnt--;
pipe->methods->close(pipe);
+#if defined(__NetBSD__) && defined(DIAGNOSTIC)
+ if (callout_pending(&pipe->abort_handle)) {
+ callout_stop(&pipe->abort_handle);
+ printf("usbd_close_pipe: abort_handle pending");
+ }
+#endif
if (pipe->intrxfer != NULL)
usbd_free_xfer(pipe->intrxfer);
free(pipe, M_USB);
@@ -359,13 +315,9 @@ usbd_alloc_buffer(usbd_xfer_handle xfer, u_int32_t size)
struct usbd_bus *bus = xfer->device->bus;
usbd_status err;
-#ifdef DIAGNOSTIC
- if (xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF))
- printf("usbd_alloc_buffer: xfer already has a buffer\n");
-#endif
err = bus->methods->allocm(bus, &xfer->dmabuf, size);
if (err)
- return (NULL);
+ return (0);
xfer->rqflags |= URQ_DEV_DMABUF;
return (KERNADDR(&xfer->dmabuf));
}
@@ -560,7 +512,7 @@ usbd_clear_endpoint_stall(usbd_pipe_handle pipe)
DPRINTFN(8, ("usbd_clear_endpoint_stall\n"));
/*
- * Clearing en endpoint stall resets the endpoint toggle, so
+ * Clearing en endpoint stall resets the enpoint toggle, so
* do the same to the HC toggle.
*/
pipe->methods->cleartoggle(pipe);
@@ -599,6 +551,7 @@ usbd_clear_endpoint_stall_async(usbd_pipe_handle pipe)
return (err);
}
+void usbd_clear_endpoint_toggle(usbd_pipe_handle pipe); /* XXXXX */
void
usbd_clear_endpoint_toggle(usbd_pipe_handle pipe)
{
@@ -627,11 +580,12 @@ usbd_interface_count(usbd_device_handle dev, u_int8_t *count)
return (USBD_NORMAL_COMPLETION);
}
-void
+usbd_status
usbd_interface2device_handle(usbd_interface_handle iface,
usbd_device_handle *dev)
{
*dev = iface->device;
+ return (USBD_NORMAL_COMPLETION);
}
usbd_status
@@ -765,13 +719,6 @@ usb_transfer_complete(usbd_xfer_handle xfer)
DPRINTFN(5, ("usb_transfer_complete: pipe=%p xfer=%p status=%d "
"actlen=%d\n", pipe, xfer, xfer->status, xfer->actlen));
-#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) {
@@ -811,7 +758,6 @@ usb_transfer_complete(usbd_xfer_handle xfer)
if (xfer != SIMPLEQ_FIRST(&pipe->queue))
printf("usb_transfer_complete: bad dequeue %p != %p\n",
xfer, SIMPLEQ_FIRST(&pipe->queue));
- xfer->busy_free = XFER_BUSY;
#endif
SIMPLEQ_REMOVE_HEAD(&pipe->queue, xfer, next);
}
@@ -865,14 +811,6 @@ usb_insert_transfer(usbd_xfer_handle xfer)
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();
SIMPLEQ_INSERT_TAIL(&pipe->queue, xfer, next);
if (pipe->running)
@@ -923,22 +861,20 @@ usbd_start_next(usbd_pipe_handle pipe)
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));
+ return (usbd_do_request_flags(dev, req, data, 0, 0));
}
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)
+ void *data, u_int16_t flags, int *actlen)
{
return (usbd_do_request_flags_pipe(dev, dev->default_pipe, req,
- data, flags, actlen, timo));
+ data, flags, actlen));
}
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)
+ usb_device_request_t *req, void *data, u_int16_t flags, int *actlen)
{
usbd_xfer_handle xfer;
usbd_status err;
@@ -957,7 +893,7 @@ usbd_do_request_flags_pipe(usbd_device_handle dev, usbd_pipe_handle pipe,
xfer = usbd_alloc_xfer(dev);
if (xfer == NULL)
return (USBD_NOMEM);
- usbd_setup_default_xfer(xfer, dev, 0, timeout, req,
+ usbd_setup_default_xfer(xfer, dev, 0, USBD_DEFAULT_TIMEOUT, req,
data, UGETW(req->wLength), flags, 0);
xfer->pipe = pipe;
err = usbd_sync_transfer(xfer);
@@ -1088,9 +1024,6 @@ usbd_set_polling(usbd_device_handle dev, int 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);
}
@@ -1135,7 +1068,7 @@ usb_match_device(const struct usb_devno *tbl, u_int nentries, u_int sz,
if (tbl->ud_vendor == vendor &&
(tproduct == product || tproduct == USB_PRODUCT_ANY))
return (tbl);
- tbl = (const struct usb_devno *)((const char *)tbl + sz);
+ tbl = (struct usb_devno *)((char *)tbl + sz);
}
return (NULL);
}
diff --git a/sys/dev/usb/usbdi.h b/sys/dev/usb/usbdi.h
index 0a571b0bcee..77c4dd6d425 100644
--- a/sys/dev/usb/usbdi.h
+++ b/sys/dev/usb/usbdi.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: usbdi.h,v 1.15 2002/05/07 18:08:05 nate Exp $ */
-/* $NetBSD: usbdi.h,v 1.61 2002/02/11 15:20:23 augustss Exp $ */
+/* $OpenBSD: usbdi.h,v 1.16 2002/05/07 18:29:19 nate Exp $ */
+/* $NetBSD: usbdi.h,v 1.53 2001/08/15 00:04:59 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/usbdi.h,v 1.18 1999/11/17 22:33:49 n_hibma Exp $ */
/*
@@ -48,25 +48,25 @@ 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 */
+ USBD_IN_PROGRESS,
/* 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_PENDING_REQUESTS,
+ USBD_NOT_STARTED,
+ USBD_INVAL,
+ USBD_NOMEM,
+ USBD_CANCELLED,
+ USBD_BAD_ADDRESS,
+ USBD_IN_USE,
+ USBD_NO_ADDR,
+ USBD_SET_ADDR_FAILED,
+ USBD_NO_POWER,
+ USBD_TOO_DEEP,
+ USBD_IOERROR,
+ USBD_NOT_CONFIGURED,
+ USBD_TIMEOUT,
+ USBD_SHORT_XFER,
+ USBD_STALLED,
+ USBD_INTERRUPTED,
USBD_ERROR_MAX /* must be last */
} usbd_status;
@@ -117,17 +117,16 @@ usb_endpoint_descriptor_t *usbd_interface2endpoint_descriptor
usbd_status usbd_abort_pipe(usbd_pipe_handle pipe);
usbd_status usbd_clear_endpoint_stall(usbd_pipe_handle pipe);
usbd_status usbd_clear_endpoint_stall_async(usbd_pipe_handle pipe);
-void usbd_clear_endpoint_toggle(usbd_pipe_handle pipe);
usbd_status usbd_endpoint_count(usbd_interface_handle dev, u_int8_t *count);
usbd_status usbd_interface_count(usbd_device_handle dev, u_int8_t *count);
-void usbd_interface2device_handle(usbd_interface_handle iface,
- usbd_device_handle *dev);
+usbd_status usbd_interface2device_handle(usbd_interface_handle iface,
+ usbd_device_handle *dev);
usbd_status usbd_device2interface_handle(usbd_device_handle dev,
u_int8_t ifaceno, usbd_interface_handle *iface);
usbd_device_handle usbd_pipe2device_handle(usbd_pipe_handle);
-void *usbd_alloc_buffer(usbd_xfer_handle xfer, u_int32_t size);
-void usbd_free_buffer(usbd_xfer_handle xfer);
+void *usbd_alloc_buffer(usbd_xfer_handle req, u_int32_t size);
+void usbd_free_buffer(usbd_xfer_handle req);
void *usbd_get_buffer(usbd_xfer_handle xfer);
usbd_status usbd_sync_transfer(usbd_xfer_handle req);
usbd_status usbd_open_pipe_intr(usbd_interface_handle iface, u_int8_t address,
@@ -140,11 +139,10 @@ usbd_status usbd_do_request_async(usbd_device_handle pipe,
usb_device_request_t *req, void *data);
usbd_status usbd_do_request_flags(usbd_device_handle pipe,
usb_device_request_t *req,
- void *data, u_int16_t flags, int*, u_int32_t);
+ void *data, u_int16_t flags, int *);
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);
+ usb_device_request_t *req, void *data, u_int16_t flags, int *actlen);
usb_interface_descriptor_t *usbd_get_interface_descriptor
(usbd_interface_handle iface);
usb_config_descriptor_t *usbd_get_config_descriptor(usbd_device_handle dev);
@@ -152,7 +150,7 @@ usb_device_descriptor_t *usbd_get_device_descriptor(usbd_device_handle dev);
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 iface, u_int8_t *aiface);
-void usbd_fill_deviceinfo(usbd_device_handle, struct usb_device_info *, int);
+void usbd_fill_deviceinfo(usbd_device_handle dev, struct usb_device_info *di, int);
int usbd_get_interface_altindex(usbd_interface_handle iface);
usb_interface_descriptor_t *usbd_find_idesc(usb_config_descriptor_t *cd,
@@ -269,15 +267,14 @@ struct usb_attach_arg {
int usbd_driver_load(module_t mod, int what, void *arg);
#endif
-/* 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
+/*
+ * XXX
+ * splusb MUST be the lowest level interrupt so that within USB callbacks
+ * the level can be raised the appropriate level.
+ * XXX Should probably use a softsplusb.
+ */
+/* XXX */
#define splusb splbio
-#endif /* USB_USE_SOFTINTR */
#define splhardusb splbio
#define IPL_USB IPL_BIO
+/* XXX */
diff --git a/sys/dev/usb/usbdi_util.c b/sys/dev/usb/usbdi_util.c
index cfe02dfea0f..ae09e7c919e 100644
--- a/sys/dev/usb/usbdi_util.c
+++ b/sys/dev/usb/usbdi_util.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: usbdi_util.c,v 1.12 2002/05/07 18:08:05 nate Exp $ */
-/* $NetBSD: usbdi_util.c,v 1.39 2001/12/27 11:24:42 augustss Exp $ */
+/* $OpenBSD: usbdi_util.c,v 1.13 2002/05/07 18:29:19 nate Exp $ */
+/* $NetBSD: usbdi_util.c,v 1.35 2001/10/26 17:58:21 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/usbdi_util.c,v 1.14 1999/11/17 22:33:50 n_hibma Exp $ */
/*
@@ -220,25 +220,6 @@ usbd_set_port_feature(usbd_device_handle dev, int port, int sel)
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)
@@ -246,12 +227,15 @@ 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;
+ usbd_status err;
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);
+ err = usbd_interface2device_handle(iface, &dev);
+ if (err)
+ return (err);
req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
req.bRequest = UR_SET_PROTOCOL;
USETW(req.wValue, report);
@@ -267,11 +251,14 @@ usbd_set_report(usbd_interface_handle iface, int type, int id, void *data,
usb_interface_descriptor_t *ifd = usbd_get_interface_descriptor(iface);
usbd_device_handle dev;
usb_device_request_t req;
+ usbd_status err;
DPRINTFN(4, ("usbd_set_report: len=%d\n", len));
if (ifd == NULL)
return (USBD_IOERROR);
- usbd_interface2device_handle(iface, &dev);
+ err = usbd_interface2device_handle(iface, &dev);
+ if (err)
+ return (err);
req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
req.bRequest = UR_SET_REPORT;
USETW2(req.wValue, type, id);
@@ -281,17 +268,20 @@ usbd_set_report(usbd_interface_handle iface, int type, int id, void *data,
}
usbd_status
-usbd_set_report_async(usbd_interface_handle iface, int type, int id,
- void *data, int len)
+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;
+ usbd_status err;
DPRINTFN(4, ("usbd_set_report_async: len=%d\n", len));
if (ifd == NULL)
return (USBD_IOERROR);
- usbd_interface2device_handle(iface, &dev);
+ err = usbd_interface2device_handle(iface, &dev);
+ if (err)
+ return (err);
req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
req.bRequest = UR_SET_REPORT;
USETW2(req.wValue, type, id);
@@ -307,11 +297,14 @@ usbd_get_report(usbd_interface_handle iface, int type, int id, void *data,
usb_interface_descriptor_t *ifd = usbd_get_interface_descriptor(iface);
usbd_device_handle dev;
usb_device_request_t req;
+ usbd_status err;
DPRINTFN(4, ("usbd_get_report: len=%d\n", len));
if (ifd == NULL)
return (USBD_IOERROR);
- usbd_interface2device_handle(iface, &dev);
+ err = usbd_interface2device_handle(iface, &dev);
+ if (err)
+ return (err);
req.bmRequestType = UT_READ_CLASS_INTERFACE;
req.bRequest = UR_GET_REPORT;
USETW2(req.wValue, type, id);
@@ -326,11 +319,14 @@ 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;
+ usbd_status err;
DPRINTFN(4, ("usbd_set_idle: %d %d\n", duration, id));
if (ifd == NULL)
return (USBD_IOERROR);
- usbd_interface2device_handle(iface, &dev);
+ err = usbd_interface2device_handle(iface, &dev);
+ if (err)
+ return (err);
req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
req.bRequest = UR_SET_IDLE;
USETW2(req.wValue, duration, id);
@@ -361,10 +357,13 @@ usbd_get_hid_descriptor(usbd_interface_handle ifc)
usb_config_descriptor_t *cdesc;
usb_hid_descriptor_t *hd;
char *p, *end;
+ usbd_status err;
if (idesc == NULL)
return (0);
- usbd_interface2device_handle(ifc, &dev);
+ err = usbd_interface2device_handle(ifc, &dev);
+ if (err)
+ return (0);
cdesc = usbd_get_config_descriptor(dev);
p = (char *)idesc + idesc->bLength;
@@ -389,7 +388,9 @@ usbd_read_report_desc(usbd_interface_handle ifc, void **descp, int *sizep,
usbd_device_handle dev;
usbd_status err;
- usbd_interface2device_handle(ifc, &dev);
+ err = usbd_interface2device_handle(ifc, &dev);
+ if (err)
+ return (err);
id = usbd_get_interface_descriptor(ifc);
if (id == NULL)
return (USBD_INVAL);
@@ -481,21 +482,3 @@ usb_detach_wakeup(device_ptr_t dv)
DPRINTF(("usb_detach_wakeup: for %s\n", USBDEVPTRNAME(dv)));
wakeup(dv);
}
-
-usb_descriptor_t *
-usb_find_desc(usbd_device_handle dev, int type)
-{
- 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)
- return (desc);
- p += desc->bLength;
- }
-
- return (NULL);
-}
diff --git a/sys/dev/usb/usbdi_util.h b/sys/dev/usb/usbdi_util.h
index 6bca3e54e7c..aef2affe9f7 100644
--- a/sys/dev/usb/usbdi_util.h
+++ b/sys/dev/usb/usbdi_util.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: usbdi_util.h,v 1.9 2002/05/07 18:08:05 nate Exp $ */
-/* $NetBSD: usbdi_util.h,v 1.27 2002/03/17 18:02:53 augustss Exp $ */
+/* $OpenBSD: usbdi_util.h,v 1.10 2002/05/07 18:29:19 nate Exp $ */
+/* $NetBSD: usbdi_util.h,v 1.23 2001/10/26 17:58:22 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/usbdi_util.h,v 1.9 1999/11/17 22:33:50 n_hibma Exp $ */
/*
@@ -53,9 +53,8 @@ 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_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);
@@ -85,4 +84,3 @@ usbd_status usbd_bulk_transfer(usbd_xfer_handle xfer, usbd_pipe_handle pipe,
void usb_detach_wait(device_ptr_t);
void usb_detach_wakeup(device_ptr_t);
-usb_descriptor_t *usb_find_desc(usbd_device_handle dev, int type);
diff --git a/sys/dev/usb/usbdivar.h b/sys/dev/usb/usbdivar.h
index d5e53c3e0f1..5bf053ed879 100644
--- a/sys/dev/usb/usbdivar.h
+++ b/sys/dev/usb/usbdivar.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: usbdivar.h,v 1.15 2002/05/07 18:08:05 nate Exp $ */
-/* $NetBSD: usbdivar.h,v 1.69 2001/12/27 18:43:46 augustss Exp $ */
+/* $OpenBSD: usbdivar.h,v 1.16 2002/05/07 18:29:19 nate Exp $ */
+/* $NetBSD: usbdivar.h,v 1.63 2001/01/21 19:00:06 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/usbdivar.h,v 1.11 1999/11/17 22:33:51 n_hibma Exp $ */
/*
@@ -80,7 +80,7 @@ struct usbd_port {
u_int8_t portno;
u_int8_t restartcnt;
#define USBD_RESTART_MAX 5
- struct usbd_device *device; /* Connected device */
+ struct usbd_device *device;
struct usbd_device *parent; /* The ports hub */
};
@@ -117,11 +117,13 @@ struct usbd_bus {
#define USBREV_2_0 4
#define USBREV_STR { "unknown", "pre 1.0", "1.0", "1.1", "2.0" }
+#if 0
#ifdef USB_USE_SOFTINTR
#ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
void *soft; /* soft interrupt cookie */
#else
- usb_callout_t softi;
+ struct callout softi;
+#endif
#endif
#endif
@@ -136,15 +138,13 @@ struct usbd_device {
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 lowspeed; /* lowspeed flag */
u_int8_t self_powered; /* flag for self powered */
u_int16_t power; /* mA the device uses */
int16_t langid; /* language for strings */
#define USBD_NOLANG (-1)
usb_event_cookie_t cookie; /* unique connection id */
struct usbd_port *powersrc; /* upstream hub port, or 0 */
- struct usbd_device *myhub; /* upstream hub */
- struct usbd_device *myhighhub; /* closest high speed hub */
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 */
@@ -179,6 +179,8 @@ struct usbd_pipe {
char repeat;
int interval;
+ usb_callout_t abort_handle;
+
/* Filled by HC driver. */
struct usbd_pipe_methods *methods;
};
@@ -197,8 +199,7 @@ struct usbd_xfer {
#ifdef DIAGNOSTIC
u_int32_t busy_free;
#define XFER_FREE 0x46524545
-#define XFER_BUSY 0x42555359
-#define XFER_ONQU 0x4f4e5155
+#define XFER_BUSY 0x42555357
#endif
/* For control pipe */
@@ -227,14 +228,6 @@ struct usbd_xfer {
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);
diff --git a/sys/dev/usb/usbhid.h b/sys/dev/usb/usbhid.h
index cd27fb55643..695c1cdb925 100644
--- a/sys/dev/usb/usbhid.h
+++ b/sys/dev/usb/usbhid.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: usbhid.h,v 1.5 2002/05/07 18:08:05 nate Exp $ */
-/* $NetBSD: usbhid.h,v 1.11 2001/12/28 00:20:24 augustss Exp $ */
+/* $OpenBSD: usbhid.h,v 1.6 2002/05/07 18:29:19 nate Exp $ */
+/* $NetBSD: usbhid.h,v 1.9 2000/09/03 19:09:14 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/usbhid.h,v 1.7 1999/11/17 22:33:51 n_hibma Exp $ */
/*
@@ -165,25 +165,12 @@ typedef struct usb_hid_descriptor {
#define HUD_ERASER 0x0045
#define HUD_TABLET_PICK 0x0046
-/* Usages LEDs */
-#define HUD_LED_NUM_LOCK 0x0001
-#define HUD_LED_CAPS_LOCK 0x0002
-#define HUD_LED_SCROLL_LOCK 0x0003
-#define HUD_LED_COMPOSE 0x0004
-#define HUD_LED_KANA 0x0005
-
-#define HID_USAGE2(p, u) (((p) << 16) | u)
-#define HID_GET_USAGE(u) ((u) & 0xffff)
-#define HID_GET_USAGE_PAGE(u) (((u) >> 16) & 0xffff)
+#define HID_USAGE2(p,u) (((p) << 16) | u)
#define UHID_INPUT_REPORT 0x01
#define UHID_OUTPUT_REPORT 0x02
#define UHID_FEATURE_REPORT 0x03
-#define HCOLL_PHYSICAL 0
-#define HCOLL_APPLICATION 1
-#define HCOLL_LOGICAL 2
-
/* Bits in the input/output/feature items */
#define HIO_CONST 0x001
#define HIO_VARIABLE 0x002
diff --git a/sys/dev/usb/uscanner.c b/sys/dev/usb/uscanner.c
index dad8296523e..2dc011c215b 100644
--- a/sys/dev/usb/uscanner.c
+++ b/sys/dev/usb/uscanner.c
@@ -1,5 +1,6 @@
-/* $OpenBSD: uscanner.c,v 1.6 2002/05/07 18:08:05 nate Exp $ */
-/* $NetBSD: uscanner.c,v 1.27 2002/02/11 10:09:14 augustss Exp $ */
+/* $OpenBSD: uscanner.c,v 1.7 2002/05/07 18:29:19 nate Exp $ */
+/* $NetBSD: uscanner.c,v 1.18 2001/10/11 12:05:10 augustss Exp $ */
+/* $FreeBSD$ */
/*
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -55,11 +56,7 @@
#endif
#include <sys/tty.h>
#include <sys/file.h>
-#if defined(__FreeBSD__) && __FreeBSD_version >= 500014
-#include <sys/selinfo.h>
-#else
#include <sys/select.h>
-#endif
#include <sys/proc.h>
#include <sys/vnode.h>
#include <sys/poll.h>
@@ -80,128 +77,104 @@ int uscannerdebug = 0;
#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[] = {
- /* Acer Peripherals */
- {{ USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_320U }, 0 },
- {{ USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_640U }, 0 },
- {{ USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_620U }, 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 },
-
- /* Kye */
- {{ USB_VENDOR_KYE, USB_PRODUCT_KYE_VIVIDPRO }, 0 },
-
- /* HP */
- {{ 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_S20 }, 0 },
- {{ USB_VENDOR_HP, USB_PRODUCT_HP_5200C }, 0 },
+static const struct scanner_id {
+ uint16_t vendor;
+ uint16_t product;
+} scanner_ids [] = {
+ /* Acer Peripherals */
+ { USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_320U },
+ { USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_640U },
+ { USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_620U },
+ { USB_VENDOR_ACERP, USB_PRODUCT_ACERP_ACERSCAN_C310U },
+
+ /* AGFA */
+ { USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCAN1212U },
+ { USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCAN1212U2 },
+ { USB_VENDOR_AGFA, USB_PRODUCT_AGFA_SNAPSCANTOUCH },
+
+ /* Kye */
+ { USB_VENDOR_KYE, USB_PRODUCT_KYE_VIVIDPRO },
+
+ /* HP */
+ { USB_VENDOR_HP, USB_PRODUCT_HP_3300C },
+ { USB_VENDOR_HP, USB_PRODUCT_HP_3400CSE },
+ { USB_VENDOR_HP, USB_PRODUCT_HP_4100C },
+ { USB_VENDOR_HP, USB_PRODUCT_HP_4200C },
+ { USB_VENDOR_HP, USB_PRODUCT_HP_S20 },
+ { USB_VENDOR_HP, USB_PRODUCT_HP_5200C },
#if 0
- /* Handled by usscanner */
- {{ USB_VENDOR_HP, USB_PRODUCT_HP_5300C }, 0 },
+ { USB_VENDOR_HP, USB_PRODUCT_HP_5300C },
#endif
- {{ USB_VENDOR_HP, USB_PRODUCT_HP_6200C }, 0 },
- {{ USB_VENDOR_HP, USB_PRODUCT_HP_6300C }, 0 },
+ { USB_VENDOR_HP, USB_PRODUCT_HP_6200C },
+ { USB_VENDOR_HP, USB_PRODUCT_HP_6300C },
+
+ /* Avision */
+ { USB_VENDOR_AVISION, USB_PRODUCT_AVISION_1200U },
#if 0
- /* XXX Should be handled by usscanner */
- /* 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 },
+ /* Microtek */
+ { USB_VENDOR_SCANLOGIC, USB_PRODUCT_SCANLOGIC_336CX },
+ { USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_X6U },
+ { USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_336CX },
+ { USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_336CX2 },
+ { USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_C6 },
+ { USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_V6USL },
+ { USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_V6USL2 },
+ { USB_VENDOR_MICROTEK, USB_PRODUCT_MICROTEK_V6UL },
#endif
- /* Mustek */
- {{ USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_1200CU }, 0 },
- {{ USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_BEARPAW1200F }, 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 },
-
- /* 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_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_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_GT9700F }, USC_KEEP_OPEN },
-
- /* 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_ASTRA2200U }, 0 },
- {{ USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA3400 }, 0 },
-
- /* Visioneer */
- {{ 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 },
-
+ /* Mustek */
+ { USB_VENDOR_MUSTEK, USB_PRODUCT_MUSTEK_1200CU },
+ { USB_VENDOR_NATIONAL, USB_PRODUCT_NATIONAL_BEARPAW1200 },
+ { USB_VENDOR_NATIONAL, USB_PRODUCT_MUSTEK_600CU },
+ { USB_VENDOR_NATIONAL, USB_PRODUCT_MUSTEK_1200USB },
+ { USB_VENDOR_NATIONAL, USB_PRODUCT_MUSTEK_1200UB },
+
+ /* Primax */
+ { USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2X300 },
+ { USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2E300 },
+ { USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2300 },
+ { USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2E3002 },
+ { USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_9600 },
+ { USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_600U },
+ { USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_19200 },
+ { USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_1200U },
+ { USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G600 },
+ { USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_636I },
+ { USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2600 },
+ { USB_VENDOR_PRIMAX, USB_PRODUCT_PRIMAX_G2E600 },
+
+ /* Epson */
+ { USB_VENDOR_EPSON, USB_PRODUCT_EPSON_636 },
+ { USB_VENDOR_EPSON, USB_PRODUCT_EPSON_610 },
+ { USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1200 },
+ { USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1240 },
+ { USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1600 },
+ { USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1640 },
+ { USB_VENDOR_EPSON, USB_PRODUCT_EPSON_640U },
+ { USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1650 },
+
+ /* UMAX */
+ { USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA1220U },
+ { USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA1236U },
+ { USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA2000U },
+ { USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA2200U },
+ { USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA3400 },
+
+ /* Visioneer */
+ { USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_5300 },
+ { USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_7600 },
+ { USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_6100 },
+ { USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_6200 },
+ { USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_8100 },
+ { USB_VENDOR_VISIONEER, USB_PRODUCT_VISIONEER_8600 },
+
+ /* Canon */
+ { USB_VENDOR_CANON, USB_PRODUCT_CANON_N656U },
+
+ { 0, 0 }
};
-#define uscanner_lookup(v, p) ((const struct uscan_info *)usb_lookup(uscanner_devs, v, p))
#define USCANNER_BUFFERSIZE 1024
@@ -210,8 +183,6 @@ struct uscanner_softc {
usbd_device_handle sc_udev;
usbd_interface_handle sc_iface;
- u_int sc_dev_flags;
-
usbd_pipe_handle sc_bulkin_pipe;
int sc_bulkin;
usbd_xfer_handle sc_bulkin_xfer;
@@ -258,9 +229,7 @@ Static struct cdevsw uscanner_cdevsw = {
/* dump */ nodump,
/* psize */ nopsize,
/* flags */ 0,
-#if !defined(__FreeBSD__) || (__FreeBSD__ < 5)
/* bmaj */ -1
-#endif
};
#endif
@@ -275,12 +244,19 @@ USB_DECLARE_DRIVER(uscanner);
USB_MATCH(uscanner)
{
USB_MATCH_START(uscanner, uaa);
+ int i;
if (uaa->iface != NULL)
return UMATCH_NONE;
- return (uscanner_lookup(uaa->vendor, uaa->product) != NULL ?
- UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
+ for (i = 0; scanner_ids[i].vendor != 0; i++) {
+ if (scanner_ids[i].vendor == uaa->vendor &&
+ scanner_ids[i].product == uaa->product) {
+ return (UMATCH_VENDOR_PRODUCT);
+ }
+ }
+
+ return (UMATCH_NONE);
}
USB_ATTACH(uscanner)
@@ -296,8 +272,6 @@ USB_ATTACH(uscanner)
USB_ATTACH_SETUP;
printf("%s: %s\n", USBDEVNAME(sc->sc_dev), devinfo);
- sc->sc_dev_flags = uscanner_lookup(uaa->vendor, uaa->product)->flags;
-
sc->sc_udev = uaa->device;
err = usbd_set_config_no(uaa->device, 1, 1); /* XXX */
@@ -361,7 +335,11 @@ USB_ATTACH(uscanner)
}
int
-uscanneropen(dev_t dev, int flag, int mode, usb_proc_ptr p)
+uscanneropen(dev, flag, mode, p)
+ dev_t dev;
+ int flag;
+ int mode;
+ struct proc *p;
{
struct uscanner_softc *sc;
int unit = USCANNERUNIT(dev);
@@ -388,25 +366,21 @@ uscanneropen(dev_t dev, int flag, int mode, usb_proc_ptr p)
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",
- USBDEVNAME(sc->sc_dev), sc->sc_bulkin);
- uscanner_do_close(sc);
- return (EIO);
- }
+ 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",
+ USBDEVNAME(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",
- USBDEVNAME(sc->sc_dev), sc->sc_bulkout);
- uscanner_do_close(sc);
- return (EIO);
- }
+ 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",
+ USBDEVNAME(sc->sc_dev), sc->sc_bulkout);
+ uscanner_do_close(sc);
+ return (EIO);
}
sc->sc_bulkin_xfer = usbd_alloc_xfer(sc->sc_udev);
@@ -424,7 +398,11 @@ uscanneropen(dev_t dev, int flag, int mode, usb_proc_ptr p)
}
int
-uscannerclose(dev_t dev, int flag, int mode, usb_proc_ptr p)
+uscannerclose(dev, flag, mode, p)
+ dev_t dev;
+ int flag;
+ int mode;
+ struct proc *p;
{
struct uscanner_softc *sc;
@@ -457,17 +435,15 @@ uscanner_do_close(struct uscanner_softc *sc)
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_pipe) {
+ usbd_abort_pipe(sc->sc_bulkin_pipe);
+ usbd_close_pipe(sc->sc_bulkin_pipe);
+ sc->sc_bulkin_pipe = NULL;
+ }
+ if (sc->sc_bulkout_pipe) {
+ usbd_abort_pipe(sc->sc_bulkout_pipe);
+ usbd_close_pipe(sc->sc_bulkout_pipe);
+ sc->sc_bulkout_pipe = NULL;
}
if (sc->sc_bulkin_buffer) {
@@ -483,7 +459,10 @@ uscanner_do_close(struct uscanner_softc *sc)
}
Static int
-uscanner_do_read(struct uscanner_softc *sc, struct uio *uio, int flag)
+uscanner_do_read(sc, uio, flag)
+ struct uscanner_softc *sc;
+ struct uio *uio;
+ int flag;
{
u_int32_t n, tn;
usbd_status err;
@@ -502,7 +481,7 @@ uscanner_do_read(struct uscanner_softc *sc, struct uio *uio, int flag)
sc->sc_bulkin_xfer, sc->sc_bulkin_pipe,
USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT,
sc->sc_bulkin_buffer, &tn,
- "uscnrb");
+ "uscannerrb");
if (err) {
if (err == USBD_INTERRUPTED)
error = EINTR;
@@ -522,7 +501,10 @@ uscanner_do_read(struct uscanner_softc *sc, struct uio *uio, int flag)
}
int
-uscannerread(dev_t dev, struct uio *uio, int flag)
+uscannerread(dev, uio, flag)
+ dev_t dev;
+ struct uio *uio;
+ int flag;
{
struct uscanner_softc *sc;
int error;
@@ -538,7 +520,10 @@ uscannerread(dev_t dev, struct uio *uio, int flag)
}
Static int
-uscanner_do_write(struct uscanner_softc *sc, struct uio *uio, int flag)
+uscanner_do_write(sc, uio, flag)
+ struct uscanner_softc *sc;
+ struct uio *uio;
+ int flag;
{
u_int32_t n;
int error = 0;
@@ -558,7 +543,7 @@ uscanner_do_write(struct uscanner_softc *sc, struct uio *uio, int flag)
sc->sc_bulkout_xfer, sc->sc_bulkout_pipe,
0, USBD_NO_TIMEOUT,
sc->sc_bulkout_buffer, &n,
- "uscnwb");
+ "uscannerwb");
if (err) {
if (err == USBD_INTERRUPTED)
error = EINTR;
@@ -572,7 +557,10 @@ uscanner_do_write(struct uscanner_softc *sc, struct uio *uio, int flag)
}
int
-uscannerwrite(dev_t dev, struct uio *uio, int flag)
+uscannerwrite(dev, uio, flag)
+ dev_t dev;
+ struct uio *uio;
+ int flag;
{
struct uscanner_softc *sc;
int error;
@@ -588,7 +576,9 @@ uscannerwrite(dev_t dev, struct uio *uio, int flag)
#if defined(__NetBSD__) || defined(__OpenBSD__)
int
-uscanner_activate(device_ptr_t self, enum devact act)
+uscanner_activate(self, act)
+ device_ptr_t self;
+ enum devact act;
{
struct uscanner_softc *sc = (struct uscanner_softc *)self;
@@ -623,12 +613,11 @@ USB_DETACH(uscanner)
#endif
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)
+ if (sc->sc_bulkin_pipe)
usbd_abort_pipe(sc->sc_bulkin_pipe);
- if (sc->sc_bulkout_pipe != NULL)
+ if (sc->sc_bulkout_pipe)
usbd_abort_pipe(sc->sc_bulkout_pipe);
s = splusb();
@@ -663,7 +652,10 @@ USB_DETACH(uscanner)
}
int
-uscannerpoll(dev_t dev, int events, usb_proc_ptr p)
+uscannerpoll(dev, events, p)
+ dev_t dev;
+ int events;
+ struct proc *p;
{
struct uscanner_softc *sc;
int revents = 0;
@@ -685,7 +677,7 @@ uscannerpoll(dev_t dev, int events, usb_proc_ptr p)
}
int
-uscannerioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, usb_proc_ptr p)
+uscannerioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
{
return (EINVAL);
}
diff --git a/sys/dev/usb/usscanner.c b/sys/dev/usb/usscanner.c
index 1d7a368d709..c8c7a530c34 100644
--- a/sys/dev/usb/usscanner.c
+++ b/sys/dev/usb/usscanner.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: usscanner.c,v 1.4 2002/05/07 18:08:05 nate Exp $ */
+/* $OpenBSD: usscanner.c,v 1.5 2002/05/07 18:29:19 nate Exp $ */
/* $NetBSD: usscanner.c,v 1.6 2001/01/23 14:04:14 augustss Exp $ */
/*
@@ -89,22 +89,6 @@ int usscannerdebug = 0;
#define DPRINTFN(n,x)
#endif
-#define XS_CTL_DATA_IN SCSI_DATA_IN
-#define XS_CTL_DATA_OUT SCSI_DATA_OUT
-#define scsipi_adapter scsi_adapter
-#define scsipi_cmd scsi_cmd
-#define scsipi_device scsi_device
-#define scsipi_done scsi_done
-#define scsipi_link scsi_link
-#define scsipi_minphys scsi_minphys
-#define scsipi_sense scsi_sense
-#define scsipi_xfer scsi_xfer
-#define show_scsipi_xs show_scsi_xs
-#define show_scsipi_cmd show_scsi_cmd
-#define xs_control flags
-#define xs_status status
-#define XS_STS_DONE ITSDONE
-#define XS_CTL_POLL SCSI_POLL
#define USSCANNER_CONFIG_NO 1
#define USSCANNER_IFACE_IDX 0
diff --git a/sys/dev/usb/uvisor.c b/sys/dev/usb/uvisor.c
index e44687355f9..53096b1d515 100644
--- a/sys/dev/usb/uvisor.c
+++ b/sys/dev/usb/uvisor.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: uvisor.c,v 1.4 2002/05/07 18:08:05 nate Exp $ */
-/* $NetBSD: uvisor.c,v 1.14 2002/02/27 23:00:03 augustss Exp $ */
+/* $OpenBSD: uvisor.c,v 1.5 2002/05/07 18:29:19 nate Exp $ */
+/* $NetBSD: uvisor.c,v 1.11 2001/01/23 21:56:17 augustss Exp $ */
/*
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -104,6 +104,7 @@ struct uvisor_connection_info {
};
#define UVISOR_CONNECTION_INFO_SIZE 18
+
/* struct uvisor_connection_info.connection[x].port_function_id defines: */
#define UVISOR_FUNCTION_GENERIC 0x00
#define UVISOR_FUNCTION_DEBUGGER 0x01
@@ -111,12 +112,6 @@ struct uvisor_connection_info {
#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 0x14
-
#define UVISORIBUFSIZE 1024
#define UVISOROBUFSIZE 1024
@@ -129,8 +124,6 @@ struct uvisor_softc {
device_ptr_t sc_subdevs[UVISOR_MAX_CONN];
int sc_numcon;
- u_int16_t sc_flags;
-
u_char sc_dying;
};
@@ -151,21 +144,6 @@ struct ucom_methods uvisor_methods = {
NULL,
};
-struct uvisor_type {
- struct usb_devno uv_dev;
- u_int16_t uv_flags;
-#define PALM4 0x0001
-};
-static const struct uvisor_type uvisor_devs[] = {
- {{ USB_VENDOR_HANDSPRING, USB_PRODUCT_HANDSPRING_VISOR }, 0 },
- {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_M500 }, PALM4 },
- {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_M505 }, PALM4 },
- {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_M125 }, PALM4 },
- {{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_40 }, PALM4 },
-/* {{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_25 }, PALM4 },*/
-};
-#define uvisor_lookup(v, p) ((struct uvisor_type *)usb_lookup(uvisor_devs, v, p))
-
USB_DECLARE_DRIVER(uvisor);
USB_MATCH(uvisor)
@@ -178,8 +156,11 @@ USB_MATCH(uvisor)
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);
+ if (uaa->vendor == USB_VENDOR_HANDSPRING &&
+ uaa->product == USB_PRODUCT_HANDSPRING_VISOR)
+ return (UMATCH_VENDOR_PRODUCT);
+
+ return (UMATCH_NONE);
}
USB_ATTACH(uvisor)
@@ -217,8 +198,6 @@ USB_ATTACH(uvisor)
USB_ATTACH_SETUP;
printf("%s: %s\n", devname, devinfo);
- sc->sc_flags = uvisor_lookup(uaa->vendor, uaa->product)->uv_flags;
-
id = usbd_get_interface_descriptor(iface);
sc->sc_udev = dev;
@@ -351,7 +330,6 @@ uvisor_init(struct uvisor_softc *sc, struct uvisor_connection_info *ci)
usb_device_request_t req;
int actlen;
uWord avail;
- char buffer[256];
DPRINTF(("uvisor_init: getting connection info\n"));
req.bmRequestType = UT_READ_VENDOR_ENDPOINT;
@@ -360,30 +338,10 @@ uvisor_init(struct uvisor_softc *sc, struct uvisor_connection_info *ci)
USETW(req.wIndex, 0);
USETW(req.wLength, UVISOR_CONNECTION_INFO_SIZE);
err = usbd_do_request_flags(sc->sc_udev, &req, ci,
- USBD_SHORT_XFER_OK, &actlen, USBD_DEFAULT_TIMEOUT);
+ USBD_SHORT_XFER_OK, &actlen);
if (err)
return (err);
- if (sc->sc_flags & PALM4) {
- /* 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(sc->sc_udev, &req, buffer);
- if (err)
- return (err);
- 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_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;
@@ -416,5 +374,5 @@ uvisor_close(void *addr, int portno)
USETW(req.wIndex, 0);
USETW(req.wLength, UVISOR_CONNECTION_INFO_SIZE);
(void)usbd_do_request_flags(sc->sc_udev, &req, &coninfo,
- USBD_SHORT_XFER_OK, &actlen, USBD_DEFAULT_TIMEOUT);
+ USBD_SHORT_XFER_OK, &actlen);
}